diff --git a/src/NzbDrone.Common/Extensions/Int64Extensions.cs b/src/NzbDrone.Common/Extensions/Int64Extensions.cs new file mode 100644 index 000000000..d389e5969 --- /dev/null +++ b/src/NzbDrone.Common/Extensions/Int64Extensions.cs @@ -0,0 +1,20 @@ +using System; + +namespace NzbDrone.Common.Extensions +{ + public static class Int64Extensions + { + private static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; + + public static string SizeSuffix(this Int64 value) + { + if (value < 0) { return "-" + SizeSuffix(-value); } + if (value == 0) { return "0.0 bytes"; } + + var mag = (int)Math.Log(value, 1024); + decimal adjustedSize = (decimal)value / (1L << (mag * 10)); + + return string.Format("{0:n1} {1}", adjustedSize, SizeSuffixes[mag]); + } + } +} diff --git a/src/NzbDrone.Common/NzbDrone.Common.csproj b/src/NzbDrone.Common/NzbDrone.Common.csproj index 99c966891..fc8d9470e 100644 --- a/src/NzbDrone.Common/NzbDrone.Common.csproj +++ b/src/NzbDrone.Common/NzbDrone.Common.csproj @@ -125,6 +125,7 @@ + diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/AcceptableSizeSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/AcceptableSizeSpecificationFixture.cs index 07cba6829..81fbf004d 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/AcceptableSizeSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/AcceptableSizeSpecificationFixture.cs @@ -88,7 +88,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests parseResultSingle.Series = series; parseResultSingle.Release.Size = sizeInMegaBytes.Megabytes(); - Subject.IsSatisfiedBy(parseResultSingle, null).Should().Be(expectedResult); + Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().Be(expectedResult); } [TestCase(30, 500, true)] @@ -103,7 +103,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests parseResultSingle.Series = series; parseResultSingle.Release.Size = sizeInMegaBytes.Megabytes(); - Subject.IsSatisfiedBy(parseResultSingle, null).Should().Be(expectedResult); + Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().Be(expectedResult); } [TestCase(30, 50 * 2, false)] @@ -118,7 +118,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests parseResultMulti.Series = series; parseResultMulti.Release.Size = sizeInMegaBytes.Megabytes(); - Subject.IsSatisfiedBy(parseResultMulti, null).Should().Be(expectedResult); + Subject.IsSatisfiedBy(parseResultMulti, null).Accepted.Should().Be(expectedResult); } [TestCase(30, 50 * 6, false)] @@ -133,7 +133,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests parseResultMultiSet.Series = series; parseResultMultiSet.Release.Size = sizeInMegaBytes.Megabytes(); - Subject.IsSatisfiedBy(parseResultMultiSet, null).Should().Be(expectedResult); + Subject.IsSatisfiedBy(parseResultMultiSet, null).Accepted.Should().Be(expectedResult); } [Test] @@ -146,7 +146,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests parseResultSingle.Release.Size = 18457280000; qualityType.MaxSize = 0; - Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue(); + Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] @@ -159,7 +159,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests parseResultSingle.Release.Size = 36857280000; qualityType.MaxSize = 0; - Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue();; + Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue(); ; } [Test] @@ -174,7 +174,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests qualityType.MaxSize = 10; - Subject.IsSatisfiedBy(parseResultSingle, null).Should().BeTrue(); + Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] @@ -185,18 +185,18 @@ namespace NzbDrone.Core.Test.DecisionEngineTests ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.RAWHD) }, }; - Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue(); } [Test] - public void should_always_return_false_if_unknown() + public void should_return_true_if_unknown() { var parseResult = new RemoteEpisode { ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.Unknown) }, }; - Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse(); + Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue(); Mocker.GetMock().Verify(c => c.Get(It.IsAny()), Times.Never()); } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/AnimeVersionUpgradeSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/AnimeVersionUpgradeSpecificationFixture.cs index f785ee6c9..9f650c17f 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/AnimeVersionUpgradeSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/AnimeVersionUpgradeSpecificationFixture.cs @@ -63,21 +63,21 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { _remoteEpisode.Episodes.First().EpisodeFileId = 0; - _subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + _subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] public void should_be_true_if_series_is_not_anime() { GivenStandardSeries(); - _subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + _subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] public void should_be_true_if_is_not_a_version_upgrade_for_existing_file() { GivenNoVersionUpgrade(); - _subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + _subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -85,27 +85,27 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { _episodeFile.ReleaseGroup = _remoteEpisode.ParsedEpisodeInfo.ReleaseGroup; - _subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + _subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] public void should_be_false_when_existing_file_doesnt_have_a_release_group() { _episodeFile.ReleaseGroup = String.Empty; - _subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + _subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] public void should_should_be_false_when_release_doesnt_have_a_release_group() { _remoteEpisode.ParsedEpisodeInfo.ReleaseGroup = String.Empty; - _subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + _subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] public void should_be_false_when_release_group_does_not_match() { - _subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + _subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs index 90b251ace..babab61b7 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs @@ -39,24 +39,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _fail2 = new Mock(); _fail3 = new Mock(); - _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(true); - _pass1.Setup(c => c.RejectionReason).Returns("_pass1"); - - _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(true); - _pass2.Setup(c => c.RejectionReason).Returns("_pass2"); - - _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(true); - _pass3.Setup(c => c.RejectionReason).Returns("_pass3"); - - - _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(false); - _fail1.Setup(c => c.RejectionReason).Returns("_fail1"); - - _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(false); - _fail2.Setup(c => c.RejectionReason).Returns("_fail2"); - - _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(false); - _fail3.Setup(c => c.RejectionReason).Returns("_fail3"); + _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Accept); + _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Accept); + _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Accept); + + _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Reject("fail1")); + _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Reject("fail2")); + _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Reject("fail3")); _reports = new List { new ReleaseInfo { Title = "The.Office.S03E115.DVDRip.XviD-OSiTV" } }; _remoteEpisode = new RemoteEpisode { Series = new Series() }; diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs index 06f96b88a..35c440766 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/HistorySpecificationFixture.cs @@ -99,7 +99,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void should_be_upgradable_if_only_episode_is_upgradable() { WithFirstReportUpgradable(); - _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue(); + _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] @@ -107,27 +107,27 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { WithFirstReportUpgradable(); WithSecondReportUpgradable(); - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } [Test] public void should_not_be_upgradable_if_both_episodes_are_not_upgradable() { - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] public void should_be_not_upgradable_if_only_first_episodes_is_upgradable() { WithFirstReportUpgradable(); - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] public void should_be_not_upgradable_if_only_second_episodes_is_upgradable() { WithSecondReportUpgradable(); - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] @@ -139,13 +139,13 @@ namespace NzbDrone.Core.Test.DecisionEngineTests Mocker.GetMock().Setup(c => c.GetBestQualityInHistory(It.IsAny(), 1)).Returns(_upgradableQuality); - _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse(); + _upgradeHistory.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } [Test] public void should_return_true_if_it_is_a_search() { - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, new SeasonSearchCriteria()).Should().BeTrue(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, new SeasonSearchCriteria()).Accepted.Should().BeTrue(); } [Test] @@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { GivenSabnzbdDownloadClient(); - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } [Test] @@ -162,7 +162,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests GivenSabnzbdDownloadClient(); GivenMostRecentForEpisode(HistoryEventType.Grabbed); - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] @@ -171,7 +171,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests GivenSabnzbdDownloadClient(); GivenMostRecentForEpisode(HistoryEventType.DownloadFailed); - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } [Test] @@ -180,7 +180,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests GivenSabnzbdDownloadClient(); GivenMostRecentForEpisode(HistoryEventType.DownloadFolderImported); - _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/LanguageSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/LanguageSpecificationFixture.cs index 37cde0cd2..f190677c3 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/LanguageSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/LanguageSpecificationFixture.cs @@ -50,7 +50,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { WithEnglishRelease(); - Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { WithGermanRelease(); - Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/MonitoredEpisodeSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/MonitoredEpisodeSpecificationFixture.cs index 0a504279d..3d681451d 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/MonitoredEpisodeSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/MonitoredEpisodeSpecificationFixture.cs @@ -64,22 +64,22 @@ namespace NzbDrone.Core.Test.DecisionEngineTests [Test] public void setup_should_return_monitored_episode_should_return_true() { - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue(); - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } [Test] public void not_monitored_series_should_be_skipped() { _fakeSeries.Monitored = false; - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] public void only_episode_not_monitored_should_return_false() { WithFirstEpisodeUnmonitored(); - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } [Test] @@ -87,28 +87,28 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { WithFirstEpisodeUnmonitored(); WithSecondEpisodeUnmonitored(); - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] public void only_first_episode_not_monitored_should_return_monitored() { WithFirstEpisodeUnmonitored(); - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } [Test] public void only_second_episode_not_monitored_should_return_monitored() { WithSecondEpisodeUnmonitored(); - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } [Test] public void should_return_true_if_it_is_a_search() { _fakeSeries.Monitored = false; - _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, new SeasonSearchCriteria()).Should().BeTrue(); + _monitoredEpisodeSpecification.IsSatisfiedBy(_parseResultMulti, new SeasonSearchCriteria()).Accepted.Should().BeTrue(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs index 6702cc669..69f9dc59a 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs @@ -81,7 +81,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void should_return_true_when_queue_is_empty() { GivenEmptyQueue(); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -93,7 +93,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Build(); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -110,7 +110,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests GivenQueue(new List { remoteEpisode }, TrackedDownloadState.DownloadFailed); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -126,7 +126,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Build(); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -142,7 +142,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Build(); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -158,7 +158,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Build(); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -174,7 +174,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Build(); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -190,7 +190,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Build(); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -208,7 +208,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _remoteEpisode.Episodes.Add(_otherEpisode); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -226,7 +226,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _remoteEpisode.Episodes.Add(_otherEpisode); GivenQueue(new List { remoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -249,7 +249,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _remoteEpisode.Episodes.Add(_otherEpisode); GivenQueue(remoteEpisodes); - Subject.IsSatisfiedBy(_remoteEpisode, null ).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/NotRestrictedReleaseSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/NotRestrictedReleaseSpecificationFixture.cs index ee09defa0..c0cab92c3 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/NotRestrictedReleaseSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/NotRestrictedReleaseSpecificationFixture.cs @@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests [Test] public void should_be_true_when_restrictions_are_empty() { - Subject.IsSatisfiedBy(_parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_parseResult, null).Accepted.Should().BeTrue(); } [TestCase("KYR")] @@ -38,7 +38,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void should_be_false_when_nzb_contains_a_restricted_term(string restrictions) { Mocker.GetMock().SetupGet(c => c.ReleaseRestrictions).Returns(restrictions); - Subject.IsSatisfiedBy(_parseResult, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_parseResult, null).Accepted.Should().BeFalse(); } [TestCase("NotReal")] @@ -47,14 +47,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void should_be_true_when_nzb_does_not_contain_a_restricted_term(string restrictions) { Mocker.GetMock().SetupGet(c => c.ReleaseRestrictions).Returns(restrictions); - Subject.IsSatisfiedBy(_parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_parseResult, null).Accepted.Should().BeTrue(); } [Test] public void should_not_try_to_find_empty_string_as_a_match() { Mocker.GetMock().SetupGet(c => c.ReleaseRestrictions).Returns("test\n"); - Subject.IsSatisfiedBy(_parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_parseResult, null).Accepted.Should().BeTrue(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs index d0b2b78fc..23a646e25 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/QualityAllowedByProfileSpecificationFixture.cs @@ -52,7 +52,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType; remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p); - Subject.IsSatisfiedBy(remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeTrue(); } [Test, TestCaseSource("DeniedTestCases")] @@ -61,7 +61,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType; remoteEpisode.Series.Profile.Value.Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p); - Subject.IsSatisfiedBy(remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeFalse(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RetentionSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RetentionSpecificationFixture.cs index 2305954bc..de2690771 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RetentionSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RetentionSpecificationFixture.cs @@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests WithRetention(0); WithAge(100); - Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue(); } [Test] @@ -49,7 +49,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests WithRetention(1000); WithAge(100); - Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue(); } [Test] @@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests WithRetention(100); WithAge(100); - Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue(); } [Test] @@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests WithRetention(10); WithAge(100); - Subject.IsSatisfiedBy(parseResult, null).Should().BeFalse(); + Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeFalse(); } [Test] @@ -76,7 +76,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests WithRetention(0); WithAge(100); - Subject.IsSatisfiedBy(parseResult, null).Should().BeTrue(); + Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs index fb784d696..536c29660 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/DelaySpecificationFixture.cs @@ -75,7 +75,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync [Test] public void should_be_true_when_search() { - Subject.IsSatisfiedBy(new RemoteEpisode(), new SingleEpisodeSearchCriteria()).Should().BeTrue(); + Subject.IsSatisfiedBy(new RemoteEpisode(), new SingleEpisodeSearchCriteria()).Accepted.Should().BeTrue(); } [Test] @@ -83,7 +83,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync { _profile.GrabDelay = 0; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -91,7 +91,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync { _remoteEpisode.ParsedEpisodeInfo.Quality = new QualityModel(Quality.Bluray720p); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -102,7 +102,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 1; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -113,7 +113,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 12; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -131,7 +131,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 12; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -149,7 +149,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 12; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -161,7 +161,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 12; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -173,7 +173,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 12; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -185,7 +185,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 12; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -198,7 +198,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _profile.GrabDelay = 12; - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -214,7 +214,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync .Setup(s => s.GetPendingRemoteEpisodes(It.IsAny())) .Returns(new List()); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -230,7 +230,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync .Setup(s => s.GetPendingRemoteEpisodes(It.IsAny())) .Returns(new List { _remoteEpisode.JsonClone() }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); } [Test] @@ -249,7 +249,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync .Setup(s => s.GetPendingRemoteEpisodes(It.IsAny())) .Returns(new List { pendingRemoteEpisode }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } [Test] @@ -271,7 +271,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync .Setup(s => s.GetPendingRemoteEpisodes(It.IsAny())) .Returns(new List { pendingRemoteEpisode1, pendingRemoteEpisode2 }); - Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); } } } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs index 6a555d96d..0d711c1a0 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs @@ -74,7 +74,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _firstFile.Quality.Quality = Quality.DVD; _firstFile.DateAdded = DateTime.Today.AddDays(-30); - Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } [Test] @@ -84,7 +84,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _secondFile.Quality.Quality = Quality.DVD; _firstFile.DateAdded = DateTime.Today.AddDays(-30); - Subject.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] @@ -94,7 +94,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _secondFile.Quality.Quality = Quality.DVD; _secondFile.DateAdded = DateTime.Today.AddDays(-30); - Subject.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] @@ -103,7 +103,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync WithFirstFileUpgradable(); _firstFile.DateAdded = DateTime.Today.AddDays(-30); - Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] @@ -112,7 +112,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync WithFirstFileUpgradable(); _firstFile.DateAdded = DateTime.Today.AddDays(-30); - Subject.IsSatisfiedBy(_parseResultSingle, new SingleEpisodeSearchCriteria()).Should().BeTrue(); + Subject.IsSatisfiedBy(_parseResultSingle, new SingleEpisodeSearchCriteria()).Accepted.Should().BeTrue(); } [Test] @@ -121,7 +121,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _firstFile.Quality.Quality = Quality.DVD; _firstFile.DateAdded = DateTime.Today; - Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse(); + Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } [Test] @@ -132,7 +132,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync _firstFile.Quality.Quality = Quality.DVD; _firstFile.DateAdded = DateTime.Today; - Subject.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue(); + Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/Search/SeriesSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/Search/SeriesSpecificationFixture.cs index a868ebc2a..279890763 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/Search/SeriesSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/Search/SeriesSpecificationFixture.cs @@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.Search { _searchCriteria.Series = _series2; - Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Should().BeFalse(); + Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeFalse(); } [Test] @@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.Search { _searchCriteria.Series = _series1; - Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Should().BeTrue(); + Subject.IsSatisfiedBy(_remoteEpisode, _searchCriteria).Accepted.Should().BeTrue(); } } } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs index 8591b9cc4..ab5795267 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs @@ -71,7 +71,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests public void should_return_true_if_episode_has_no_existing_file() { _parseResultSingle.Episodes.ForEach(c => c.EpisodeFileId = 0); - _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue(); + _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] @@ -79,14 +79,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { _parseResultSingle.Episodes = new List(); - _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue(); + _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] public void should_be_upgradable_if_only_episode_is_upgradable() { WithFirstFileUpgradable(); - _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Should().BeTrue(); + _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue(); } [Test] @@ -94,27 +94,27 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { WithFirstFileUpgradable(); WithSecondFileUpgradable(); - _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue(); + _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue(); } [Test] public void should_be_not_upgradable_if_both_episodes_are_not_upgradable() { - _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] public void should_be_not_upgradable_if_only_first_episodes_is_upgradable() { WithFirstFileUpgradable(); - _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] public void should_be_not_upgradable_if_only_second_episodes_is_upgradable() { WithSecondFileUpgradable(); - _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse(); + _upgradeDisk.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse(); } [Test] @@ -122,7 +122,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests { _firstFile.Quality = new QualityModel(Quality.WEBDL1080p); _parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.WEBDL1080p); - _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Should().BeFalse(); + _upgradeDisk.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/DecisionEngine/Decision.cs b/src/NzbDrone.Core/DecisionEngine/Decision.cs new file mode 100644 index 000000000..4f3199079 --- /dev/null +++ b/src/NzbDrone.Core/DecisionEngine/Decision.cs @@ -0,0 +1,32 @@ +using System; + +namespace NzbDrone.Core.DecisionEngine +{ + public class Decision + { + public Boolean Accepted { get; private set; } + public String Reason { get; private set; } + + public static Decision Accept() + { + return new Decision + { + Accepted = true + }; + } + + public static Decision Reject(String reason, params object[] args) + { + return Reject(String.Format(reason, args)); + } + + public static Decision Reject(String reason) + { + return new Decision + { + Accepted = false, + Reason = reason + }; + } + } +} diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index 722b31b73..ec8e982c8 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -8,6 +8,7 @@ using NzbDrone.Common.Serializer; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; +using Prowlin; namespace NzbDrone.Core.DecisionEngine { @@ -19,7 +20,7 @@ namespace NzbDrone.Core.DecisionEngine public class DownloadDecisionMaker : IMakeDownloadDecision { - private readonly IEnumerable _specifications; + private readonly IEnumerable _specifications; private readonly IParsingService _parsingService; private readonly Logger _logger; @@ -116,19 +117,15 @@ namespace NzbDrone.Core.DecisionEngine return new DownloadDecision(remoteEpisode, reasons.ToArray()); } - private Rejection EvaluateSpec(IRejectWithReason spec, RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteriaBase = null) + private Rejection EvaluateSpec(IDecisionEngineSpecification spec, RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteriaBase = null) { try { - if (spec.RejectionReason.IsNullOrWhiteSpace()) - { - throw new InvalidOperationException("[Need Rejection Text]"); - } + var result = spec.IsSatisfiedBy(remoteEpisode, searchCriteriaBase); - var generalSpecification = spec as IDecisionEngineSpecification; - if (generalSpecification != null && !generalSpecification.IsSatisfiedBy(remoteEpisode, searchCriteriaBase)) + if (!result.Accepted) { - return new Rejection(spec.RejectionReason, generalSpecification.Type); + return new Rejection(result.Reason, spec.Type); } } catch (Exception e) diff --git a/src/NzbDrone.Core/DecisionEngine/IDecisionEngineSpecification.cs b/src/NzbDrone.Core/DecisionEngine/IDecisionEngineSpecification.cs index 69cbdc894..199984734 100644 --- a/src/NzbDrone.Core/DecisionEngine/IDecisionEngineSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/IDecisionEngineSpecification.cs @@ -1,13 +1,12 @@ -using System; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.DecisionEngine { - public interface IDecisionEngineSpecification : IRejectWithReason + public interface IDecisionEngineSpecification { RejectionType Type { get; } - - Boolean IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria); + + Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria); } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs index 0983a9a50..9dd0e79b0 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using NLog; +using NzbDrone.Common.Extensions; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; @@ -22,14 +23,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public String RejectionReason - { - get { return "File size too big or small"; } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); @@ -38,13 +34,13 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (quality == Quality.RAWHD) { _logger.Debug("Raw-HD release found, skipping size check."); - return true; + return Decision.Accept(); } if (quality == Quality.Unknown) { _logger.Debug("Unknown quality. skipping size check."); - return false; + return Decision.Accept(); } var qualityDefinition = _qualityDefinitionService.Get(quality); @@ -56,8 +52,8 @@ namespace NzbDrone.Core.DecisionEngine.Specifications //If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { - _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2}), rejecting.", subject, subject.Release.Size, minSize); - return false; + _logger.Debug("Item: {0}, Size: {1:0n} is smaller than minimum allowed size ({2:0}), rejecting.", subject, subject.Release.Size, minSize); + return Decision.Reject("{0} is smaller than minimum allowed: {1}", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix()); } if (qualityDefinition.MaxSize == 0) { @@ -97,11 +93,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (subject.Release.Size > maxSize) { _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Release.Size, maxSize); - return false; + return Decision.Reject("{0} is larger than maximum allowed: {1}", subject.Release.Size, maxSize); } } + _logger.Debug("Item: {0}, meets size constraints.", subject); - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/AnimeVersionUpgradeSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/AnimeVersionUpgradeSpecification.cs index 57c7c44bf..25e23ce93 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/AnimeVersionUpgradeSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/AnimeVersionUpgradeSpecification.cs @@ -18,23 +18,15 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Version upgrade for a different release group"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { var releaseGroup = subject.ParsedEpisodeInfo.ReleaseGroup; if (subject.Series.SeriesType != SeriesTypes.Anime) { - return true; + return Decision.Accept(); } foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value)) @@ -44,24 +36,24 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (file.ReleaseGroup.IsNullOrWhiteSpace()) { _logger.Debug("Unable to compare release group, existing file's release group is unknown"); - return false; + return Decision.Reject("Existing release group is unknown"); } if (releaseGroup.IsNullOrWhiteSpace()) { _logger.Debug("Unable to compare release group, release's release group is unknown"); - return false; + return Decision.Reject("Release group is unknown"); } if (file.ReleaseGroup != releaseGroup) { _logger.Debug("Existing Release group is: {0} - release's release group is: {1}", file.ReleaseGroup, releaseGroup); - return false; + return Decision.Reject("{0} does not match existing release group {1}", releaseGroup, file.ReleaseGroup); } } } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/BlacklistSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/BlacklistSpecification.cs index 3e3f28a60..38db97b71 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/BlacklistSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/BlacklistSpecification.cs @@ -19,31 +19,23 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Release is blacklisted"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { if (!_configService.EnableFailedDownloadHandling) { _logger.Debug("Failed Download Handling is not enabled"); - return true; + return Decision.Accept(); } if (_blacklistService.Blacklisted(subject.Series.Id, subject.Release.Title, subject.Release.PublishDate)) { _logger.Debug("{0} is blacklisted, rejecting.", subject.Release.Title); - return false; + return Decision.Reject("Release is blacklisted"); } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs index 198e26a39..113f669c2 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/CutoffSpecification.cs @@ -16,17 +16,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Cutoff has already been met"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value)) { @@ -36,11 +28,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (!_qualityUpgradableSpecification.CutoffNotMet(subject.Series.Profile, file.Quality, subject.ParsedEpisodeInfo.Quality)) { _logger.Debug("Cutoff already met, rejecting."); - return false; + return Decision.Reject("Existing file meets cutoff: {0}", subject.Series.Profile); } } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs index b8916846f..54bbecce1 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs @@ -13,17 +13,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Language is not wanted"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { var wantedLanguage = subject.Series.Profile.Value.Language; @@ -32,10 +24,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (subject.ParsedEpisodeInfo.Language != wantedLanguage) { _logger.Debug("Report Language: {0} rejected because it is not wanted, wanted {1}", subject.ParsedEpisodeInfo.Language, wantedLanguage); - return false; + return Decision.Reject("{0} is wanted, but found {1}", wantedLanguage, subject.ParsedEpisodeInfo.Language); } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs index 40940d3eb..29c187c68 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs @@ -19,17 +19,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Already in download queue."; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { var queue = _downloadTrackingService.GetQueuedDownloads() .Where(v => v.State == TrackedDownloadState.Downloading) @@ -38,10 +30,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (IsInQueue(subject, queue)) { _logger.Debug("Already in queue, rejecting."); - return false; + return Decision.Reject("Already in download queue"); } - return true; + return Decision.Accept(); } private bool IsInQueue(RemoteEpisode newEpisode, IEnumerable queue) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/NotRestrictedReleaseSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/NotRestrictedReleaseSpecification.cs index 6818ab5fa..deb8428b9 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/NotRestrictedReleaseSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/NotRestrictedReleaseSpecification.cs @@ -17,17 +17,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Contains restricted term."; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Checking if release contains any restricted terms: {0}", subject); @@ -36,7 +28,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (String.IsNullOrWhiteSpace(restrictionsString)) { _logger.Debug("No restrictions configured, allowing: {0}", subject); - return true; + return Decision.Accept(); } var restrictions = restrictionsString.Split(new []{ '\n' }, StringSplitOptions.RemoveEmptyEntries); @@ -46,12 +38,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (subject.Release.Title.ToLowerInvariant().Contains(restriction.ToLowerInvariant())) { _logger.Debug("{0} is restricted: {1}", subject, restriction); - return false; + return Decision.Reject("Contains restricted term: {0}", restriction); } } _logger.Debug("No restrictions apply, allowing: {0}", subject); - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs index a7568c96a..da2c4bc35 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs @@ -8,7 +8,6 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { private readonly Logger _logger; - public string RejectionReason { get { return "Sample"; } } public RejectionType Type { get { return RejectionType.Permanent; } } public NotSampleSpecification(Logger logger) @@ -16,15 +15,15 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { if (subject.Release.Title.ToLower().Contains("sample") && subject.Release.Size < 70.Megabytes()) { _logger.Debug("Sample release, rejecting."); - return false; + return Decision.Reject("Sample"); } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs index b40a1acab..3e8b7259d 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs @@ -13,26 +13,18 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Quality rejected by series profile"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Checking if report meets quality requirements. {0}", subject.ParsedEpisodeInfo.Quality); if (!subject.Series.Profile.Value.Items.Exists(v => v.Allowed && v.Quality == subject.ParsedEpisodeInfo.Quality.Quality)) { _logger.Debug("Quality {0} rejected by Series' quality profile", subject.ParsedEpisodeInfo.Quality); - return false; + return Decision.Reject("{0} is not wanted in profile", subject.ParsedEpisodeInfo.Quality.Quality); } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs index 5aa7539d2..66edfe97e 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs @@ -16,18 +16,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - - public string RejectionReason - { - get - { - return "Report past retention limit."; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { var age = subject.Release.Age; var retention = _configService.Retention; @@ -36,10 +27,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (retention > 0 && age > retention) { _logger.Debug("Report age: {0} rejected by user's retention limit", age); - return false; + return Decision.Reject("Older than configured retention"); } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RetrySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RetrySpecification.cs index dc964932f..b445aac2c 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RetrySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RetrySpecification.cs @@ -22,22 +22,14 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Release has been retried too many times"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { if (!_configService.EnableFailedDownloadHandling) { _logger.Debug("Failed Download Handling is not enabled"); - return true; + return Decision.Accept(); } var history = _historyService.FindBySourceTitle(subject.Release.Title); @@ -47,10 +39,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _configService.BlacklistRetryLimit) { _logger.Debug("Release has been attempted more times than allowed, rejecting"); - return false; + return Decision.Reject("Retried too many times"); } - return true; + return Decision.Accept(); } private bool HasSamePublishedDate(History.History item, DateTime publishedDate) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs index a7760340c..3c18d0d4d 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs @@ -21,17 +21,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync _logger = logger; } - public string RejectionReason - { - get - { - return "Waiting for better quality release"; - } - } - public RejectionType Type { get { return RejectionType.Temporary; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { //How do we want to handle drone being off and the automatic search being triggered? //TODO: Add a flag to the search to state it is a "scheduled" search @@ -39,7 +31,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (searchCriteria != null) { _logger.Debug("Ignore delay for searches"); - return true; + return Decision.Accept(); } var profile = subject.Series.Profile.Value; @@ -47,7 +39,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (profile.GrabDelay == 0) { _logger.Debug("Profile does not delay before download"); - return true; + return Decision.Accept(); } var comparer = new QualityModelComparer(profile); @@ -63,7 +55,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (revisionUpgrade) { _logger.Debug("New quality is a better revision for existing quality, skipping delay"); - return true; + return Decision.Accept(); } } } @@ -75,7 +67,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (bestCompare >= 0) { _logger.Debug("Quality is highest in profile, will not delay"); - return true; + return Decision.Accept(); } if (profile.GrabDelayMode == GrabDelayMode.Cutoff) @@ -86,7 +78,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (cutoffCompare >= 0) { _logger.Debug("Quality meets or exceeds the cutoff, will not delay"); - return true; + return Decision.Accept(); } } @@ -101,17 +93,17 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (oldest != null && oldest.Release.AgeHours > profile.GrabDelay) { - return true; + return Decision.Accept(); } } if (subject.Release.AgeHours < profile.GrabDelay) { _logger.Debug("Age ({0}) is less than delay {1}, delaying", subject.Release.AgeHours, profile.GrabDelay); - return false; + return Decision.Reject("Waiting for better quality release"); } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs index d2e49d18c..8c035a865 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs @@ -26,22 +26,14 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync _logger = logger; } - public string RejectionReason - { - get - { - return "Existing file in history is of equal or higher quality"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { if (searchCriteria != null) { _logger.Debug("Skipping history check during search"); - return true; + return Decision.Accept(); } var downloadClients = _downloadClientProvider.GetDownloadClients(); @@ -57,10 +49,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (mostRecent != null && mostRecent.EventType == HistoryEventType.Grabbed) { _logger.Debug("Latest history item is downloading, rejecting."); - return false; + return Decision.Reject("Download has not been imported yet"); } } - return true; + return Decision.Accept(); } foreach (var episode in subject.Episodes) @@ -69,12 +61,15 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (bestQualityInHistory != null) { _logger.Debug("Comparing history quality with report. History is {0}", bestQualityInHistory); + if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.Profile, bestQualityInHistory, subject.ParsedEpisodeInfo.Quality)) - return false; + { + return Decision.Reject("Existing file in history is of equal or higher quality: {0}", bestQualityInHistory); + } } } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredEpisodeSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredEpisodeSpecification.cs index 62f21bceb..dadd2dafd 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredEpisodeSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredEpisodeSpecification.cs @@ -14,38 +14,30 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync _logger = logger; } - public string RejectionReason - { - get - { - return "Series or Episode is not monitored"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { if (searchCriteria != null) { _logger.Debug("Skipping monitored check during search"); - return true; + return Decision.Accept(); } if (!subject.Series.Monitored) { _logger.Debug("{0} is present in the DB but not tracked. skipping.", subject.Series); - return false; + return Decision.Reject("Series is not monitored"); } //return monitored if any of the episodes are monitored if (subject.Episodes.Any(episode => episode.Monitored)) { - return true; + return Decision.Accept(); } _logger.Debug("No episodes are monitored. skipping."); - return false; + return Decision.Reject("Episode is not monitored"); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs index ab7dda8ac..151b45e46 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs @@ -20,21 +20,13 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync _logger = logger; } - public string RejectionReason - { - get - { - return "Proper for old episode"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { if (searchCriteria != null) { - return true; + return Decision.Accept(); } foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value)) @@ -44,18 +36,18 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync if (file.DateAdded < DateTime.Today.AddDays(-7)) { _logger.Debug("Proper for old file, rejecting: {0}", subject); - return false; + return Decision.Reject("Proper for old file"); } if (!_configService.AutoDownloadPropers) { _logger.Debug("Auto downloading of propers is disabled"); - return false; + return Decision.Reject("Proper downloading is disabled"); } } } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/DailyEpisodeMatchSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/DailyEpisodeMatchSpecification.cs index 576deaa62..fe21a2537 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/DailyEpisodeMatchSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/DailyEpisodeMatchSpecification.cs @@ -16,36 +16,28 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search _episodeService = episodeService; } - public string RejectionReason - { - get - { - return "Episode doesn't match"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) { if (searchCriteria == null) { - return true; + return Decision.Accept(); } var dailySearchSpec = searchCriteria as DailyEpisodeSearchCriteria; - if (dailySearchSpec == null) return true; + if (dailySearchSpec == null) return Decision.Accept(); var episode = _episodeService.GetEpisode(dailySearchSpec.Series.Id, dailySearchSpec.AirDate.ToString(Episode.AIR_DATE_FORMAT)); if (!remoteEpisode.ParsedEpisodeInfo.IsDaily || remoteEpisode.ParsedEpisodeInfo.AirDate != episode.AirDate) { _logger.Debug("Episode AirDate does not match searched episode number, skipping."); - return false; + return Decision.Reject("Episode does not match"); } - return true; + return Decision.Accept(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/EpisodeRequestedSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/EpisodeRequestedSpecification.cs index 506d0790e..fa4538546 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/EpisodeRequestedSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/EpisodeRequestedSpecification.cs @@ -15,31 +15,25 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search _logger = logger; } - public string RejectionReason - { - get - { - return "Episode wasn't requested"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) { if (searchCriteria == null) { - return true; + return Decision.Accept(); } + var criteriaEpisodes = searchCriteria.Episodes.Select(v => v.Id).ToList(); var remoteEpisodes = remoteEpisode.Episodes.Select(v => v.Id).ToList(); + if (!criteriaEpisodes.Intersect(remoteEpisodes).Any()) { _logger.Debug("Release rejected since the episode wasn't requested: {0}", remoteEpisode.ParsedEpisodeInfo); - return false; + return Decision.Reject("Episode wasn't requested"); } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeasonMatchSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeasonMatchSpecification.cs index 2ce482905..6a3cad319 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeasonMatchSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeasonMatchSpecification.cs @@ -13,33 +13,25 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search _logger = logger; } - public string RejectionReason - { - get - { - return "Episode doesn't match"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) { if (searchCriteria == null) { - return true; + return Decision.Accept(); } var singleEpisodeSpec = searchCriteria as SeasonSearchCriteria; - if (singleEpisodeSpec == null) return true; + if (singleEpisodeSpec == null) return Decision.Accept(); if (singleEpisodeSpec.SeasonNumber != remoteEpisode.ParsedEpisodeInfo.SeasonNumber) { _logger.Debug("Season number does not match searched season number, skipping."); - return false; + return Decision.Reject("Wrong season"); } - return true; + return Decision.Accept(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeriesSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeriesSpecification.cs index abf15f4b4..2ce382f6a 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeriesSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SeriesSpecification.cs @@ -13,21 +13,13 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search _logger = logger; } - public string RejectionReason - { - get - { - return "Wrong series"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) { if (searchCriteria == null) { - return true; + return Decision.Accept(); } _logger.Debug("Checking if series matches searched series"); @@ -35,10 +27,10 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search if (remoteEpisode.Series.Id != searchCriteria.Series.Id) { _logger.Debug("Series {0} does not match {1}", remoteEpisode.Series, searchCriteria.Series); - return false; + return Decision.Reject("Wrong series"); } - return true; + return Decision.Accept(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SingleEpisodeSearchMatchSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SingleEpisodeSearchMatchSpecification.cs index c24dd8821..a13ac5285 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SingleEpisodeSearchMatchSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/SingleEpisodeSearchMatchSpecification.cs @@ -14,39 +14,31 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search _logger = logger; } - public string RejectionReason - { - get - { - return "Episode doesn't match"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) + public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria) { if (searchCriteria == null) { - return true; + return Decision.Accept(); } var singleEpisodeSpec = searchCriteria as SingleEpisodeSearchCriteria; - if (singleEpisodeSpec == null) return true; + if (singleEpisodeSpec == null) return Decision.Accept(); if (singleEpisodeSpec.SeasonNumber != remoteEpisode.ParsedEpisodeInfo.SeasonNumber) { _logger.Debug("Season number does not match searched season number, skipping."); - return false; + return Decision.Reject("Wrong season"); } if (!remoteEpisode.ParsedEpisodeInfo.EpisodeNumbers.Contains(singleEpisodeSpec.EpisodeNumber)) { _logger.Debug("Episode number does not match searched episode number, skipping."); - return false; + return Decision.Reject("Wrong episode"); } - return true; + return Decision.Accept(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs index d71bc9225..86f52c408 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs @@ -16,17 +16,9 @@ namespace NzbDrone.Core.DecisionEngine.Specifications _logger = logger; } - public string RejectionReason - { - get - { - return "Existing file on disk is of equal or higher quality"; - } - } - public RejectionType Type { get { return RejectionType.Permanent; } } - public virtual bool IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) { foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value)) { @@ -34,11 +26,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.Profile, file.Quality, subject.ParsedEpisodeInfo.Quality)) { - return false; + return Decision.Reject("Existing file on disk is of equal or higher quality: {0}", file.Quality); } } - return true; + return Decision.Accept(); } } } diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 1a6b45ed4..4d7374cbf 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -247,6 +247,7 @@ +