From 04c71ff64c8e314d015d3faeb5474ac2005f1ecb Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 23 Nov 2011 16:39:21 -0800 Subject: [PATCH 1/8] Extended the actions column width on Series Grid - FF was creating two rows of buttons. --- NzbDrone.Core/Providers/Jobs/BacklogSearchJob.cs | 2 ++ NzbDrone.Web/Views/Series/Index.cshtml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NzbDrone.Core/Providers/Jobs/BacklogSearchJob.cs b/NzbDrone.Core/Providers/Jobs/BacklogSearchJob.cs index aa53b9b5d..a0c1d71c6 100644 --- a/NzbDrone.Core/Providers/Jobs/BacklogSearchJob.cs +++ b/NzbDrone.Core/Providers/Jobs/BacklogSearchJob.cs @@ -59,6 +59,8 @@ namespace NzbDrone.Core.Providers.Jobs var countInDb = _episodeProvider.GetEpisodeNumbersBySeason(seriesId, seasonNumber).Count; + //Todo: Download a full season if more than n% is missing? + if (count != countInDb) { //Add the episodes to be processed manually diff --git a/NzbDrone.Web/Views/Series/Index.cshtml b/NzbDrone.Web/Views/Series/Index.cshtml index 03208a7e4..20f17f398 100644 --- a/NzbDrone.Web/Views/Series/Index.cshtml +++ b/NzbDrone.Web/Views/Series/Index.cshtml @@ -85,7 +85,7 @@ NzbDrone { commands.Edit().ButtonType(GridButtonType.Image); commands.Delete().ButtonType(GridButtonType.Image); - }).Title("Actions").Width(80); + }).Title("Actions").Width(90); }) .Editable(editor => editor.Mode(GridEditMode.PopUp)) From e7815010215ba9c36eae9270b653d195fbfbd184 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 23 Nov 2011 17:09:09 -0800 Subject: [PATCH 2/8] Added RecentBacklogSearchJob to fill missing episodes from the last 30 days, runs nightly. --- .../JobTests/RecentBacklogSearchJobTest.cs | 83 +++++++++++++++++++ NzbDrone.Core.Test/NzbDrone.Core.Test.csproj | 1 + NzbDrone.Core/CentralDispatch.cs | 1 + NzbDrone.Core/NzbDrone.Core.csproj | 1 + .../Providers/Jobs/RecentBacklogSearchJob.cs | 51 ++++++++++++ 5 files changed, 137 insertions(+) create mode 100644 NzbDrone.Core.Test/JobTests/RecentBacklogSearchJobTest.cs create mode 100644 NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs diff --git a/NzbDrone.Core.Test/JobTests/RecentBacklogSearchJobTest.cs b/NzbDrone.Core.Test/JobTests/RecentBacklogSearchJobTest.cs new file mode 100644 index 000000000..3a21b6ff4 --- /dev/null +++ b/NzbDrone.Core.Test/JobTests/RecentBacklogSearchJobTest.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using FizzWare.NBuilder; +using Moq; +using NUnit.Framework; +using NzbDrone.Core.Model.Notification; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Jobs; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common.AutoMoq; + +namespace NzbDrone.Core.Test.JobTests +{ + [TestFixture] + public class RecentBacklogSearchJobTest : CoreTest + { + [SetUp] + public void Setup() + { + + } + + [Test] + public void no_missing_epsiodes_should_not_trigger_any_search() + { + //Setup + var episodes = new List(); + + Mocker.GetMock() + .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); + + //Act + Mocker.Resolve().Start(MockNotification, 0, 0); + + //Assert + Mocker.GetMock().Verify(c => c.Start(MockNotification, It.IsAny(), 0), + Times.Never()); + } + + [Test] + public void should_only_process_missing_episodes_from_the_last_30_days() + { + //Setup + var episodes = Builder.CreateListOfSize(50) + .TheFirst(5) + .With(e => e.AirDate = DateTime.Today) + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-1)) //Today + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-5)) //Yeserday + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-10)) + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-15)) + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-20)) + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-25)) + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-30)) + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-31)) //31 Days + .TheNext(5) + .With(e => e.AirDate = DateTime.Today.AddDays(-35)) + .Build(); + + Mocker.GetMock() + .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); + + Mocker.GetMock().Setup(c => c.Start(It.IsAny(), It.IsAny(), 0)); + + //Act + Mocker.Resolve().Start(MockNotification, 0, 0); + + //Assert + Mocker.GetMock().Verify(c => c.Start(It.IsAny(), It.IsAny(), 0), + Times.Exactly(40)); + } + } +} diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 1645b0f7d..ad6b33b72 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -96,6 +96,7 @@ + diff --git a/NzbDrone.Core/CentralDispatch.cs b/NzbDrone.Core/CentralDispatch.cs index 30e4686cc..8830485e0 100644 --- a/NzbDrone.Core/CentralDispatch.cs +++ b/NzbDrone.Core/CentralDispatch.cs @@ -95,6 +95,7 @@ namespace NzbDrone.Core Kernel.Bind().To().InSingletonScope(); Kernel.Bind().To().InSingletonScope(); Kernel.Bind().To().InSingletonScope(); + Kernel.Bind().To().InSingletonScope(); Kernel.Get().Initialize(); Kernel.Get().StartTimer(30); diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 794da4ac6..f4f155d70 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -235,6 +235,7 @@ + diff --git a/NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs b/NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs new file mode 100644 index 000000000..ae0e13746 --- /dev/null +++ b/NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NLog; +using NzbDrone.Core.Model; +using NzbDrone.Core.Model.Notification; +using NzbDrone.Core.Model.Search; +using NzbDrone.Core.Repository; + +namespace NzbDrone.Core.Providers.Jobs +{ + public class RecentBacklogSearchJob : IJob + { + private readonly EpisodeProvider _episodeProvider; + private readonly EpisodeSearchJob _episodeSearchJob; + private readonly SeasonSearchJob _seasonSearchJob; + + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + public RecentBacklogSearchJob(EpisodeProvider episodeProvider, EpisodeSearchJob episodeSearchJob, + SeasonSearchJob seasonSearchJob) + { + _episodeProvider = episodeProvider; + _episodeSearchJob = episodeSearchJob; + _seasonSearchJob = seasonSearchJob; + } + + public string Name + { + get { return "Recent Backlog Search"; } + } + + public int DefaultInterval + { + get { return 1440; } + } + + public void Start(ProgressNotification notification, int targetId, int secondaryTargetId) + { + //Get episodes that are considered missing and aired in the last 30 days + var missingEpisodes = _episodeProvider.EpisodesWithoutFiles(true).Where(e => e.AirDate >= DateTime.Today.AddDays(-30)); + + Logger.Debug("Processing missing episodes from the last 30 days"); + //Process the list of remaining episodes, 1 by 1 + foreach (var episode in missingEpisodes) + { + _episodeSearchJob.Start(notification, episode.EpisodeId, 0); + } + } + } +} \ No newline at end of file From 90e15dbcdf7ee80d86ba99c674bac1ca531e3085 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 23 Nov 2011 17:10:20 -0800 Subject: [PATCH 3/8] Removed Injection for SeasonSearchJob on RecentBacklogSearchJob. --- NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs b/NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs index ae0e13746..801e138a9 100644 --- a/NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs +++ b/NzbDrone.Core/Providers/Jobs/RecentBacklogSearchJob.cs @@ -13,16 +13,13 @@ namespace NzbDrone.Core.Providers.Jobs { private readonly EpisodeProvider _episodeProvider; private readonly EpisodeSearchJob _episodeSearchJob; - private readonly SeasonSearchJob _seasonSearchJob; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - public RecentBacklogSearchJob(EpisodeProvider episodeProvider, EpisodeSearchJob episodeSearchJob, - SeasonSearchJob seasonSearchJob) + public RecentBacklogSearchJob(EpisodeProvider episodeProvider, EpisodeSearchJob episodeSearchJob) { _episodeProvider = episodeProvider; _episodeSearchJob = episodeSearchJob; - _seasonSearchJob = seasonSearchJob; } public string Name From 576f5c5c09804cabc0df2425d6a2857fafe3bb17 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 23 Nov 2011 20:50:09 -0800 Subject: [PATCH 4/8] EpisodeSearch will now notify if no download is found. --- NzbDrone.Core/Providers/SearchProvider.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/NzbDrone.Core/Providers/SearchProvider.cs b/NzbDrone.Core/Providers/SearchProvider.cs index 9b5f43a21..3e07d6d1e 100644 --- a/NzbDrone.Core/Providers/SearchProvider.cs +++ b/NzbDrone.Core/Providers/SearchProvider.cs @@ -155,15 +155,12 @@ namespace NzbDrone.Core.Providers Logger.Debug("Finished searching all indexers. Total {0}", reports.Count); notification.CurrentMessage = "Processing search results"; + if (ProcessSearchResults(notification, reports, series, episode.SeasonNumber, episode.EpisodeNumber).Count == 1) + return true; - //TODO:fix this so when search returns more than one episode - //TODO:-its populated with more than the original episode. - reports.ForEach(c => - { - c.Series = series; - }); - - return (ProcessSearchResults(notification, reports, series, episode.SeasonNumber, episode.EpisodeNumber).Count == 1); + Logger.Warn("Unable to find {0} in any of indexers.", episode); + notification.CurrentMessage = String.Format("Unable to find {0} in any of indexers.", episode); + return false; } public List PerformSearch(ProgressNotification notification, Series series, int seasonNumber, IList episodes = null) From 2aaa23b11d0410c10bdb345d41c8ba740701f12d Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 23 Nov 2011 22:28:52 -0800 Subject: [PATCH 5/8] Refreshing EpisodeInfo will now set new or existing episodes that have air times prior to 1900 to null. --- .../ProviderTests/EpisodeProviderTest.cs | 45 +++++++++++++++++++ NzbDrone.Core/Providers/EpisodeProvider.cs | 5 ++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs index 036fb8a52..0b75cb2a0 100644 --- a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest.cs @@ -326,6 +326,51 @@ namespace NzbDrone.Core.Test.ProviderTests mocker.VerifyAllMocks(); } + [Test] + public void RefreshEpisodeInfo_should_set_older_than_1900_to_null_for_existing_episodes() + { + //Arrange + const int seriesId = 71663; + + var fakeEpisode = Builder.CreateNew() + .With(e => e.TvDbEpisodeId = 12345) + .With(e => e.AirDate = DateTime.Today) + .Build(); + + var fakeTvDbEpisodes = Builder.CreateNew().With( + c => c.Episodes = + new List(Builder.CreateListOfSize(1) + .All() + .With(l => l.Language = new TvdbLanguage(0, "eng", "a")).And(e => e.FirstAired = DateTime.Now) + .TheFirst(1).With(e => e.FirstAired = new DateTime(1800, 1, 1)) + .Build()) + ).With(c => c.Id = seriesId).Build(); + + var fakeSeries = Builder.CreateNew().With(c => c.SeriesId = seriesId).Build(); + + var mocker = new AutoMoqer(); + + var db = TestDbHelper.GetEmptyDatabase(); + mocker.SetConstant(db); + + db.Insert(fakeSeries); + db.Insert(fakeEpisode); + + mocker.GetMock() + .Setup(c => c.GetSeries(seriesId, true)) + .Returns(fakeTvDbEpisodes); + + //Act + mocker.Resolve().RefreshEpisodeInfo(fakeSeries); + + //Assert + var storedEpisodes = mocker.Resolve().GetEpisodeBySeries(seriesId).ToList(); + storedEpisodes.Should().HaveCount(1); + storedEpisodes.Where(e => e.AirDate == null).Should().HaveCount(1); + + mocker.VerifyAllMocks(); + } + [Test] public void RefreshEpisodeInfo_ignore_episode_zero() { diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index 508abcf1c..a740800d5 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -258,9 +258,10 @@ namespace NzbDrone.Core.Providers episodeToUpdate.Overview = episode.Overview; if (episode.FirstAired.Year > 1900) - { episodeToUpdate.AirDate = episode.FirstAired.Date; - } + + else + episodeToUpdate.AirDate = null; successCount++; } From 1317b8fbefafe8f12700deae8f3a00498451dd25 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 23 Nov 2011 23:11:13 -0800 Subject: [PATCH 6/8] Fixed issue with seriesLookup boxes not autocompleting after adding or removing a rootDir. --- NzbDrone.Web/Scripts/NzbDrone/AutoComplete.js | 11 ++++++++++- NzbDrone.Web/Scripts/NzbDrone/addSeries.js | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/NzbDrone.Web/Scripts/NzbDrone/AutoComplete.js b/NzbDrone.Web/Scripts/NzbDrone/AutoComplete.js index d6ade9fef..9b520fe73 100644 --- a/NzbDrone.Web/Scripts/NzbDrone/AutoComplete.js +++ b/NzbDrone.Web/Scripts/NzbDrone/AutoComplete.js @@ -3,10 +3,19 @@ cache: false }); + bindAutoCompletes(); +}); + +// +$('.folderLookup:not(.ui-autocomplete-input), .seriesLookup:not(.ui-autocomplete-input), .localSeriesLookup:not(.ui-autocomplete-input)').live('focus', function (event) { + bindAutoCompletes(); +}); + +function bindAutoCompletes() { bindFolderAutoComplete(".folderLookup"); bindSeriesAutoComplete(".seriesLookup"); bindLocalSeriesAutoComplete(".localSeriesLookup"); -}); +} function bindFolderAutoComplete(selector) { diff --git a/NzbDrone.Web/Scripts/NzbDrone/addSeries.js b/NzbDrone.Web/Scripts/NzbDrone/addSeries.js index a00814c0d..5a93ca03b 100644 --- a/NzbDrone.Web/Scripts/NzbDrone/addSeries.js +++ b/NzbDrone.Web/Scripts/NzbDrone/addSeries.js @@ -74,7 +74,7 @@ function refreshRoot() { $('#rootDirs').html(data); }); reloadAddNew(); - reloadExistingSeries(); + reloadExistingSeries(); } From 38790e9f9c3d20738dfde26e7f163640b2f6c416 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 24 Nov 2011 00:28:20 -0800 Subject: [PATCH 7/8] GetEpisodesByParseResult will properly handle Daily episodes. --- ...deProviderTest_GetEpisodesByParseResult.cs | 54 +++++++++++++++++++ .../InventoryProvider_IsMonitoredTest.cs | 28 ++++++++++ NzbDrone.Core/Providers/EpisodeProvider.cs | 24 +++++++++ 3 files changed, 106 insertions(+) diff --git a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_GetEpisodesByParseResult.cs b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_GetEpisodesByParseResult.cs index c0e57037e..0db4ffd3b 100644 --- a/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_GetEpisodesByParseResult.cs +++ b/NzbDrone.Core.Test/ProviderTests/EpisodeProviderTest_GetEpisodesByParseResult.cs @@ -1,16 +1,19 @@ // ReSharper disable RedundantUsingDirective +using System; using System.Collections.Generic; using System.Linq; using FizzWare.NBuilder; using FluentAssertions; +using Moq; using NUnit.Framework; using NzbDrone.Core.Model; using NzbDrone.Core.Providers; using NzbDrone.Core.Repository; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common.AutoMoq; +using PetaPoco; namespace NzbDrone.Core.Test.ProviderTests { @@ -255,6 +258,57 @@ namespace NzbDrone.Core.Test.ProviderTests episodes.Should().BeEmpty(); } + [Test] + public void GetEpisodeParseResult_should_return_single_episode_when_air_date_is_provided() + { + //Setup + var fakeEpisode = Builder.CreateListOfSize(1) + .All() + .With(e => e.AirDate = DateTime.Today) + .Build() + .ToList(); + + var fakeSeries = Builder.CreateNew() + .With(s => s.SeriesId = 1) + .Build(); + + Mocker.GetMock().Setup(s => s.Fetch(It.IsAny(), It.IsAny())) + .Returns(fakeEpisode); + + //Act + var episodes = Mocker.Resolve() + .GetEpisodesByParseResult(new EpisodeParseResult { AirDate = DateTime.Today, Series = fakeSeries }, true); + + //Assert + episodes.Should().HaveCount(1); + episodes.First().AirDate.Should().Be(DateTime.Today); + + Mocker.GetMock().Verify(v=> v.Insert(It.IsAny()), Times.Never()); + } + + [Test] + public void GetEpisodeParseResult_get_daily_should_add_new_episode() + { + //Setup + var fakeSeries = Builder.CreateNew() + .With(s => s.SeriesId = 1) + .Build(); + + Mocker.GetMock().Setup(s => s.Fetch(It.IsAny(), It.IsAny())) + .Returns(new List()); + + Mocker.GetMock().Setup(s => s.Insert(It.IsAny())) + .Returns(1); + + //Act + var episodes = Mocker.Resolve() + .GetEpisodesByParseResult(new EpisodeParseResult { AirDate = DateTime.Today, Series = fakeSeries }, true); + + //Assert + episodes.Should().HaveCount(1); + episodes.First().AirDate.Should().Be(DateTime.Today); + Mocker.GetMock().Verify(v => v.Insert(It.IsAny()), Times.Once()); + } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsMonitoredTest.cs b/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsMonitoredTest.cs index 2911231c9..125718c5c 100644 --- a/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsMonitoredTest.cs +++ b/NzbDrone.Core.Test/ProviderTests/InventoryProvider_IsMonitoredTest.cs @@ -25,6 +25,7 @@ namespace NzbDrone.Core.Test.ProviderTests private Episode episode; private Episode episode2; private EpisodeParseResult parseResultSingle; + private EpisodeParseResult parseResultDaily; [SetUp] public void Setup() @@ -49,6 +50,14 @@ namespace NzbDrone.Core.Test.ProviderTests AirDate = DateTime.Now.AddDays(-12).Date, }; + parseResultDaily = new EpisodeParseResult() + { + CleanTitle = "Title", + Language = LanguageType.English, + Quality = new Quality(QualityTypes.Bluray720p, true), + AirDate = DateTime.Now.AddDays(-12).Date, + }; + episode = Builder.CreateNew() .With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[0]) @@ -239,6 +248,25 @@ namespace NzbDrone.Core.Test.ProviderTests mocker.VerifyAllMocks(); } + [Test] + public void IsMonitored_daily_not_ignored_should_return_true() + { + var mocker = new AutoMoqer(MockBehavior.Strict); + + mocker.GetMock() + .Setup(p => p.FindSeries(It.IsAny())) + .Returns(series); + + mocker.GetMock() + .Setup(p => p.GetEpisodesByParseResult(It.IsAny(), true)) + .Returns(new List { episode }); + + episode.Ignored = false; + + var result = mocker.Resolve().IsMonitored(parseResultDaily); + //Assert + result.Should().BeTrue(); + } } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index a740800d5..ae522868f 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -125,6 +125,30 @@ namespace NzbDrone.Core.Providers { var result = new List(); + if (parseResult.AirDate.HasValue) + { + var episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate.Value); + + //if still null we should add the temp episode + if (episodeInfo == null && autoAddNew) + { + Logger.Debug("Episode {0} doesn't exist in db. adding it now.", parseResult); + episodeInfo = new Episode + { + SeriesId = parseResult.Series.SeriesId, + AirDate = parseResult.AirDate.Value, + Title = "TBD", + Overview = String.Empty, + }; + + AddEpisode(episodeInfo); + } + + //Add to Result and Return (There will only be one episode to return) + result.Add(episodeInfo); + return result; + } + if (parseResult.EpisodeNumbers == null) return result; From 290e5d58975b937355ab112c2f77579b643fd7e6 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 24 Nov 2011 23:56:07 -0800 Subject: [PATCH 8/8] Daily episodes that are added via RSS feed will have proper season and episode numbers. --- NzbDrone.Core.Test/FluentTest.cs | 27 ++++++++++++++++++++++ NzbDrone.Core/Fluent.cs | 11 +++++++++ NzbDrone.Core/Providers/EpisodeProvider.cs | 18 ++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/NzbDrone.Core.Test/FluentTest.cs b/NzbDrone.Core.Test/FluentTest.cs index 8a703d3fa..797bc5a4a 100644 --- a/NzbDrone.Core.Test/FluentTest.cs +++ b/NzbDrone.Core.Test/FluentTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using FluentAssertions; using NUnit.Framework; @@ -164,5 +165,31 @@ namespace NzbDrone.Core.Test //Resolve result.Should().Be("http://www.nzbdrone.com"); } + + [Test] + public void MaxOrDefault_should_return_zero_when_collection_is_empty() + { + //Setup + + + //Act + var result = (new List()).MaxOrDefault(); + + //Resolve + result.Should().Be(0); + } + + [Test] + public void MaxOrDefault_should_return_max_when_collection_is_not_empty() + { + //Setup + var list = new List {6, 4, 5, 3, 8, 10}; + + //Act + var result = list.MaxOrDefault(); + + //Resolve + result.Should().Be(10); + } } } diff --git a/NzbDrone.Core/Fluent.cs b/NzbDrone.Core/Fluent.cs index fe611d249..f99c0d038 100644 --- a/NzbDrone.Core/Fluent.cs +++ b/NzbDrone.Core/Fluent.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Text; @@ -51,5 +52,15 @@ namespace NzbDrone.Core { return uri.AbsoluteUri.Remove(uri.AbsoluteUri.Length - String.Join("", uri.Segments).Length - uri.Query.Length); } + + public static int MaxOrDefault(this IEnumerable ints) + { + var intList = ints.ToList(); + + if (intList.Count() == 0) + return 0; + + return intList.Max(); + } } } diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index ae522868f..597ed7746 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -138,9 +138,25 @@ namespace NzbDrone.Core.Providers SeriesId = parseResult.Series.SeriesId, AirDate = parseResult.AirDate.Value, Title = "TBD", - Overview = String.Empty, + Overview = String.Empty }; + var episodesInSeries = GetEpisodeBySeries(parseResult.Series.SeriesId); + + //Find the current season number + var maxSeasonNumber = episodesInSeries.Select(s => s.SeasonNumber).MaxOrDefault(); + + //Set the season number + episodeInfo.SeasonNumber = (maxSeasonNumber == 0) ? 1 : maxSeasonNumber; + + //Find the latest episode number + var maxEpisodeNumber = episodesInSeries + .Where(w => w.SeasonNumber == episodeInfo.SeasonNumber) + .Select(s => s.EpisodeNumber).MaxOrDefault(); + + //Set the episode number to max + 1 + episodeInfo.EpisodeNumber = maxEpisodeNumber + 1; + AddEpisode(episodeInfo); }