diff --git a/NzbDrone.Core.Test/MediaFileTests/DropFolderImportServiceFixture.cs b/NzbDrone.Core.Test/MediaFileTests/DropFolderImportServiceFixture.cs index 643fd1047..27cf613ae 100644 --- a/NzbDrone.Core.Test/MediaFileTests/DropFolderImportServiceFixture.cs +++ b/NzbDrone.Core.Test/MediaFileTests/DropFolderImportServiceFixture.cs @@ -128,7 +128,7 @@ namespace NzbDrone.Core.Test.MediaFileTests imported.Add(new ImportDecision(localEpisode)); Mocker.GetMock() - .Setup(s => s.GetImportDecisions(It.IsAny>(), It.IsAny())) + .Setup(s => s.GetImportDecisions(It.IsAny>(), It.IsAny(), true)) .Returns(imported); Mocker.GetMock() diff --git a/NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/ImportDecisionMakerFixture.cs b/NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/ImportDecisionMakerFixture.cs index 3a9cefd26..5d74e307d 100644 --- a/NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/ImportDecisionMakerFixture.cs +++ b/NzbDrone.Core.Test/MediaFileTests/EpisodeImportTests/ImportDecisionMakerFixture.cs @@ -64,7 +64,8 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests _series = new Series(); _localEpisode = new LocalEpisode { Series = _series, Path = @"C:\Test\Unsorted\The.Office.S03E115.DVDRip.XviD-OSiTV.avi" }; - Mocker.GetMock().Setup(c => c.GetEpisodes(It.IsAny(), It.IsAny())) + Mocker.GetMock() + .Setup(c => c.GetEpisodes(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(_localEpisode); @@ -84,7 +85,7 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests { GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3); - Subject.GetImportDecisions(_videoFiles, new Series()); + Subject.GetImportDecisions(_videoFiles, new Series(), false); _fail1.Verify(c => c.IsSatisfiedBy(_localEpisode), Times.Once()); _fail2.Verify(c => c.IsSatisfiedBy(_localEpisode), Times.Once()); @@ -99,7 +100,7 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests { GivenSpecifications(_fail1); - var result = Subject.GetImportDecisions(_videoFiles, new Series()); + var result = Subject.GetImportDecisions(_videoFiles, new Series(), false); result.Single().Approved.Should().BeFalse(); } @@ -109,7 +110,7 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests { GivenSpecifications(_pass1, _fail1, _pass2, _pass3); - var result = Subject.GetImportDecisions(_videoFiles, new Series()); + var result = Subject.GetImportDecisions(_videoFiles, new Series(), false); result.Single().Approved.Should().BeFalse(); } @@ -119,7 +120,7 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests { GivenSpecifications(_pass1, _pass2, _pass3); - var result = Subject.GetImportDecisions(_videoFiles, new Series()); + var result = Subject.GetImportDecisions(_videoFiles, new Series(), false); result.Single().Approved.Should().BeTrue(); } @@ -129,7 +130,7 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests { GivenSpecifications(_pass1, _pass2, _pass3, _fail1, _fail2, _fail3); - var result = Subject.GetImportDecisions(_videoFiles, new Series()); + var result = Subject.GetImportDecisions(_videoFiles, new Series(), false); result.Single().Rejections.Should().HaveCount(3); } @@ -138,7 +139,7 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests { GivenSpecifications(_pass1); - Mocker.GetMock().Setup(c => c.GetEpisodes(It.IsAny(), It.IsAny())) + Mocker.GetMock().Setup(c => c.GetEpisodes(It.IsAny(), It.IsAny(), It.IsAny())) .Throws(); _videoFiles = new List @@ -153,7 +154,7 @@ namespace NzbDrone.Core.Test.MediaFileTests.EpisodeImportTests .Setup(c => c.FilterExistingFiles(_videoFiles, It.IsAny())) .Returns(_videoFiles); - Subject.GetImportDecisions(_videoFiles, new Series()); + Subject.GetImportDecisions(_videoFiles, new Series(), false); Mocker.GetMock() .Verify(c => c.GetEpisodes(It.IsAny(), It.IsAny()), Times.Exactly(_videoFiles.Count)); diff --git a/NzbDrone.Core/IndexerSearch/NzbSearchService.cs b/NzbDrone.Core/IndexerSearch/NzbSearchService.cs index 2144986be..368c57916 100644 --- a/NzbDrone.Core/IndexerSearch/NzbSearchService.cs +++ b/NzbDrone.Core/IndexerSearch/NzbSearchService.cs @@ -56,23 +56,31 @@ namespace NzbDrone.Core.IndexerSearch return SearchDaily(episode.SeriesId, episode.AirDate.Value.Date); } - return SearchSingle(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber); + return SearchSingle(series, episode); } - private List SearchSingle(int seriesId, int seasonNumber, int episodeNumber) + private List SearchSingle(Series series, Episode episode) { - var searchSpec = Get(seriesId, seasonNumber); + var searchSpec = Get(series.Id, episode.SeasonNumber); - if (_seriesService.GetSeries(seriesId).UseSceneNumbering) + if (series.UseSceneNumbering) { - var episode = _episodeService.GetEpisode(seriesId, seasonNumber, episodeNumber); - searchSpec.EpisodeNumber = episode.SceneEpisodeNumber; - searchSpec.SeasonNumber = episode.SceneSeasonNumber; + if (episode.SceneSeasonNumber > 0 && episode.SceneEpisodeNumber > 0) + { + searchSpec.EpisodeNumber = episode.SceneEpisodeNumber; + searchSpec.SeasonNumber = episode.SceneSeasonNumber; + } + + else + { + searchSpec.EpisodeNumber = episode.EpisodeNumber; + searchSpec.SeasonNumber = episode.SeasonNumber; + } } else { - searchSpec.EpisodeNumber = episodeNumber; - searchSpec.SeasonNumber = seasonNumber; + searchSpec.EpisodeNumber = episode.EpisodeNumber; + searchSpec.SeasonNumber = episode.SeasonNumber; } return Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec); diff --git a/NzbDrone.Core/Jobs/TaskManager.cs b/NzbDrone.Core/Jobs/TaskManager.cs index 15da35a94..706dc6b19 100644 --- a/NzbDrone.Core/Jobs/TaskManager.cs +++ b/NzbDrone.Core/Jobs/TaskManager.cs @@ -40,7 +40,7 @@ namespace NzbDrone.Core.Jobs var defaultTasks = new[] { new ScheduledTask{ Interval = 15, TypeName = typeof(RssSyncCommand).FullName}, - new ScheduledTask{ Interval = 12*60, TypeName = typeof(UpdateXemMappings).FullName}, + new ScheduledTask{ Interval = 12*60, TypeName = typeof(UpdateXemMappingsCommand).FullName}, new ScheduledTask{ Interval = 12*60, TypeName = typeof(RefreshSeriesCommand).FullName}, new ScheduledTask{ Interval = 1, TypeName = typeof(DownloadedEpisodesScanCommand).FullName}, new ScheduledTask{ Interval = 5, TypeName = typeof(ApplicationUpdateCommand).FullName}, diff --git a/NzbDrone.Core/MediaFiles/DiskScanService.cs b/NzbDrone.Core/MediaFiles/DiskScanService.cs index 2f21a9c26..3b08b8898 100644 --- a/NzbDrone.Core/MediaFiles/DiskScanService.cs +++ b/NzbDrone.Core/MediaFiles/DiskScanService.cs @@ -52,7 +52,7 @@ namespace NzbDrone.Core.MediaFiles var mediaFileList = GetVideoFiles(series.Path); - var decisions = _importDecisionMaker.GetImportDecisions(mediaFileList, series); + var decisions = _importDecisionMaker.GetImportDecisions(mediaFileList, series, false); _importApprovedEpisodes.Import(decisions); } diff --git a/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs b/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs index 8a1e188ea..939e07ffe 100644 --- a/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs +++ b/NzbDrone.Core/MediaFiles/DownloadedEpisodesImportService.cs @@ -135,7 +135,7 @@ namespace NzbDrone.Core.MediaFiles private List ProcessFiles(IEnumerable videoFiles, Series series) { - var decisions = _importDecisionMaker.GetImportDecisions(videoFiles, series); + var decisions = _importDecisionMaker.GetImportDecisions(videoFiles, series, true); return _importApprovedEpisodes.Import(decisions, true); } diff --git a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs index e748787b0..b585a58c5 100644 --- a/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs +++ b/NzbDrone.Core/MediaFiles/EpisodeImport/ImportDecisionMaker.cs @@ -14,7 +14,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport { public interface IMakeImportDecision { - List GetImportDecisions(IEnumerable videoFiles, Series series); + List GetImportDecisions(IEnumerable videoFiles, Series series, bool sceneSource); } public class ImportDecisionMaker : IMakeImportDecision @@ -39,16 +39,16 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport _logger = logger; } - public List GetImportDecisions(IEnumerable videoFiles, Series series) + public List GetImportDecisions(IEnumerable videoFiles, Series series, bool sceneSource) { var newFiles = _mediaFileService.FilterExistingFiles(videoFiles.ToList(), series.Id); _logger.Debug("Analysing {0}/{1} files.", newFiles.Count, videoFiles.Count()); - return GetDecisions(newFiles, series).ToList(); + return GetDecisions(newFiles, series, sceneSource).ToList(); } - private IEnumerable GetDecisions(IEnumerable videoFiles, Series series) + private IEnumerable GetDecisions(IEnumerable videoFiles, Series series, bool sceneSource) { foreach (var file in videoFiles) { @@ -56,7 +56,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport try { - var parsedEpisode = _parsingService.GetEpisodes(file, series); + var parsedEpisode = _parsingService.GetEpisodes(file, series, sceneSource); if (parsedEpisode != null) { diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 820e86709..65090ba22 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -382,7 +382,7 @@ - + diff --git a/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs b/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs index f872b381d..492248882 100644 --- a/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs +++ b/NzbDrone.Core/Parser/Model/ParsedEpisodeInfo.cs @@ -14,7 +14,6 @@ namespace NzbDrone.Core.Parser.Model public Language Language { get; set; } public bool FullSeason { get; set; } - public bool SceneSource { get; set; } public override string ToString() { diff --git a/NzbDrone.Core/Parser/ParsingService.cs b/NzbDrone.Core/Parser/ParsingService.cs index aad685e33..e647799de 100644 --- a/NzbDrone.Core/Parser/ParsingService.cs +++ b/NzbDrone.Core/Parser/ParsingService.cs @@ -9,6 +9,7 @@ namespace NzbDrone.Core.Parser public interface IParsingService { LocalEpisode GetEpisodes(string filename, Series series); + LocalEpisode GetEpisodes(string filename, Series series, bool sceneSource); Series GetSeries(string title); RemoteEpisode Map(ParsedEpisodeInfo parsedEpisodeInfo); } @@ -27,6 +28,11 @@ namespace NzbDrone.Core.Parser } public LocalEpisode GetEpisodes(string filename, Series series) + { + return GetEpisodes(filename, series, false); + } + + public LocalEpisode GetEpisodes(string filename, Series series, bool sceneSource) { var parsedEpisodeInfo = Parser.ParsePath(filename); @@ -35,7 +41,7 @@ namespace NzbDrone.Core.Parser return null; } - var episodes = GetEpisodes(parsedEpisodeInfo, series); + var episodes = GetEpisodes(parsedEpisodeInfo, series, sceneSource); if (!episodes.Any()) { @@ -43,13 +49,13 @@ namespace NzbDrone.Core.Parser } return new LocalEpisode - { - Series = series, - Quality = parsedEpisodeInfo.Quality, - Episodes = episodes, - Path = filename, - ParsedEpisodeInfo = parsedEpisodeInfo - }; + { + Series = series, + Quality = parsedEpisodeInfo.Quality, + Episodes = episodes, + Path = filename, + ParsedEpisodeInfo = parsedEpisodeInfo + }; } public Series GetSeries(string title) @@ -82,12 +88,12 @@ namespace NzbDrone.Core.Parser } remoteEpisode.Series = series; - remoteEpisode.Episodes = GetEpisodes(parsedEpisodeInfo, series); + remoteEpisode.Episodes = GetEpisodes(parsedEpisodeInfo, series, true); return remoteEpisode; } - private List GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series) + private List GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series series, bool sceneSource) { var result = new List(); @@ -98,7 +104,6 @@ namespace NzbDrone.Core.Parser _logger.Warn("Found daily-style episode for non-daily series: {0}.", series); return new List(); } - //TODO: this will fail since parsed date will be local, and stored date will be UTC //which means they will probably end up on different dates @@ -119,25 +124,11 @@ namespace NzbDrone.Core.Parser { Episode episodeInfo = null; - if (series.UseSceneNumbering && parsedEpisodeInfo.SceneSource) + if (series.UseSceneNumbering && sceneSource) { episodeInfo = _episodeService.FindEpisode(series.Id, parsedEpisodeInfo.SeasonNumber, episodeNumber, true); - } - if (episodeInfo == null) - { - episodeInfo = _episodeService.GetEpisode(series.Id, parsedEpisodeInfo.SeasonNumber, episodeNumber); - if (episodeInfo == null && parsedEpisodeInfo.AirDate != null) - { - episodeInfo = _episodeService.FindEpisode(series.Id, parsedEpisodeInfo.AirDate.Value); - } - } - - if (episodeInfo != null) - { - result.Add(episodeInfo); - - if (series.UseSceneNumbering) + if (episodeInfo != null) { _logger.Info("Using Scene to TVDB Mapping for: {0} - Scene: {1}x{2:00} - TVDB: {3}x{4:00}", series.Title, @@ -147,6 +138,16 @@ namespace NzbDrone.Core.Parser episodeInfo.EpisodeNumber); } } + + if (episodeInfo == null) + { + episodeInfo = _episodeService.GetEpisode(series.Id, parsedEpisodeInfo.SeasonNumber, episodeNumber); + } + + if (episodeInfo != null) + { + result.Add(episodeInfo); + } else { _logger.Debug("Unable to find {0}", parsedEpisodeInfo); diff --git a/NzbDrone.Core/Providers/UpdateXemMappings.cs b/NzbDrone.Core/Providers/UpdateXemMappings.cs deleted file mode 100644 index 7b4b416a0..000000000 --- a/NzbDrone.Core/Providers/UpdateXemMappings.cs +++ /dev/null @@ -1,8 +0,0 @@ -using NzbDrone.Common.Messaging; - -namespace NzbDrone.Core.Providers -{ - public class UpdateXemMappings : ICommand - { - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/UpdateXemMappingsCommand.cs b/NzbDrone.Core/Providers/UpdateXemMappingsCommand.cs new file mode 100644 index 000000000..da4b4b53f --- /dev/null +++ b/NzbDrone.Core/Providers/UpdateXemMappingsCommand.cs @@ -0,0 +1,14 @@ +using NzbDrone.Common.Messaging; + +namespace NzbDrone.Core.Providers +{ + public class UpdateXemMappingsCommand : ICommand + { + public int? SeriesId { get; private set; } + + public UpdateXemMappingsCommand(int? seriesId) + { + SeriesId = seriesId; + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Providers/XemProvider.cs b/NzbDrone.Core/Providers/XemProvider.cs index 387ab99ea..f5161c340 100644 --- a/NzbDrone.Core/Providers/XemProvider.cs +++ b/NzbDrone.Core/Providers/XemProvider.cs @@ -4,32 +4,41 @@ using System.Linq; using NLog; using NzbDrone.Common.Messaging; using NzbDrone.Core.Tv; +using NzbDrone.Core.Tv.Events; namespace NzbDrone.Core.Providers { - public class XemProvider : IExecute + public interface IXemProvider + { + void UpdateMappings(); + void UpdateMappings(int seriesId); + void PerformUpdate(Series series); + } + + public class XemProvider : IXemProvider, IExecute, IHandle { private readonly IEpisodeService _episodeService; private readonly XemCommunicationProvider _xemCommunicationProvider; - private readonly ISeriesRepository _seriesRepository; + private readonly ISeriesService _seriesService; private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); - public XemProvider(IEpisodeService episodeService, XemCommunicationProvider xemCommunicationProvider, ISeriesRepository seriesRepository) + public XemProvider(IEpisodeService episodeService, XemCommunicationProvider xemCommunicationProvider, ISeriesService seriesService) { + if (seriesService == null) throw new ArgumentNullException("seriesService"); _episodeService = episodeService; _xemCommunicationProvider = xemCommunicationProvider; - _seriesRepository = seriesRepository; + _seriesService = seriesService; } - public virtual void UpdateMappings() + public void UpdateMappings() { _logger.Trace("Starting scene numbering update"); try { var ids = _xemCommunicationProvider.GetXemSeriesIds(); - var series = _seriesRepository.All(); - var wantedSeries = series.Where(s => ids.Contains(s.Id)).ToList(); + var series = _seriesService.GetAllSeries(); + var wantedSeries = series.Where(s => ids.Contains(s.TvdbId)).ToList(); foreach (var ser in wantedSeries) { @@ -46,17 +55,9 @@ namespace NzbDrone.Core.Providers } } - public virtual void UpdateMappings(int seriesId) + public void UpdateMappings(int seriesId) { - var xemIds = _xemCommunicationProvider.GetXemSeriesIds(); - - if (!xemIds.Contains(seriesId)) - { - _logger.Trace("Xem doesn't have a mapping for this series: {0}", seriesId); - return; - } - - var series = _seriesRepository.Get(seriesId); + var series = _seriesService.GetSeries(seriesId); if (series == null) { @@ -64,16 +65,24 @@ namespace NzbDrone.Core.Providers return; } + var xemIds = _xemCommunicationProvider.GetXemSeriesIds(); + + if (!xemIds.Contains(series.TvdbId)) + { + _logger.Trace("Xem doesn't have a mapping for this series: {0}", series.TvdbId); + return; + } + PerformUpdate(series); } - public virtual void PerformUpdate(Series series) + public void PerformUpdate(Series series) { _logger.Trace("Updating scene numbering mapping for: {0}", series); try { var episodesToUpdate = new List(); - var mappings = _xemCommunicationProvider.GetSceneTvdbMappings(series.Id); + var mappings = _xemCommunicationProvider.GetSceneTvdbMappings(series.TvdbId); if (mappings == null) { @@ -106,7 +115,7 @@ namespace NzbDrone.Core.Providers _logger.Trace("Setting UseSceneMapping for {0}", series); series.UseSceneNumbering = true; - _seriesRepository.Update(series); + _seriesService.UpdateSeries(series); } catch (Exception ex) @@ -115,9 +124,21 @@ namespace NzbDrone.Core.Providers } } - public void Execute(UpdateXemMappings message) + public void Execute(UpdateXemMappingsCommand message) { - UpdateMappings(); + if (message.SeriesId.HasValue) + { + UpdateMappings(message.SeriesId.Value); + } + else + { + UpdateMappings(); + } + } + + public void Handle(SeriesUpdatedEvent message) + { + PerformUpdate(message.Series); } } } diff --git a/NzbDrone.ncrunchsolution b/NzbDrone.ncrunchsolution index 444b34b1d..6cb47a29a 100644 --- a/NzbDrone.ncrunchsolution +++ b/NzbDrone.ncrunchsolution @@ -2,7 +2,6 @@ 1 False true - true UseDynamicAnalysis Disabled Disabled