diff --git a/NzbDrone.Core/Model/SeriesMappingModel.cs b/NzbDrone.Core/Model/SeriesMappingModel.cs
new file mode 100644
index 000000000..30632266a
--- /dev/null
+++ b/NzbDrone.Core/Model/SeriesMappingModel.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace NzbDrone.Core.Model
+{
+ public class SeriesMappingModel
+ {
+ public string Path { get; set; }
+ public int TvDbId { get; set; }
+ }
+}
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index 08ac3e453..fa7378821 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -174,6 +174,7 @@
+
diff --git a/NzbDrone.Core/Providers/ISeriesProvider.cs b/NzbDrone.Core/Providers/ISeriesProvider.cs
index 88ea1fd12..f9d09e7d3 100644
--- a/NzbDrone.Core/Providers/ISeriesProvider.cs
+++ b/NzbDrone.Core/Providers/ISeriesProvider.cs
@@ -19,6 +19,7 @@ namespace NzbDrone.Core.Providers
/// Whether or not the show is monitored
bool IsMonitored(long id);
TvdbSeries MapPathToSeries(string path);
+ TvdbSeries MapPathToSeries(int tvDbId);
void AddSeries(string path, TvdbSeries series);
Series FindSeries(string cleanTitle);
bool QualityWanted(int seriesId, QualityTypes quality);
diff --git a/NzbDrone.Core/Providers/ISyncProvider.cs b/NzbDrone.Core/Providers/ISyncProvider.cs
index ceec4ea3d..6a0018460 100644
--- a/NzbDrone.Core/Providers/ISyncProvider.cs
+++ b/NzbDrone.Core/Providers/ISyncProvider.cs
@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
+using NzbDrone.Core.Model;
namespace NzbDrone.Core.Providers
{
public interface ISyncProvider
{
- bool BeginSyncUnmappedFolders(List paths);
+ bool BeginSyncUnmappedFolders(List unmapped);
List GetUnmappedFolders(string path);
}
}
\ No newline at end of file
diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs
index c38aea801..4e8dbcc56 100644
--- a/NzbDrone.Core/Providers/SeriesProvider.cs
+++ b/NzbDrone.Core/Providers/SeriesProvider.cs
@@ -76,6 +76,11 @@ namespace NzbDrone.Core.Providers
return _tvDb.GetSeries(searchResults.Id, false);
}
+ public TvdbSeries MapPathToSeries(int tvDbId)
+ {
+ return _tvDb.GetSeries(tvDbId, false);
+ }
+
public void AddSeries(string path, TvdbSeries series)
{
Logger.Info("Adding Series [{0}]:{1} Path: {2}", series.Id, series.SeriesName, path);
diff --git a/NzbDrone.Core/Providers/SyncProvider.cs b/NzbDrone.Core/Providers/SyncProvider.cs
index 00c9b0959..7dba12904 100644
--- a/NzbDrone.Core/Providers/SyncProvider.cs
+++ b/NzbDrone.Core/Providers/SyncProvider.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using NLog;
+using NzbDrone.Core.Model;
using NzbDrone.Core.Model.Notification;
namespace NzbDrone.Core.Providers
@@ -19,7 +20,7 @@ namespace NzbDrone.Core.Providers
private ProgressNotification _seriesSyncNotification;
private Thread _seriesSyncThread;
- private List _syncList;
+ private List _syncList;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
@@ -62,7 +63,7 @@ namespace NzbDrone.Core.Providers
#endregion
- public bool BeginSyncUnmappedFolders(List paths)
+ public bool BeginSyncUnmappedFolders(List unmapped)
{
Logger.Debug("User has request series folder scan");
if (_seriesSyncThread == null || !_seriesSyncThread.IsAlive)
@@ -74,7 +75,7 @@ namespace NzbDrone.Core.Providers
Priority = ThreadPriority.Lowest
};
- _syncList = paths;
+ _syncList = unmapped;
_seriesSyncThread.Start();
}
else
@@ -105,20 +106,20 @@ namespace NzbDrone.Core.Providers
{
try
{
- _seriesSyncNotification.CurrentStatus = String.Format("Searching For: {0}", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(new DirectoryInfo(seriesFolder).Name));
+ _seriesSyncNotification.CurrentStatus = String.Format("Searching For: {0}", new DirectoryInfo(seriesFolder.Path).Name);
- if (_seriesProvider.SeriesPathExists(Parser.NormalizePath(seriesFolder)))
+ if (_seriesProvider.SeriesPathExists(Parser.NormalizePath(seriesFolder.Path)))
{
Logger.Debug("Folder '{0}' is mapped in the database. Skipping.'", seriesFolder);
continue;
}
Logger.Debug("Folder '{0}' isn't mapped in the database. Trying to map it.'", seriesFolder);
- var mappedSeries = _seriesProvider.MapPathToSeries(seriesFolder);
+ var mappedSeries = _seriesProvider.MapPathToSeries(seriesFolder.TvDbId);
if (mappedSeries == null)
{
- Logger.Warn("Unable to find a matching series for '{0}'", seriesFolder);
+ Logger.Warn("Invalid TVDB ID '{0}' Unable to map: '{1}'", seriesFolder.TvDbId, seriesFolder.Path);
}
else
{
@@ -126,7 +127,7 @@ namespace NzbDrone.Core.Providers
if (_seriesProvider.GetSeries(mappedSeries.Id) == null)
{
_seriesSyncNotification.CurrentStatus = String.Format("{0}: downloading series info...", mappedSeries.SeriesName);
- _seriesProvider.AddSeries(seriesFolder, mappedSeries);
+ _seriesProvider.AddSeries(seriesFolder.Path, mappedSeries);
_episodeProvider.RefreshEpisodeInfo(mappedSeries.Id);
_seriesSyncNotification.CurrentStatus = String.Format("{0}: finding episodes on disk...", mappedSeries.SeriesName);
_mediaFileProvider.Scan(_seriesProvider.GetSeries(mappedSeries.Id));
diff --git a/NzbDrone.Web/Controllers/SeriesController.cs b/NzbDrone.Web/Controllers/SeriesController.cs
index a429649cb..ea6256f65 100644
--- a/NzbDrone.Web/Controllers/SeriesController.cs
+++ b/NzbDrone.Web/Controllers/SeriesController.cs
@@ -1,14 +1,18 @@
using System;
using System.Collections.Generic;
+using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
+using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
using NzbDrone.Web.Models;
using Telerik.Web.Mvc;
+using TvdbLib.Data;
+using EpisodeModel = NzbDrone.Web.Models.EpisodeModel;
namespace NzbDrone.Web.Controllers
{
@@ -50,7 +54,7 @@ namespace NzbDrone.Web.Controllers
public ActionResult Add()
{
- return View(new AddSeriesModel());
+ return View(new AddNewSeriesModel());
}
public ActionResult AddExisting()
@@ -58,13 +62,6 @@ namespace NzbDrone.Web.Controllers
return View();
}
- public ActionResult Sync(List paths)
- {
- //Todo: Make this do something...
- _syncProvider.BeginSyncUnmappedFolders(paths);
- return RedirectToAction("Index");
- }
-
public ActionResult RssSync()
{
_rssSyncProvider.Begin();
@@ -115,18 +112,52 @@ namespace NzbDrone.Web.Controllers
[GridAction]
public ActionResult _AjaxUnmappedFoldersGrid()
{
- var unmappedList = new List();
+ var unmappedList = new List();
foreach (var folder in _rootDirProvider.GetAll())
- unmappedList.AddRange(_syncProvider.GetUnmappedFolders(folder.Path));
+ {
+ foreach (var unmappedFolder in _syncProvider.GetUnmappedFolders(folder.Path))
+ {
+ var tvDbSeries = _seriesProvider.MapPathToSeries(unmappedFolder);
+
+ //We still want to show this series as unmapped, but we don't know what it will be when mapped
+ //Todo: Provide the user with a way to manually map a folder to a TvDb series (or make them rename the folder...)
+ if (tvDbSeries == null)
+ tvDbSeries = new TvdbSeries {Id = 0, SeriesName = String.Empty};
+
+ unmappedList.Add(new AddExistingSeriesModel
+ {
+ IsWanted = true,
+ Path = unmappedFolder,
+ TvDbId = tvDbSeries.Id,
+ TvDbName = tvDbSeries.SeriesName
+ });
+ }
+ }
+
+ return View(new GridModel(unmappedList));
+ }
+
+ public ActionResult SyncSelectedSeries(List checkedRecords)
+ {
- var seriesPaths = unmappedList.Select(c => new AddExistingSeriesModel
- {
- IsWanted = true,
- Path = c
- });
+ var unmappedList = new List();
+
+ foreach (var checkedRecord in checkedRecords)
+ {
+ NameValueCollection nvc = HttpUtility.ParseQueryString(checkedRecord);
+
+ var path = HttpUtility.UrlDecode(nvc["path"]);
+ var tvDbId = Convert.ToInt32(HttpUtility.UrlDecode(nvc["tvdbid"]));
+
+ //If the TvDbId for this show is 0 then skip it... User made a mistake... They will have to manually map it
+ if (tvDbId < 1) continue;
+
+ unmappedList.Add(new SeriesMappingModel{Path = path, TvDbId = tvDbId});
+ }
- return View(new GridModel(seriesPaths));
+ _syncProvider.BeginSyncUnmappedFolders(unmappedList);
+ return Content("Sync Started for Selected Series");
}
private IEnumerable GetData(GridCommand command)
diff --git a/NzbDrone.Web/Models/AddExistingSeriesModel.cs b/NzbDrone.Web/Models/AddExistingSeriesModel.cs
index ecb0b0b46..bde01e0f1 100644
--- a/NzbDrone.Web/Models/AddExistingSeriesModel.cs
+++ b/NzbDrone.Web/Models/AddExistingSeriesModel.cs
@@ -9,5 +9,7 @@ namespace NzbDrone.Web.Models
{
public bool IsWanted { get; set; }
public string Path { get; set; }
+ public int TvDbId { get; set; }
+ public string TvDbName { get; set; }
}
}
\ No newline at end of file
diff --git a/NzbDrone.Web/Models/AddSeriesModel.cs b/NzbDrone.Web/Models/AddNewSeriesModel.cs
similarity index 56%
rename from NzbDrone.Web/Models/AddSeriesModel.cs
rename to NzbDrone.Web/Models/AddNewSeriesModel.cs
index dd46101b6..e2da0d96b 100644
--- a/NzbDrone.Web/Models/AddSeriesModel.cs
+++ b/NzbDrone.Web/Models/AddNewSeriesModel.cs
@@ -7,16 +7,12 @@ using System.Web;
namespace NzbDrone.Web.Models
{
- public class AddSeriesModel
+ public class AddNewSeriesModel
{
+ [Required(ErrorMessage = "Please enter a series name")]
[DataType(DataType.Text)]
[DisplayName("Single Series Path")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
- public string SingleSeries { get; set; }
-
- [DataType(DataType.Text)]
- [DisplayName("Series Root Path")]
- [DisplayFormat(ConvertEmptyStringToNull = false)]
- public string SeriesRoot { get; set; }
+ public string SeriesName { get; set; }
}
}
\ No newline at end of file
diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj
index 30317fca1..9d015b340 100644
--- a/NzbDrone.Web/NzbDrone.Web.csproj
+++ b/NzbDrone.Web/NzbDrone.Web.csproj
@@ -70,6 +70,10 @@
+
+ False
+ ..\NzbDrone.Core\Libraries\TvdbLib.dll
+
@@ -87,7 +91,7 @@
-
+
@@ -273,6 +277,7 @@
+
diff --git a/NzbDrone.Web/Views/Series/Add.aspx b/NzbDrone.Web/Views/Series/Add.aspx
index 66535023f..3df4ce31b 100644
--- a/NzbDrone.Web/Views/Series/Add.aspx
+++ b/NzbDrone.Web/Views/Series/Add.aspx
@@ -1,4 +1,4 @@
-<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
+<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
Add Series
diff --git a/NzbDrone.Web/Views/Series/AddExisting.aspx b/NzbDrone.Web/Views/Series/AddExisting.aspx
index 5da2116a1..53984e81e 100644
--- a/NzbDrone.Web/Views/Series/AddExisting.aspx
+++ b/NzbDrone.Web/Views/Series/AddExisting.aspx
@@ -12,24 +12,103 @@
%>
+
+
//Get AJAX listing of unmapped directories
+ //When getting unmapped, also do a quick lookup on TVDB to see which series we would map this to... Don't do the mapping though...
+ //ITvDbProvider.GetSeries(string title);
<%
- Html.Telerik().Grid().Name("Unmapped Series Folders")
- .Columns(columns =>
- {
- columns.Bound(c => c.IsWanted).Width(0).Title("Is Wanted?");
- columns.Bound(c => c.Path);
- })
- //.DetailView(detailView => detailView.Template(e => Html.RenderPartial("EpisodeDetail", e)))
- //.DetailView(detailView => detailView.ClientTemplate("<#= Overview #>
"))
- //.Sortable(rows => rows.OrderBy(epSort => epSort.Add(c => c.EpisodeNumber).Descending()).Enabled(true))
- .Footer(false)
- .DataBinding(d => d.Ajax().Select("_AjaxUnmappedFoldersGrid", "Series"))
- //.EnableCustomBinding(true)
- //.ClientEvents(e => e.OnDetailViewExpand("episodeDetailExpanded")) //Causes issues displaying the episode detail multiple times...
+ Html.Telerik().Grid().Name("Unmapped_Series_Folders")
+ .TableHtmlAttributes(new { id = "UnmappedSeriesGrid" })
+ .Columns(columns =>
+ {
+ columns.Bound(c => c.IsWanted).ClientTemplate(" ")
+ .Width(20).Title(" ")
+ .HtmlAttributes(new { style = "text-align:center" });
+
+ columns.Bound(c => c.Path);
+ columns.Bound(c => c.TvDbName);
+ })
+ .DataBinding(d => d.Ajax().Select("_AjaxUnmappedFoldersGrid", "Series"))
+ .ClientEvents(events => events.OnRowDataBound("Grid_onRowDataBound"))
+ .Footer(false)
.Render();
- %>`
+ %>
+
+
+ Sync Selected Series
+
+
+
+
+
+
diff --git a/NzbDrone.Web/Views/Series/AddNew.aspx b/NzbDrone.Web/Views/Series/AddNew.aspx
new file mode 100644
index 000000000..16b2eb32b
--- /dev/null
+++ b/NzbDrone.Web/Views/Series/AddNew.aspx
@@ -0,0 +1,32 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
+<%@ Import Namespace="NzbDrone.Web.Models" %>
+<%@ Import Namespace="Telerik.Web.Mvc.UI" %>
+
+
+ Add New Series
+
+
+
+
+ //Add a new series
+
+ <%= Html.Label("Enter a Series Name") %>
+ <%= Html.TextBox("new_series_name", new { id="new_series_id" }) %>
+
+ //Browse Button??
+ //Auto-Complete?
+
+ //Search Button - Perform AJAX search for this Series on TVDB
+
+ //Return results with Radio Box + First Aired information, (link to TVDB too?) + Hidden ID text
+
+ User selects radio button and then presses add (or skips which clears results and #new_series_id)
+
+ Add, ask user to choose where to save the show in (used when sorting) then add the show... Possibly ask user to choose Quality Profile
+
+
+
diff --git a/NzbDrone.Web/Views/Series/SubMenu.ascx b/NzbDrone.Web/Views/Series/SubMenu.ascx
index 887e9cf00..1fd8646df 100644
--- a/NzbDrone.Web/Views/Series/SubMenu.ascx
+++ b/NzbDrone.Web/Views/Series/SubMenu.ascx
@@ -5,7 +5,6 @@
<% Html.Telerik().Menu().Name("telerikGrid").Items(items =>
{
items.Add().Text("View Unmapped Folders").Action("Unmapped", "Series");
- items.Add().Text("Sync With Disk").Action("Sync", "Series", new { paths = "test" });
items.Add().Text("Start RSS Sync").Action("RssSync", "Series");
items.Add().Text("Rename All").Action("RenameAll", "Series");
items.Add().Text("Add Series").Action("Add", "Series");