New: Setting to prevent download of early releases (#485)

* New: Setting to prevent download of early releases

* Fixup! Test and Wording
pull/502/head
Qstick 6 years ago committed by GitHub
parent 9b0a7c60ed
commit e08f39ebe0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Indexers.TorrentRss;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Music;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.DecisionEngineTests
{
[TestFixture]
public class EarlyReleaseSpecificationFixture : TestBase<EarlyReleaseSpecification>
{
private Artist _artist;
private Album _album1;
private Album _album2;
private RemoteAlbum _remoteAlbum;
private IndexerDefinition _indexerDefinition;
[SetUp]
public void Setup()
{
_artist = Builder<Artist>.CreateNew().With(s => s.Id = 1).Build();
_album1 = Builder<Album>.CreateNew().With(s => s.ReleaseDate = DateTime.Today).Build();
_album2 = Builder<Album>.CreateNew().With(s => s.ReleaseDate = DateTime.Today).Build();
_remoteAlbum = new RemoteAlbum
{
Artist = _artist,
Albums = new List<Album>{_album1},
Release = new TorrentInfo
{
IndexerId = 1,
Title = "Artist - Album [FLAC-RlsGrp]",
PublishDate = DateTime.Today
}
};
_indexerDefinition = new IndexerDefinition
{
Settings = new TorrentRssIndexerSettings { EarlyReleaseLimit = 5 }
};
Mocker.GetMock<IIndexerFactory>()
.Setup(v => v.Get(1))
.Returns(_indexerDefinition);
}
private void GivenPublishDateFromToday(int days)
{
(_remoteAlbum.Release).PublishDate = DateTime.Today.AddDays(days);
}
[Test]
public void should_return_true_if_indexer_not_specified()
{
_remoteAlbum.Release.IndexerId = 0;
Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_true_if_release_contains_multiple_albums()
{
_remoteAlbum.Albums.Add(_album2);
Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_true_if_indexer_no_longer_exists()
{
Mocker.GetMock<IIndexerFactory>()
.Setup(v => v.Get(It.IsAny<int>()))
.Callback<int>(i => { throw new ModelNotFoundException(typeof(IndexerDefinition), i); });
Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue();
}
[TestCase(-2)]
[TestCase(-5)]
public void should_return_true_if_publish_date_above_or_equal_to_limit(int days)
{
GivenPublishDateFromToday(days);
Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue();
}
[TestCase(-10)]
[TestCase(-20)]
public void should_return_false_if_publish_date_belove_limit(int days)
{
GivenPublishDateFromToday(days);
Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeFalse();
}
[TestCase(-10)]
[TestCase(-100)]
public void should_return_true_if_limit_null(int days)
{
GivenPublishDateFromToday(days);
_indexerDefinition.Settings = new TorrentRssIndexerSettings{EarlyReleaseLimit = null};
Subject.IsSatisfiedBy(_remoteAlbum, null).Accepted.Should().BeTrue();
}
}
}

@ -13,5 +13,6 @@ namespace NzbDrone.Core.Test.IndexerTests
}
public string BaseUrl { get; set; }
public int? EarlyReleaseLimit { get; set; }
}
}

@ -150,6 +150,7 @@
<Compile Include="DecisionEngineTests\Search\ArtistSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\RawDiskSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\Search\TorrentSeedingSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\EarlyReleaseSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\UpgradeDiskSpecificationFixture.cs" />
<Compile Include="DiskSpace\DiskSpaceServiceFixture.cs" />
<Compile Include="Download\CompletedDownloadServiceFixture.cs" />

@ -0,0 +1,68 @@
using System.Linq;
using NLog;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
public class EarlyReleaseSpecification : IDecisionEngineSpecification
{
private readonly IIndexerFactory _indexerFactory;
private readonly Logger _logger;
public EarlyReleaseSpecification(IIndexerFactory indexerFactory, Logger logger)
{
_indexerFactory = indexerFactory;
_logger = logger;
}
public SpecificationPriority Priority => SpecificationPriority.Default;
public RejectionType Type => RejectionType.Permanent;
public Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria)
{
var releaseInfo = subject.Release;
if (releaseInfo == null || releaseInfo.IndexerId == 0)
{
return Decision.Accept();
}
IndexerDefinition indexer;
try
{
indexer = _indexerFactory.Get(subject.Release.IndexerId);
}
catch (ModelNotFoundException)
{
_logger.Debug("Indexer with id {0} does not exist, skipping early release check", subject.Release.IndexerId);
return Decision.Accept();
}
var indexerSettings = indexer.Settings as IIndexerSettings;
if (subject.Albums.Count != 1 || indexerSettings?.EarlyReleaseLimit == null)
{
return Decision.Accept();
}
var releaseDate = subject.Albums.First().ReleaseDate;
if (releaseDate == null) return Decision.Accept();
var isEarly = (releaseDate.Value > subject.Release.PublishDate.AddDays(indexerSettings.EarlyReleaseLimit.Value));
if (isEarly)
{
var message = $"Release published date, {subject.Release.PublishDate.ToShortDateString()}, is outside of {indexerSettings.EarlyReleaseLimit.Value} day early grab limit allowed by user";
_logger.Debug(message);
return Decision.Reject(message);
}
return Decision.Accept();
}
}
}

