diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index cfaef9e0f..93eea64bf 100644 --- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -114,6 +114,7 @@ + diff --git a/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/AllowedReleaseGroupSpecificationFixture.cs b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/AllowedReleaseGroupSpecificationFixture.cs new file mode 100644 index 000000000..760496dcb --- /dev/null +++ b/NzbDrone.Core.Test/ProviderTests/DecisionEngineTests/AllowedReleaseGroupSpecificationFixture.cs @@ -0,0 +1,69 @@ +// ReSharper disable RedundantUsingDirective + +using System.Linq; +using System; +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using Moq; +using NUnit.Framework; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers; +using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Providers.DecisionEngine; +using NzbDrone.Core.Repository; +using NzbDrone.Core.Repository.Quality; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests +{ + [TestFixture] + // ReSharper disable InconsistentNaming + public class AllowedReleaseGroupSpecificationFixture : CoreTest + { + private EpisodeParseResult parseResult; + + [SetUp] + public void Setup() + { + parseResult = new EpisodeParseResult + { + SeriesTitle = "Title", + Language = LanguageType.English, + Quality = new Quality(QualityTypes.SDTV, true), + EpisodeNumbers = new List { 3 }, + SeasonNumber = 12, + AirDate = DateTime.Now.AddDays(-12).Date, + ReleaseGroup = "2HD" + }; + } + + [Test] + public void should_be_true_when_allowedReleaseGroups_is_empty() + { + Mocker.GetMock().SetupGet(s => s.AllowedReleaseGroups).Returns(String.Empty); + Mocker.Resolve().IsSatisfiedBy(parseResult).Should().BeTrue(); + } + + [Test] + public void should_be_true_when_allowedReleaseGroups_is_nzbs_releaseGroup() + { + Mocker.GetMock().SetupGet(s => s.AllowedReleaseGroups).Returns("2HD"); + Mocker.Resolve().IsSatisfiedBy(parseResult).Should().BeTrue(); + } + + [Test] + public void should_be_true_when_allowedReleaseGroups_contains_nzbs_releaseGroup() + { + Mocker.GetMock().SetupGet(s => s.AllowedReleaseGroups).Returns("2HD, LOL"); + Mocker.Resolve().IsSatisfiedBy(parseResult).Should().BeTrue(); + } + + [Test] + public void should_be_false_when_allowedReleaseGroups_does_not_contain_nzbs_releaseGroup() + { + Mocker.GetMock().SetupGet(s => s.AllowedReleaseGroups).Returns("LOL,DTD"); + Mocker.Resolve().IsSatisfiedBy(parseResult).Should().BeFalse(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Core/Model/ReportRejectionType.cs b/NzbDrone.Core/Model/ReportRejectionType.cs index 867f37565..b4cf7336f 100644 --- a/NzbDrone.Core/Model/ReportRejectionType.cs +++ b/NzbDrone.Core/Model/ReportRejectionType.cs @@ -17,5 +17,6 @@ namespace NzbDrone.Core.Model DownloadClientFailure = 10, Skipped = 11, Failure = 12, + ReleaseGroupNotWanted = 13 } } diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index 99eef5003..00692a8c2 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -289,6 +289,7 @@ + diff --git a/NzbDrone.Core/Providers/Core/ConfigProvider.cs b/NzbDrone.Core/Providers/Core/ConfigProvider.cs index a296c23e5..605af206b 100644 --- a/NzbDrone.Core/Providers/Core/ConfigProvider.cs +++ b/NzbDrone.Core/Providers/Core/ConfigProvider.cs @@ -514,6 +514,12 @@ namespace NzbDrone.Core.Providers.Core set { SetValue("MetadataUseBanners", value); } } + public virtual string AllowedReleaseGroups + { + get { return GetValue("AllowedReleaseGroups"); } + set { SetValue("AllowedReleaseGroups", value); } + } + private string GetValue(string key) { return GetValue(key, String.Empty); diff --git a/NzbDrone.Core/Providers/DecisionEngine/AllowedDownloadSpecification.cs b/NzbDrone.Core/Providers/DecisionEngine/AllowedDownloadSpecification.cs index c6e437c5f..df58a271f 100644 --- a/NzbDrone.Core/Providers/DecisionEngine/AllowedDownloadSpecification.cs +++ b/NzbDrone.Core/Providers/DecisionEngine/AllowedDownloadSpecification.cs @@ -13,18 +13,21 @@ namespace NzbDrone.Core.Providers.DecisionEngine private readonly AcceptableSizeSpecification _acceptableSizeSpecification; private readonly AlreadyInQueueSpecification _alreadyInQueueSpecification; private readonly RetentionSpecification _retentionSpecification; + private readonly AllowedReleaseGroupSpecification _allowedReleaseGroupSpecification; private static readonly Logger logger = LogManager.GetCurrentClassLogger(); [Inject] public AllowedDownloadSpecification(QualityAllowedByProfileSpecification qualityAllowedByProfileSpecification, UpgradeDiskSpecification upgradeDiskSpecification, AcceptableSizeSpecification acceptableSizeSpecification, - AlreadyInQueueSpecification alreadyInQueueSpecification, RetentionSpecification retentionSpecification) + AlreadyInQueueSpecification alreadyInQueueSpecification, RetentionSpecification retentionSpecification, + AllowedReleaseGroupSpecification allowedReleaseGroupSpecification) { _qualityAllowedByProfileSpecification = qualityAllowedByProfileSpecification; _upgradeDiskSpecification = upgradeDiskSpecification; _acceptableSizeSpecification = acceptableSizeSpecification; _alreadyInQueueSpecification = alreadyInQueueSpecification; _retentionSpecification = retentionSpecification; + _allowedReleaseGroupSpecification = allowedReleaseGroupSpecification; } public AllowedDownloadSpecification() @@ -37,8 +40,9 @@ namespace NzbDrone.Core.Providers.DecisionEngine if (!_upgradeDiskSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.ExistingQualityIsEqualOrBetter; if (!_retentionSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.Retention; if (!_acceptableSizeSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.Size; + if (!_allowedReleaseGroupSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.ReleaseGroupNotWanted; if (_alreadyInQueueSpecification.IsSatisfiedBy(subject)) return ReportRejectionType.AlreadyInQueue; - + logger.Debug("Episode {0} is needed", subject); return ReportRejectionType.None; } diff --git a/NzbDrone.Core/Providers/DecisionEngine/AllowedReleaseGroupSpecification.cs b/NzbDrone.Core/Providers/DecisionEngine/AllowedReleaseGroupSpecification.cs new file mode 100644 index 000000000..4d24886ea --- /dev/null +++ b/NzbDrone.Core/Providers/DecisionEngine/AllowedReleaseGroupSpecification.cs @@ -0,0 +1,48 @@ +using System; +using System.Linq; +using NLog; +using Ninject; +using NzbDrone.Core.Model; +using NzbDrone.Core.Providers.Core; + +namespace NzbDrone.Core.Providers.DecisionEngine +{ + public class AllowedReleaseGroupSpecification + { + private readonly ConfigProvider _configProvider; + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + + [Inject] + public AllowedReleaseGroupSpecification(ConfigProvider configProvider) + { + _configProvider = configProvider; + } + + public AllowedReleaseGroupSpecification() + { + + } + + public virtual bool IsSatisfiedBy(EpisodeParseResult subject) + { + logger.Trace("Beginning release group check for: {0}", subject); + + var allowed = _configProvider.AllowedReleaseGroups; + + if (string.IsNullOrWhiteSpace(allowed)) + return true; + + foreach(var group in allowed.Trim(',', ' ').Split(',')) + { + if (subject.ReleaseGroup.Equals(group.Trim(' '), StringComparison.CurrentCultureIgnoreCase)) + { + logger.Trace("Item: {0}'s release group is wanted: {1}", subject, subject.ReleaseGroup); + return true; + } + } + + logger.Trace("Item: {0}'s release group is not wanted: {1}", subject, subject.ReleaseGroup); + return false; + } + } +}