Merge branch 'markus101'

Conflicts:
	NzbDrone.Core/Providers/EpisodeProvider.cs
pull/4/head
kay.one 13 years ago
commit f819a24e65

@ -55,5 +55,17 @@ namespace NzbDrone.Core.Helpers
return String.Format("{0} - S{1:00}E{2} - {3}", erm.SeriesName, erm.EpisodeFile.Episodes[0].SeasonNumber, return String.Format("{0} - S{1:00}E{2} - {3}", erm.SeriesName, erm.EpisodeFile.Episodes[0].SeasonNumber,
epNumberString, epNameString); epNumberString, epNameString);
} }
public static string CleanFilename(string name)
{
string result = name;
string[] badCharacters = {"\\", "/", "<", ">", "?", "*", ":", "|", "\""};
string[] goodCharacters = {"+", "+", "{", "}", "!", "@", "-", "#", "`"};
for (int i = 0; i < badCharacters.Length; i++)
result = result.Replace(badCharacters[i], goodCharacters[i]);
return result.Trim();
}
} }
} }

@ -2,6 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Web.Mvc; using System.Web.Mvc;
using System.Linq;
using NzbDrone.Core.Helpers;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.Jobs; using NzbDrone.Core.Providers.Jobs;
@ -18,11 +20,13 @@ namespace NzbDrone.Web.Controllers
private readonly JobProvider _jobProvider; private readonly JobProvider _jobProvider;
private readonly SyncProvider _syncProvider; private readonly SyncProvider _syncProvider;
private readonly TvDbProvider _tvDbProvider; private readonly TvDbProvider _tvDbProvider;
private readonly DiskProvider _diskProvider;
public AddSeriesController(SyncProvider syncProvider, RootDirProvider rootFolderProvider, public AddSeriesController(SyncProvider syncProvider, RootDirProvider rootFolderProvider,
ConfigProvider configProvider, ConfigProvider configProvider,
QualityProvider qualityProvider, TvDbProvider tvDbProvider, QualityProvider qualityProvider, TvDbProvider tvDbProvider,
SeriesProvider seriesProvider, JobProvider jobProvider) SeriesProvider seriesProvider, JobProvider jobProvider,
DiskProvider diskProvider)
{ {
_syncProvider = syncProvider; _syncProvider = syncProvider;
_rootFolderProvider = rootFolderProvider; _rootFolderProvider = rootFolderProvider;
@ -31,6 +35,7 @@ namespace NzbDrone.Web.Controllers
_tvDbProvider = tvDbProvider; _tvDbProvider = tvDbProvider;
_seriesProvider = seriesProvider; _seriesProvider = seriesProvider;
_jobProvider = jobProvider; _jobProvider = jobProvider;
_diskProvider = diskProvider;
} }
[HttpPost] [HttpPost]
@ -42,25 +47,28 @@ namespace NzbDrone.Web.Controllers
public ActionResult AddNew() public ActionResult AddNew()
{ {
ViewData["RootDirs"] = _rootFolderProvider.GetAll(); var rootDirs =_rootFolderProvider.GetAll().Select(r =>
ViewData["DirSep"] = Path.DirectorySeparatorChar; new RootDirModel
{
Path = r.Path,
CleanPath = r.Path.Replace(Path.DirectorySeparatorChar, '|').Replace(Path.VolumeSeparatorChar, '^').Replace('\'', '`')
}).ToList();
ViewData["RootDirs"] = rootDirs;
ViewData["DirSep"] = Path.DirectorySeparatorChar.ToString().Replace(Path.DirectorySeparatorChar, '|');
var profiles = _qualityProvider.GetAllProfiles(); var defaultQuality = _configProvider.DefaultQualityProfile;
var selectList = new SelectList(profiles, "QualityProfileId", "Name"); var qualityProfiles = _qualityProvider.GetAllProfiles();
var defaultQuality = Convert.ToInt32(_configProvider.DefaultQualityProfile);
var model = new AddNewSeriesModel ViewData["quality"] = new SelectList(
{ qualityProfiles,
DirectorySeparatorChar = Path.DirectorySeparatorChar.ToString(), "QualityProfileId",
RootDirectories = _rootFolderProvider.GetAll(), "Name",
QualityProfileId = defaultQuality, defaultQuality);
QualitySelectList = selectList
};
return View(model); return View();
} }
public ActionResult AddExisting() public ActionResult Add()
{ {
var unmappedList = new List<String>(); var unmappedList = new List<String>();
@ -98,6 +106,20 @@ namespace NzbDrone.Web.Controllers
return PartialView("AddSeriesItem", suggestions); return PartialView("AddSeriesItem", suggestions);
} }
[HttpPost]
public JsonResult AddNewSeries(string rootPath, string seriesName, int seriesId, int qualityProfileId)
{
var path = rootPath.Replace('|', Path.DirectorySeparatorChar).Replace('^', Path.VolumeSeparatorChar).Replace('`', '\'') +
Path.DirectorySeparatorChar + EpisodeRenameHelper.CleanFilename(seriesName);
//Create the folder for the new series and then Add it
_diskProvider.CreateDirectory(path);
_seriesProvider.AddSeries(path, seriesId, qualityProfileId);
ScanNewSeries();
return new JsonResult { Data = "ok" };
}
public JsonResult AddSeries(string path, int seriesId, int qualityProfileId) public JsonResult AddSeries(string path, int seriesId, int qualityProfileId)
{ {
//Get TVDB Series Name //Get TVDB Series Name

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace NzbDrone.Web.Models
{
public class RootDirModel
{
public string Path { get; set; }
public string CleanPath { get; set; }
}
}

@ -237,6 +237,7 @@
<Compile Include="Models\AddExistingManualModel.cs" /> <Compile Include="Models\AddExistingManualModel.cs" />
<Compile Include="Models\AddExistingSeriesModel.cs" /> <Compile Include="Models\AddExistingSeriesModel.cs" />
<Compile Include="Models\AddNewSeriesModel.cs" /> <Compile Include="Models\AddNewSeriesModel.cs" />
<Compile Include="Models\RootDirModel.cs" />
<Compile Include="Models\SabnzbdSettingsModel.cs" /> <Compile Include="Models\SabnzbdSettingsModel.cs" />
<Compile Include="Models\EpisodeSortingModel.cs" /> <Compile Include="Models\EpisodeSortingModel.cs" />
<Compile Include="Models\HistoryModel.cs" /> <Compile Include="Models\HistoryModel.cs" />
@ -662,7 +663,7 @@
<Content Include="Scripts\jquery-tgc-countdown-1.0.js" /> <Content Include="Scripts\jquery-tgc-countdown-1.0.js" />
<Content Include="Scripts\jquery.simpledropdown.js" /> <Content Include="Scripts\jquery.simpledropdown.js" />
<Content Include="Scripts\Notification.js" /> <Content Include="Scripts\Notification.js" />
<Content Include="Views\AddSeries\AddExisting.cshtml" /> <Content Include="Views\AddSeries\Add.cshtml" />
<Content Include="Views\AddSeries\AddNew.cshtml" /> <Content Include="Views\AddSeries\AddNew.cshtml" />
<Content Include="Views\AddSeries\AddSeriesItem.cshtml" /> <Content Include="Views\AddSeries\AddSeriesItem.cshtml" />
<Content Include="Web.config"> <Content Include="Web.config">
@ -870,6 +871,9 @@
<ItemGroup> <ItemGroup>
<Content Include="Views\Series\SingleSeason.cshtml" /> <Content Include="Views\Series\SingleSeason.cshtml" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Views\AddSeries\Copy of AddNew.cshtml" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

@ -0,0 +1,70 @@
@model IEnumerable<String>
<script type="text/javascript" src="../../Scripts/2011.1.315/telerik.window.min.js"></script>
@section TitleContent{
Add Existing Series
}
@section MainContent{
@{ Html.Telerik().Window()
.Name("Window")
.Title("Add New Series")
.Modal(true)
.Buttons(b => b.Close())
.Width(500)
.Height(200)
.Visible(false)
.Draggable(true)
.Resizable(resizing => resizing.Enabled(false))
.LoadContentFrom("AddNew", "AddSeries")
.Render();
}
@if (Model.Count() == 0)
{
@Html.DisplayText("No Series to Add");
}
@Html.Telerik().DropDownList().Name("masterDropbox").BindTo((SelectList) ViewData["qualities"]).HtmlAttributes(
new {style = "width: 100px; margin-left:5px;"}).ClientEvents(events => events.OnChange("masterChanged"))
<button onclick="openAddNewSeries(); return false;" class="listButton" style="margin-left:210px">Add New</button>
@foreach (var path in Model)
{
Html.RenderAction("RenderPartial", "AddSeries", new {path});
}
}
<script type="text/javascript">
function openAddNewSeries() {
var windowElement = $('#Window');
windowElement.data('tWindow').center().open();
}
function closeAddNewSeries() {
var window = $('#Window').data("tWindow");
window.close();
}
function masterChanged() {
var masterQuality = $('#masterDropbox').data("tDropDownList").value();
var qualityDropbox = $(".qualityDropbox");
qualityDropbox.each(function () {
var child = $(this).children("[id^='qualityList']");
var comboBox = child.data("tDropDownList");
comboBox.value(masterQuality);
});
}
function testValue() {
var comboBox = $('#qualityList_tester').data("tDropDownList");
comboBox.value('2');
}
</script>

@ -1,35 +0,0 @@
@model IEnumerable<String>
@section TitleContent{
Add Existing Series
}
@section MainContent{
@if (Model.Count() == 0)
{
@Html.DisplayText("No Series to Add");
}
@Html.DropDownList("masterDropbox", (SelectList) ViewData["qualities"],
new {style = "width: 100px;", id = "masterDropboxId"})
@Html.Telerik().DropDownList().Name("tester").BindTo((SelectList) ViewData["qualities"]).HtmlAttributes(
new {style = "width: 100px", @class = "qualityDropbox"})
@foreach (var path in Model)
{
Html.RenderAction("RenderPartial", "AddSeries", new {path});
}
<script type="text/javascript">
$("#masterDropboxId").change(function () {
var selectedQuality = $('#masterDropboxId').get(0).selectedIndex;
//$(".qualityDropbox").data("tComboBox").value(selectedQuality);
//$(".qualityDropbox").data("tDropDownList").val(selectedQuality);
var comboBox = $(".qualityDropbox").data("tDropDownList");
comboBox.select(selectedQuality);
});
</script>
}

@ -1,98 +1,67 @@
@model NzbDrone.Web.Models.AddNewSeriesModel @using NzbDrone.Web.Models
@model NzbDrone.Web.Models.AddNewSeriesModel
@section TitleContent{ @{
Add New Series Layout = null;
<script type="text/javascript">
jQuery(document).ready(function () {
$('#searchButton').attr('disabled', '');
});
</script>
} }
@section MainContent{ <div>
<div style="width: 60%"> <fieldset>
<div style="display: inline"> <legend>Root Directory</legend>
@Html.Label("Enter a Series Name")
@Html.TextBox("new_series_name", String.Empty, new {id = "new_series_id"}) @{int d = 0;
<button class="t.button" id="searchButton" disabled="disabled" onclick="searchSeries ()">
Search</button> foreach (var dir in ViewData["RootDirs"] as List<RootDirModel>)
</div> {
<div style="display: inline; float: right;"> <div>
@Html.LabelFor(m => m.QualityProfileId) @Html.RadioButton("selectedRootDir", dir.CleanPath, d == 0, new { @class = "dirList examplePart", id = "dirRadio_" + d })
@Html.DropDownListFor(m => m.QualityProfileId, Model.QualitySelectList) @Html.Label(dir.Path)
</div> @{ d++; }
</div> </div>
<div id="result"></div>
<div id="RootDirectories" class="rootDirectories" style="display: none">
<fieldset>
<legend>Root TV Folders</legend>
@{int d = 0;}
@foreach (var dir in Model.RootDirectories)
{
@Html.RadioButton("selectedRootDir", dir.Path, d == 0, new {@class = "dirList examplePart", id = "dirRadio_" + d});
@Html.Label(dir.Path)
} }
</fieldset>
<div id="example">
</div>
<button class="t.button" onclick="addSeries ()">
Add New Series</button>
</div>
<div id="addResult"></div>
<script type="text/javascript" language="javascript">
$('#new_series_id').bind('keydown', function (e) {
if (e.keyCode == 13) {
$('#searchButton').click();
}
});
function searchSeries() {
var seriesSearch = $('#new_series_id');
$("#result").text("Searching...");
$("#result").load('@Url.Action("SearchForSeries", "Series")', {
seriesName: seriesSearch.val()
});
document.getElementById('RootDirectories').style.display = 'inline';
}
function addSeries() {
var checkedSeries = $("input[name='selectedSeries']:checked").val();
var checkedDir = $("input[name='selectedRootDir']:checked").val();
var id = "#" + checkedSeries + "_text";
var seriesName = $(id).val();
var qualityProfileId = $("#QualityProfileId").val();
$("#addResult").load('@Url.Action("AddSeries", "AddSeries")', {
dir: checkedDir,
seriesId: checkedSeries,
seriesName: seriesName,
qualityProfileId: qualityProfileId
});
} }
</fieldset>
//Need to figure out how to use 'ViewData["DirSep"]' instead of hardcoding '\' </div>
$(".examplePart").live("change", function () { <br/>
var dir = $("input[name='selectedRootDir']:checked").val(); <div>
var series = $("input[name='selectedSeries']:checked").val(); @{Html.Telerik().ComboBox()
.Name("seriesList_new")
var id = "#" + series + "_text"; .DataBinding(binding => binding.Ajax().Select("_textLookUp", "AddSeries").Delay(400))
var seriesName = $(id).val(); .Filterable(f => f.FilterMode(AutoCompleteFilterMode.Contains))
.HighlightFirstMatch(true)
var sep = "\\"; .HtmlAttributes(new { style = "width: 300px;" })
.Render();}
var str = "Target: " + dir + sep + seriesName; @Html.Telerik().DropDownList().Name("qualityList_new").BindTo((SelectList)ViewData["quality"]).HtmlAttributes(new { style = "width: 100px", @class = "qualityDropbox" })
<button class="listButton" onclick="addNewSeries()">
$('#example').text(str); Add</button>
</div>
<script type="text/javascript" language="javascript">
var addNewSeriesUrl = '@Url.Action("AddNewSeries", "AddSeries")';
function addNewSeries() {
var seriesComboBox = $("#seriesList_new").data("tComboBox");
var qualityComboBox = $("#qualityList_new").data("tDropDownList");
var path = $("input[name='selectedRootDir']:checked").val();
sendToServerNew(seriesComboBox.value(), path, seriesComboBox.text(), qualityComboBox.value());
}
function sendToServerNew(id, rootPath, seriesName, quality) {
$.ajax({
type: "POST",
url: addNewSeriesUrl,
data: jQuery.param({ rootPath: rootPath, seriesName: seriesName, seriesId: id, qualityProfileId: quality }),
error: function (req, status, error) {
alert("Sorry! We could not add " + path + " at this time. " + error);
},
success: function (){
//Clear the search box
$("#seriesList_new").data("tComboBox").text('');
//Close the Window!
closeAddNewSeries();
}
}); });
</script> }
} </script>

@ -2,16 +2,7 @@
@{Html.Telerik().Menu().Name("telerikGrid").Items(items => @{Html.Telerik().Menu().Name("telerikGrid").Items(items =>
{ {
items.Add().Text("Add Series") items.Add().Text("Add Series").Action<AddSeriesController>(c => c.Add());
.Items( items.Add().Text("Start RSS Sync").Action<SeriesController>(c => c.RssSync());
subItem => items.Add().Text("Rename All").Action<SeriesController>(c => c.RenameAll());
subItem.Add().Text("New Series").Action<AddSeriesController>(c => c.AddNew()))
.Items(
subItem =>
subItem.Add().Text("Existing Series").Action<AddSeriesController>(c => c.AddExisting()));
items.Add().Text("Start RSS Sync").Action<SeriesController>(
c => c.RssSync());
items.Add().Text("Rename All").Action<SeriesController>(
c => c.RenameAll());
}).Render();} }).Render();}

@ -1,58 +1 @@
<style> Hello World
#container {
width: 850px;
margin: auto;
}
.back
{
position:absolute;
top:0;left:0;
}
.wrap
{
width:550px;
height:390px;
position:relative;
margin:auto;
overflow:hidden;
}
.comment
{
position: absolute;
width: 550px;
height: auto;
top: 400px;
left: 0px;
letter-spacing: -1px;
color: white; font: 24px/45px Berlin Sans FB, Sans-Serif;
background: #4A4D4A;
padding: 10px;
filter:alpha(opacity=60);
-moz-opacity:0.6;
-khtml-opacity: 0.6;
opacity: 0.6;
line-height: 90%
}
</style>
<button onclick="overlay()">Click Me!</button>
<div class="wrap">
<img class="backer" src="../../Content/leopard.jpg" alt="image"/>
<span class="comment">
Loading...
</span>
</div>
<script type="text/javascript">
function overlay() {
$('.wrap').children('.comment').stop().css("top", "0px");
}
</script>
Loading…
Cancel
Save