From 8519b6494716ef366c9c38238b86a312aeea83a6 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 19 Feb 2018 08:18:14 +0100 Subject: [PATCH 1/3] Cleanup TV related code in API (#2530) --- .../Blacklist/BlacklistResource.cs | 9 +- src/NzbDrone.Api/Calendar/CalendarModule.cs | 4 +- .../EpisodeFiles/EpisodeFileModule.cs | 88 ------ .../EpisodeFiles/EpisodeFileResource.cs | 64 ---- src/NzbDrone.Api/Episodes/EpisodeModule.cs | 41 --- .../Episodes/EpisodeModuleWithSignalR.cs | 126 -------- src/NzbDrone.Api/Episodes/EpisodeResource.cs | 78 ----- .../Episodes/RenameEpisodeModule.cs | 37 --- .../Episodes/RenameEpisodeResource.cs | 39 --- src/NzbDrone.Api/History/HistoryModule.cs | 4 +- src/NzbDrone.Api/History/HistoryResource.cs | 15 +- .../ManualImport/ManualImportResource.cs | 12 +- .../{Movies => MovieFiles}/MovieFileModule.cs | 7 +- .../MovieFileResource.cs | 6 +- .../Movies/AlternativeTitleModule.cs | 5 +- .../AlternativeTitleResource.cs | 5 +- .../Movies/AlternativeYearModule.cs | 5 +- .../Movies/AlternativeYearResource.cs | 5 +- .../FetchMovieListModule.cs | 6 +- .../Movies/MovieBulkImportModule.cs | 3 +- .../{Series => Movies}/MovieDiscoverModule.cs | 6 +- src/NzbDrone.Api/Movies/MovieEditorModule.cs | 4 +- .../{Series => Movies}/MovieLookupModule.cs | 2 +- src/NzbDrone.Api/Movies/MovieModule.cs | 293 ++++++++++++++++- .../Movies/MovieModuleWithSignalR.cs | 2 +- .../{Series => Movies}/MovieResource.cs | 6 +- src/NzbDrone.Api/Movies/RenameMovieModule.cs | 2 +- .../Movies/RenameMovieResource.cs | 2 +- .../NetImport/ImportExclusionsModule.cs | 50 +-- .../NetImport/ImportExclusionsResource.cs | 74 ++--- .../NetImport/ListImportModule.cs | 4 +- .../NetImport/NetImportResource.cs | 1 - src/NzbDrone.Api/NzbDrone.Api.csproj | 31 +- src/NzbDrone.Api/Parse/ParseModule.cs | 20 +- src/NzbDrone.Api/Parse/ParseResource.cs | 12 +- src/NzbDrone.Api/Queue/QueueResource.cs | 11 +- .../SeasonPass/SeasonPassModule.cs | 31 -- .../SeasonPass/SeasonPassResource.cs | 11 - src/NzbDrone.Api/Series/MovieModule.cs | 298 ------------------ src/NzbDrone.Api/Series/SeasonResource.cs | 47 --- .../Series/SeasonStatisticsResource.cs | 43 --- src/NzbDrone.Api/Series/SeriesEditorModule.cs | 31 -- src/NzbDrone.Api/Series/SeriesLookupModule.cs | 44 --- src/NzbDrone.Api/Series/SeriesModule.cs | 215 +------------ src/NzbDrone.Api/Series/SeriesResource.cs | 223 +------------ src/NzbDrone.Api/Wanted/CutoffModule.cs | 42 --- src/NzbDrone.Api/Wanted/MissingModule.cs | 38 --- src/NzbDrone.Api/Wanted/MovieCutoffModule.cs | 3 +- src/NzbDrone.Api/Wanted/MovieMissingModule.cs | 1 - .../ApiTests/BlacklistFixture.cs | 2 +- .../ApiTests/CalendarFixture.cs | 2 +- .../Client/MovieClient.cs | 2 +- .../HttpLogFixture.cs | 2 +- .../IntegrationTestBase.cs | 12 +- 54 files changed, 444 insertions(+), 1682 deletions(-) delete mode 100644 src/NzbDrone.Api/EpisodeFiles/EpisodeFileModule.cs delete mode 100644 src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs delete mode 100644 src/NzbDrone.Api/Episodes/EpisodeModule.cs delete mode 100644 src/NzbDrone.Api/Episodes/EpisodeModuleWithSignalR.cs delete mode 100644 src/NzbDrone.Api/Episodes/EpisodeResource.cs delete mode 100644 src/NzbDrone.Api/Episodes/RenameEpisodeModule.cs delete mode 100644 src/NzbDrone.Api/Episodes/RenameEpisodeResource.cs rename src/NzbDrone.Api/{Movies => MovieFiles}/MovieFileModule.cs (96%) rename src/NzbDrone.Api/{Series => MovieFiles}/MovieFileResource.cs (97%) rename src/NzbDrone.Api/{Series => Movies}/AlternativeTitleResource.cs (97%) rename src/NzbDrone.Api/{Series => Movies}/FetchMovieListModule.cs (96%) rename src/NzbDrone.Api/{Series => Movies}/MovieDiscoverModule.cs (96%) rename src/NzbDrone.Api/{Series => Movies}/MovieLookupModule.cs (98%) rename src/NzbDrone.Api/{Series => Movies}/MovieResource.cs (99%) delete mode 100644 src/NzbDrone.Api/SeasonPass/SeasonPassModule.cs delete mode 100644 src/NzbDrone.Api/SeasonPass/SeasonPassResource.cs delete mode 100644 src/NzbDrone.Api/Series/MovieModule.cs delete mode 100644 src/NzbDrone.Api/Series/SeasonResource.cs delete mode 100644 src/NzbDrone.Api/Series/SeasonStatisticsResource.cs delete mode 100644 src/NzbDrone.Api/Series/SeriesEditorModule.cs delete mode 100644 src/NzbDrone.Api/Series/SeriesLookupModule.cs delete mode 100644 src/NzbDrone.Api/Wanted/CutoffModule.cs delete mode 100644 src/NzbDrone.Api/Wanted/MissingModule.cs diff --git a/src/NzbDrone.Api/Blacklist/BlacklistResource.cs b/src/NzbDrone.Api/Blacklist/BlacklistResource.cs index f29a2a8cb..305e7966f 100644 --- a/src/NzbDrone.Api/Blacklist/BlacklistResource.cs +++ b/src/NzbDrone.Api/Blacklist/BlacklistResource.cs @@ -1,9 +1,8 @@ -using System; +using System; using System.Collections.Generic; -using NzbDrone.Api.Movie; +using NzbDrone.Api.Movies; using NzbDrone.Api.REST; using NzbDrone.Core.Qualities; -using NzbDrone.Api.Series; using NzbDrone.Core.Indexers; namespace NzbDrone.Api.Blacklist @@ -20,7 +19,6 @@ public class BlacklistResource : RestResource public string Indexer { get; set; } public string Message { get; set; } public MovieResource Movie { get; set; } - public SeriesResource Series { get; set; } } public static class BlacklistResourceMapper @@ -41,8 +39,7 @@ public static BlacklistResource MapToResource(this Core.Blacklisting.Blacklist m Protocol = model.Protocol, Indexer = model.Indexer, Message = model.Message, - Movie = model.Movie.ToResource(), - Series = model.Series.ToResource() + Movie = model.Movie.ToResource() }; } } diff --git a/src/NzbDrone.Api/Calendar/CalendarModule.cs b/src/NzbDrone.Api/Calendar/CalendarModule.cs index efe600e6b..a44cf2f37 100644 --- a/src/NzbDrone.Api/Calendar/CalendarModule.cs +++ b/src/NzbDrone.Api/Calendar/CalendarModule.cs @@ -2,9 +2,7 @@ using System.Collections.Generic; using System.Linq; using Nancy; -using NzbDrone.Api.Episodes; -using NzbDrone.Api.Movie; -using NzbDrone.Api.Series; +using NzbDrone.Api.Movies; using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaFiles; diff --git a/src/NzbDrone.Api/EpisodeFiles/EpisodeFileModule.cs b/src/NzbDrone.Api/EpisodeFiles/EpisodeFileModule.cs deleted file mode 100644 index 1afab0b93..000000000 --- a/src/NzbDrone.Api/EpisodeFiles/EpisodeFileModule.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using NLog; -using NzbDrone.Api.REST; -using NzbDrone.Core.Datastore.Events; -using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.Tv; -using NzbDrone.Core.DecisionEngine; -using NzbDrone.SignalR; - -namespace NzbDrone.Api.EpisodeFiles -{ - public class EpisodeFileModule : NzbDroneRestModuleWithSignalR, - IHandle - { - private readonly IMediaFileService _mediaFileService; - private readonly IRecycleBinProvider _recycleBinProvider; - private readonly ISeriesService _seriesService; - private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification; - private readonly Logger _logger; - - public EpisodeFileModule(IBroadcastSignalRMessage signalRBroadcaster, - IMediaFileService mediaFileService, - IRecycleBinProvider recycleBinProvider, - ISeriesService seriesService, - IQualityUpgradableSpecification qualityUpgradableSpecification, - Logger logger) - : base(signalRBroadcaster) - { - _mediaFileService = mediaFileService; - _recycleBinProvider = recycleBinProvider; - _seriesService = seriesService; - _qualityUpgradableSpecification = qualityUpgradableSpecification; - _logger = logger; - GetResourceById = GetEpisodeFile; - GetResourceAll = GetEpisodeFiles; - UpdateResource = SetQuality; - DeleteResource = DeleteEpisodeFile; - } - - private EpisodeFileResource GetEpisodeFile(int id) - { - var episodeFile = _mediaFileService.Get(id); - var series = _seriesService.GetSeries(episodeFile.SeriesId); - - return episodeFile.ToResource(series, _qualityUpgradableSpecification); - } - - private List GetEpisodeFiles() - { - if (!Request.Query.SeriesId.HasValue) - { - throw new BadRequestException("seriesId is missing"); - } - - var seriesId = (int)Request.Query.SeriesId; - - var series = _seriesService.GetSeries(seriesId); - - return _mediaFileService.GetFilesBySeries(seriesId).ConvertAll(f => f.ToResource(series, _qualityUpgradableSpecification)); - } - - private void SetQuality(EpisodeFileResource episodeFileResource) - { - var episodeFile = _mediaFileService.Get(episodeFileResource.Id); - episodeFile.Quality = episodeFileResource.Quality; - _mediaFileService.Update(episodeFile); - } - - private void DeleteEpisodeFile(int id) - { - var episodeFile = _mediaFileService.Get(id); - var series = _seriesService.GetSeries(episodeFile.SeriesId); - var fullPath = Path.Combine(series.Path, episodeFile.RelativePath); - - _logger.Info("Deleting episode file: {0}", fullPath); - _recycleBinProvider.DeleteFile(fullPath); - _mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual); - } - - public void Handle(EpisodeFileAddedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id); - } - } -} \ No newline at end of file diff --git a/src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs b/src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs deleted file mode 100644 index bd856776d..000000000 --- a/src/NzbDrone.Api/EpisodeFiles/EpisodeFileResource.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.IO; -using NzbDrone.Api.REST; -using NzbDrone.Core.Qualities; - -namespace NzbDrone.Api.EpisodeFiles -{ - public class EpisodeFileResource : RestResource - { - public int SeriesId { get; set; } - public int SeasonNumber { get; set; } - public string RelativePath { get; set; } - public string Path { get; set; } - public long Size { get; set; } - public DateTime DateAdded { get; set; } - public string SceneName { get; set; } - public QualityModel Quality { get; set; } - - public bool QualityCutoffNotMet { get; set; } - } - - public static class EpisodeFileResourceMapper - { - private static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model) - { - if (model == null) return null; - - return new EpisodeFileResource - { - Id = model.Id, - - SeriesId = model.SeriesId, - SeasonNumber = model.SeasonNumber, - RelativePath = model.RelativePath, - //Path - Size = model.Size, - DateAdded = model.DateAdded, - SceneName = model.SceneName, - Quality = model.Quality, - //QualityCutoffNotMet - }; - } - - public static EpisodeFileResource ToResource(this Core.MediaFiles.EpisodeFile model, Core.Tv.Series series, Core.DecisionEngine.IQualityUpgradableSpecification qualityUpgradableSpecification) - { - if (model == null) return null; - - return new EpisodeFileResource - { - Id = model.Id, - - SeriesId = model.SeriesId, - SeasonNumber = model.SeasonNumber, - RelativePath = model.RelativePath, - Path = Path.Combine(series.Path, model.RelativePath), - Size = model.Size, - DateAdded = model.DateAdded, - SceneName = model.SceneName, - Quality = model.Quality, - QualityCutoffNotMet = qualityUpgradableSpecification.CutoffNotMet(series.Profile.Value, model.Quality) - }; - } - } -} diff --git a/src/NzbDrone.Api/Episodes/EpisodeModule.cs b/src/NzbDrone.Api/Episodes/EpisodeModule.cs deleted file mode 100644 index c318cca92..000000000 --- a/src/NzbDrone.Api/Episodes/EpisodeModule.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using NzbDrone.Api.REST; -using NzbDrone.Core.Tv; -using NzbDrone.Core.DecisionEngine; -using NzbDrone.SignalR; -using Nancy; - -namespace NzbDrone.Api.Episodes -{ - public class EpisodeModule : EpisodeModuleWithSignalR - { - public EpisodeModule(ISeriesService seriesService, - IEpisodeService episodeService, - IQualityUpgradableSpecification qualityUpgradableSpecification, - IBroadcastSignalRMessage signalRBroadcaster) - : base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster) - { - GetResourceAll = GetEpisodes; - UpdateResource = SetMonitored; - } - - private List GetEpisodes() - { - if (!Request.Query.SeriesId.HasValue) - { - throw new BadRequestException("seriesId is missing"); - } - - var seriesId = (int)Request.Query.SeriesId; - - var resources = MapToResource(_episodeService.GetEpisodeBySeries(seriesId), false, true); - - return resources; - } - - private void SetMonitored(EpisodeResource episodeResource) - { - _episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored); - } - } -} diff --git a/src/NzbDrone.Api/Episodes/EpisodeModuleWithSignalR.cs b/src/NzbDrone.Api/Episodes/EpisodeModuleWithSignalR.cs deleted file mode 100644 index d4c1deb27..000000000 --- a/src/NzbDrone.Api/Episodes/EpisodeModuleWithSignalR.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System.Collections.Generic; -using NzbDrone.Common.Extensions; -using NzbDrone.Api.EpisodeFiles; -using NzbDrone.Api.Series; -using NzbDrone.Core.Datastore.Events; -using NzbDrone.Core.DecisionEngine; -using NzbDrone.Core.Download; -using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.Tv; -using NzbDrone.SignalR; - -namespace NzbDrone.Api.Episodes -{ - public abstract class EpisodeModuleWithSignalR : NzbDroneRestModuleWithSignalR, - IHandle, - IHandle - { - protected readonly IEpisodeService _episodeService; - protected readonly ISeriesService _seriesService; - protected readonly IQualityUpgradableSpecification _qualityUpgradableSpecification; - - protected EpisodeModuleWithSignalR(IEpisodeService episodeService, - ISeriesService seriesService, - IQualityUpgradableSpecification qualityUpgradableSpecification, - IBroadcastSignalRMessage signalRBroadcaster) - : base(signalRBroadcaster) - { - _episodeService = episodeService; - _seriesService = seriesService; - _qualityUpgradableSpecification = qualityUpgradableSpecification; - - GetResourceById = GetEpisode; - } - - protected EpisodeModuleWithSignalR(IEpisodeService episodeService, - ISeriesService seriesService, - IQualityUpgradableSpecification qualityUpgradableSpecification, - IBroadcastSignalRMessage signalRBroadcaster, - string resource) - : base(signalRBroadcaster, resource) - { - _episodeService = episodeService; - _seriesService = seriesService; - _qualityUpgradableSpecification = qualityUpgradableSpecification; - - GetResourceById = GetEpisode; - } - - protected EpisodeResource GetEpisode(int id) - { - var episode = _episodeService.GetEpisode(id); - var resource = MapToResource(episode, true, true); - return resource; - } - - protected EpisodeResource MapToResource(Episode episode, bool includeSeries, bool includeEpisodeFile) - { - var resource = episode.ToResource(); - - if (includeSeries || includeEpisodeFile) - { - var series = episode.Series ?? _seriesService.GetSeries(episode.SeriesId); - - if (includeSeries) - { - resource.Series = series.ToResource(); - } - if (includeEpisodeFile && episode.EpisodeFileId != 0) - { - resource.EpisodeFile = episode.EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification); - } - } - - return resource; - } - - protected List MapToResource(List episodes, bool includeSeries, bool includeEpisodeFile) - { - var result = episodes.ToResource(); - - if (includeSeries || includeEpisodeFile) - { - var seriesDict = new Dictionary(); - for (var i = 0; i < episodes.Count; i++) - { - var episode = episodes[i]; - var resource = result[i]; - - var series = episode.Series ?? seriesDict.GetValueOrDefault(episodes[i].SeriesId) ?? _seriesService.GetSeries(episodes[i].SeriesId); - seriesDict[series.Id] = series; - - if (includeSeries) - { - resource.Series = series.ToResource(); - } - if (includeEpisodeFile && episodes[i].EpisodeFileId != 0) - { - resource.EpisodeFile = episodes[i].EpisodeFile.Value.ToResource(series, _qualityUpgradableSpecification); - } - } - } - - return result; - } - - public void Handle(EpisodeGrabbedEvent message) - { - foreach (var episode in message.Episode.Episodes) - { - var resource = episode.ToResource(); - resource.Grabbed = true; - - BroadcastResourceChange(ModelAction.Updated, resource); - } - } - - public void Handle(EpisodeDownloadedEvent message) - { - foreach (var episode in message.Episode.Episodes) - { - BroadcastResourceChange(ModelAction.Updated, episode.Id); - } - } - } -} diff --git a/src/NzbDrone.Api/Episodes/EpisodeResource.cs b/src/NzbDrone.Api/Episodes/EpisodeResource.cs deleted file mode 100644 index 3ff489f38..000000000 --- a/src/NzbDrone.Api/Episodes/EpisodeResource.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using NzbDrone.Api.EpisodeFiles; -using NzbDrone.Api.REST; -using NzbDrone.Api.Series; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Api.Episodes -{ - public class EpisodeResource : RestResource - { - public int SeriesId { get; set; } - public int EpisodeFileId { get; set; } - public int SeasonNumber { get; set; } - public int EpisodeNumber { get; set; } - public string Title { get; set; } - public string AirDate { get; set; } - public DateTime? AirDateUtc { get; set; } - public string Overview { get; set; } - public EpisodeFileResource EpisodeFile { get; set; } - - public bool HasFile { get; set; } - public bool Monitored { get; set; } - public int? AbsoluteEpisodeNumber { get; set; } - public int? SceneAbsoluteEpisodeNumber { get; set; } - public int? SceneEpisodeNumber { get; set; } - public int? SceneSeasonNumber { get; set; } - public bool UnverifiedSceneNumbering { get; set; } - public string SeriesTitle { get; set; } - public SeriesResource Series { get; set; } - - //Hiding this so people don't think its usable (only used to set the initial state) - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool Grabbed { get; set; } - } - - public static class EpisodeResourceMapper - { - public static EpisodeResource ToResource(this Episode model) - { - if (model == null) return null; - - return new EpisodeResource - { - Id = model.Id, - - SeriesId = model.SeriesId, - EpisodeFileId = model.EpisodeFileId, - SeasonNumber = model.SeasonNumber, - EpisodeNumber = model.EpisodeNumber, - Title = model.Title, - AirDate = model.AirDate, - AirDateUtc = model.AirDateUtc, - Overview = model.Overview, - //EpisodeFile - - HasFile = model.HasFile, - Monitored = model.Monitored, - AbsoluteEpisodeNumber = model.AbsoluteEpisodeNumber, - SceneAbsoluteEpisodeNumber = model.SceneAbsoluteEpisodeNumber, - SceneEpisodeNumber = model.SceneEpisodeNumber, - SceneSeasonNumber = model.SceneSeasonNumber, - UnverifiedSceneNumbering = model.UnverifiedSceneNumbering, - SeriesTitle = model.SeriesTitle, - //Series = model.Series.MapToResource(), - }; - } - - public static List ToResource(this IEnumerable models) - { - if (models == null) return null; - - return models.Select(ToResource).ToList(); - } - } -} diff --git a/src/NzbDrone.Api/Episodes/RenameEpisodeModule.cs b/src/NzbDrone.Api/Episodes/RenameEpisodeModule.cs deleted file mode 100644 index 87f39b964..000000000 --- a/src/NzbDrone.Api/Episodes/RenameEpisodeModule.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Collections.Generic; -using NzbDrone.Api.REST; -using NzbDrone.Core.MediaFiles; - -namespace NzbDrone.Api.Episodes -{ - public class RenameEpisodeModule : NzbDroneRestModule - { - private readonly IRenameEpisodeFileService _renameEpisodeFileService; - - public RenameEpisodeModule(IRenameEpisodeFileService renameEpisodeFileService) - : base("rename") - { - _renameEpisodeFileService = renameEpisodeFileService; - - GetResourceAll = GetEpisodes; - } - - private List GetEpisodes() - { - if (!Request.Query.SeriesId.HasValue) - { - throw new BadRequestException("seriesId is missing"); - } - - var seriesId = (int)Request.Query.SeriesId; - - if (Request.Query.SeasonNumber.HasValue) - { - var seasonNumber = (int)Request.Query.SeasonNumber; - return _renameEpisodeFileService.GetRenamePreviews(seriesId, seasonNumber).ToResource(); - } - - return _renameEpisodeFileService.GetRenamePreviews(seriesId).ToResource(); - } - } -} diff --git a/src/NzbDrone.Api/Episodes/RenameEpisodeResource.cs b/src/NzbDrone.Api/Episodes/RenameEpisodeResource.cs deleted file mode 100644 index c48f2cdf4..000000000 --- a/src/NzbDrone.Api/Episodes/RenameEpisodeResource.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using NzbDrone.Api.REST; - -namespace NzbDrone.Api.Episodes -{ - public class RenameEpisodeResource : RestResource - { - public int SeriesId { get; set; } - public int SeasonNumber { get; set; } - public List EpisodeNumbers { get; set; } - public int EpisodeFileId { get; set; } - public string ExistingPath { get; set; } - public string NewPath { get; set; } - } - - public static class RenameEpisodeResourceMapper - { - public static RenameEpisodeResource ToResource(this Core.MediaFiles.RenameEpisodeFilePreview model) - { - if (model == null) return null; - - return new RenameEpisodeResource - { - SeriesId = model.SeriesId, - SeasonNumber = model.SeasonNumber, - EpisodeNumbers = model.EpisodeNumbers.ToList(), - EpisodeFileId = model.EpisodeFileId, - ExistingPath = model.ExistingPath, - NewPath = model.NewPath - }; - } - - public static List ToResource(this IEnumerable models) - { - return models.Select(ToResource).ToList(); - } - } -} diff --git a/src/NzbDrone.Api/History/HistoryModule.cs b/src/NzbDrone.Api/History/HistoryModule.cs index 1cf40b95c..2e2c8d004 100644 --- a/src/NzbDrone.Api/History/HistoryModule.cs +++ b/src/NzbDrone.Api/History/HistoryModule.cs @@ -1,7 +1,7 @@ -using System; +using System; using Nancy; using NzbDrone.Api.Extensions; -using NzbDrone.Api.Movie; +using NzbDrone.Api.Movies; using NzbDrone.Core.Datastore; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; diff --git a/src/NzbDrone.Api/History/HistoryResource.cs b/src/NzbDrone.Api/History/HistoryResource.cs index 93ec372c7..c4415d079 100644 --- a/src/NzbDrone.Api/History/HistoryResource.cs +++ b/src/NzbDrone.Api/History/HistoryResource.cs @@ -1,9 +1,7 @@ -using System; +using System; using System.Collections.Generic; -using NzbDrone.Api.Episodes; using NzbDrone.Api.REST; -using NzbDrone.Api.Series; -using NzbDrone.Api.Movie; +using NzbDrone.Api.Movies; using NzbDrone.Core.History; using NzbDrone.Core.Qualities; @@ -12,9 +10,7 @@ namespace NzbDrone.Api.History { public class HistoryResource : RestResource { - public int EpisodeId { get; set; } public int MovieId { get; set; } - public int SeriesId { get; set; } public string SourceTitle { get; set; } public QualityModel Quality { get; set; } public bool QualityCutoffNotMet { get; set; } @@ -25,8 +21,6 @@ public class HistoryResource : RestResource public Dictionary Data { get; set; } public MovieResource Movie { get; set; } - public EpisodeResource Episode { get; set; } - public SeriesResource Series { get; set; } } public static class HistoryResourceMapper @@ -38,9 +32,6 @@ public static HistoryResource ToResource(this Core.History.History model) return new HistoryResource { Id = model.Id, - - EpisodeId = model.EpisodeId, - SeriesId = model.SeriesId, MovieId = model.MovieId, SourceTitle = model.SourceTitle, Quality = model.Quality, @@ -51,8 +42,6 @@ public static HistoryResource ToResource(this Core.History.History model) EventType = model.EventType, Data = model.Data - //Episode - //Series }; } } diff --git a/src/NzbDrone.Api/ManualImport/ManualImportResource.cs b/src/NzbDrone.Api/ManualImport/ManualImportResource.cs index 70b86dfdd..6fff834c7 100644 --- a/src/NzbDrone.Api/ManualImport/ManualImportResource.cs +++ b/src/NzbDrone.Api/ManualImport/ManualImportResource.cs @@ -1,9 +1,7 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using NzbDrone.Api.Episodes; -using NzbDrone.Api.Movie; +using NzbDrone.Api.Movies; using NzbDrone.Api.REST; -using NzbDrone.Api.Series; using NzbDrone.Common.Crypto; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Qualities; @@ -16,10 +14,7 @@ public class ManualImportResource : RestResource public string RelativePath { get; set; } public string Name { get; set; } public long Size { get; set; } - public SeriesResource Series { get; set; } public MovieResource Movie { get; set; } - public int? SeasonNumber { get; set; } - public List Episodes { get; set; } public QualityModel Quality { get; set; } public int QualityWeight { get; set; } public string DownloadId { get; set; } @@ -40,10 +35,7 @@ public static ManualImportResource ToResource(this Core.MediaFiles.EpisodeImport RelativePath = model.RelativePath, Name = model.Name, Size = model.Size, - Series = model.Series.ToResource(), Movie = model.Movie.ToResource(), - SeasonNumber = model.SeasonNumber, - Episodes = model.Episodes.ToResource(), Quality = model.Quality, //QualityWeight DownloadId = model.DownloadId, diff --git a/src/NzbDrone.Api/Movies/MovieFileModule.cs b/src/NzbDrone.Api/MovieFiles/MovieFileModule.cs similarity index 96% rename from src/NzbDrone.Api/Movies/MovieFileModule.cs rename to src/NzbDrone.Api/MovieFiles/MovieFileModule.cs index 1356182b9..b706d703f 100644 --- a/src/NzbDrone.Api/Movies/MovieFileModule.cs +++ b/src/NzbDrone.Api/MovieFiles/MovieFileModule.cs @@ -1,8 +1,7 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using NLog; using NzbDrone.Api.REST; -using NzbDrone.Api.Movie; using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.Events; @@ -11,7 +10,7 @@ using NzbDrone.Core.DecisionEngine; using NzbDrone.SignalR; -namespace NzbDrone.Api.EpisodeFiles +namespace NzbDrone.Api.MovieFiles { public class MovieFileModule : NzbDroneRestModuleWithSignalR, IHandle { @@ -72,4 +71,4 @@ public void Handle(MovieFileAddedEvent message) BroadcastResourceChange(ModelAction.Updated, message.MovieFile.Id); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Api/Series/MovieFileResource.cs b/src/NzbDrone.Api/MovieFiles/MovieFileResource.cs similarity index 97% rename from src/NzbDrone.Api/Series/MovieFileResource.cs rename to src/NzbDrone.Api/MovieFiles/MovieFileResource.cs index a7a9fe16f..e4679ccce 100644 --- a/src/NzbDrone.Api/Series/MovieFileResource.cs +++ b/src/NzbDrone.Api/MovieFiles/MovieFileResource.cs @@ -1,14 +1,14 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Api.REST; +using NzbDrone.Api.Movies; using NzbDrone.Core.MediaCover; using NzbDrone.Core.Tv; using NzbDrone.Core.Qualities; -using NzbDrone.Api.Series; using NzbDrone.Core.MediaFiles; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.MovieFiles { public class MovieFileResource : RestResource { diff --git a/src/NzbDrone.Api/Movies/AlternativeTitleModule.cs b/src/NzbDrone.Api/Movies/AlternativeTitleModule.cs index 45937114d..4a88e932d 100644 --- a/src/NzbDrone.Api/Movies/AlternativeTitleModule.cs +++ b/src/NzbDrone.Api/Movies/AlternativeTitleModule.cs @@ -4,7 +4,6 @@ using Marr.Data; using Nancy; using NzbDrone.Api; -using NzbDrone.Api.Movie; using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; using NzbDrone.Core.MediaCover; @@ -18,7 +17,7 @@ using NzbDrone.Core.Tv; using NzbDrone.Core.Tv.Events; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.Movies { public class AlternativeTitleModule : NzbDroneRestModule { @@ -54,4 +53,4 @@ private AlternativeTitleResource GetTitle(int id) return _altTitleService.GetById(id).ToResource(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Api/Series/AlternativeTitleResource.cs b/src/NzbDrone.Api/Movies/AlternativeTitleResource.cs similarity index 97% rename from src/NzbDrone.Api/Series/AlternativeTitleResource.cs rename to src/NzbDrone.Api/Movies/AlternativeTitleResource.cs index b0b538dc9..64254a9f1 100644 --- a/src/NzbDrone.Api/Series/AlternativeTitleResource.cs +++ b/src/NzbDrone.Api/Movies/AlternativeTitleResource.cs @@ -1,16 +1,15 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Api.REST; using NzbDrone.Core.MediaCover; using NzbDrone.Core.Tv; using NzbDrone.Core.Qualities; -using NzbDrone.Api.Series; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies.AlternativeTitles; using NzbDrone.Core.Parser; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.Movies { public class AlternativeTitleResource : RestResource { diff --git a/src/NzbDrone.Api/Movies/AlternativeYearModule.cs b/src/NzbDrone.Api/Movies/AlternativeYearModule.cs index 9da0898ec..cf58a9f5b 100644 --- a/src/NzbDrone.Api/Movies/AlternativeYearModule.cs +++ b/src/NzbDrone.Api/Movies/AlternativeYearModule.cs @@ -4,7 +4,6 @@ using Marr.Data; using Nancy; using NzbDrone.Api; -using NzbDrone.Api.Movie; using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; using NzbDrone.Common.Messaging; @@ -19,7 +18,7 @@ using NzbDrone.Core.Tv; using NzbDrone.Core.Tv.Events; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.Movies { public class AlternativeYearModule : NzbDroneRestModule { @@ -60,4 +59,4 @@ private AlternativeYearResource GetYear(int id) }; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Api/Movies/AlternativeYearResource.cs b/src/NzbDrone.Api/Movies/AlternativeYearResource.cs index d145fd8ae..e075b0445 100644 --- a/src/NzbDrone.Api/Movies/AlternativeYearResource.cs +++ b/src/NzbDrone.Api/Movies/AlternativeYearResource.cs @@ -1,16 +1,15 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Api.REST; using NzbDrone.Core.MediaCover; using NzbDrone.Core.Tv; using NzbDrone.Core.Qualities; -using NzbDrone.Api.Series; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies.AlternativeTitles; using NzbDrone.Core.Parser; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.Movies { public class AlternativeYearResource : RestResource { diff --git a/src/NzbDrone.Api/Series/FetchMovieListModule.cs b/src/NzbDrone.Api/Movies/FetchMovieListModule.cs similarity index 96% rename from src/NzbDrone.Api/Series/FetchMovieListModule.cs rename to src/NzbDrone.Api/Movies/FetchMovieListModule.cs index 871ebd7bc..0c56fd483 100644 --- a/src/NzbDrone.Api/Series/FetchMovieListModule.cs +++ b/src/NzbDrone.Api/Movies/FetchMovieListModule.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Nancy; using NzbDrone.Api.Extensions; using NzbDrone.Core.MediaCover; @@ -6,7 +6,7 @@ using System.Linq; using NzbDrone.Core.NetImport; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.Movies { public class FetchMovieListModule : NzbDroneRestModule { @@ -57,4 +57,4 @@ private static IEnumerable MapToResource(IEnumerable diff --git a/src/NzbDrone.Api/Series/MovieDiscoverModule.cs b/src/NzbDrone.Api/Movies/MovieDiscoverModule.cs similarity index 96% rename from src/NzbDrone.Api/Series/MovieDiscoverModule.cs rename to src/NzbDrone.Api/Movies/MovieDiscoverModule.cs index 6670eab67..cd78ea850 100644 --- a/src/NzbDrone.Api/Series/MovieDiscoverModule.cs +++ b/src/NzbDrone.Api/Movies/MovieDiscoverModule.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Nancy; using NzbDrone.Api.Extensions; using NzbDrone.Core.MediaCover; @@ -9,7 +9,7 @@ using NzbDrone.Core.NetImport; using NzbDrone.Api.NetImport; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.Movies { public class MovieDiscoverModule : NzbDroneRestModule { @@ -60,4 +60,4 @@ private static IEnumerable MapToResource(IEnumerable { diff --git a/src/NzbDrone.Api/Movies/MovieModule.cs b/src/NzbDrone.Api/Movies/MovieModule.cs index 2a4d405fc..2b8c08c04 100644 --- a/src/NzbDrone.Api/Movies/MovieModule.cs +++ b/src/NzbDrone.Api/Movies/MovieModule.cs @@ -1,11 +1,298 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; -using System.Text; +using FluentValidation; +using NzbDrone.Common.Extensions; +using NzbDrone.Api.Extensions; +using NzbDrone.Core.Datastore.Events; +using NzbDrone.Core.MediaCover; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.MediaFiles.Events; +using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.MovieStats; +using NzbDrone.Core.Tv; +using NzbDrone.Core.Tv.Events; +using NzbDrone.Core.Validation.Paths; +using NzbDrone.Core.DataAugmentation.Scene; +using NzbDrone.Core.Validation; +using NzbDrone.SignalR; +using NzbDrone.Core.Datastore; +using Microsoft.CSharp.RuntimeBinder; +using Nancy; namespace NzbDrone.Api.Movies { - class MovieModule + public class MovieModule : NzbDroneRestModuleWithSignalR, + IHandle, + IHandle, + IHandle, + IHandle, + IHandle, + IHandle, + IHandle + { + protected readonly IMovieService _moviesService; + private readonly IMovieStatisticsService _moviesStatisticsService; + private readonly IMapCoversToLocal _coverMapper; + + private const string TITLE_SLUG_ROUTE = "/titleslug/(?[^/]+)"; + + public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, + IMovieService moviesService, + IMovieStatisticsService moviesStatisticsService, + ISceneMappingService sceneMappingService, + IMapCoversToLocal coverMapper, + RootFolderValidator rootFolderValidator, + MoviePathValidator moviesPathValidator, + MovieExistsValidator moviesExistsValidator, + DroneFactoryValidator droneFactoryValidator, + MovieAncestorValidator moviesAncestorValidator, + ProfileExistsValidator profileExistsValidator + ) + : base(signalRBroadcaster) + { + _moviesService = moviesService; + _moviesStatisticsService = moviesStatisticsService; + + _coverMapper = coverMapper; + + GetResourceAll = AllMovie; + GetResourcePaged = GetMoviePaged; + GetResourceById = GetMovie; + Get[TITLE_SLUG_ROUTE] = GetByTitleSlug; /*(options) => { + return ReqResExtensions.AsResponse(GetByTitleSlug(options.slug), Nancy.HttpStatusCode.OK); + };*/ + + + + CreateResource = AddMovie; + UpdateResource = UpdateMovie; + DeleteResource = DeleteMovie; + + Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId)); + + SharedValidator.RuleFor(s => s.Path) + .Cascade(CascadeMode.StopOnFirstFailure) + .IsValidPath() + .SetValidator(rootFolderValidator) + .SetValidator(moviesPathValidator) + .SetValidator(droneFactoryValidator) + .SetValidator(moviesAncestorValidator) + .When(s => !s.Path.IsNullOrWhiteSpace()); + + SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator); + + PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace()); + PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace()); + PostValidator.RuleFor(s => s.Title).NotEmpty(); + PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator); + + PutValidator.RuleFor(s => s.Path).IsValidPath(); + } + + public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, + IMovieService moviesService, + IMovieStatisticsService moviesStatisticsService, + ISceneMappingService sceneMappingService, + IMapCoversToLocal coverMapper, + string resource) + : base(signalRBroadcaster, resource) + { + _moviesService = moviesService; + _moviesStatisticsService = moviesStatisticsService; + + _coverMapper = coverMapper; + + GetResourceAll = AllMovie; + GetResourceById = GetMovie; + CreateResource = AddMovie; + UpdateResource = UpdateMovie; + DeleteResource = DeleteMovie; + } + + private MovieResource GetMovie(int id) + { + var movies = _moviesService.GetMovie(id); + return MapToResource(movies); + } + + private PagingResource GetMoviePaged(PagingResource pagingResource) + { + var pagingSpec = pagingResource.MapToPagingSpec(); + + pagingSpec.FilterExpression = _moviesService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue, pagingResource.FilterType); + + return ApplyToPage(_moviesService.Paged, pagingSpec, MapToResource); + } + + protected MovieResource MapToResource(Core.Tv.Movie movies) + { + if (movies == null) return null; + + var resource = movies.ToResource(); + MapCoversToLocal(resource); + //FetchAndLinkMovieStatistics(resource); + //PopulateAlternateTitles(resource); + + return resource; + } + + private List AllMovie() + { + var moviesStats = _moviesStatisticsService.MovieStatistics(); + var moviesResources = _moviesService.GetAllMovies().ToResource(); + + MapCoversToLocal(moviesResources.ToArray()); + LinkMovieStatistics(moviesResources, moviesStats); + PopulateAlternateTitles(moviesResources); + + return moviesResources; + } + + private Response GetByTitleSlug(dynamic options) + { + var slug = ""; + try + { + slug = options.slug; + // do stuff with x + } + catch (RuntimeBinderException) + { + return new NotFoundResponse(); + } + + try + { + return MapToResource(_moviesService.FindByTitleSlug(slug)).AsResponse(Nancy.HttpStatusCode.OK); + } + catch (ModelNotFoundException) + { + return new NotFoundResponse(); + } + } + + private int AddMovie(MovieResource moviesResource) + { + var model = moviesResource.ToModel(); + + return _moviesService.AddMovie(model).Id; + } + + private void UpdateMovie(MovieResource moviesResource) + { + var model = moviesResource.ToModel(_moviesService.GetMovie(moviesResource.Id)); + + _moviesService.UpdateMovie(model); + + BroadcastResourceChange(ModelAction.Updated, moviesResource); + } + + private void DeleteMovie(int id) + { + var deleteFiles = false; + var addExclusion = false; + var deleteFilesQuery = Request.Query.deleteFiles; + var addExclusionQuery = Request.Query.addExclusion; + + if (deleteFilesQuery.HasValue) + { + deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value); + } + if (addExclusionQuery.HasValue) + { + addExclusion = Convert.ToBoolean(addExclusionQuery.Value); + } + + _moviesService.DeleteMovie(id, deleteFiles, addExclusion); + } + + private void MapCoversToLocal(params MovieResource[] movies) + { + foreach (var moviesResource in movies) + { + _coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images); + } + } + + private void FetchAndLinkMovieStatistics(MovieResource resource) + { + LinkMovieStatistics(resource, _moviesStatisticsService.MovieStatistics(resource.Id)); + } + + private void LinkMovieStatistics(List resources, List moviesStatistics) + { + var dictMovieStats = moviesStatistics.ToDictionary(v => v.MovieId); + + foreach (var movies in resources) + { + var stats = dictMovieStats.GetValueOrDefault(movies.Id); + if (stats == null) continue; + + LinkMovieStatistics(movies, stats); + } + } + + private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics) + { + //resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk; + } + + private void PopulateAlternateTitles(List resources) + { + foreach (var resource in resources) + { + PopulateAlternateTitles(resource); + } + } + + private void PopulateAlternateTitles(MovieResource resource) + { + //var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId); + + //if (mappings == null) return; + + //Not necessary anymore + + //resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList(); + } + + public void Handle(EpisodeImportedEvent message) + { + //BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.MovieId); + } + + public void Handle(EpisodeFileDeletedEvent message) + { + if (message.Reason == DeleteMediaFileReason.Upgrade) return; + + //BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.MovieId); + } + + public void Handle(MovieUpdatedEvent message) + { + BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); + } + + public void Handle(MovieEditedEvent message) + { + BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); + } + + public void Handle(MovieDeletedEvent message) + { + BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource()); + } + + public void Handle(MovieRenamedEvent message) + { + BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); + } + + public void Handle(MediaCoversUpdatedEvent message) + { + BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); + } } } diff --git a/src/NzbDrone.Api/Movies/MovieModuleWithSignalR.cs b/src/NzbDrone.Api/Movies/MovieModuleWithSignalR.cs index e03b37418..280376596 100644 --- a/src/NzbDrone.Api/Movies/MovieModuleWithSignalR.cs +++ b/src/NzbDrone.Api/Movies/MovieModuleWithSignalR.cs @@ -1,4 +1,4 @@ -using NzbDrone.Api.Movie; +using NzbDrone.Api.Movies; using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; diff --git a/src/NzbDrone.Api/Series/MovieResource.cs b/src/NzbDrone.Api/Movies/MovieResource.cs similarity index 99% rename from src/NzbDrone.Api/Series/MovieResource.cs rename to src/NzbDrone.Api/Movies/MovieResource.cs index ec4a16ed2..c4581beb2 100644 --- a/src/NzbDrone.Api/Series/MovieResource.cs +++ b/src/NzbDrone.Api/Movies/MovieResource.cs @@ -1,12 +1,12 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Api.REST; using NzbDrone.Core.MediaCover; using NzbDrone.Core.Tv; -using NzbDrone.Api.Series; +using NzbDrone.Api.MovieFiles; -namespace NzbDrone.Api.Movie +namespace NzbDrone.Api.Movies { public class MovieResource : RestResource { diff --git a/src/NzbDrone.Api/Movies/RenameMovieModule.cs b/src/NzbDrone.Api/Movies/RenameMovieModule.cs index a55d4ac60..e965545c5 100644 --- a/src/NzbDrone.Api/Movies/RenameMovieModule.cs +++ b/src/NzbDrone.Api/Movies/RenameMovieModule.cs @@ -1,4 +1,4 @@ -using NzbDrone.Api.REST; +using NzbDrone.Api.REST; using NzbDrone.Core.MediaFiles; using System; using System.Collections.Generic; diff --git a/src/NzbDrone.Api/Movies/RenameMovieResource.cs b/src/NzbDrone.Api/Movies/RenameMovieResource.cs index d71f1bbcf..04eeef97c 100644 --- a/src/NzbDrone.Api/Movies/RenameMovieResource.cs +++ b/src/NzbDrone.Api/Movies/RenameMovieResource.cs @@ -1,4 +1,4 @@ -using NzbDrone.Api.REST; +using NzbDrone.Api.REST; using System.Collections.Generic; using System.Linq; diff --git a/src/NzbDrone.Api/NetImport/ImportExclusionsModule.cs b/src/NzbDrone.Api/NetImport/ImportExclusionsModule.cs index c4e1d995d..4615c65f7 100644 --- a/src/NzbDrone.Api/NetImport/ImportExclusionsModule.cs +++ b/src/NzbDrone.Api/NetImport/ImportExclusionsModule.cs @@ -1,34 +1,34 @@ -using System.Collections.Generic; -using FluentValidation; -using NzbDrone.Api.ClientSchema; -using NzbDrone.Core.NetImport; -using NzbDrone.Core.NetImport.ImportExclusions; -using NzbDrone.Core.Validation.Paths; - -namespace NzbDrone.Api.NetImport -{ - public class ImportExclusionsModule : NzbDroneRestModule - { - private readonly IImportExclusionsService _exclusionService; - - public ImportExclusionsModule(NetImportFactory netImportFactory, IImportExclusionsService exclusionService) : base("exclusions") - { +using System.Collections.Generic; +using FluentValidation; +using NzbDrone.Api.ClientSchema; +using NzbDrone.Core.NetImport; +using NzbDrone.Core.NetImport.ImportExclusions; +using NzbDrone.Core.Validation.Paths; + +namespace NzbDrone.Api.NetImport +{ + public class ImportExclusionsModule : NzbDroneRestModule + { + private readonly IImportExclusionsService _exclusionService; + + public ImportExclusionsModule(NetImportFactory netImportFactory, IImportExclusionsService exclusionService) : base("exclusions") + { _exclusionService = exclusionService; GetResourceAll = GetAll; CreateResource = AddExclusion; DeleteResource = RemoveExclusion; - GetResourceById = GetById; - } - - public List GetAll() - { - return _exclusionService.GetAllExclusions().ToResource(); + GetResourceById = GetById; + } + + public List GetAll() + { + return _exclusionService.GetAllExclusions().ToResource(); } public ImportExclusionsResource GetById(int id) { return _exclusionService.GetById(id).ToResource(); - } + } public int AddExclusion(ImportExclusionsResource exclusionResource) { @@ -40,6 +40,6 @@ public int AddExclusion(ImportExclusionsResource exclusionResource) public void RemoveExclusion (int id) { _exclusionService.RemoveExclusion(new ImportExclusion { Id = id }); - } - } -} + } + } +} diff --git a/src/NzbDrone.Api/NetImport/ImportExclusionsResource.cs b/src/NzbDrone.Api/NetImport/ImportExclusionsResource.cs index a3cab77a7..9233cb815 100644 --- a/src/NzbDrone.Api/NetImport/ImportExclusionsResource.cs +++ b/src/NzbDrone.Api/NetImport/ImportExclusionsResource.cs @@ -1,46 +1,46 @@ -using System.Collections.Generic; -using System.Linq; -using NzbDrone.Core.NetImport; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Api.NetImport -{ - public class ImportExclusionsResource : ProviderResource +using System.Collections.Generic; +using System.Linq; +using NzbDrone.Core.NetImport; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Api.NetImport +{ + public class ImportExclusionsResource : ProviderResource { - //public int Id { get; set; } - public int TmdbId { get; set; } - public string MovieTitle { get; set; } - public int MovieYear { get; set; } - } - - public static class ImportExclusionsResourceMapper - { - public static ImportExclusionsResource ToResource(this Core.NetImport.ImportExclusions.ImportExclusion model) - { - if (model == null) return null; - - return new ImportExclusionsResource + //public int Id { get; set; } + public int TmdbId { get; set; } + public string MovieTitle { get; set; } + public int MovieYear { get; set; } + } + + public static class ImportExclusionsResourceMapper + { + public static ImportExclusionsResource ToResource(this Core.NetImport.ImportExclusions.ImportExclusion model) + { + if (model == null) return null; + + return new ImportExclusionsResource { - Id = model.Id, - TmdbId = model.TmdbId, - MovieTitle = model.MovieTitle, - MovieYear = model.MovieYear - }; - } - - public static List ToResource(this IEnumerable exclusions) - { - return exclusions.Select(ToResource).ToList(); + Id = model.Id, + TmdbId = model.TmdbId, + MovieTitle = model.MovieTitle, + MovieYear = model.MovieYear + }; + } + + public static List ToResource(this IEnumerable exclusions) + { + return exclusions.Select(ToResource).ToList(); } public static Core.NetImport.ImportExclusions.ImportExclusion ToModel(this ImportExclusionsResource resource) { - return new Core.NetImport.ImportExclusions.ImportExclusion - { + return new Core.NetImport.ImportExclusions.ImportExclusion + { TmdbId = resource.TmdbId, MovieTitle = resource.MovieTitle, - MovieYear = resource.MovieYear + MovieYear = resource.MovieYear }; - } - } -} + } + } +} diff --git a/src/NzbDrone.Api/NetImport/ListImportModule.cs b/src/NzbDrone.Api/NetImport/ListImportModule.cs index f1d81aefd..789a1556f 100644 --- a/src/NzbDrone.Api/NetImport/ListImportModule.cs +++ b/src/NzbDrone.Api/NetImport/ListImportModule.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Nancy; using Nancy.Extensions; using NzbDrone.Api.Extensions; -using NzbDrone.Api.Movie; +using NzbDrone.Api.Movies; using NzbDrone.Core.MetadataSource; using NzbDrone.Core.Tv; diff --git a/src/NzbDrone.Api/NetImport/NetImportResource.cs b/src/NzbDrone.Api/NetImport/NetImportResource.cs index f01520784..01a9104a6 100644 --- a/src/NzbDrone.Api/NetImport/NetImportResource.cs +++ b/src/NzbDrone.Api/NetImport/NetImportResource.cs @@ -1,4 +1,3 @@ -using NzbDrone.Core.NetImport; using NzbDrone.Core.Tv; namespace NzbDrone.Api.NetImport diff --git a/src/NzbDrone.Api/NzbDrone.Api.csproj b/src/NzbDrone.Api/NzbDrone.Api.csproj index 179760435..b9b0f0506 100644 --- a/src/NzbDrone.Api/NzbDrone.Api.csproj +++ b/src/NzbDrone.Api/NzbDrone.Api.csproj @@ -125,8 +125,8 @@ - - + + @@ -161,13 +161,6 @@ - - - - - - - @@ -243,19 +236,13 @@ - - - - - - - - - + + + + - + - @@ -270,12 +257,10 @@ - - - + diff --git a/src/NzbDrone.Api/Parse/ParseModule.cs b/src/NzbDrone.Api/Parse/ParseModule.cs index df36307ff..064e1bbf1 100644 --- a/src/NzbDrone.Api/Parse/ParseModule.cs +++ b/src/NzbDrone.Api/Parse/ParseModule.cs @@ -1,5 +1,4 @@ -using NzbDrone.Api.Episodes; -using NzbDrone.Api.Series; +using NzbDrone.Api.Movies; using NzbDrone.Core.Parser; namespace NzbDrone.Api.Parse @@ -18,23 +17,22 @@ public ParseModule(IParsingService parsingService) private ParseResource Parse() { var title = Request.Query.Title.Value as string; - var parsedEpisodeInfo = Parser.ParseTitle(title); + var parsedMovieInfo = Parser.ParseMovieTitle(title, false); - if (parsedEpisodeInfo == null) + if (parsedMovieInfo == null) { return null; } - var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); + var remoteMovie = _parsingService.Map(parsedMovieInfo, ""); - if (remoteEpisode != null) + if (remoteMovie != null) { return new ParseResource { Title = title, - ParsedEpisodeInfo = remoteEpisode.ParsedEpisodeInfo, - Series = remoteEpisode.Series.ToResource(), - Episodes = remoteEpisode.Episodes.ToResource() + ParsedMovieInfo = remoteMovie.RemoteMovie.ParsedMovieInfo, + Movie = remoteMovie.Movie.ToResource() }; } else @@ -42,9 +40,9 @@ private ParseResource Parse() return new ParseResource { Title = title, - ParsedEpisodeInfo = parsedEpisodeInfo + ParsedMovieInfo = parsedMovieInfo }; } } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Api/Parse/ParseResource.cs b/src/NzbDrone.Api/Parse/ParseResource.cs index c795f09c3..de0dbcc2c 100644 --- a/src/NzbDrone.Api/Parse/ParseResource.cs +++ b/src/NzbDrone.Api/Parse/ParseResource.cs @@ -1,7 +1,6 @@ -using System.Collections.Generic; -using NzbDrone.Api.Episodes; +using System.Collections.Generic; +using NzbDrone.Api.Movies; using NzbDrone.Api.REST; -using NzbDrone.Api.Series; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Api.Parse @@ -9,8 +8,7 @@ namespace NzbDrone.Api.Parse public class ParseResource : RestResource { public string Title { get; set; } - public ParsedEpisodeInfo ParsedEpisodeInfo { get; set; } - public SeriesResource Series { get; set; } - public List Episodes { get; set; } + public ParsedMovieInfo ParsedMovieInfo { get; set; } + public MovieResource Movie { get; set; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Api/Queue/QueueResource.cs b/src/NzbDrone.Api/Queue/QueueResource.cs index e90a9bace..ea82956ad 100644 --- a/src/NzbDrone.Api/Queue/QueueResource.cs +++ b/src/NzbDrone.Api/Queue/QueueResource.cs @@ -1,10 +1,8 @@ -using System; +using System; using System.Collections.Generic; using NzbDrone.Api.REST; using NzbDrone.Core.Qualities; -using NzbDrone.Api.Series; -using NzbDrone.Api.Episodes; -using NzbDrone.Api.Movie; +using NzbDrone.Api.Movies; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.Indexers; using System.Linq; @@ -13,8 +11,6 @@ namespace NzbDrone.Api.Queue { public class QueueResource : RestResource { - public SeriesResource Series { get; set; } - public EpisodeResource Episode { get; set; } public MovieResource Movie { get; set; } public QualityModel Quality { get; set; } public decimal Size { get; set; } @@ -38,9 +34,6 @@ public static QueueResource ToResource(this Core.Queue.Queue model) return new QueueResource { Id = model.Id, - - Series = model.Series.ToResource(), - Episode = model.Episode.ToResource(), Quality = model.Quality, Size = model.Size, Title = model.Title, diff --git a/src/NzbDrone.Api/SeasonPass/SeasonPassModule.cs b/src/NzbDrone.Api/SeasonPass/SeasonPassModule.cs deleted file mode 100644 index 93cd25ce5..000000000 --- a/src/NzbDrone.Api/SeasonPass/SeasonPassModule.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Nancy; -using NzbDrone.Api.Extensions; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Api.SeasonPass -{ - public class SeasonPassModule : NzbDroneApiModule - { - private readonly IEpisodeMonitoredService _episodeMonitoredService; - - public SeasonPassModule(IEpisodeMonitoredService episodeMonitoredService) - : base("/seasonpass") - { - _episodeMonitoredService = episodeMonitoredService; - Post["/"] = series => UpdateAll(); - } - - private Response UpdateAll() - { - //Read from request - var request = Request.Body.FromJson(); - - foreach (var s in request.Series) - { - _episodeMonitoredService.SetEpisodeMonitoredStatus(s, request.MonitoringOptions); - } - - return "ok".AsResponse(HttpStatusCode.Accepted); - } - } -} diff --git a/src/NzbDrone.Api/SeasonPass/SeasonPassResource.cs b/src/NzbDrone.Api/SeasonPass/SeasonPassResource.cs deleted file mode 100644 index af537e7f9..000000000 --- a/src/NzbDrone.Api/SeasonPass/SeasonPassResource.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Api.SeasonPass -{ - public class SeasonPassResource - { - public List Series { get; set; } - public MonitoringOptions MonitoringOptions { get; set; } - } -} diff --git a/src/NzbDrone.Api/Series/MovieModule.cs b/src/NzbDrone.Api/Series/MovieModule.cs deleted file mode 100644 index 03e9fdcdb..000000000 --- a/src/NzbDrone.Api/Series/MovieModule.cs +++ /dev/null @@ -1,298 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using FluentValidation; -using NzbDrone.Common.Extensions; -using NzbDrone.Api.Extensions; -using NzbDrone.Core.Datastore.Events; -using NzbDrone.Core.MediaCover; -using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.MovieStats; -using NzbDrone.Core.Tv; -using NzbDrone.Core.Tv.Events; -using NzbDrone.Core.Validation.Paths; -using NzbDrone.Core.DataAugmentation.Scene; -using NzbDrone.Core.Validation; -using NzbDrone.SignalR; -using NzbDrone.Core.Datastore; -using Microsoft.CSharp.RuntimeBinder; -using Nancy; - -namespace NzbDrone.Api.Movie -{ - public class MovieModule : NzbDroneRestModuleWithSignalR, - IHandle, - IHandle, - IHandle, - IHandle, - IHandle, - IHandle, - IHandle - - { - protected readonly IMovieService _moviesService; - private readonly IMovieStatisticsService _moviesStatisticsService; - private readonly IMapCoversToLocal _coverMapper; - - private const string TITLE_SLUG_ROUTE = "/titleslug/(?[^/]+)"; - - public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, - IMovieService moviesService, - IMovieStatisticsService moviesStatisticsService, - ISceneMappingService sceneMappingService, - IMapCoversToLocal coverMapper, - RootFolderValidator rootFolderValidator, - MoviePathValidator moviesPathValidator, - MovieExistsValidator moviesExistsValidator, - DroneFactoryValidator droneFactoryValidator, - MovieAncestorValidator moviesAncestorValidator, - ProfileExistsValidator profileExistsValidator - ) - : base(signalRBroadcaster) - { - _moviesService = moviesService; - _moviesStatisticsService = moviesStatisticsService; - - _coverMapper = coverMapper; - - GetResourceAll = AllMovie; - GetResourcePaged = GetMoviePaged; - GetResourceById = GetMovie; - Get[TITLE_SLUG_ROUTE] = GetByTitleSlug; /*(options) => { - return ReqResExtensions.AsResponse(GetByTitleSlug(options.slug), Nancy.HttpStatusCode.OK); - };*/ - - - - CreateResource = AddMovie; - UpdateResource = UpdateMovie; - DeleteResource = DeleteMovie; - - Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId)); - - SharedValidator.RuleFor(s => s.Path) - .Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() - .SetValidator(rootFolderValidator) - .SetValidator(moviesPathValidator) - .SetValidator(droneFactoryValidator) - .SetValidator(moviesAncestorValidator) - .When(s => !s.Path.IsNullOrWhiteSpace()); - - SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator); - - PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace()); - PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace()); - PostValidator.RuleFor(s => s.Title).NotEmpty(); - PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator); - - PutValidator.RuleFor(s => s.Path).IsValidPath(); - } - - public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, - IMovieService moviesService, - IMovieStatisticsService moviesStatisticsService, - ISceneMappingService sceneMappingService, - IMapCoversToLocal coverMapper, - string resource) - : base(signalRBroadcaster, resource) - { - _moviesService = moviesService; - _moviesStatisticsService = moviesStatisticsService; - - _coverMapper = coverMapper; - - GetResourceAll = AllMovie; - GetResourceById = GetMovie; - CreateResource = AddMovie; - UpdateResource = UpdateMovie; - DeleteResource = DeleteMovie; - } - - private MovieResource GetMovie(int id) - { - var movies = _moviesService.GetMovie(id); - return MapToResource(movies); - } - - private PagingResource GetMoviePaged(PagingResource pagingResource) - { - var pagingSpec = pagingResource.MapToPagingSpec(); - - pagingSpec.FilterExpression = _moviesService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue, pagingResource.FilterType); - - return ApplyToPage(_moviesService.Paged, pagingSpec, MapToResource); - } - - protected MovieResource MapToResource(Core.Tv.Movie movies) - { - if (movies == null) return null; - - var resource = movies.ToResource(); - MapCoversToLocal(resource); - //FetchAndLinkMovieStatistics(resource); - //PopulateAlternateTitles(resource); - - return resource; - } - - private List AllMovie() - { - var moviesStats = _moviesStatisticsService.MovieStatistics(); - var moviesResources = _moviesService.GetAllMovies().ToResource(); - - MapCoversToLocal(moviesResources.ToArray()); - LinkMovieStatistics(moviesResources, moviesStats); - PopulateAlternateTitles(moviesResources); - - return moviesResources; - } - - private Response GetByTitleSlug(dynamic options) - { - var slug = ""; - try - { - slug = options.slug; - // do stuff with x - } - catch (RuntimeBinderException) - { - return new NotFoundResponse(); - } - - try - { - return MapToResource(_moviesService.FindByTitleSlug(slug)).AsResponse(Nancy.HttpStatusCode.OK); - } - catch (ModelNotFoundException) - { - return new NotFoundResponse(); - } - } - - private int AddMovie(MovieResource moviesResource) - { - var model = moviesResource.ToModel(); - - return _moviesService.AddMovie(model).Id; - } - - private void UpdateMovie(MovieResource moviesResource) - { - var model = moviesResource.ToModel(_moviesService.GetMovie(moviesResource.Id)); - - _moviesService.UpdateMovie(model); - - BroadcastResourceChange(ModelAction.Updated, moviesResource); - } - - private void DeleteMovie(int id) - { - var deleteFiles = false; - var addExclusion = false; - var deleteFilesQuery = Request.Query.deleteFiles; - var addExclusionQuery = Request.Query.addExclusion; - - if (deleteFilesQuery.HasValue) - { - deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value); - } - if (addExclusionQuery.HasValue) - { - addExclusion = Convert.ToBoolean(addExclusionQuery.Value); - } - - _moviesService.DeleteMovie(id, deleteFiles, addExclusion); - } - - private void MapCoversToLocal(params MovieResource[] movies) - { - foreach (var moviesResource in movies) - { - _coverMapper.ConvertToLocalUrls(moviesResource.Id, moviesResource.Images); - } - } - - private void FetchAndLinkMovieStatistics(MovieResource resource) - { - LinkMovieStatistics(resource, _moviesStatisticsService.MovieStatistics(resource.Id)); - } - - private void LinkMovieStatistics(List resources, List moviesStatistics) - { - var dictMovieStats = moviesStatistics.ToDictionary(v => v.MovieId); - - foreach (var movies in resources) - { - var stats = dictMovieStats.GetValueOrDefault(movies.Id); - if (stats == null) continue; - - LinkMovieStatistics(movies, stats); - } - } - - private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics) - { - //resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk; - } - - private void PopulateAlternateTitles(List resources) - { - foreach (var resource in resources) - { - PopulateAlternateTitles(resource); - } - } - - private void PopulateAlternateTitles(MovieResource resource) - { - //var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId); - - //if (mappings == null) return; - - //Not necessary anymore - - //resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList(); - } - - public void Handle(EpisodeImportedEvent message) - { - //BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.MovieId); - } - - public void Handle(EpisodeFileDeletedEvent message) - { - if (message.Reason == DeleteMediaFileReason.Upgrade) return; - - //BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.MovieId); - } - - public void Handle(MovieUpdatedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); - } - - public void Handle(MovieEditedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); - } - - public void Handle(MovieDeletedEvent message) - { - BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource()); - } - - public void Handle(MovieRenamedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); - } - - public void Handle(MediaCoversUpdatedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); - } - } -} diff --git a/src/NzbDrone.Api/Series/SeasonResource.cs b/src/NzbDrone.Api/Series/SeasonResource.cs deleted file mode 100644 index 2231502d9..000000000 --- a/src/NzbDrone.Api/Series/SeasonResource.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using NzbDrone.Core.Tv; -namespace NzbDrone.Api.Series -{ - public class SeasonResource - { - public int SeasonNumber { get; set; } - public bool Monitored { get; set; } - public SeasonStatisticsResource Statistics { get; set; } - } - - public static class SeasonResourceMapper - { - public static SeasonResource ToResource(this Season model) - { - if (model == null) return null; - - return new SeasonResource - { - SeasonNumber = model.SeasonNumber, - Monitored = model.Monitored - }; - } - - public static Season ToModel(this SeasonResource resource) - { - if (resource == null) return null; - - return new Season - { - SeasonNumber = resource.SeasonNumber, - Monitored = resource.Monitored - }; - } - - public static List ToResource(this IEnumerable models) - { - return models.Select(ToResource).ToList(); - } - - public static List ToModel(this IEnumerable resources) - { - return resources.Select(ToModel).ToList(); - } - } -} diff --git a/src/NzbDrone.Api/Series/SeasonStatisticsResource.cs b/src/NzbDrone.Api/Series/SeasonStatisticsResource.cs deleted file mode 100644 index 34acc721e..000000000 --- a/src/NzbDrone.Api/Series/SeasonStatisticsResource.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using NzbDrone.Core.SeriesStats; - -namespace NzbDrone.Api.Series -{ - public class SeasonStatisticsResource - { - public DateTime? NextAiring { get; set; } - public DateTime? PreviousAiring { get; set; } - public int EpisodeFileCount { get; set; } - public int EpisodeCount { get; set; } - public int TotalEpisodeCount { get; set; } - public long SizeOnDisk { get; set; } - - public decimal PercentOfEpisodes - { - get - { - if (EpisodeCount == 0) return 0; - - return (decimal)EpisodeFileCount / (decimal)EpisodeCount * 100; - } - } - } - - public static class SeasonStatisticsResourceMapper - { - public static SeasonStatisticsResource ToResource(this SeasonStatistics model) - { - if (model == null) return null; - - return new SeasonStatisticsResource - { - NextAiring = model.NextAiring, - PreviousAiring = model.PreviousAiring, - EpisodeFileCount = model.EpisodeFileCount, - EpisodeCount = model.EpisodeFileCount, - TotalEpisodeCount = model.TotalEpisodeCount, - SizeOnDisk = model.SizeOnDisk - }; - } - } -} diff --git a/src/NzbDrone.Api/Series/SeriesEditorModule.cs b/src/NzbDrone.Api/Series/SeriesEditorModule.cs deleted file mode 100644 index 87cd53113..000000000 --- a/src/NzbDrone.Api/Series/SeriesEditorModule.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Nancy; -using NzbDrone.Api.Extensions; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Api.Series -{ - public class SeriesEditorModule : NzbDroneApiModule - { - private readonly ISeriesService _seriesService; - - public SeriesEditorModule(ISeriesService seriesService) - : base("/series/editor") - { - _seriesService = seriesService; - Put["/"] = series => SaveAll(); - } - - private Response SaveAll() - { - var resources = Request.Body.FromJson>(); - - var series = resources.Select(seriesResource => seriesResource.ToModel(_seriesService.GetSeries(seriesResource.Id))).ToList(); - - return _seriesService.UpdateSeries(series) - .ToResource() - .AsResponse(HttpStatusCode.Accepted); - } - } -} diff --git a/src/NzbDrone.Api/Series/SeriesLookupModule.cs b/src/NzbDrone.Api/Series/SeriesLookupModule.cs deleted file mode 100644 index 6506c1f82..000000000 --- a/src/NzbDrone.Api/Series/SeriesLookupModule.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; -using Nancy; -using NzbDrone.Api.Extensions; -using NzbDrone.Core.MediaCover; -using NzbDrone.Core.MetadataSource; -using System.Linq; - -namespace NzbDrone.Api.Series -{ - public class SeriesLookupModule : NzbDroneRestModule - { - private readonly ISearchForNewSeries _searchProxy; - - public SeriesLookupModule(ISearchForNewSeries searchProxy) - : base("/series/lookup") - { - _searchProxy = searchProxy; - Get["/"] = x => Search(); - } - - - private Response Search() - { - var tvDbResults = _searchProxy.SearchForNewSeries((string)Request.Query.term); - return MapToResource(tvDbResults).AsResponse(); - } - - - private static IEnumerable MapToResource(IEnumerable series) - { - foreach (var currentSeries in series) - { - var resource = currentSeries.ToResource(); - var poster = currentSeries.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster); - if (poster != null) - { - resource.RemotePoster = poster.Url; - } - - yield return resource; - } - } - } -} \ No newline at end of file diff --git a/src/NzbDrone.Api/Series/SeriesModule.cs b/src/NzbDrone.Api/Series/SeriesModule.cs index 5d0529be6..e018b1614 100644 --- a/src/NzbDrone.Api/Series/SeriesModule.cs +++ b/src/NzbDrone.Api/Series/SeriesModule.cs @@ -1,242 +1,47 @@ -using System; +using System; using System.Collections.Generic; -using System.Linq; -using FluentValidation; -using NzbDrone.Common.Extensions; -using NzbDrone.Core.Datastore.Events; -using NzbDrone.Core.MediaCover; -using NzbDrone.Core.MediaFiles; -using NzbDrone.Core.MediaFiles.Events; -using NzbDrone.Core.Messaging.Events; -using NzbDrone.Core.SeriesStats; -using NzbDrone.Core.Tv; -using NzbDrone.Core.Tv.Events; -using NzbDrone.Core.Validation.Paths; -using NzbDrone.Core.DataAugmentation.Scene; -using NzbDrone.Core.Validation; using NzbDrone.SignalR; namespace NzbDrone.Api.Series { - public class SeriesModule : NzbDroneRestModuleWithSignalR, - IHandle, - IHandle, - IHandle, - IHandle, - IHandle, - IHandle, - IHandle + [Obsolete("SeriesModule is Obsolete, Remove with new UI")] + public class SeriesModule : NzbDroneRestModuleWithSignalR { - private readonly ISeriesService _seriesService; - private readonly ISeriesStatisticsService _seriesStatisticsService; - private readonly ISceneMappingService _sceneMappingService; - private readonly IMapCoversToLocal _coverMapper; - - public SeriesModule(IBroadcastSignalRMessage signalRBroadcaster, - ISeriesService seriesService, - ISeriesStatisticsService seriesStatisticsService, - ISceneMappingService sceneMappingService, - IMapCoversToLocal coverMapper, - RootFolderValidator rootFolderValidator, - SeriesPathValidator seriesPathValidator, - SeriesExistsValidator seriesExistsValidator, - DroneFactoryValidator droneFactoryValidator, - SeriesAncestorValidator seriesAncestorValidator, - ProfileExistsValidator profileExistsValidator - ) + public SeriesModule(IBroadcastSignalRMessage signalRBroadcaster + ) : base(signalRBroadcaster) { - _seriesService = seriesService; - _seriesStatisticsService = seriesStatisticsService; - _sceneMappingService = sceneMappingService; - - _coverMapper = coverMapper; - GetResourceAll = AllSeries; GetResourceById = GetSeries; CreateResource = AddSeries; UpdateResource = UpdateSeries; DeleteResource = DeleteSeries; - - Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.ProfileId)); - - SharedValidator.RuleFor(s => s.Path) - .Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() - .SetValidator(rootFolderValidator) - .SetValidator(seriesPathValidator) - .SetValidator(droneFactoryValidator) - .SetValidator(seriesAncestorValidator) - .When(s => !s.Path.IsNullOrWhiteSpace()); - - SharedValidator.RuleFor(s => s.ProfileId).SetValidator(profileExistsValidator); - - PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace()); - PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace()); - PostValidator.RuleFor(s => s.Title).NotEmpty(); - PostValidator.RuleFor(s => s.TvdbId).GreaterThan(0).SetValidator(seriesExistsValidator); - - PutValidator.RuleFor(s => s.Path).IsValidPath(); } private SeriesResource GetSeries(int id) { - var series = _seriesService.GetSeries(id); - return MapToResource(series); - } - - private SeriesResource MapToResource(Core.Tv.Series series) - { - if (series == null) return null; - - var resource = series.ToResource(); - MapCoversToLocal(resource); - FetchAndLinkSeriesStatistics(resource); - PopulateAlternateTitles(resource); - - return resource; + return new SeriesResource(); } private List AllSeries() { - var seriesStats = _seriesStatisticsService.SeriesStatistics(); - var seriesResources = _seriesService.GetAllSeries().ToResource(); - - MapCoversToLocal(seriesResources.ToArray()); - LinkSeriesStatistics(seriesResources, seriesStats); - PopulateAlternateTitles(seriesResources); - - return seriesResources; + return new List(); } private int AddSeries(SeriesResource seriesResource) { - var model = seriesResource.ToModel(); - - return _seriesService.AddSeries(model).Id; + return 0; } private void UpdateSeries(SeriesResource seriesResource) { - var model = seriesResource.ToModel(_seriesService.GetSeries(seriesResource.Id)); - - _seriesService.UpdateSeries(model); - - BroadcastResourceChange(ModelAction.Updated, seriesResource); + throw new NotImplementedException(); } private void DeleteSeries(int id) { - var deleteFiles = false; - var deleteFilesQuery = Request.Query.deleteFiles; - - if (deleteFilesQuery.HasValue) - { - deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value); - } - - _seriesService.DeleteSeries(id, deleteFiles); - } - - private void MapCoversToLocal(params SeriesResource[] series) - { - foreach (var seriesResource in series) - { - _coverMapper.ConvertToLocalUrls(seriesResource.Id, seriesResource.Images); - } - } - - private void FetchAndLinkSeriesStatistics(SeriesResource resource) - { - LinkSeriesStatistics(resource, _seriesStatisticsService.SeriesStatistics(resource.Id)); - } - - private void LinkSeriesStatistics(List resources, List seriesStatistics) - { - var dictSeriesStats = seriesStatistics.ToDictionary(v => v.SeriesId); - - foreach (var series in resources) - { - var stats = dictSeriesStats.GetValueOrDefault(series.Id); - if (stats == null) continue; - - LinkSeriesStatistics(series, stats); - } - } - - private void LinkSeriesStatistics(SeriesResource resource, SeriesStatistics seriesStatistics) - { - resource.TotalEpisodeCount = seriesStatistics.TotalEpisodeCount; - resource.EpisodeCount = seriesStatistics.EpisodeCount; - resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount; - resource.NextAiring = seriesStatistics.NextAiring; - resource.PreviousAiring = seriesStatistics.PreviousAiring; - resource.SizeOnDisk = seriesStatistics.SizeOnDisk; - - if (seriesStatistics.SeasonStatistics != null) - { - var dictSeasonStats = seriesStatistics.SeasonStatistics.ToDictionary(v => v.SeasonNumber); - - foreach (var season in resource.Seasons) - { - season.Statistics = SeasonStatisticsResourceMapper.ToResource(dictSeasonStats.GetValueOrDefault(season.SeasonNumber)); - } - } - } - - private void PopulateAlternateTitles(List resources) - { - foreach (var resource in resources) - { - PopulateAlternateTitles(resource); - } - } - - private void PopulateAlternateTitles(SeriesResource resource) - { - var mappings = _sceneMappingService.FindByTvdbId(resource.TvdbId); - - if (mappings == null) return; - - //resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList(); - } - - public void Handle(EpisodeImportedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.ImportedEpisode.SeriesId); - } - - public void Handle(EpisodeFileDeletedEvent message) - { - if (message.Reason == DeleteMediaFileReason.Upgrade) return; - - BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.SeriesId); - } - - public void Handle(SeriesUpdatedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.Series.Id); - } - - public void Handle(SeriesEditedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.Series.Id); - } - - public void Handle(SeriesDeletedEvent message) - { - BroadcastResourceChange(ModelAction.Deleted, message.Series.ToResource()); - } - - public void Handle(SeriesRenamedEvent message) - { - BroadcastResourceChange(ModelAction.Updated, message.Series.Id); - } - - public void Handle(MediaCoversUpdatedEvent message) - { - //BroadcastResourceChange(ModelAction.Updated, message.Series.Id); + throw new NotImplementedException(); } } } diff --git a/src/NzbDrone.Api/Series/SeriesResource.cs b/src/NzbDrone.Api/Series/SeriesResource.cs index 198c6602c..068da9dc6 100644 --- a/src/NzbDrone.Api/Series/SeriesResource.cs +++ b/src/NzbDrone.Api/Series/SeriesResource.cs @@ -1,232 +1,19 @@ -using System; +using System; using System.Collections.Generic; -using System.Linq; using NzbDrone.Api.REST; -using NzbDrone.Core.MediaCover; -using NzbDrone.Core.Tv; namespace NzbDrone.Api.Series { + [Obsolete("SeriesResource is Obsolete, Remove with new UI")] public class SeriesResource : RestResource { public SeriesResource() { - Monitored = true; + Title = "Series Endpoint Obsolete"; } - - //Todo: Sorters should be done completely on the client - //Todo: Is there an easy way to keep IgnoreArticlesWhenSorting in sync between, Series, History, Missing? - //Todo: We should get the entire Profile instead of ID and Name separately - + //View Only public string Title { get; set; } - //public List AlternateTitles { get; set; } - public string SortTitle { get; set; } - - public int SeasonCount - { - get - { - if (Seasons == null) return 0; - - return Seasons.Where(s => s.SeasonNumber > 0).Count(); - } - } - - public int? TotalEpisodeCount { get; set; } - public int? EpisodeCount { get; set; } - public int? EpisodeFileCount { get; set; } - public long? SizeOnDisk { get; set; } - public SeriesStatusType Status { get; set; } - public string Overview { get; set; } - public DateTime? NextAiring { get; set; } - public DateTime? PreviousAiring { get; set; } - public string Network { get; set; } - public string AirTime { get; set; } - public List Images { get; set; } - - public string RemotePoster { get; set; } - public List Seasons { get; set; } - public int Year { get; set; } - - //View & Edit - public string Path { get; set; } - public int ProfileId { get; set; } - - //Editing Only - public bool SeasonFolder { get; set; } - public bool Monitored { get; set; } - - public bool UseSceneNumbering { get; set; } - public int Runtime { get; set; } - public int TvdbId { get; set; } - public int TvRageId { get; set; } - public int TvMazeId { get; set; } - public DateTime? FirstAired { get; set; } - public DateTime? LastInfoSync { get; set; } - public SeriesTypes SeriesType { get; set; } - public string CleanTitle { get; set; } - public string ImdbId { get; set; } - public string TitleSlug { get; set; } - public string RootFolderPath { get; set; } - public string Certification { get; set; } - public List Genres { get; set; } - public HashSet Tags { get; set; } - public DateTime Added { get; set; } - public AddSeriesOptions AddOptions { get; set; } - public Ratings Ratings { get; set; } - - //TODO: Add series statistics as a property of the series (instead of individual properties) - - //Used to support legacy consumers - public int QualityProfileId - { - get - { - return ProfileId; - } - set - { - if (value > 0 && ProfileId == 0) - { - ProfileId = value; - } - } - } - } - - public static class SeriesResourceMapper - { - public static SeriesResource ToResource(this Core.Tv.Series model) - { - if (model == null) return null; - - return new SeriesResource - { - Id = model.Id, - - Title = model.Title, - //AlternateTitles - SortTitle = model.SortTitle, - - //TotalEpisodeCount - //EpisodeCount - //EpisodeFileCount - //SizeOnDisk - Status = model.Status, - Overview = model.Overview, - //NextAiring - //PreviousAiring - Network = model.Network, - AirTime = model.AirTime, - Images = model.Images, - - Seasons = model.Seasons.ToResource(), - Year = model.Year, - - Path = model.Path, - ProfileId = model.ProfileId, - - SeasonFolder = model.SeasonFolder, - Monitored = model.Monitored, - - UseSceneNumbering = model.UseSceneNumbering, - Runtime = model.Runtime, - TvdbId = model.TvdbId, - TvRageId = model.TvRageId, - TvMazeId = model.TvMazeId, - FirstAired = model.FirstAired, - LastInfoSync = model.LastInfoSync, - SeriesType = model.SeriesType, - CleanTitle = model.CleanTitle, - ImdbId = model.ImdbId, - TitleSlug = model.TitleSlug, - RootFolderPath = model.RootFolderPath, - Certification = model.Certification, - Genres = model.Genres, - Tags = model.Tags, - Added = model.Added, - AddOptions = model.AddOptions, - Ratings = model.Ratings - }; - } - - public static Core.Tv.Series ToModel(this SeriesResource resource) - { - if (resource == null) return null; - - return new Core.Tv.Series - { - Id = resource.Id, - - Title = resource.Title, - //AlternateTitles - SortTitle = resource.SortTitle, - - //TotalEpisodeCount - //EpisodeCount - //EpisodeFileCount - //SizeOnDisk - Status = resource.Status, - Overview = resource.Overview, - //NextAiring - //PreviousAiring - Network = resource.Network, - AirTime = resource.AirTime, - Images = resource.Images, - - Seasons = resource.Seasons.ToModel(), - Year = resource.Year, - - Path = resource.Path, - ProfileId = resource.ProfileId, - - SeasonFolder = resource.SeasonFolder, - Monitored = resource.Monitored, - - UseSceneNumbering = resource.UseSceneNumbering, - Runtime = resource.Runtime, - TvdbId = resource.TvdbId, - TvRageId = resource.TvRageId, - TvMazeId = resource.TvMazeId, - FirstAired = resource.FirstAired, - LastInfoSync = resource.LastInfoSync, - SeriesType = resource.SeriesType, - CleanTitle = resource.CleanTitle, - ImdbId = resource.ImdbId, - TitleSlug = resource.TitleSlug, - RootFolderPath = resource.RootFolderPath, - Certification = resource.Certification, - Genres = resource.Genres, - Tags = resource.Tags, - Added = resource.Added, - AddOptions = resource.AddOptions, - Ratings = resource.Ratings - }; - } - - public static Core.Tv.Series ToModel(this SeriesResource resource, Core.Tv.Series series) - { - series.TvdbId = resource.TvdbId; - - series.Seasons = resource.Seasons.ToModel(); - series.Path = resource.Path; - series.ProfileId = resource.ProfileId; - - series.SeasonFolder = resource.SeasonFolder; - series.Monitored = resource.Monitored; - - series.SeriesType = resource.SeriesType; - series.RootFolderPath = resource.RootFolderPath; - series.Tags = resource.Tags; - series.AddOptions = resource.AddOptions; - - return series; - } - - public static List ToResource(this IEnumerable series) - { - return series.Select(ToResource).ToList(); - } } + } diff --git a/src/NzbDrone.Api/Wanted/CutoffModule.cs b/src/NzbDrone.Api/Wanted/CutoffModule.cs deleted file mode 100644 index a4ff1d2ea..000000000 --- a/src/NzbDrone.Api/Wanted/CutoffModule.cs +++ /dev/null @@ -1,42 +0,0 @@ -using NzbDrone.Api.Episodes; -using NzbDrone.Core.Datastore; -using NzbDrone.Core.DecisionEngine; -using NzbDrone.Core.Tv; -using NzbDrone.SignalR; - -namespace NzbDrone.Api.Wanted -{ - public class CutoffModule : EpisodeModuleWithSignalR - { - private readonly IEpisodeCutoffService _episodeCutoffService; - - public CutoffModule(IEpisodeCutoffService episodeCutoffService, - IEpisodeService episodeService, - ISeriesService seriesService, - IQualityUpgradableSpecification qualityUpgradableSpecification, - IBroadcastSignalRMessage signalRBroadcaster) - : base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff-old") - { - _episodeCutoffService = episodeCutoffService; - GetResourcePaged = GetCutoffUnmetEpisodes; - } - - private PagingResource GetCutoffUnmetEpisodes(PagingResource pagingResource) - { - var pagingSpec = pagingResource.MapToPagingSpec("airDateUtc", SortDirection.Descending); - - if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false") - { - pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false; - } - else - { - pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true; - } - - var resource = ApplyToPage(_episodeCutoffService.EpisodesWhereCutoffUnmet, pagingSpec, v => MapToResource(v, true, true)); - - return resource; - } - } -} diff --git a/src/NzbDrone.Api/Wanted/MissingModule.cs b/src/NzbDrone.Api/Wanted/MissingModule.cs deleted file mode 100644 index 52470cd1a..000000000 --- a/src/NzbDrone.Api/Wanted/MissingModule.cs +++ /dev/null @@ -1,38 +0,0 @@ -using NzbDrone.Api.Episodes; -using NzbDrone.Core.Datastore; -using NzbDrone.Core.DecisionEngine; -using NzbDrone.Core.Tv; -using NzbDrone.SignalR; - -namespace NzbDrone.Api.Wanted -{ - public class MissingModule : EpisodeModuleWithSignalR - { - public MissingModule(IEpisodeService episodeService, - ISeriesService seriesService, - IQualityUpgradableSpecification qualityUpgradableSpecification, - IBroadcastSignalRMessage signalRBroadcaster) - : base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing_episodes") - { - GetResourcePaged = GetMissingEpisodes; - } - - private PagingResource GetMissingEpisodes(PagingResource pagingResource) - { - var pagingSpec = pagingResource.MapToPagingSpec("airDateUtc", SortDirection.Descending); - - if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false") - { - pagingSpec.FilterExpression = v => v.Monitored == false || v.Series.Monitored == false; - } - else - { - pagingSpec.FilterExpression = v => v.Monitored == true && v.Series.Monitored == true; - } - - var resource = ApplyToPage(_episodeService.EpisodesWithoutFiles, pagingSpec, v => MapToResource(v, true, false)); - - return resource; - } - } -} diff --git a/src/NzbDrone.Api/Wanted/MovieCutoffModule.cs b/src/NzbDrone.Api/Wanted/MovieCutoffModule.cs index 0b60491f0..7f4ebbf76 100644 --- a/src/NzbDrone.Api/Wanted/MovieCutoffModule.cs +++ b/src/NzbDrone.Api/Wanted/MovieCutoffModule.cs @@ -1,4 +1,3 @@ -using NzbDrone.Api.Movie; using NzbDrone.Api.Movies; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Tv; @@ -32,4 +31,4 @@ private PagingResource GetCutoffUnmetMovies(PagingResource RootFolders; public MovieClient Movies; public ClientBase Tags; - public ClientBase WantedMissing; - public ClientBase WantedCutoffUnmet; + public ClientBase WantedMissing; + public ClientBase WantedCutoffUnmet; private List _signalRReceived; private Connection _signalrConnection; @@ -109,8 +109,8 @@ protected virtual void InitRestClients() RootFolders = new ClientBase(RestClient, ApiKey); Movies = new MovieClient(RestClient, ApiKey); Tags = new ClientBase(RestClient, ApiKey); - WantedMissing = new ClientBase(RestClient, ApiKey, "wanted/missing"); - WantedCutoffUnmet = new ClientBase(RestClient, ApiKey, "wanted/cutoff"); + WantedMissing = new ClientBase(RestClient, ApiKey, "wanted/missing"); + WantedCutoffUnmet = new ClientBase(RestClient, ApiKey, "wanted/cutoff"); } [OneTimeTearDown] From ae886451800566937863e8c9a0c7164550b4aa30 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 19 Feb 2018 08:18:36 +0100 Subject: [PATCH 2/3] Added: Device names for Join notifications (#2544) Closes #2364 --- src/NzbDrone.Core/Notifications/Join/JoinProxy.cs | 9 +++++++-- src/NzbDrone.Core/Notifications/Join/JoinSettings.cs | 9 ++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs b/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs index e50feb89a..cafb16934 100644 --- a/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs +++ b/src/NzbDrone.Core/Notifications/Join/JoinProxy.cs @@ -1,6 +1,7 @@ -using System; +using System; using FluentValidation.Results; using NLog; +using NzbDrone.Common.Extensions; using RestSharp; using NzbDrone.Core.Rest; using NzbDrone.Common.Serializer; @@ -75,7 +76,11 @@ private void SendNotification(string title, string message, RestRequest request, var client = RestClientFactory.BuildClient(URL); - if (!string.IsNullOrEmpty(settings.DeviceIds)) + if (settings.DeviceNames.IsNotNullOrWhiteSpace()) + { + request.AddParameter("deviceNames", settings.DeviceNames); + } + else if (settings.DeviceIds.IsNotNullOrWhiteSpace()) { request.AddParameter("deviceIds", settings.DeviceIds); } diff --git a/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs b/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs index 29d750782..ac305867f 100644 --- a/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs +++ b/src/NzbDrone.Core/Notifications/Join/JoinSettings.cs @@ -1,4 +1,4 @@ -using FluentValidation; +using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; @@ -10,7 +10,7 @@ public class JoinSettingsValidator : AbstractValidator public JoinSettingsValidator() { RuleFor(s => s.ApiKey).NotEmpty(); - RuleFor(s => s.DeviceIds).Matches(@"\A\S+\z").When(s => !string.IsNullOrEmpty(s.DeviceIds)); + RuleFor(s => s.DeviceIds).Empty().WithMessage("Use Device Names instead"); } } @@ -21,9 +21,12 @@ public class JoinSettings : IProviderConfig [FieldDefinition(0, Label = "API Key", HelpText = "The API Key from your Join account settings (click Join API button).", HelpLink = "https://joinjoaomgcd.appspot.com/")] public string ApiKey { get; set; } - [FieldDefinition(1, Label = "Device IDs", HelpText = "Comma separated list of Device IDs you'd like to send notifications to. If unset, all devices will receive notifications.", HelpLink = "https://joinjoaomgcd.appspot.com/")] + [FieldDefinition(1, Label = "Device IDs", HelpText = "Deprecated, use Device Names instead. Comma separated list of Device IDs you'd like to send notifications to. If unset, all devices will receive notifications.")] public string DeviceIds { get; set; } + [FieldDefinition(2, Label = "Device Names", HelpText = "Comma separated list of full or partial device names you'd like to send notifications to. If unset, all devices will receive notifications.", HelpLink = "https://joaoapps.com/join/api/")] + public string DeviceNames { get; set; } + public NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); From d0406ced40dec4a9f3b5148f543cdf1462b67be0 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 19 Feb 2018 08:19:14 +0100 Subject: [PATCH 3/3] Fixed: Unable to execute custom scripts if IMDB ID is null (#2543) fixes #1460 --- .../Processes/ProcessProvider.cs | 36 ++++++++++++++----- .../CustomScript/CustomScript.cs | 6 ++-- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/NzbDrone.Common/Processes/ProcessProvider.cs b/src/NzbDrone.Common/Processes/ProcessProvider.cs index c3e3dcb64..a6a837f8c 100644 --- a/src/NzbDrone.Common/Processes/ProcessProvider.cs +++ b/src/NzbDrone.Common/Processes/ProcessProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; @@ -98,9 +98,9 @@ public void OpenDefaultBrowser(string url) var process = new Process { StartInfo = new ProcessStartInfo(url) - { - UseShellExecute = true - } + { + UseShellExecute = true + } }; process.Start(); @@ -129,16 +129,34 @@ public Process Start(string path, string args = null, StringDictionary environme { foreach (DictionaryEntry environmentVariable in environmentVariables) { - startInfo.EnvironmentVariables.Add(environmentVariable.Key.ToString(), environmentVariable.Value.ToString()); + try + { + _logger.Trace("Setting environment variable '{0}' to '{1}'", environmentVariable.Key, environmentVariable.Value); + startInfo.EnvironmentVariables.Add(environmentVariable.Key.ToString(), environmentVariable.Value.ToString()); + } + catch (Exception e) + { + if (environmentVariable.Value == null) + { + _logger.Error(e, "Unable to set environment variable '{0}', value is null", environmentVariable.Key); + } + + else + { + _logger.Error(e, "Unable to set environment variable '{0}'", environmentVariable.Key); + } + + throw; + } } } logger.Debug("Starting {0} {1}", path, args); var process = new Process - { - StartInfo = startInfo - }; + { + StartInfo = startInfo + }; process.OutputDataReceived += (sender, eventArgs) => { @@ -315,7 +333,7 @@ private List GetProcessesByName(string name) var monoProcesses = Process.GetProcessesByName("mono") .Union(Process.GetProcessesByName("mono-sgen")) - .Union(Process.GetProcessesByName("mono-sgen32")) + .Union(Process.GetProcessesByName("mono-sgen32")) .Where(process => process.Modules.Cast() .Any(module => diff --git a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs index 3d39c56e1..314a83ce3 100755 --- a/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs +++ b/src/NzbDrone.Core/Notifications/CustomScript/CustomScript.cs @@ -37,7 +37,7 @@ public override void OnGrab(GrabMessage message) environmentVariables.Add("Radarr_EventType", "Grab"); environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString()); environmentVariables.Add("Radarr_Movie_Title", movie.Title); - environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId); + environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId ?? string.Empty); environmentVariables.Add("Radarr_Movie_TmdbId", movie.TmdbId.ToString()); environmentVariables.Add("Radarr_Release_Title", remoteMovie.Release.Title); environmentVariables.Add("Radarr_Release_Indexer", remoteMovie.Release.Indexer); @@ -61,7 +61,7 @@ public override void OnDownload(DownloadMessage message) environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString()); environmentVariables.Add("Radarr_Movie_Title", movie.Title); environmentVariables.Add("Radarr_Movie_Path", movie.Path); - environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId); + environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId ?? string.Empty); environmentVariables.Add("Radarr_Movie_TmdbId", movie.TmdbId.ToString()); environmentVariables.Add("Radarr_MovieFile_Id", movieFile.Id.ToString()); environmentVariables.Add("Radarr_MovieFile_RelativePath", movieFile.RelativePath); @@ -90,7 +90,7 @@ public override void OnMovieRename(Movie movie) environmentVariables.Add("Radarr_Movie_Id", movie.Id.ToString()); environmentVariables.Add("Radarr_Movie_Title", movie.Title); environmentVariables.Add("Radarr_Movie_Path", movie.Path); - environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId); + environmentVariables.Add("Radarr_Movie_ImdbId", movie.ImdbId ?? string.Empty); environmentVariables.Add("Radarr_Movie_TmdbId", movie.TmdbId.ToString()); ExecuteScript(environmentVariables);