diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/TorrentSeedingSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/TorrentSeedingSpecification.cs
deleted file mode 100644
index 65230ef12..000000000
--- a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/TorrentSeedingSpecification.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using NLog;
-using NzbDrone.Core.IndexerSearch.Definitions;
-using NzbDrone.Core.Parser.Model;
-
-namespace NzbDrone.Core.DecisionEngine.Specifications.Search
-{
- public class TorrentSeedingSpecification : IDecisionEngineSpecification
- {
- private readonly Logger _logger;
-
- public TorrentSeedingSpecification(Logger logger)
- {
- _logger = logger;
- }
-
- public SpecificationPriority Priority => SpecificationPriority.Default;
- public RejectionType Type => RejectionType.Permanent;
-
-
- public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria)
- {
- var torrentInfo = remoteEpisode.Release as TorrentInfo;
-
- if (torrentInfo == null)
- {
- return Decision.Accept();
- }
-
- if (torrentInfo.Seeders != null && torrentInfo.Seeders < 1)
- {
- _logger.Debug("Not enough seeders. ({0})", torrentInfo.Seeders);
- return Decision.Reject("Not enough seeders. ({0})", torrentInfo.Seeders);
- }
-
- return Decision.Accept();
- }
- }
-}
diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/TorrentSeedingSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/TorrentSeedingSpecification.cs
new file mode 100644
index 000000000..f095170c4
--- /dev/null
+++ b/src/NzbDrone.Core/DecisionEngine/Specifications/TorrentSeedingSpecification.cs
@@ -0,0 +1,51 @@
+using System.Linq;
+using NLog;
+using NzbDrone.Common.Reflection;
+using NzbDrone.Core.Indexers;
+using NzbDrone.Core.IndexerSearch.Definitions;
+using NzbDrone.Core.Parser.Model;
+
+namespace NzbDrone.Core.DecisionEngine.Specifications.Search
+{
+ public class TorrentSeedingSpecification : IDecisionEngineSpecification
+ {
+ private readonly IndexerFactory _indexerFactory;
+ private readonly Logger _logger;
+
+ public TorrentSeedingSpecification(IndexerFactory indexerFactory, Logger logger)
+ {
+ _indexerFactory = indexerFactory;
+ _logger = logger;
+ }
+
+ public SpecificationPriority Priority => SpecificationPriority.Default;
+ public RejectionType Type => RejectionType.Permanent;
+
+
+ public Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria)
+ {
+ var torrentInfo = remoteEpisode.Release as TorrentInfo;
+
+ if (torrentInfo == null)
+ {
+ return Decision.Accept();
+ }
+
+ var indexer = _indexerFactory.Get(torrentInfo.IndexerId);
+ var torrentIndexerSettings = indexer.Settings as ITorrentIndexerSettings;
+
+ if (torrentIndexerSettings != null)
+ {
+ var minimumSeeders = torrentIndexerSettings.MinimumSeeders;
+
+ if (torrentInfo.Seeders.HasValue && torrentInfo.Seeders.Value < minimumSeeders)
+ {
+ _logger.Debug("Not enough seeders: {0}. Minimum seeders: {1}", torrentInfo.Seeders, minimumSeeders);
+ return Decision.Reject("Not enough seeders: {0}. Minimum seeders: {1}", torrentInfo.Seeders, minimumSeeders);
+ }
+ }
+
+ return Decision.Accept();
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvSettings.cs b/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvSettings.cs
index 843dac050..a858192d5 100644
--- a/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvSettings.cs
+++ b/src/NzbDrone.Core/Indexers/BitMeTv/BitMeTvSettings.cs
@@ -1,7 +1,6 @@
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Core.Annotations;
-using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.BitMeTv
@@ -23,13 +22,14 @@ public BitMeTvSettingsValidator()
}
}
- public class BitMeTvSettings : IIndexerSettings
+ public class BitMeTvSettings : ITorrentIndexerSettings
{
private static readonly BitMeTvSettingsValidator Validator = new BitMeTvSettingsValidator();
public BitMeTvSettings()
{
BaseUrl = "https://www.bitmetv.org";
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "Website URL")]
@@ -44,6 +44,9 @@ public BitMeTvSettings()
[FieldDefinition(3, Label = "Cookie", HelpText = "BitMeTv uses a login cookie needed to access the rss, you'll have to retrieve it via a browser.")]
public string Cookie { get; set; }
+ [FieldDefinition(4, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs b/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs
index 1c3f8ae13..3890fef1f 100644
--- a/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs
+++ b/src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetSettings.cs
@@ -1,6 +1,5 @@
-using FluentValidation;
+using FluentValidation;
using NzbDrone.Core.Annotations;
-using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.BroadcastheNet
@@ -14,13 +13,14 @@ public BroadcastheNetSettingsValidator()
}
}
- public class BroadcastheNetSettings : IIndexerSettings
+ public class BroadcastheNetSettings : ITorrentIndexerSettings
{
private static readonly BroadcastheNetSettingsValidator Validator = new BroadcastheNetSettingsValidator();
public BroadcastheNetSettings()
{
BaseUrl = "http://api.broadcasthe.net/";
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
@@ -29,6 +29,9 @@ public BroadcastheNetSettings()
[FieldDefinition(1, Label = "API Key")]
public string ApiKey { get; set; }
+ [FieldDefinition(2, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs b/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs
index 802b5e7d1..fb2890c9c 100644
--- a/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs
+++ b/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs
@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
-using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.HDBits
@@ -14,13 +13,14 @@ public HDBitsSettingsValidator()
}
}
- public class HDBitsSettings : IIndexerSettings
+ public class HDBitsSettings : ITorrentIndexerSettings
{
private static readonly HDBitsSettingsValidator Validator = new HDBitsSettingsValidator();
public HDBitsSettings()
{
BaseUrl = "https://hdbits.org";
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "Username")]
@@ -32,6 +32,9 @@ public HDBitsSettings()
[FieldDefinition(2, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
public string BaseUrl { get; set; }
+ [FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/IIndexerSettings.cs b/src/NzbDrone.Core/Indexers/IIndexerSettings.cs
index 85731eb23..87e7f03d2 100644
--- a/src/NzbDrone.Core/Indexers/IIndexerSettings.cs
+++ b/src/NzbDrone.Core/Indexers/IIndexerSettings.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using NzbDrone.Core.ThingiProvider;
+using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers
{
diff --git a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs
index e3e7993d8..16d78430b 100644
--- a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs
+++ b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs
@@ -1,4 +1,4 @@
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
@@ -21,17 +21,21 @@ public IPTorrentsSettingsValidator()
}
}
- public class IPTorrentsSettings : IIndexerSettings
+ public class IPTorrentsSettings : ITorrentIndexerSettings
{
private static readonly IPTorrentsSettingsValidator Validator = new IPTorrentsSettingsValidator();
public IPTorrentsSettings()
{
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "Feed URL", HelpText = "The full RSS feed url generated by IPTorrents, using only the categories you selected (HD, SD, x264, etc ...)")]
public string BaseUrl { get; set; }
+ [FieldDefinition(1, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/ITorrentIndexerSettings.cs b/src/NzbDrone.Core/Indexers/ITorrentIndexerSettings.cs
new file mode 100644
index 000000000..9ac4fafcb
--- /dev/null
+++ b/src/NzbDrone.Core/Indexers/ITorrentIndexerSettings.cs
@@ -0,0 +1,7 @@
+namespace NzbDrone.Core.Indexers
+{
+ public interface ITorrentIndexerSettings : IIndexerSettings
+ {
+ int MinimumSeeders { get; set; }
+ }
+}
diff --git a/src/NzbDrone.Core/Indexers/IndexerDefaults.cs b/src/NzbDrone.Core/Indexers/IndexerDefaults.cs
new file mode 100644
index 000000000..134126fab
--- /dev/null
+++ b/src/NzbDrone.Core/Indexers/IndexerDefaults.cs
@@ -0,0 +1,7 @@
+namespace NzbDrone.Core.Indexers
+{
+ public static class IndexerDefaults
+ {
+ public const int MINIMUM_SEEDERS = 1;
+ }
+}
diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs
index 9fc988c10..ead8d1e62 100644
--- a/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabSettings.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using FluentValidation;
@@ -79,6 +79,9 @@ public NewznabSettings()
[FieldDefinition(4, Label = "Additional Parameters", HelpText = "Additional Newznab parameters", Advanced = true)]
public string AdditionalParameters { get; set; }
+ // Field 5 is used by TorznabSettings MinimumSeeders
+ // If you need to add another field here, update TorznabSettings as well and this comment
+
public virtual NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs b/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs
index 83ef2c60a..105686a9b 100644
--- a/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs
@@ -1,6 +1,5 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
-using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
using System.Text.RegularExpressions;
namespace NzbDrone.Core.Indexers.Nyaa
@@ -14,7 +13,7 @@ public NyaaSettingsValidator()
}
}
- public class NyaaSettings : IIndexerSettings
+ public class NyaaSettings : ITorrentIndexerSettings
{
private static readonly NyaaSettingsValidator Validator = new NyaaSettingsValidator();
@@ -22,6 +21,7 @@ public NyaaSettings()
{
BaseUrl = "https://www.nyaa.se";
AdditionalParameters = "&cats=1_37&filter=1";
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "Website URL")]
@@ -30,6 +30,9 @@ public NyaaSettings()
[FieldDefinition(1, Label = "Additional Parameters", Advanced = true, HelpText = "Please note if you change the category you will have to add required/restricted rules about the subgroups to avoid foreign language releases.")]
public string AdditionalParameters { get; set; }
+ [FieldDefinition(2, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs
index c4888b307..2b4d76020 100644
--- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs
@@ -1,6 +1,5 @@
-using FluentValidation;
+using FluentValidation;
using NzbDrone.Core.Annotations;
-using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Rarbg
@@ -13,7 +12,7 @@ public RarbgSettingsValidator()
}
}
- public class RarbgSettings : IIndexerSettings
+ public class RarbgSettings : ITorrentIndexerSettings
{
private static readonly RarbgSettingsValidator Validator = new RarbgSettingsValidator();
@@ -21,6 +20,7 @@ public RarbgSettings()
{
BaseUrl = "https://torrentapi.org";
RankedOnly = false;
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "API URL", HelpText = "URL to Rarbg api, not the website.")]
@@ -32,6 +32,9 @@ public RarbgSettings()
[FieldDefinition(2, Type = FieldType.Captcha, Label = "CAPTCHA Token", HelpText = "CAPTCHA Clearance token used to handle CloudFlare Anti-DDOS measures on shared-ip VPNs.")]
public string CaptchaToken { get; set; }
+ [FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs
index 57606af46..8c24f9ba4 100644
--- a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs
+++ b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs
@@ -1,6 +1,5 @@
-using FluentValidation;
+using FluentValidation;
using NzbDrone.Core.Annotations;
-using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.TorrentRss
@@ -13,7 +12,7 @@ public TorrentRssIndexerSettingsValidator()
}
}
- public class TorrentRssIndexerSettings : IIndexerSettings
+ public class TorrentRssIndexerSettings : ITorrentIndexerSettings
{
private static readonly TorrentRssIndexerSettingsValidator validator = new TorrentRssIndexerSettingsValidator();
@@ -21,6 +20,7 @@ public TorrentRssIndexerSettings()
{
BaseUrl = string.Empty;
AllowZeroSize = false;
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "Full RSS Feed URL")]
@@ -32,6 +32,9 @@ public TorrentRssIndexerSettings()
[FieldDefinition(2, Type = FieldType.Checkbox, Label = "Allow Zero Size", HelpText="Enabling this will allow you to use feeds that don't specify release size, but be careful, size related checks will not be performed.")]
public bool AllowZeroSize { get; set; }
+ [FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs b/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs
index 18392c520..f7b06ec59 100644
--- a/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Torrentleech/TorrentleechSettings.cs
@@ -1,6 +1,5 @@
-using FluentValidation;
+using FluentValidation;
using NzbDrone.Core.Annotations;
-using NzbDrone.Core.ThingiProvider;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Torrentleech
@@ -14,13 +13,14 @@ public TorrentleechSettingsValidator()
}
}
- public class TorrentleechSettings : IIndexerSettings
+ public class TorrentleechSettings : ITorrentIndexerSettings
{
private static readonly TorrentleechSettingsValidator Validator = new TorrentleechSettingsValidator();
public TorrentleechSettings()
{
BaseUrl = "http://rss.torrentleech.org";
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(0, Label = "Website URL")]
@@ -29,6 +29,9 @@ public TorrentleechSettings()
[FieldDefinition(1, Label = "API Key")]
public string ApiKey { get; set; }
+ [FieldDefinition(2, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs
index 9a328d6b6..7e847c294 100644
--- a/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs
@@ -1,8 +1,9 @@
-using System.Linq;
+using System.Linq;
using System.Text.RegularExpressions;
using FluentValidation;
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
+using NzbDrone.Core.Annotations;
using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Validation;
@@ -46,10 +47,18 @@ public TorznabSettingsValidator()
}
}
- public class TorznabSettings : NewznabSettings
+ public class TorznabSettings : NewznabSettings, ITorrentIndexerSettings
{
private static readonly TorznabSettingsValidator Validator = new TorznabSettingsValidator();
+ public TorznabSettings()
+ {
+ MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
+ }
+
+ [FieldDefinition(5, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
+ public int MinimumSeeders { get; set; }
+
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj
index a22cd6751..25b4ece55 100644
--- a/src/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/src/NzbDrone.Core/NzbDrone.Core.csproj
@@ -345,7 +345,7 @@
-
+
@@ -630,6 +630,7 @@
+
@@ -645,6 +646,7 @@
+