New: Setting for absolute maximum size for a release
Closes #2367 #1996
This commit is contained in:
parent
d0e8aef949
commit
d25e5fe329
|
@ -13,6 +13,9 @@ namespace NzbDrone.Api.Config
|
|||
SharedValidator.RuleFor(c => c.MinimumAge)
|
||||
.GreaterThanOrEqualTo(0);
|
||||
|
||||
SharedValidator.RuleFor(c => c.MaximumSize)
|
||||
.GreaterThanOrEqualTo(0);
|
||||
|
||||
SharedValidator.RuleFor(c => c.Retention)
|
||||
.GreaterThanOrEqualTo(0);
|
||||
|
||||
|
@ -25,4 +28,4 @@ namespace NzbDrone.Api.Config
|
|||
return IndexerConfigResourceMapper.ToResource(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace NzbDrone.Api.Config
|
|||
public class IndexerConfigResource : RestResource
|
||||
{
|
||||
public int MinimumAge { get; set; }
|
||||
public int MaximumSize { get; set; }
|
||||
public int Retention { get; set; }
|
||||
public int RssSyncInterval { get; set; }
|
||||
}
|
||||
|
@ -17,6 +18,7 @@ namespace NzbDrone.Api.Config
|
|||
return new IndexerConfigResource
|
||||
{
|
||||
MinimumAge = model.MinimumAge,
|
||||
MaximumSize = model.MaximumSize,
|
||||
Retention = model.Retention,
|
||||
RssSyncInterval = model.RssSyncInterval,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
public class MaximumSizeSpecificationFixture : CoreTest<MaximumSizeSpecification>
|
||||
{
|
||||
private RemoteEpisode _remoteEpisode;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_remoteEpisode = new RemoteEpisode() { Release = new ReleaseInfo() };
|
||||
}
|
||||
|
||||
private void WithMaximumSize(int size)
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().SetupGet(c => c.MaximumSize).Returns(size);
|
||||
}
|
||||
|
||||
private void WithSize(int size)
|
||||
{
|
||||
_remoteEpisode.Release.Size = size * 1024 * 1024;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_maximum_size_is_set_to_zero()
|
||||
{
|
||||
WithMaximumSize(0);
|
||||
WithSize(1000);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_size_is_smaller_than_maximum_size()
|
||||
{
|
||||
WithMaximumSize(2000);
|
||||
WithSize(1999);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_size_is_equals_to_maximum_size()
|
||||
{
|
||||
WithMaximumSize(2000);
|
||||
WithSize(2000);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_size_is_bigger_than_maximum_size()
|
||||
{
|
||||
WithMaximumSize(2000);
|
||||
WithSize(2001);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_size_is_zero()
|
||||
{
|
||||
WithMaximumSize(2000);
|
||||
WithSize(0);
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -146,6 +146,7 @@
|
|||
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\AnimeVersionUpgradeSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\FullSeasonSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\MaximumSizeSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\ProtocolSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\CutoffSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\DownloadDecisionMakerFixture.cs" />
|
||||
|
|
|
@ -106,6 +106,12 @@ namespace NzbDrone.Core.Configuration
|
|||
set { SetValue("RssSyncInterval", value); }
|
||||
}
|
||||
|
||||
public int MaximumSize
|
||||
{
|
||||
get { return GetValueInt("MaximumSize", 0); }
|
||||
set { SetValue("MaximumSize", value); }
|
||||
}
|
||||
|
||||
public int MinimumAge
|
||||
{
|
||||
get { return GetValueInt("MinimumAge", 0); }
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace NzbDrone.Core.Configuration
|
|||
//Indexers
|
||||
int Retention { get; set; }
|
||||
int RssSyncInterval { get; set; }
|
||||
int MaximumSize { get; set; }
|
||||
int MinimumAge { get; set; }
|
||||
|
||||
//UI
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class MaximumSizeSpecification : IDecisionEngineSpecification
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MaximumSizeSpecification(IConfigService configService, Logger logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public SpecificationPriority Priority => SpecificationPriority.Default;
|
||||
public RejectionType Type => RejectionType.Permanent;
|
||||
|
||||
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
var size = subject.Release.Size;
|
||||
var maximumSize = _configService.MaximumSize.Megabytes();
|
||||
|
||||
if (maximumSize == 0)
|
||||
{
|
||||
_logger.Debug("Maximum size is not set.");
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
if (subject.Release.Size == 0)
|
||||
{
|
||||
_logger.Debug("Release has unknown size, skipping size check.");
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
_logger.Debug("Checking if release meets maximum size requirements. {0}", size.SizeSuffix());
|
||||
|
||||
if (size > maximumSize)
|
||||
{
|
||||
var message = $"{size.SizeSuffix()} is too big, maximum size is {maximumSize.SizeSuffix()}";
|
||||
|
||||
_logger.Debug(message);
|
||||
return Decision.Reject(message);
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -332,6 +332,7 @@
|
|||
<Compile Include="DecisionEngine\Specifications\AnimeVersionUpgradeSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\FullSeasonSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\CutoffSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\MaximumSizeSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\ProtocolSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\LanguageSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\QueueSpecification.cs" />
|
||||
|
|
|
@ -12,6 +12,18 @@
|
|||
<input type="number" min="0" name="minimumAge" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Maximum Size</label>
|
||||
|
||||
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||
<i class="icon-sonarr-form-info" title="Maximum size for a release to be grabbed in MB. Set to zero to set to unlimited"/>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 col-sm-pull-1">
|
||||
<input type="number" min="0" name="maximumSize" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Retention</label>
|
||||
|
|
Loading…
Reference in New Issue