@ -41,6 +41,9 @@ namespace NzbDrone.Core.Indexers.Gazelle
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
[FieldDefinition(5, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -53,6 +53,9 @@ namespace NzbDrone.Core.Indexers.Headphones
[FieldDefinition(2, Label = "Password", Type = FieldType.Password)]
public string Password { get; set; }
[FieldDefinition(3, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public virtual NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.Indexers
@ -9,5 +5,6 @@ namespace NzbDrone.Core.Indexers
public interface IIndexerSettings : IProviderConfig
{
string BaseUrl { get; set; }
int? EarlyReleaseLimit { get; set; }
}
}

@ -38,6 +38,9 @@ namespace NzbDrone.Core.Indexers.IPTorrents
[FieldDefinition(2)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
[FieldDefinition(3, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -76,10 +76,13 @@ namespace NzbDrone.Core.Indexers.Newznab
[FieldDefinition(3, Label = "Categories", HelpText = "Comma Separated list, leave blank to disable standard/daily shows", Advanced = true)]
public IEnumerable<int> Categories { get; set; }
[FieldDefinition(4, Label = "Additional Parameters", HelpText = "Additional Newznab parameters", Advanced = true)]
[FieldDefinition(4, Type = FieldType.Number, Label = "Early Download Limit", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Unit = "days", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
[FieldDefinition(5, Label = "Additional Parameters", HelpText = "Additional Newznab parameters", Advanced = true)]
public string AdditionalParameters { get; set; }
// Field 5 is used by TorznabSettings MinimumSeeders
// Field 6 is used by TorznabSettings MinimumSeeders
// If you need to add another field here, update TorznabSettings as well and this comment
public virtual NzbDroneValidationResult Validate()

@ -36,6 +36,9 @@ namespace NzbDrone.Core.Indexers.Nyaa
[FieldDefinition(3)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
[FieldDefinition(4, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -36,6 +36,9 @@ namespace NzbDrone.Core.Indexers.Omgwtfnzbs
[FieldDefinition(2, Label = "Delay", HelpText = "Time in minutes to delay new nzbs before they appear on the RSS feed", Advanced = true)]
public int Delay { get; set; }
[FieldDefinition(3, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -40,6 +40,9 @@ namespace NzbDrone.Core.Indexers.Rarbg
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
[FieldDefinition(5, Type = FieldType.Number, Label = "Early Download Limit", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -40,6 +40,9 @@ namespace NzbDrone.Core.Indexers.TorrentRss
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
[FieldDefinition(5, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(validator.Validate(this));

@ -37,6 +37,9 @@ namespace NzbDrone.Core.Indexers.Torrentleech
[FieldDefinition(3)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
[FieldDefinition(4, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

@ -59,10 +59,10 @@ namespace NzbDrone.Core.Indexers.Torznab
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
}
[FieldDefinition(5, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(6)]
[FieldDefinition(7)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
public override NzbDroneValidationResult Validate()

@ -40,6 +40,9 @@ namespace NzbDrone.Core.Indexers.Waffles
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; } = new SeedCriteriaSettings();
[FieldDefinition(5, Type = FieldType.Number, Label = "Early Download Limit", Unit = "days", HelpText = "Time before release date Lidarr will download from this indexer, empty is no limit", Advanced = true)]
public int? EarlyReleaseLimit { get; set; }
public NzbDroneValidationResult Validate()
{

@ -225,6 +225,7 @@
<Compile Include="DecisionEngine\Specifications\BlockedIndexerSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\DiscographySpecification.cs" />
<Compile Include="DecisionEngine\Specifications\CutoffSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\EarlyReleaseSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\MaximumSizeSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\ProtocolSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\LanguageSpecification.cs" />

Loading…
Cancel
Save