2010-09-23 05:19:47 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2012-09-19 09:07:19 +02:00
|
|
|
|
using System.Globalization;
|
2011-02-25 02:18:22 +01:00
|
|
|
|
using System.IO;
|
2010-09-23 05:19:47 +02:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Web.Mvc;
|
2012-02-16 06:53:00 +01:00
|
|
|
|
using System.Web.Script.Serialization;
|
2012-01-24 07:29:32 +01:00
|
|
|
|
using NzbDrone.Common.Model;
|
2011-09-28 02:10:08 +02:00
|
|
|
|
using NzbDrone.Core;
|
2011-09-05 21:59:39 +02:00
|
|
|
|
using NzbDrone.Core.Helpers;
|
2011-12-02 02:33:17 +01:00
|
|
|
|
using NzbDrone.Core.Jobs;
|
2012-01-24 07:29:32 +01:00
|
|
|
|
using NzbDrone.Core.Model;
|
2010-09-28 06:25:41 +02:00
|
|
|
|
using NzbDrone.Core.Providers;
|
2012-12-21 06:36:48 +01:00
|
|
|
|
using NzbDrone.Core.Providers.Core;
|
2010-10-30 04:46:32 +02:00
|
|
|
|
using NzbDrone.Core.Repository;
|
2012-01-20 08:50:45 +01:00
|
|
|
|
using NzbDrone.Core.Repository.Quality;
|
2012-10-01 02:05:16 +02:00
|
|
|
|
using NzbDrone.Web.Filters;
|
2010-10-30 04:46:32 +02:00
|
|
|
|
using NzbDrone.Web.Models;
|
2010-09-23 05:19:47 +02:00
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Web.Controllers
|
|
|
|
|
{
|
2010-10-08 05:35:04 +02:00
|
|
|
|
[HandleError]
|
2010-09-23 05:19:47 +02:00
|
|
|
|
public class SeriesController : Controller
|
|
|
|
|
{
|
2011-04-10 04:44:01 +02:00
|
|
|
|
private readonly QualityProvider _qualityProvider;
|
|
|
|
|
private readonly SeriesProvider _seriesProvider;
|
2011-04-20 09:44:13 +02:00
|
|
|
|
private readonly JobProvider _jobProvider;
|
2012-02-21 07:50:38 +01:00
|
|
|
|
private readonly SeasonProvider _seasonProvider;
|
2012-12-21 06:36:48 +01:00
|
|
|
|
private readonly ConfigProvider _configProvider;
|
2010-09-23 05:19:47 +02:00
|
|
|
|
//
|
|
|
|
|
// GET: /Series/
|
|
|
|
|
|
2012-12-21 06:36:48 +01:00
|
|
|
|
public SeriesController(SeriesProvider seriesProvider, QualityProvider qualityProvider,
|
|
|
|
|
JobProvider jobProvider, SeasonProvider seasonProvider,
|
|
|
|
|
ConfigProvider configProvider)
|
2010-09-23 05:19:47 +02:00
|
|
|
|
{
|
2010-09-28 06:25:41 +02:00
|
|
|
|
_seriesProvider = seriesProvider;
|
2011-02-18 03:50:40 +01:00
|
|
|
|
_qualityProvider = qualityProvider;
|
2011-04-20 09:44:13 +02:00
|
|
|
|
_jobProvider = jobProvider;
|
2012-02-21 07:50:38 +01:00
|
|
|
|
_seasonProvider = seasonProvider;
|
2012-12-21 06:36:48 +01:00
|
|
|
|
_configProvider = configProvider;
|
2010-09-23 05:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ActionResult Index()
|
2012-09-27 22:54:40 +02:00
|
|
|
|
{
|
|
|
|
|
return View();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpGet]
|
|
|
|
|
public ActionResult Series()
|
2012-02-05 21:17:23 +01:00
|
|
|
|
{
|
2012-02-16 06:53:00 +01:00
|
|
|
|
var series = GetSeriesModels(_seriesProvider.GetAllSeriesWithEpisodeCount());
|
|
|
|
|
|
2012-09-27 22:54:40 +02:00
|
|
|
|
return Json(new { aaData = series }, JsonRequestBehavior.AllowGet);
|
2012-02-05 21:17:23 +01:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 09:07:19 +02:00
|
|
|
|
public ActionResult Edit(int seriesId)
|
2010-09-23 05:19:47 +02:00
|
|
|
|
{
|
2011-07-08 07:41:08 +02:00
|
|
|
|
var profiles = _qualityProvider.All();
|
2011-05-10 08:32:33 +02:00
|
|
|
|
ViewData["SelectList"] = new SelectList(profiles, "QualityProfileId", "Name");
|
|
|
|
|
|
2012-01-24 07:29:32 +01:00
|
|
|
|
var backlogStatusTypes = new List<KeyValuePair<int, string>>();
|
|
|
|
|
|
2012-01-26 02:02:21 +01:00
|
|
|
|
foreach (BacklogSettingType backlogStatusType in Enum.GetValues(typeof(BacklogSettingType)))
|
2012-01-24 07:29:32 +01:00
|
|
|
|
{
|
|
|
|
|
backlogStatusTypes.Add(new KeyValuePair<int, string>((int)backlogStatusType, backlogStatusType.ToString()));
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-26 02:02:21 +01:00
|
|
|
|
ViewData["BacklogSettingSelectList"] = new SelectList(backlogStatusTypes, "Key", "Value");
|
2012-01-24 07:29:32 +01:00
|
|
|
|
|
2012-02-05 21:17:23 +01:00
|
|
|
|
var series = GetSeriesModels(new List<Series>{_seriesProvider.GetSeries(seriesId)}).Single();
|
|
|
|
|
return View(series);
|
2010-09-23 05:19:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-05 21:17:23 +01:00
|
|
|
|
[HttpPost]
|
2012-09-19 09:07:19 +02:00
|
|
|
|
public EmptyResult Edit(SeriesModel seriesModel)
|
2011-05-10 08:32:33 +02:00
|
|
|
|
{
|
2012-02-05 21:17:23 +01:00
|
|
|
|
var series = _seriesProvider.GetSeries(seriesModel.SeriesId);
|
|
|
|
|
series.Monitored = seriesModel.Monitored;
|
|
|
|
|
series.SeasonFolder = seriesModel.SeasonFolder;
|
|
|
|
|
series.QualityProfileId = seriesModel.QualityProfileId;
|
|
|
|
|
series.Path = seriesModel.Path;
|
|
|
|
|
series.BacklogSetting = (BacklogSettingType)seriesModel.BacklogSetting;
|
2011-05-10 08:32:33 +02:00
|
|
|
|
|
2012-09-20 17:37:40 +02:00
|
|
|
|
if (!String.IsNullOrWhiteSpace(seriesModel.CustomStartDate))
|
|
|
|
|
series.CustomStartDate = DateTime.Parse(seriesModel.CustomStartDate, null, DateTimeStyles.RoundtripKind);
|
2012-09-19 09:07:19 +02:00
|
|
|
|
|
2012-10-18 20:50:52 +02:00
|
|
|
|
else
|
|
|
|
|
series.CustomStartDate = null;
|
|
|
|
|
|
2012-02-05 21:17:23 +01:00
|
|
|
|
_seriesProvider.UpdateSeries(series);
|
2011-05-10 08:32:33 +02:00
|
|
|
|
|
2012-02-05 22:36:57 +01:00
|
|
|
|
return new EmptyResult();
|
2011-05-12 04:53:19 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-05 21:17:23 +01:00
|
|
|
|
[HttpPost]
|
2012-09-12 07:52:25 +02:00
|
|
|
|
public EmptyResult Delete(int seriesId, bool deleteFiles)
|
2011-05-12 04:53:19 +02:00
|
|
|
|
{
|
2012-09-10 21:04:17 +02:00
|
|
|
|
_jobProvider.QueueJob(typeof(DeleteSeriesJob), new { SeriesId = seriesId, DeleteFiles = deleteFiles });
|
2011-05-18 07:32:23 +02:00
|
|
|
|
|
2012-02-05 22:36:57 +01:00
|
|
|
|
return new EmptyResult();
|
2011-05-10 08:32:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-10-01 02:05:16 +02:00
|
|
|
|
[JsonErrorFilter]
|
2011-10-21 01:36:47 +02:00
|
|
|
|
public JsonResult LocalSearch(string term)
|
2011-03-11 10:04:56 +01:00
|
|
|
|
{
|
2011-10-21 01:36:47 +02:00
|
|
|
|
var results = _seriesProvider.SearchForSeries(term).Select(s => new SeriesSearchResultModel
|
|
|
|
|
{
|
|
|
|
|
Id = s.SeriesId,
|
|
|
|
|
Title = s.Title
|
|
|
|
|
}).ToList();
|
2011-03-11 10:04:56 +01:00
|
|
|
|
|
2011-10-21 01:36:47 +02:00
|
|
|
|
return Json(results, JsonRequestBehavior.AllowGet);
|
2011-03-09 08:40:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-04 05:34:02 +01:00
|
|
|
|
public ActionResult Details(int seriesId)
|
|
|
|
|
{
|
|
|
|
|
var series = _seriesProvider.GetSeries(seriesId);
|
|
|
|
|
|
|
|
|
|
var model = new SeriesDetailsModel();
|
|
|
|
|
|
|
|
|
|
if (series.AirsDayOfWeek != null)
|
|
|
|
|
{
|
|
|
|
|
model.AirsDayOfWeek = series.AirsDayOfWeek.Value.ToString();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
model.AirsDayOfWeek = "N/A";
|
|
|
|
|
}
|
|
|
|
|
model.Overview = series.Overview;
|
|
|
|
|
model.Title = series.Title;
|
|
|
|
|
model.SeriesId = series.SeriesId;
|
|
|
|
|
model.HasBanner = !String.IsNullOrEmpty(series.BannerUrl);
|
|
|
|
|
|
2012-02-21 07:50:38 +01:00
|
|
|
|
var seasons = _seasonProvider.All(seriesId).Select(s => new SeasonModel
|
|
|
|
|
{
|
|
|
|
|
SeriesId = seriesId,
|
|
|
|
|
SeasonNumber = s.SeasonNumber,
|
|
|
|
|
Ignored = s.Ignored,
|
|
|
|
|
Episodes = GetEpisodeModels(s.Episodes).OrderByDescending(e => e.EpisodeNumber).ToList(),
|
|
|
|
|
CommonStatus = GetCommonStatus(s.Episodes)
|
|
|
|
|
}).ToList();
|
2012-02-04 05:34:02 +01:00
|
|
|
|
model.Seasons = seasons;
|
2012-09-04 01:26:52 +02:00
|
|
|
|
|
2012-10-14 19:10:23 +02:00
|
|
|
|
var qualities = QualityTypes.All().ToList();
|
2012-09-04 01:26:52 +02:00
|
|
|
|
|
|
|
|
|
model.QualitySelectList = new SelectList(qualities.Where(q => q.Id > 0), "Id", "Name");
|
2012-02-04 05:34:02 +01:00
|
|
|
|
|
|
|
|
|
return View(model);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-27 05:47:49 +01:00
|
|
|
|
public ActionResult Editor()
|
2012-01-20 08:50:45 +01:00
|
|
|
|
{
|
|
|
|
|
var profiles = _qualityProvider.All();
|
|
|
|
|
ViewData["QualityProfiles"] = profiles;
|
|
|
|
|
|
|
|
|
|
//Create the select lists
|
|
|
|
|
var masterProfiles = profiles.ToList();
|
2012-02-27 05:47:49 +01:00
|
|
|
|
masterProfiles.Insert(0, new QualityProfile {QualityProfileId = -10, Name = "Select..."});
|
2012-01-20 08:50:45 +01:00
|
|
|
|
ViewData["MasterProfileSelectList"] = new SelectList(masterProfiles, "QualityProfileId", "Name");
|
|
|
|
|
|
|
|
|
|
ViewData["BoolSelectList"] = new SelectList(new List<KeyValuePair<int, string>>
|
|
|
|
|
{
|
2012-02-27 05:47:49 +01:00
|
|
|
|
new KeyValuePair<int, string>(-10, "Select..."),
|
2012-01-20 08:50:45 +01:00
|
|
|
|
new KeyValuePair<int, string>(1, "True"),
|
|
|
|
|
new KeyValuePair<int, string>(0, "False")
|
|
|
|
|
}, "Key", "Value"
|
|
|
|
|
);
|
|
|
|
|
|
2012-01-26 02:02:21 +01:00
|
|
|
|
var backlogSettingTypes = new List<KeyValuePair<int, string>>();
|
2012-01-24 07:29:32 +01:00
|
|
|
|
|
2012-01-26 02:02:21 +01:00
|
|
|
|
foreach (BacklogSettingType backlogSettingType in Enum.GetValues(typeof(BacklogSettingType)))
|
2012-01-24 07:29:32 +01:00
|
|
|
|
{
|
2012-01-26 02:02:21 +01:00
|
|
|
|
backlogSettingTypes.Add(new KeyValuePair<int, string>((int)backlogSettingType, backlogSettingType.ToString()));
|
2012-01-24 07:29:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-26 02:02:21 +01:00
|
|
|
|
ViewData["BacklogSettingTypes"] = backlogSettingTypes;
|
2012-01-24 07:29:32 +01:00
|
|
|
|
|
2012-01-26 02:02:21 +01:00
|
|
|
|
var masterBacklogList = backlogSettingTypes.ToList();
|
2012-02-27 05:47:49 +01:00
|
|
|
|
masterBacklogList.Insert(0, new KeyValuePair<int, string>(-10, "Select..."));
|
2012-01-26 02:02:21 +01:00
|
|
|
|
ViewData["MasterBacklogSettingSelectList"] = new SelectList(masterBacklogList, "Key", "Value");
|
2012-01-24 07:29:32 +01:00
|
|
|
|
|
2012-12-21 06:36:48 +01:00
|
|
|
|
var series = GetSeriesModels(_seriesProvider.GetAllSeries());
|
2012-01-20 08:50:45 +01:00
|
|
|
|
|
|
|
|
|
return View(series);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[HttpPost]
|
2012-09-19 09:32:34 +02:00
|
|
|
|
public JsonResult Editor(List<SeriesModel> series)
|
2012-01-20 08:50:45 +01:00
|
|
|
|
{
|
|
|
|
|
//Save edits
|
|
|
|
|
if (series == null || series.Count == 0)
|
2012-02-23 23:31:50 +01:00
|
|
|
|
return JsonNotificationResult.Oops("Invalid post data");
|
2012-01-20 08:50:45 +01:00
|
|
|
|
|
2012-09-19 09:32:34 +02:00
|
|
|
|
_seriesProvider.UpdateFromSeriesEditor(series.Select(s => new Series
|
|
|
|
|
{
|
|
|
|
|
SeriesId = s.SeriesId,
|
|
|
|
|
QualityProfileId = s.QualityProfileId,
|
|
|
|
|
Monitored = s.Monitored,
|
|
|
|
|
SeasonFolder = s.SeasonFolder,
|
|
|
|
|
BacklogSetting = (BacklogSettingType)s.BacklogSetting,
|
|
|
|
|
Path = s.Path,
|
2012-09-20 17:37:40 +02:00
|
|
|
|
CustomStartDate = String.IsNullOrWhiteSpace(s.CustomStartDate) ? (DateTime?)null
|
|
|
|
|
: DateTime.Parse(s.CustomStartDate, null, DateTimeStyles.RoundtripKind)
|
2012-09-19 09:32:34 +02:00
|
|
|
|
}
|
|
|
|
|
).ToList());
|
2012-01-20 08:50:45 +01:00
|
|
|
|
return JsonNotificationResult.Info("Series Mass Edit Saved");
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-22 08:39:45 +02:00
|
|
|
|
private List<SeriesModel> GetSeriesModels(IList<Series> seriesInDb)
|
2011-05-12 04:53:19 +02:00
|
|
|
|
{
|
2012-12-21 06:36:48 +01:00
|
|
|
|
var ignoreArticles = _configProvider.IgnoreArticlesWhenSortingSeries;
|
|
|
|
|
|
2011-06-20 09:13:17 +02:00
|
|
|
|
var series = seriesInDb.Select(s => new SeriesModel
|
|
|
|
|
{
|
|
|
|
|
SeriesId = s.SeriesId,
|
|
|
|
|
Title = s.Title,
|
2012-12-21 06:36:48 +01:00
|
|
|
|
TitleSorter = ignoreArticles? s.Title.IgnoreArticles() : s.Title,
|
2011-06-20 09:13:17 +02:00
|
|
|
|
AirsDayOfWeek = s.AirsDayOfWeek.ToString(),
|
|
|
|
|
Monitored = s.Monitored,
|
|
|
|
|
Overview = s.Overview,
|
|
|
|
|
Path = s.Path,
|
|
|
|
|
QualityProfileId = s.QualityProfileId,
|
|
|
|
|
QualityProfileName = s.QualityProfile.Name,
|
2012-02-29 08:20:40 +01:00
|
|
|
|
Network = s.Network,
|
2011-06-20 09:13:17 +02:00
|
|
|
|
SeasonFolder = s.SeasonFolder,
|
2012-01-26 02:02:21 +01:00
|
|
|
|
BacklogSetting = (int)s.BacklogSetting,
|
2011-06-20 09:13:17 +02:00
|
|
|
|
Status = s.Status,
|
|
|
|
|
SeasonsCount = s.SeasonCount,
|
|
|
|
|
EpisodeCount = s.EpisodeCount,
|
2011-09-28 19:56:30 +02:00
|
|
|
|
EpisodeFileCount = s.EpisodeFileCount,
|
2012-02-16 06:53:00 +01:00
|
|
|
|
NextAiring = s.NextAiring == null ? String.Empty : s.NextAiring.Value.ToBestDateString(),
|
2012-12-06 02:54:09 +01:00
|
|
|
|
NextAiringSorter = s.NextAiring == null ? new DateTime(9999, 12, 31).ToString("o", CultureInfo.InvariantCulture) : s.NextAiring.Value.ToString("o", CultureInfo.InvariantCulture),
|
2012-09-19 09:07:19 +02:00
|
|
|
|
AirTime = s.AirTimes,
|
2012-09-20 17:37:40 +02:00
|
|
|
|
CustomStartDate = s.CustomStartDate.HasValue ? s.CustomStartDate.Value.ToString("yyyy-MM-dd") : String.Empty
|
2011-06-20 09:13:17 +02:00
|
|
|
|
}).ToList();
|
2011-05-12 04:53:19 +02:00
|
|
|
|
|
|
|
|
|
return series;
|
|
|
|
|
}
|
2011-05-16 08:27:02 +02:00
|
|
|
|
|
2011-06-06 00:19:07 +02:00
|
|
|
|
private List<EpisodeModel> GetEpisodeModels(IList<Episode> episodesInDb)
|
|
|
|
|
{
|
|
|
|
|
var episodes = new List<EpisodeModel>();
|
|
|
|
|
|
|
|
|
|
foreach (var e in episodesInDb)
|
|
|
|
|
{
|
|
|
|
|
var episodeFileId = 0;
|
2011-06-17 05:29:39 +02:00
|
|
|
|
var episodePath = String.Empty;
|
2012-02-05 05:34:56 +01:00
|
|
|
|
var episodeQuality = "N/A";
|
2012-09-04 01:26:52 +02:00
|
|
|
|
var episodeQualityId = 0;
|
2011-06-17 05:29:39 +02:00
|
|
|
|
|
2011-06-22 07:43:45 +02:00
|
|
|
|
if (e.EpisodeFile != null)
|
2011-06-06 00:19:07 +02:00
|
|
|
|
{
|
2011-06-22 07:43:45 +02:00
|
|
|
|
episodePath = e.EpisodeFile.Path;
|
|
|
|
|
episodeFileId = e.EpisodeFile.EpisodeFileId;
|
|
|
|
|
episodeQuality = e.EpisodeFile.Quality.ToString();
|
2012-09-04 01:26:52 +02:00
|
|
|
|
episodeQualityId = (int)e.EpisodeFile.Quality;
|
2011-06-06 00:19:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-06-23 20:37:17 +02:00
|
|
|
|
var airDate = String.Empty;
|
|
|
|
|
|
|
|
|
|
if (e.AirDate != null)
|
2011-09-28 02:10:08 +02:00
|
|
|
|
airDate = e.AirDate.Value.ToBestDateString();
|
2011-06-23 20:37:17 +02:00
|
|
|
|
|
2011-06-06 00:19:07 +02:00
|
|
|
|
episodes.Add(new EpisodeModel
|
|
|
|
|
{
|
|
|
|
|
EpisodeId = e.EpisodeId,
|
2012-09-04 01:26:52 +02:00
|
|
|
|
EpisodeFileId = episodeFileId,
|
2011-06-06 00:19:07 +02:00
|
|
|
|
EpisodeNumber = e.EpisodeNumber,
|
|
|
|
|
SeasonNumber = e.SeasonNumber,
|
|
|
|
|
Title = e.Title,
|
|
|
|
|
Overview = e.Overview,
|
2011-06-23 20:37:17 +02:00
|
|
|
|
AirDate = airDate,
|
2011-06-06 00:19:07 +02:00
|
|
|
|
Path = episodePath,
|
|
|
|
|
Status = e.Status.ToString(),
|
2011-08-03 09:26:39 +02:00
|
|
|
|
Quality = episodeQuality,
|
2012-09-04 01:26:52 +02:00
|
|
|
|
QualityId = episodeQualityId,
|
2011-08-03 09:26:39 +02:00
|
|
|
|
Ignored = e.Ignored
|
2011-06-06 00:19:07 +02:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return episodes;
|
|
|
|
|
}
|
2012-02-21 07:50:38 +01:00
|
|
|
|
|
|
|
|
|
private string GetCommonStatus(IList<Episode> episodes)
|
|
|
|
|
{
|
|
|
|
|
var commonStatusList = episodes.Select(s => s.Status).Distinct().ToList();
|
|
|
|
|
var commonStatus = commonStatusList.Count > 1 ? "Missing" : commonStatusList.First().ToString();
|
|
|
|
|
return commonStatus;
|
|
|
|
|
}
|
2010-09-23 05:19:47 +02:00
|
|
|
|
}
|
2011-04-10 04:44:01 +02:00
|
|
|
|
}
|