From 9c6d78d4794aa5b691c9d38f77a5f977245ea736 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 17 Oct 2012 00:39:06 -0700 Subject: [PATCH] Cleanup and updates for XEM SceneSource added to signify to lookup via scene name Use Episodes for naming instead of EpisodeNumbers (in ParseResult) --- NzbDrone.Common.Test/DiskProviderFixture.cs | 12 +++++ NzbDrone.Common/DiskProvider.cs | 8 ++++ .../NzbDrone.Core.Test.ncrunchproject | 3 ++ .../CustomStartDateSpecificationFixture.cs | 14 +++--- .../UpgradeDiskSpecificationFixtrue.cs | 22 +++++---- .../UpgradeHistorySpecificationFixtrue.cs | 19 ++++---- .../ImportFileFixture.cs | 45 +++++++++++++++++++ .../ProviderTests/DownloadProviderFixture.cs | 9 +++- .../Datastore/Migrations/Migration20121016.cs | 2 + NzbDrone.Core/Model/EpisodeParseResult.cs | 4 ++ NzbDrone.Core/NzbDrone.Core.csproj | 2 + .../CustomStartDateSpecification.cs | 4 +- .../MonitoredEpisodeSpecification.cs | 1 + .../UpgradeDiskSpecification.cs | 2 +- .../UpgradeHistorySpecification.cs | 2 +- NzbDrone.Core/Providers/DiskScanProvider.cs | 4 ++ NzbDrone.Core/Providers/DownloadProvider.cs | 8 ++-- NzbDrone.Core/Providers/EpisodeProvider.cs | 31 +++++++++++-- .../Providers/Indexer/IndexerBase.cs | 1 + .../Providers/SearchHistoryProvider.cs | 2 + NzbDrone.Core/Providers/SearchProvider.cs | 4 ++ NzbDrone.Core/Repository/Series.cs | 2 + 22 files changed, 157 insertions(+), 44 deletions(-) diff --git a/NzbDrone.Common.Test/DiskProviderFixture.cs b/NzbDrone.Common.Test/DiskProviderFixture.cs index a4762bbdd..469cc77ab 100644 --- a/NzbDrone.Common.Test/DiskProviderFixture.cs +++ b/NzbDrone.Common.Test/DiskProviderFixture.cs @@ -175,6 +175,18 @@ namespace NzbDrone.Common.Test Console.WriteLine(new DirectoryInfo(@"C:\DRIVERS").LastWriteTimeUtc); } + [Test] + public void IsChildOfPath_should_return_true_when_it_is_a_child() + { + Mocker.Resolve().IsChildOfPath(@"C:\Test\TV", @"C:\Test").Should().BeTrue(); + } + + [Test] + public void IsChildOfPath_should_return_false_when_it_is_not_a_child() + { + Mocker.Resolve().IsChildOfPath(@"C:\NOT_Test\TV", @"C:\Test").Should().BeFalse(); + } + private void VerifyCopy() { BinFolder.Refresh(); diff --git a/NzbDrone.Common/DiskProvider.cs b/NzbDrone.Common/DiskProvider.cs index a56e72b1f..9e1bb334d 100644 --- a/NzbDrone.Common/DiskProvider.cs +++ b/NzbDrone.Common/DiskProvider.cs @@ -235,5 +235,13 @@ namespace NzbDrone.Common { Directory.SetLastWriteTimeUtc(path, dateTime); } + + public virtual bool IsChildOfPath(string child, string parent) + { + if (Path.GetFullPath(child).StartsWith(Path.GetFullPath(parent))) + return true; + + return false; + } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.ncrunchproject b/NzbDrone.Core.Test/NzbDrone.Core.Test.ncrunchproject index 19f185295..35a316e01 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.ncrunchproject +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.ncrunchproject @@ -23,5 +23,8 @@ NzbDrone.Core.Test.Integeration.ServiceIntegerationFixture.should_be_able_to_submit_exceptions + + NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests.ImportFileFixture.import_unparsable_file_should_skip + \ No newline at end of file diff --git a/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/CustomStartDateSpecificationFixture.cs b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/CustomStartDateSpecificationFixture.cs index 6e5b5d0da..f122e2cfa 100644 --- a/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/CustomStartDateSpecificationFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/CustomStartDateSpecificationFixture.cs @@ -32,6 +32,9 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests { _customStartDateSpecification = Mocker.Resolve(); + firstEpisode = new Episode { AirDate = DateTime.Today }; + secondEpisode = new Episode { AirDate = DateTime.Today }; + fakeSeries = Builder.CreateNew() .With(c => c.Monitored = true) .With(c => c.CustomStartDate = null) @@ -43,6 +46,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Series = fakeSeries, EpisodeNumbers = new List { 3, 4 }, SeasonNumber = 12, + Episodes = new List { firstEpisode, secondEpisode } }; parseResultSingle = new EpisodeParseResult @@ -51,16 +55,8 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Series = fakeSeries, EpisodeNumbers = new List { 3 }, SeasonNumber = 12, + Episodes = new List { firstEpisode } }; - - firstEpisode = new Episode { AirDate = DateTime.Today }; - secondEpisode = new Episode { AirDate = DateTime.Today }; - - var singleEpisodeList = new List { firstEpisode }; - var doubleEpisodeList = new List { firstEpisode, secondEpisode }; - - Mocker.GetMock().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList); - Mocker.GetMock().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList); } private void WithFirstEpisodeLastYear() diff --git a/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeDiskSpecificationFixtrue.cs b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeDiskSpecificationFixtrue.cs index bd8a2a39f..ae377f332 100644 --- a/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeDiskSpecificationFixtrue.cs +++ b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeDiskSpecificationFixtrue.cs @@ -31,6 +31,12 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Mocker.Resolve(); _upgradeDisk = Mocker.Resolve(); + firstFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true }; + secondFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true }; + + var singleEpisodeList = new List { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = null } }; + var doubleEpisodeList = new List { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = secondFile }, new Episode { EpisodeFile = null } }; + var fakeSeries = Builder.CreateNew() .With(c => c.QualityProfile = new QualityProfile { Cutoff = QualityTypes.Bluray1080p }) .Build(); @@ -41,6 +47,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Quality = new Quality(QualityTypes.DVD, true), EpisodeNumbers = new List { 3, 4 }, SeasonNumber = 12, + Episodes = doubleEpisodeList }; parseResultSingle = new EpisodeParseResult @@ -49,17 +56,8 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Quality = new Quality(QualityTypes.DVD, true), EpisodeNumbers = new List { 3 }, SeasonNumber = 12, + Episodes = singleEpisodeList }; - - - firstFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true }; - secondFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true }; - - var singleEpisodeList = new List { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = null } }; - var doubleEpisodeList = new List { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = secondFile }, new Episode { EpisodeFile = null } }; - - Mocker.GetMock().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList); - Mocker.GetMock().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList); } private void WithFirstFileUpgradable() @@ -73,9 +71,9 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests } [Test] - public void should_return_false_if_single_episode_doesnt_exist_on_disk() + public void should_return_true_if_single_episode_doesnt_exist_on_disk() { - Mocker.GetMock().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(new List()); + parseResultSingle.Episodes = new List(); _upgradeDisk.IsSatisfiedBy(parseResultSingle).Should().BeTrue(); } diff --git a/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeHistorySpecificationFixtrue.cs b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeHistorySpecificationFixtrue.cs index 85e0ff0fe..ce5fff251 100644 --- a/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeHistorySpecificationFixtrue.cs +++ b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/UpgradeHistorySpecificationFixtrue.cs @@ -31,6 +31,13 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Mocker.Resolve(); _upgradeHistory = Mocker.Resolve(); + var singleEpisodeList = new List { new Episode { SeasonNumber = 12, EpisodeNumber = 3 } }; + var doubleEpisodeList = new List { + new Episode { SeasonNumber = 12, EpisodeNumber = 3 }, + new Episode { SeasonNumber = 12, EpisodeNumber = 4 }, + new Episode { SeasonNumber = 12, EpisodeNumber = 5 } + }; + var fakeSeries = Builder.CreateNew() .With(c => c.QualityProfile = new QualityProfile { Cutoff = QualityTypes.Bluray1080p }) .Build(); @@ -41,6 +48,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Quality = new Quality(QualityTypes.DVD, true), EpisodeNumbers = new List { 3, 4 }, SeasonNumber = 12, + Episodes = doubleEpisodeList }; parseResultSingle = new EpisodeParseResult @@ -49,21 +57,12 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests Quality = new Quality(QualityTypes.DVD, true), EpisodeNumbers = new List { 3 }, SeasonNumber = 12, + Episodes = singleEpisodeList }; firstQuality = new Quality(QualityTypes.Bluray1080p, true); secondQuality = new Quality(QualityTypes.Bluray1080p, true); - var singleEpisodeList = new List { new Episode { SeasonNumber = 12, EpisodeNumber = 3 } }; - var doubleEpisodeList = new List { - new Episode { SeasonNumber = 12, EpisodeNumber = 3 }, - new Episode { SeasonNumber = 12, EpisodeNumber = 4 }, - new Episode { SeasonNumber = 12, EpisodeNumber = 5 } - }; - - Mocker.GetMock().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList); - Mocker.GetMock().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList); - Mocker.GetMock().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 3)).Returns(firstQuality); Mocker.GetMock().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 4)).Returns(secondQuality); Mocker.GetMock().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 5)).Returns(null); diff --git a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ImportFileFixture.cs b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ImportFileFixture.cs index 21b9acf69..52670e1c9 100644 --- a/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ImportFileFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/DiskScanProviderTests/ImportFileFixture.cs @@ -201,6 +201,9 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests Mocker.GetMock(MockBehavior.Strict) .Setup(e => e.GetSize(fileName)).Returns(90000000000); + Mocker.GetMock(MockBehavior.Strict) + .Setup(e => e.IsChildOfPath(fileName, fakeSeries.Path)).Returns(false); + Mocker.GetMock() .Setup(c => c.GetEpisodesByParseResult(It.IsAny())) .Returns(new List()); @@ -416,5 +419,47 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests Mocker.GetMock().Verify(p => p.UpdateEpisode(It.IsAny()), Times.Never()); Mocker.GetMock().Verify(p => p.DeleteFile(It.IsAny()), Times.Never()); } + + [Test] + public void should_set_parseResult_SceneSource_if_not_in_series_Path() + { + var series = Builder + .CreateNew() + .With(s => s.Path == @"C:\Test\TV\30 Rock") + .Build(); + + const string path = @"C:\Test\Unsorted TV\30 Rock\30.rock.s01e01.pilot.mkv"; + + Mocker.GetMock().Setup(s => s.GetEpisodesByParseResult(It.IsAny())) + .Returns(new List()); + + Mocker.GetMock().Setup(s => s.IsChildOfPath(path, series.Path)) + .Returns(false); + + Mocker.Resolve().ImportFile(series, path); + + Mocker.Verify(s => s.GetEpisodesByParseResult(It.Is(p => p.SceneSource)), Times.Once()); + } + + [Test] + public void should_not_set_parseResult_SceneSource_if_in_series_Path() + { + var series = Builder + .CreateNew() + .With(s => s.Path == @"C:\Test\TV\30 Rock") + .Build(); + + const string path = @"C:\Test\TV\30 Rock\30.rock.s01e01.pilot.mkv"; + + Mocker.GetMock().Setup(s => s.GetEpisodesByParseResult(It.IsAny())) + .Returns(new List()); + + Mocker.GetMock().Setup(s => s.IsChildOfPath(path, series.Path)) + .Returns(true); + + Mocker.Resolve().ImportFile(series, path); + + Mocker.Verify(s => s.GetEpisodesByParseResult(It.Is(p => p.SceneSource == false)), Times.Once()); + } } } diff --git a/NzbDrone.Core.Test/ProviderTests/DownloadProviderFixture.cs b/NzbDrone.Core.Test/ProviderTests/DownloadProviderFixture.cs index 179478611..2886b8074 100644 --- a/NzbDrone.Core.Test/ProviderTests/DownloadProviderFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/DownloadProviderFixture.cs @@ -43,6 +43,7 @@ namespace NzbDrone.Core.Test.ProviderTests .With(c => c.Quality = new Quality(QualityTypes.DVD, false)) .With(c => c.Series = Builder.CreateNew().Build()) .With(c => c.EpisodeNumbers = new List{2}) + .With(c => c.Episodes = episodes) .Build(); } @@ -191,6 +192,11 @@ namespace NzbDrone.Core.Test.ProviderTests .With(c => c.Title = "My Series Name") .Build(); + var fakeEpisodes = new List(); + + foreach(var episode in episodes) + fakeEpisodes.Add(Builder.CreateNew().With(e => e.EpisodeNumber = episode).Build()); + var parsResult = new EpisodeParseResult() { AirDate = DateTime.Now, @@ -198,7 +204,8 @@ namespace NzbDrone.Core.Test.ProviderTests Quality = new Quality(quality, proper), SeasonNumber = seasons, Series = series, - EpisodeTitle = title + EpisodeTitle = title, + Episodes = fakeEpisodes }; return Mocker.Resolve().GetDownloadTitle(parsResult); diff --git a/NzbDrone.Core/Datastore/Migrations/Migration20121016.cs b/NzbDrone.Core/Datastore/Migrations/Migration20121016.cs index 22aec34fc..0a8c55e5b 100644 --- a/NzbDrone.Core/Datastore/Migrations/Migration20121016.cs +++ b/NzbDrone.Core/Datastore/Migrations/Migration20121016.cs @@ -13,6 +13,8 @@ namespace NzbDrone.Core.Datastore.Migrations Database.AddColumn("Episodes", new Column("SceneAbsoluteEpisodeNumber", DbType.Int32, ColumnProperty.Null)); Database.AddColumn("Episodes", new Column("SceneSeasonNumber", DbType.Int32, ColumnProperty.Null)); Database.AddColumn("Episodes", new Column("SceneEpisodeNumber", DbType.Int32, ColumnProperty.Null)); + + Database.AddColumn("Series", new Column("UseSceneNumbering", DbType.Boolean, ColumnProperty.Null)); } } } \ No newline at end of file diff --git a/NzbDrone.Core/Model/EpisodeParseResult.cs b/NzbDrone.Core/Model/EpisodeParseResult.cs index e2385d5ff..6cf26464a 100644 --- a/NzbDrone.Core/Model/EpisodeParseResult.cs +++ b/NzbDrone.Core/Model/EpisodeParseResult.cs @@ -46,6 +46,10 @@ namespace NzbDrone.Core.Model public string ReleaseGroup { get; set; } + public bool SceneSource { get; set; } + + public IList Episodes { get; set; } + public override string ToString() { diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index fd55c83f4..f46817a93 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -227,6 +227,7 @@ + @@ -334,6 +335,7 @@ + diff --git a/NzbDrone.Core/Providers/DecisionEngine/CustomStartDateSpecification.cs b/NzbDrone.Core/Providers/DecisionEngine/CustomStartDateSpecification.cs index 53db72ff1..d96f41a07 100644 --- a/NzbDrone.Core/Providers/DecisionEngine/CustomStartDateSpecification.cs +++ b/NzbDrone.Core/Providers/DecisionEngine/CustomStartDateSpecification.cs @@ -29,9 +29,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine return true; } - var episodes = _episodeProvider.GetEpisodesByParseResult(subject); - - if (episodes.Any(episode => episode.AirDate > subject.Series.CustomStartDate.Value)) + if (subject.Episodes.Any(episode => episode.AirDate > subject.Series.CustomStartDate.Value)) { logger.Debug("One or more episodes aired after cutoff, downloading."); return true; diff --git a/NzbDrone.Core/Providers/DecisionEngine/MonitoredEpisodeSpecification.cs b/NzbDrone.Core/Providers/DecisionEngine/MonitoredEpisodeSpecification.cs index 713b556e3..d92e79ae5 100644 --- a/NzbDrone.Core/Providers/DecisionEngine/MonitoredEpisodeSpecification.cs +++ b/NzbDrone.Core/Providers/DecisionEngine/MonitoredEpisodeSpecification.cs @@ -42,6 +42,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine } var episodes = _episodeProvider.GetEpisodesByParseResult(subject); + subject.Episodes = episodes; //return monitored if any of the episodes are monitored if (episodes.Any(episode => !episode.Ignored)) diff --git a/NzbDrone.Core/Providers/DecisionEngine/UpgradeDiskSpecification.cs b/NzbDrone.Core/Providers/DecisionEngine/UpgradeDiskSpecification.cs index ee9a500e0..fc37ae424 100644 --- a/NzbDrone.Core/Providers/DecisionEngine/UpgradeDiskSpecification.cs +++ b/NzbDrone.Core/Providers/DecisionEngine/UpgradeDiskSpecification.cs @@ -24,7 +24,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { - foreach (var file in _episodeProvider.GetEpisodesByParseResult(subject).Select(c => c.EpisodeFile).Where(c => c != null)) + foreach (var file in subject.Episodes.Select(c => c.EpisodeFile).Where(c => c != null)) { logger.Trace("Comparing file quality with report. Existing file is {0} proper:{1}", file.Quality, file.Proper); if (!_qualityUpgradeSpecification.IsSatisfiedBy(new Quality { QualityType = file.Quality, Proper = file.Proper }, subject.Quality, subject.Series.QualityProfile.Cutoff)) diff --git a/NzbDrone.Core/Providers/DecisionEngine/UpgradeHistorySpecification.cs b/NzbDrone.Core/Providers/DecisionEngine/UpgradeHistorySpecification.cs index 86c61c586..11bcb161b 100644 --- a/NzbDrone.Core/Providers/DecisionEngine/UpgradeHistorySpecification.cs +++ b/NzbDrone.Core/Providers/DecisionEngine/UpgradeHistorySpecification.cs @@ -27,7 +27,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine public virtual bool IsSatisfiedBy(EpisodeParseResult subject) { - foreach (var episode in _episodeProvider.GetEpisodesByParseResult(subject)) + foreach (var episode in subject.Episodes) { var bestQualityInHistory = _historyProvider.GetBestQualityInHistory(subject.Series.SeriesId, episode.SeasonNumber, episode.EpisodeNumber); if (bestQualityInHistory != null) diff --git a/NzbDrone.Core/Providers/DiskScanProvider.cs b/NzbDrone.Core/Providers/DiskScanProvider.cs index bf9e2db24..746b5d77b 100644 --- a/NzbDrone.Core/Providers/DiskScanProvider.cs +++ b/NzbDrone.Core/Providers/DiskScanProvider.cs @@ -122,6 +122,9 @@ namespace NzbDrone.Core.Providers if (parseResult == null) return null; + if (!_diskProvider.IsChildOfPath(filePath, series.Path)) + parseResult.SceneSource = true; + parseResult.SeriesTitle = series.Title; //replaces the nasty path as title to help with logging parseResult.Series = series; @@ -203,6 +206,7 @@ namespace NzbDrone.Core.Providers var parseResult = Parser.ParsePath(episodeFile.Path); parseResult.Series = series; parseResult.Quality = new Quality{ QualityType = episodeFile.Quality, Proper = episodeFile.Proper }; + parseResult.Episodes = episodes; var message = _downloadProvider.GetDownloadTitle(parseResult); diff --git a/NzbDrone.Core/Providers/DownloadProvider.cs b/NzbDrone.Core/Providers/DownloadProvider.cs index a4114022b..046047442 100644 --- a/NzbDrone.Core/Providers/DownloadProvider.cs +++ b/NzbDrone.Core/Providers/DownloadProvider.cs @@ -48,13 +48,13 @@ namespace NzbDrone.Core.Providers var provider = GetActiveDownloadClient(); - bool success = provider.DownloadNzb(parseResult.NzbUrl, GetDownloadTitle(parseResult)); + bool success = provider.DownloadNzb(parseResult.NzbUrl, downloadTitle); if (success) { logger.Trace("Download added to Queue: {0}", downloadTitle); - foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parseResult)) + foreach (var episode in parseResult.Episodes) { var history = new History { @@ -127,9 +127,9 @@ namespace NzbDrone.Core.Providers //Show Name - 1x01 - Episode Name var episodeString = new List(); - foreach (var episode in parseResult.EpisodeNumbers) + foreach (var episode in parseResult.Episodes) { - episodeString.Add(String.Format("{0}x{1:00}", parseResult.SeasonNumber, episode)); + episodeString.Add(String.Format("{0}x{1:00}", parseResult.SeasonNumber, episode.EpisodeNumber)); } var epNumberString = String.Join("-", episodeString); diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index 398938c5e..f5514a698 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -188,11 +188,20 @@ namespace NzbDrone.Core.Providers foreach (var episodeNumber in parseResult.EpisodeNumbers) { - var episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber); - if (episodeInfo == null && parseResult.AirDate != null) + Episode episodeInfo; + + if (parseResult.SceneSource && parseResult.Series.UseSceneNumbering) + episodeInfo = GetEpisodeFromSceneNumbering(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber); + + else { - episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate.Value); + episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber); + if (episodeInfo == null && parseResult.AirDate != null) + { + episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate.Value); + } } + //if still null we should add the temp episode if (episodeInfo == null && autoAddNew) { @@ -440,5 +449,21 @@ namespace NzbDrone.Core.Providers { _database.UpdateMany(episodes); } + + public virtual Episode GetEpisodeFromSceneNumbering(int seriesId, int seasonNumber, int episodeNumber) + { + var episode = _database.Fetch(@"SELECT * FROM Episodes + INNER JOIN Series ON Episodes.SeriesId = Series.SeriesId + LEFT JOIN EpisodeFiles ON Episodes.EpisodeFileId = EpisodeFiles.EpisodeFileId + WHERE Episodes.SeriesId = @0 AND Episodes.SceneSeasonNumber = @1 AND Episodes.SceneEpisodeNumber = @2", seriesId, seasonNumber, episodeNumber).SingleOrDefault(); + + if (episode == null) + return null; + + if (episode.EpisodeFileId == 0) + episode.EpisodeFile = null; + + return episode; + } } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/Indexer/IndexerBase.cs b/NzbDrone.Core/Providers/Indexer/IndexerBase.cs index 76243629e..11b8c2d91 100644 --- a/NzbDrone.Core/Providers/Indexer/IndexerBase.cs +++ b/NzbDrone.Core/Providers/Indexer/IndexerBase.cs @@ -247,6 +247,7 @@ namespace NzbDrone.Core.Providers.Indexer { episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PublishDate.Date).Days; episodeParseResult.OriginalString = title; + episodeParseResult.SceneSource = true; } _logger.Trace("Parsed: {0} from: {1}", episodeParseResult, item.Title.Text); diff --git a/NzbDrone.Core/Providers/SearchHistoryProvider.cs b/NzbDrone.Core/Providers/SearchHistoryProvider.cs index fae40927b..4fb7e97a8 100644 --- a/NzbDrone.Core/Providers/SearchHistoryProvider.cs +++ b/NzbDrone.Core/Providers/SearchHistoryProvider.cs @@ -112,6 +112,8 @@ namespace NzbDrone.Core.Providers parseResult.NzbUrl = item.NzbUrl; parseResult.Series = series; parseResult.Indexer = item.Indexer; + parseResult.Episodes = _episodeProvider.GetEpisodesByParseResult(parseResult); + parseResult.SceneSource = true; logger.Info("Forcing Download of: {0}", item.ReportTitle); _downloadProvider.DownloadReport(parseResult); diff --git a/NzbDrone.Core/Providers/SearchProvider.cs b/NzbDrone.Core/Providers/SearchProvider.cs index 8aa86a491..727554d59 100644 --- a/NzbDrone.Core/Providers/SearchProvider.cs +++ b/NzbDrone.Core/Providers/SearchProvider.cs @@ -319,6 +319,8 @@ namespace NzbDrone.Core.Providers continue; } + episodeParseResult.Episodes = _episodeProvider.GetEpisodesByParseResult(episodeParseResult); + item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult); if (item.SearchError == ReportRejectionType.None) { @@ -403,6 +405,8 @@ namespace NzbDrone.Core.Providers continue; } + episodeParseResult.Episodes = _episodeProvider.GetEpisodesByParseResult(episodeParseResult); + item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult); if (item.SearchError == ReportRejectionType.None) { diff --git a/NzbDrone.Core/Repository/Series.cs b/NzbDrone.Core/Repository/Series.cs index 70d19cead..35a66ba92 100644 --- a/NzbDrone.Core/Repository/Series.cs +++ b/NzbDrone.Core/Repository/Series.cs @@ -50,6 +50,8 @@ namespace NzbDrone.Core.Repository public DateTime? CustomStartDate { get; set; } + public bool UseSceneNumbering { get; set; } + /// /// Gets or sets a value indicating whether this is hidden. ///