mirror of
https://github.com/Sonarr/Sonarr
synced 2025-01-03 05:35:29 +00:00
parent
4d8a443681
commit
4b5ff3927d
5 changed files with 176 additions and 19 deletions
|
@ -210,9 +210,6 @@ class MediaManagement extends Component {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
{
|
|
||||||
isWindows ?
|
|
||||||
null :
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
advancedSettings={advancedSettings}
|
advancedSettings={advancedSettings}
|
||||||
isAdvanced={true}
|
isAdvanced={true}
|
||||||
|
@ -223,12 +220,11 @@ class MediaManagement extends Component {
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.CHECK}
|
type={inputTypes.CHECK}
|
||||||
name="skipFreeSpaceCheckWhenImporting"
|
name="skipFreeSpaceCheckWhenImporting"
|
||||||
helpText={translate('SkipFreeSpaceCheckWhenImportingHelpText')}
|
helpText={translate('SkipFreeSpaceCheckHelpText')}
|
||||||
onChange={onInputChange}
|
onChange={onInputChange}
|
||||||
{...settings.skipFreeSpaceCheckWhenImporting}
|
{...settings.skipFreeSpaceCheckWhenImporting}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
}
|
|
||||||
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
advancedSettings={advancedSettings}
|
advancedSettings={advancedSettings}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
{
|
||||||
|
public class FreeSpaceSpecificationFixture : CoreTest<FreeSpaceSpecification>
|
||||||
|
{
|
||||||
|
private RemoteEpisode _remoteEpisode;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_remoteEpisode = new RemoteEpisode() { Release = new ReleaseInfo(), Series = new Series { Path = @"C:\Test\TV\Series".AsOsAgnostic() } };
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithMinimumFreeSpace(int size)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IConfigService>().SetupGet(c => c.MinimumFreeSpaceWhenImporting).Returns(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithAvailableSpace(int size)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetAvailableSpace(It.IsAny<string>())).Returns(size.Megabytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WithSize(int size)
|
||||||
|
{
|
||||||
|
_remoteEpisode.Release.Size = size.Megabytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_when_available_space_is_more_than_size()
|
||||||
|
{
|
||||||
|
WithMinimumFreeSpace(0);
|
||||||
|
WithAvailableSpace(200);
|
||||||
|
WithSize(100);
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_when_available_space_minus_size_is_more_than_minimum_free_space()
|
||||||
|
{
|
||||||
|
WithMinimumFreeSpace(50);
|
||||||
|
WithAvailableSpace(200);
|
||||||
|
WithSize(100);
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_available_space_is_less_than_size()
|
||||||
|
{
|
||||||
|
WithMinimumFreeSpace(0);
|
||||||
|
WithAvailableSpace(200);
|
||||||
|
WithSize(1000);
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_when_available_space_minus_size_is_less_than_minimum_free_space()
|
||||||
|
{
|
||||||
|
WithMinimumFreeSpace(150);
|
||||||
|
WithAvailableSpace(200);
|
||||||
|
WithSize(100);
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_if_skip_free_space_check_is_true()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IConfigService>()
|
||||||
|
.Setup(s => s.SkipFreeSpaceCheckWhenImporting)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
WithMinimumFreeSpace(150);
|
||||||
|
WithAvailableSpace(200);
|
||||||
|
WithSize(100);
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -186,6 +186,7 @@ namespace NzbDrone.Core.Configuration
|
||||||
set { SetValue("DownloadClientHistoryLimit", value); }
|
set { SetValue("DownloadClientHistoryLimit", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Rename to 'Skip Free Space Check'
|
||||||
public bool SkipFreeSpaceCheckWhenImporting
|
public bool SkipFreeSpaceCheckWhenImporting
|
||||||
{
|
{
|
||||||
get { return GetValueBoolean("SkipFreeSpaceCheckWhenImporting", false); }
|
get { return GetValueBoolean("SkipFreeSpaceCheckWhenImporting", false); }
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
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 FreeSpaceSpecification : IDecisionEngineSpecification
|
||||||
|
{
|
||||||
|
private readonly IConfigService _configService;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public FreeSpaceSpecification(IConfigService configService, IDiskProvider diskProvider, Logger logger)
|
||||||
|
{
|
||||||
|
_configService = configService;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpecificationPriority Priority => SpecificationPriority.Default;
|
||||||
|
public RejectionType Type => RejectionType.Permanent;
|
||||||
|
|
||||||
|
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
|
{
|
||||||
|
if (_configService.SkipFreeSpaceCheckWhenImporting)
|
||||||
|
{
|
||||||
|
_logger.Debug("Skipping free space check");
|
||||||
|
return Decision.Accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
var size = subject.Release.Size;
|
||||||
|
var freeSpace = _diskProvider.GetAvailableSpace(subject.Series.Path);
|
||||||
|
|
||||||
|
if (!freeSpace.HasValue)
|
||||||
|
{
|
||||||
|
_logger.Debug("Unable to get available space for {0}. Skipping", subject.Series.Path);
|
||||||
|
|
||||||
|
return Decision.Accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
var minimumSpace = _configService.MinimumFreeSpaceWhenImporting.Megabytes();
|
||||||
|
var remainingSpace = freeSpace.Value - size;
|
||||||
|
|
||||||
|
if (remainingSpace <= 0)
|
||||||
|
{
|
||||||
|
var message = "Importing after download will exceed available disk space";
|
||||||
|
|
||||||
|
_logger.Debug(message);
|
||||||
|
return Decision.Reject(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainingSpace < minimumSpace)
|
||||||
|
{
|
||||||
|
var message = $"Not enough free space ({minimumSpace.SizeSuffix()}) to import after download: {remainingSpace.SizeSuffix()}. (Settings: Media Management: Minimum Free Space)";
|
||||||
|
|
||||||
|
_logger.Debug(message);
|
||||||
|
return Decision.Reject(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Decision.Accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1903,7 +1903,7 @@
|
||||||
"SizeLimit": "Size Limit",
|
"SizeLimit": "Size Limit",
|
||||||
"SizeOnDisk": "Size on disk",
|
"SizeOnDisk": "Size on disk",
|
||||||
"SkipFreeSpaceCheck": "Skip Free Space Check",
|
"SkipFreeSpaceCheck": "Skip Free Space Check",
|
||||||
"SkipFreeSpaceCheckWhenImportingHelpText": "Use when {appName} is unable to detect free space of your root folder during file import",
|
"SkipFreeSpaceCheckHelpText": "Use when {appName} is unable to detect free space of your root folder",
|
||||||
"SkipRedownload": "Skip Redownload",
|
"SkipRedownload": "Skip Redownload",
|
||||||
"SkipRedownloadHelpText": "Prevents {appName} from trying to download an alternative release for this item",
|
"SkipRedownloadHelpText": "Prevents {appName} from trying to download an alternative release for this item",
|
||||||
"Small": "Small",
|
"Small": "Small",
|
||||||
|
|
Loading…
Reference in a new issue