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;
+ }
+ }
+}