mirror of https://github.com/Radarr/Radarr
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.
This commit is contained in:
parent
53ced94af9
commit
edb0b3af86
|
@ -20,22 +20,12 @@ namespace NzbDrone.Core.Test.JobTests
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
public class SeasonSearchJobTest : CoreTest
|
public class SeasonSearchJobTest : CoreTest
|
||||||
{
|
{
|
||||||
[Test]
|
private ProgressNotification notification;
|
||||||
public void SeasonSearch_full_season_success()
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
{
|
{
|
||||||
var notification = new ProgressNotification("Season Search");
|
notification = new ProgressNotification("Search");
|
||||||
|
|
||||||
Mocker.GetMock<SearchProvider>()
|
|
||||||
.Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(true);
|
|
||||||
|
|
||||||
//Act
|
|
||||||
Mocker.Resolve<SeasonSearchJob>().Start(notification, 1, 1);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
Mocker.VerifyAllMocks();
|
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once());
|
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Never());
|
|
||||||
Mocker.GetMock<EpisodeSearchJob>().Verify(c => c.Start(notification, It.IsAny<int>(), 0), Times.Never());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -53,11 +43,6 @@ namespace NzbDrone.Core.Test.JobTests
|
||||||
.With(e => e.SeriesId = 5)
|
.With(e => e.SeriesId = 5)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var notification = new ProgressNotification("Season Search");
|
|
||||||
|
|
||||||
Mocker.GetMock<SearchProvider>()
|
|
||||||
.Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(false);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
.Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes);
|
.Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes);
|
||||||
|
|
||||||
|
@ -70,7 +55,6 @@ namespace NzbDrone.Core.Test.JobTests
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
Mocker.VerifyAllMocks();
|
Mocker.VerifyAllMocks();
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once());
|
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once());
|
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once());
|
||||||
Mocker.GetMock<EpisodeSearchJob>().Verify(c => c.Start(notification, It.IsAny<int>(), 0), Times.Never());
|
Mocker.GetMock<EpisodeSearchJob>().Verify(c => c.Start(notification, It.IsAny<int>(), 0), Times.Never());
|
||||||
}
|
}
|
||||||
|
@ -86,14 +70,6 @@ namespace NzbDrone.Core.Test.JobTests
|
||||||
.With(e => e.AirDate = DateTime.Today.AddDays(-1))
|
.With(e => e.AirDate = DateTime.Today.AddDays(-1))
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var notification = new ProgressNotification("Season Search");
|
|
||||||
|
|
||||||
Mocker.GetMock<SearchProvider>()
|
|
||||||
.Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(false);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes);
|
|
||||||
|
|
||||||
Mocker.GetMock<SearchProvider>()
|
Mocker.GetMock<SearchProvider>()
|
||||||
.Setup(c => c.PartialSeasonSearch(notification, 1, 1))
|
.Setup(c => c.PartialSeasonSearch(notification, 1, 1))
|
||||||
.Returns(new List<int>());
|
.Returns(new List<int>());
|
||||||
|
@ -103,7 +79,6 @@ namespace NzbDrone.Core.Test.JobTests
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
Mocker.VerifyAllMocks();
|
Mocker.VerifyAllMocks();
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once());
|
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once());
|
Mocker.GetMock<SearchProvider>().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))
|
.With(e => e.AirDate = DateTime.Today.AddDays(2))
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var notification = new ProgressNotification("Season Search");
|
|
||||||
|
|
||||||
Mocker.GetMock<SearchProvider>()
|
|
||||||
.Setup(c => c.SeasonSearch(notification, 1, 1)).Returns(false);
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>()
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
.Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes);
|
.Setup(c => c.GetEpisodesBySeason(1, 1)).Returns(episodes);
|
||||||
|
|
||||||
Mocker.GetMock<SearchProvider>()
|
Mocker.GetMock<SearchProvider>()
|
||||||
.Setup(c => c.PartialSeasonSearch(notification, 1, 1))
|
.Setup(c => c.PartialSeasonSearch(notification, 1, 1))
|
||||||
.Returns(new List<int>());
|
.Returns(new List<int>{1});
|
||||||
|
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
|
@ -138,23 +108,19 @@ namespace NzbDrone.Core.Test.JobTests
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
Mocker.VerifyAllMocks();
|
Mocker.VerifyAllMocks();
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.SeasonSearch(notification, 1, 1), Times.Once());
|
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once());
|
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SeasonSearch_should_allow_searching_of_season_zero()
|
public void SeasonSearch_should_allow_searching_of_season_zero()
|
||||||
{
|
{
|
||||||
var notification = new ProgressNotification("Season Search");
|
|
||||||
|
|
||||||
Mocker.GetMock<SearchProvider>()
|
Mocker.GetMock<SearchProvider>()
|
||||||
.Setup(c => c.SeasonSearch(notification, 1, 0)).Returns(true);
|
.Setup(c => c.PartialSeasonSearch(notification, 1, 0)).Returns(new List<int>());
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
Mocker.Resolve<SeasonSearchJob>().Start(notification, 1, 0);
|
Mocker.Resolve<SeasonSearchJob>().Start(notification, 1, 0);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.SeasonSearch(notification, 1, 0), Times.Once());
|
|
||||||
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Never());
|
Mocker.GetMock<SearchProvider>().Verify(c => c.PartialSeasonSearch(notification, 1, 1), Times.Never());
|
||||||
Mocker.GetMock<EpisodeSearchJob>().Verify(c => c.Start(notification, It.IsAny<int>(), 0), Times.Never());
|
Mocker.GetMock<EpisodeSearchJob>().Verify(c => c.Start(notification, It.IsAny<int>(), 0), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ namespace NzbDrone.Core.Test.ProviderTests.SearchProviderTests
|
||||||
var result = Mocker.Resolve<SearchProvider>().SeasonSearch(MockNotification, _series.SeriesId, 1);
|
var result = Mocker.Resolve<SearchProvider>().SeasonSearch(MockNotification, _series.SeriesId, 1);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
result.Should().BeFalse();
|
result.Should().BeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -45,7 +45,11 @@ namespace NzbDrone.Core.Jobs
|
||||||
if (secondaryTargetId < 0)
|
if (secondaryTargetId < 0)
|
||||||
throw new ArgumentOutOfRangeException("secondaryTargetId");
|
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;
|
return;
|
||||||
|
|
||||||
Logger.Debug("Getting episodes from database for series: {0} and season: {1}", targetId, secondaryTargetId);
|
Logger.Debug("Getting episodes from database for series: {0} and season: {1}", targetId, secondaryTargetId);
|
||||||
|
@ -57,25 +61,15 @@ namespace NzbDrone.Core.Jobs
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Perform a Partial Season Search
|
if (episodes.Count == successes.Count)
|
||||||
var addedSeries = _searchProvider.PartialSeasonSearch(notification, targetId, secondaryTargetId);
|
return;
|
||||||
|
|
||||||
//addedSeries.Distinct().ToList().Sort();
|
var missingEpisodes = episodes.Select(e => e.EpisodeNumber).Except(successes).ToList();
|
||||||
//var episodeNumbers = episodes.Where(w => w.AirDate <= DateTime.Today.AddDays(1)).Select(s => s.EpisodeNumber).ToList();
|
|
||||||
//episodeNumbers.Sort();
|
|
||||||
|
|
||||||
//if (addedSeries.SequenceEqual(episodeNumbers))
|
foreach (var episode in episodes.Where(e => !e.Ignored && missingEpisodes.Contains(e.EpisodeNumber)).OrderBy(o => o.EpisodeNumber))
|
||||||
// return;
|
{
|
||||||
|
_episodeSearchJob.Start(notification, episode.EpisodeId, 0);
|
||||||
////Get the list of episodes that weren't downloaded
|
}
|
||||||
//var missingEpisodes = episodeNumbers.Except(addedSeries).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);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@ namespace NzbDrone.Core.Providers
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool SeasonSearch(ProgressNotification notification, int seriesId, int seasonNumber)
|
public virtual List<int> SeasonSearch(ProgressNotification notification, int seriesId, int seasonNumber)
|
||||||
{
|
{
|
||||||
var searchResult = new SearchHistory
|
var searchResult = new SearchHistory
|
||||||
{
|
{
|
||||||
|
@ -60,12 +60,12 @@ namespace NzbDrone.Core.Providers
|
||||||
if (series == null)
|
if (series == null)
|
||||||
{
|
{
|
||||||
Logger.Error("Unable to find an series {0} in database", seriesId);
|
Logger.Error("Unable to find an series {0} in database", seriesId);
|
||||||
return false;
|
return new List<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Return false if the series is a daily series (we only support individual episode searching
|
//Return false if the series is a daily series (we only support individual episode searching
|
||||||
if (series.IsDaily)
|
if (series.IsDaily)
|
||||||
return false;
|
return new List<int>();
|
||||||
|
|
||||||
notification.CurrentMessage = String.Format("Searching for {0} Season {1}", series.Title, seasonNumber);
|
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);
|
Logger.Debug("Finished searching all indexers. Total {0}", reports.Count);
|
||||||
|
|
||||||
if (reports.Count == 0)
|
if (reports.Count == 0)
|
||||||
return false;
|
return new List<int>();
|
||||||
|
|
||||||
Logger.Debug("Getting episodes from database for series: {0} and season: {1}", seriesId, seasonNumber);
|
Logger.Debug("Getting episodes from database for series: {0} and season: {1}", seriesId, seasonNumber);
|
||||||
var episodeNumbers = _episodeProvider.GetEpisodeNumbersBySeason(seriesId, seasonNumber);
|
var episodeNumbers = _episodeProvider.GetEpisodeNumbersBySeason(seriesId, seasonNumber);
|
||||||
|
@ -82,7 +82,7 @@ namespace NzbDrone.Core.Providers
|
||||||
if (episodeNumbers == null || episodeNumbers.Count == 0)
|
if (episodeNumbers == null || episodeNumbers.Count == 0)
|
||||||
{
|
{
|
||||||
Logger.Warn("No episodes in database found for series: {0} and season: {1}.", seriesId, seasonNumber);
|
Logger.Warn("No episodes in database found for series: {0} and season: {1}.", seriesId, seasonNumber);
|
||||||
return false;
|
return new List<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
notification.CurrentMessage = "Processing search results";
|
notification.CurrentMessage = "Processing search results";
|
||||||
|
@ -94,7 +94,7 @@ namespace NzbDrone.Core.Providers
|
||||||
searchResult.SearchHistoryItems = ProcessSearchResults(notification, reports, searchResult, series, seasonNumber);
|
searchResult.SearchHistoryItems = ProcessSearchResults(notification, reports, searchResult, series, seasonNumber);
|
||||||
_searchHistoryProvider.Add(searchResult);
|
_searchHistoryProvider.Add(searchResult);
|
||||||
|
|
||||||
return (searchResult.Successes.Count == episodeNumbers.Count);
|
return searchResult.Successes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual List<int> PartialSeasonSearch(ProgressNotification notification, int seriesId, int seasonNumber)
|
public virtual List<int> PartialSeasonSearch(ProgressNotification notification, int seriesId, int seasonNumber)
|
||||||
|
|
Loading…
Reference in New Issue