From edb0b3af863c16aff3af066d60a41f9f7a3298ab Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 17 May 2012 16:52:26 -0700 Subject: [PATCH] SeasonSearchJob will do a partial search search and then individual searches, when it is still missing results (greater than 0, but all not found). Fixed: Season/Series searching shouldn't add duplicate episodes. --- .../JobTests/SeasonSearchJobTest.cs | 48 +++---------------- .../SearchProviderTests/SearchFixture.cs | 2 +- NzbDrone.Core/Jobs/SeasonSearchJob.cs | 30 +++++------- NzbDrone.Core/Providers/SearchProvider.cs | 12 ++--- 4 files changed, 26 insertions(+), 66 deletions(-) diff --git a/NzbDrone.Core.Test/JobTests/SeasonSearchJobTest.cs b/NzbDrone.Core.Test/JobTests/SeasonSearchJobTest.cs index f5050ac6b..cf526885b 100644 --- a/NzbDrone.Core.Test/JobTests/SeasonSearchJobTest.cs +++ b/NzbDrone.Core.Test/JobTests/SeasonSearchJobTest.cs @@ -20,22 +20,12 @@ namespace NzbDrone.Core.Test.JobTests // ReSharper disable InconsistentNaming public class SeasonSearchJobTest : CoreTest { - [Test] - public void SeasonSearch_full_season_success() - { - var notification = new ProgressNotification("Season Search"); - - Mocker.GetMock() - .Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(true); - - //Act - Mocker.Resolve().Start(notification, 1, 1); + private ProgressNotification notification; - //Assert - Mocker.VerifyAllMocks(); - Mocker.GetMock().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once()); - Mocker.GetMock().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Never()); - Mocker.GetMock().Verify(c => c.Start(notification, It.IsAny(), 0), Times.Never()); + [SetUp] + public void Setup() + { + notification = new ProgressNotification("Search"); } [Test] @@ -53,11 +43,6 @@ namespace NzbDrone.Core.Test.JobTests .With(e => e.SeriesId = 5) .Build(); - var notification = new ProgressNotification("Season Search"); - - Mocker.GetMock() - .Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(false); - Mocker.GetMock() .Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes); @@ -70,7 +55,6 @@ namespace NzbDrone.Core.Test.JobTests //Assert Mocker.VerifyAllMocks(); - Mocker.GetMock().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once()); Mocker.GetMock().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once()); Mocker.GetMock().Verify(c => c.Start(notification, It.IsAny(), 0), Times.Never()); } @@ -86,14 +70,6 @@ namespace NzbDrone.Core.Test.JobTests .With(e => e.AirDate = DateTime.Today.AddDays(-1)) .Build(); - var notification = new ProgressNotification("Season Search"); - - Mocker.GetMock() - .Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(false); - - Mocker.GetMock() - .Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes); - Mocker.GetMock() .Setup(c => c.PartialSeasonSearch(notification, 1, 1)) .Returns(new List()); @@ -103,7 +79,6 @@ namespace NzbDrone.Core.Test.JobTests //Assert Mocker.VerifyAllMocks(); - Mocker.GetMock().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once()); Mocker.GetMock().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once()); } @@ -120,17 +95,12 @@ namespace NzbDrone.Core.Test.JobTests .With(e => e.AirDate = DateTime.Today.AddDays(2)) .Build(); - var notification = new ProgressNotification("Season Search"); - - Mocker.GetMock() - .Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(false); - Mocker.GetMock() .Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes); Mocker.GetMock() .Setup(c => c.PartialSeasonSearch(notification, 1, 1)) - .Returns(new List()); + .Returns(new List{1}); //Act @@ -138,23 +108,19 @@ namespace NzbDrone.Core.Test.JobTests //Assert Mocker.VerifyAllMocks(); - Mocker.GetMock().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once()); Mocker.GetMock().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once()); } [Test] public void SeasonSearch_should_allow_searching_of_season_zero() { - var notification = new ProgressNotification("Season Search"); - Mocker.GetMock() - .Setup(c => c.SeasonSearch(notification, 1, 0)).Returns(true); + .Setup(c => c.PartialSeasonSearch(notification, 1, 0)).Returns(new List()); //Act Mocker.Resolve().Start(notification, 1, 0); //Assert - Mocker.GetMock().Verify(c => c.SeasonSearch(notification, 1, 0), Times.Once()); Mocker.GetMock().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Never()); Mocker.GetMock().Verify(c => c.Start(notification, It.IsAny(), 0), Times.Never()); } diff --git a/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs b/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs index 3fcac983a..11b119803 100644 --- a/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/SearchProviderTests/SearchFixture.cs @@ -166,7 +166,7 @@ namespace NzbDrone.Core.Test.ProviderTests.SearchProviderTests var result = Mocker.Resolve().SeasonSearch(MockNotification, _series.SeriesId, 1); //Assert - result.Should().BeFalse(); + result.Should().BeEmpty(); } [Test] diff --git a/NzbDrone.Core/Jobs/SeasonSearchJob.cs b/NzbDrone.Core/Jobs/SeasonSearchJob.cs index ea1957389..ddde3e265 100644 --- a/NzbDrone.Core/Jobs/SeasonSearchJob.cs +++ b/NzbDrone.Core/Jobs/SeasonSearchJob.cs @@ -45,7 +45,11 @@ namespace NzbDrone.Core.Jobs if (secondaryTargetId < 0) throw new ArgumentOutOfRangeException("secondaryTargetId"); - if (_searchProvider.SeasonSearch(notification, targetId, secondaryTargetId)) + //Perform a Partial Season Search - Because a full season search is a waste + //3 searches should guarentee results, (24 eps) versus, a potential 4 to get the same eps. + var successes = _searchProvider.PartialSeasonSearch(notification, targetId, secondaryTargetId); + + if (successes.Count == 0) return; Logger.Debug("Getting episodes from database for series: {0} and season: {1}", targetId, secondaryTargetId); @@ -57,25 +61,15 @@ namespace NzbDrone.Core.Jobs return; } - //Perform a Partial Season Search - var addedSeries = _searchProvider.PartialSeasonSearch(notification, targetId, secondaryTargetId); - - //addedSeries.Distinct().ToList().Sort(); - //var episodeNumbers = episodes.Where(w => w.AirDate <= DateTime.Today.AddDays(1)).Select(s => s.EpisodeNumber).ToList(); - //episodeNumbers.Sort(); + if (episodes.Count == successes.Count) + return; - //if (addedSeries.SequenceEqual(episodeNumbers)) - // return; - - ////Get the list of episodes that weren't downloaded - //var missingEpisodes = episodeNumbers.Except(addedSeries).ToList(); + var missingEpisodes = episodes.Select(e => e.EpisodeNumber).Except(successes).ToList(); - //TODO: do one by one check only when max number of feeds have been returned by the indexer - //Only process episodes that is in missing episodes (To ensure we double check if the episode is available) - //foreach (var episode in episodes.Where(e => !e.Ignored && missingEpisodes.Contains(e.EpisodeNumber)).OrderBy(o => o.EpisodeNumber)) - //{ - // _episodeSearchJob.Start(notification, episode.EpisodeId, 0); - //} + foreach (var episode in episodes.Where(e => !e.Ignored && missingEpisodes.Contains(e.EpisodeNumber)).OrderBy(o => o.EpisodeNumber)) + { + _episodeSearchJob.Start(notification, episode.EpisodeId, 0); + } } } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/SearchProvider.cs b/NzbDrone.Core/Providers/SearchProvider.cs index 65789b7e5..299176b2e 100644 --- a/NzbDrone.Core/Providers/SearchProvider.cs +++ b/NzbDrone.Core/Providers/SearchProvider.cs @@ -46,7 +46,7 @@ namespace NzbDrone.Core.Providers { } - public virtual bool SeasonSearch(ProgressNotification notification, int seriesId, int seasonNumber) + public virtual List SeasonSearch(ProgressNotification notification, int seriesId, int seasonNumber) { var searchResult = new SearchHistory { @@ -60,12 +60,12 @@ namespace NzbDrone.Core.Providers if (series == null) { Logger.Error("Unable to find an series {0} in database", seriesId); - return false; + return new List(); } //Return false if the series is a daily series (we only support individual episode searching if (series.IsDaily) - return false; + return new List(); notification.CurrentMessage = String.Format("Searching for {0} Season {1}", series.Title, seasonNumber); @@ -74,7 +74,7 @@ namespace NzbDrone.Core.Providers Logger.Debug("Finished searching all indexers. Total {0}", reports.Count); if (reports.Count == 0) - return false; + return new List(); Logger.Debug("Getting episodes from database for series: {0} and season: {1}", seriesId, seasonNumber); var episodeNumbers = _episodeProvider.GetEpisodeNumbersBySeason(seriesId, seasonNumber); @@ -82,7 +82,7 @@ namespace NzbDrone.Core.Providers if (episodeNumbers == null || episodeNumbers.Count == 0) { Logger.Warn("No episodes in database found for series: {0} and season: {1}.", seriesId, seasonNumber); - return false; + return new List(); } notification.CurrentMessage = "Processing search results"; @@ -94,7 +94,7 @@ namespace NzbDrone.Core.Providers searchResult.SearchHistoryItems = ProcessSearchResults(notification, reports, searchResult, series, seasonNumber); _searchHistoryProvider.Add(searchResult); - return (searchResult.Successes.Count == episodeNumbers.Count); + return searchResult.Successes; } public virtual List PartialSeasonSearch(ProgressNotification notification, int seriesId, int seasonNumber)