diff --git a/frontend/src/Settings/MediaManagement/MediaManagement.js b/frontend/src/Settings/MediaManagement/MediaManagement.js index c7754470f..c5e7e56be 100644 --- a/frontend/src/Settings/MediaManagement/MediaManagement.js +++ b/frontend/src/Settings/MediaManagement/MediaManagement.js @@ -299,11 +299,27 @@ class MediaManagement extends Component { type={inputTypes.PATH} name="recycleBin" helpText="Track files will go here when deleted instead of being permanently deleted" - helpTextWarning="Files in the recycle bin older than a week will be cleaned up automatically" onChange={onInputChange} {...settings.recycleBin} /> + + + Recycling Bin Cleanup + + + { diff --git a/src/Lidarr.Api.V1/Config/MediaManagementConfigModule.cs b/src/Lidarr.Api.V1/Config/MediaManagementConfigModule.cs index cb3e24941..e83767548 100644 --- a/src/Lidarr.Api.V1/Config/MediaManagementConfigModule.cs +++ b/src/Lidarr.Api.V1/Config/MediaManagementConfigModule.cs @@ -9,6 +9,7 @@ namespace Lidarr.Api.V1.Config public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator) : base(configService) { + SharedValidator.RuleFor(c => c.RecycleBinCleanupDays).GreaterThanOrEqualTo(0); SharedValidator.RuleFor(c => c.FileChmod).NotEmpty(); SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty(); SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); diff --git a/src/Lidarr.Api.V1/Config/MediaManagementConfigResource.cs b/src/Lidarr.Api.V1/Config/MediaManagementConfigResource.cs index 7be39b3f1..b2abd60d5 100644 --- a/src/Lidarr.Api.V1/Config/MediaManagementConfigResource.cs +++ b/src/Lidarr.Api.V1/Config/MediaManagementConfigResource.cs @@ -9,6 +9,7 @@ namespace Lidarr.Api.V1.Config { public bool AutoUnmonitorPreviouslyDownloadedTracks { get; set; } public string RecycleBin { get; set; } + public int RecycleBinCleanupDays { get; set; } public ProperDownloadTypes DownloadPropersAndRepacks { get; set; } public bool CreateEmptyArtistFolders { get; set; } public bool DeleteEmptyFolders { get; set; } @@ -36,6 +37,7 @@ namespace Lidarr.Api.V1.Config { AutoUnmonitorPreviouslyDownloadedTracks = model.AutoUnmonitorPreviouslyDownloadedTracks, RecycleBin = model.RecycleBin, + RecycleBinCleanupDays = model.RecycleBinCleanupDays, DownloadPropersAndRepacks = model.DownloadPropersAndRepacks, CreateEmptyArtistFolders = model.CreateEmptyArtistFolders, DeleteEmptyFolders = model.DeleteEmptyFolders, diff --git a/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs b/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs index 4080b6d05..d7bf8853f 100644 --- a/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs +++ b/src/NzbDrone.Core.Test/ProviderTests/RecycleBinProviderTests/CleanupFixture.cs @@ -37,6 +37,7 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests public void Setup() { Mocker.GetMock().SetupGet(s => s.RecycleBin).Returns(RecycleBin); + Mocker.GetMock().SetupGet(s => s.RecycleBinCleanupDays).Returns(7); Mocker.GetMock().Setup(s => s.GetDirectories(RecycleBin)) .Returns(new [] { @"C:\Test\RecycleBin\Folder1", @"C:\Test\RecycleBin\Folder2", @"C:\Test\RecycleBin\Folder3" }); @@ -56,12 +57,13 @@ namespace NzbDrone.Core.Test.ProviderTests.RecycleBinProviderTests } [Test] - public void should_delete_all_expired_folders() - { - WithExpired(); + public void should_return_if_recycleBinCleanupDays_is_zero() + { + Mocker.GetMock().SetupGet(s => s.RecycleBinCleanupDays).Returns(0); + Mocker.Resolve().Cleanup(); - Mocker.GetMock().Verify(v => v.DeleteFolder(It.IsAny(), true), Times.Exactly(3)); + Mocker.GetMock().Verify(v => v.GetDirectories(It.IsAny()), Times.Never()); } [Test] diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index 153f76beb..0043d3cb3 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -92,6 +92,12 @@ namespace NzbDrone.Core.Configuration set { SetValue("RecycleBin", value); } } + public int RecycleBinCleanupDays + { + get { return GetValueInt("RecycleBinCleanupDays", 7); } + set { SetValue("RecycleBinCleanupDays", value); } + } + public int RssSyncInterval { get { return GetValueInt("RssSyncInterval", 15); } diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs index 8232db566..fc03d5344 100644 --- a/src/NzbDrone.Core/Configuration/IConfigService.cs +++ b/src/NzbDrone.Core/Configuration/IConfigService.cs @@ -25,6 +25,7 @@ namespace NzbDrone.Core.Configuration //Media Management bool AutoUnmonitorPreviouslyDownloadedTracks { get; set; } string RecycleBin { get; set; } + int RecycleBinCleanupDays { get; set; } ProperDownloadTypes DownloadPropersAndRepacks { get; set; } bool CreateEmptyArtistFolders { get; set; } bool DeleteEmptyFolders { get; set; } diff --git a/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs b/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs index fabb4d3fd..a267fd87e 100644 --- a/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs +++ b/src/NzbDrone.Core/MediaFiles/RecycleBinProvider.cs @@ -157,7 +157,15 @@ namespace NzbDrone.Core.MediaFiles return; } - _logger.Info("Removing items older than 7 days from the recycling bin"); + var cleanupDays = _configService.RecycleBinCleanupDays; + + if (cleanupDays == 0) + { + _logger.Info("Automatic cleanup of Recycle Bin is disabled"); + return; + } + + _logger.Info("Removing items older than {0} days from the recycling bin", cleanupDays); foreach (var folder in _diskProvider.GetDirectories(_configService.RecycleBin)) { @@ -172,7 +180,7 @@ namespace NzbDrone.Core.MediaFiles foreach (var file in _diskProvider.GetFiles(_configService.RecycleBin, SearchOption.TopDirectoryOnly)) { - if (_diskProvider.FileGetLastWrite(file).AddDays(7) > DateTime.UtcNow) + if (_diskProvider.FileGetLastWrite(file).AddDays(cleanupDays) > DateTime.UtcNow) { _logger.Debug("File hasn't expired yet, skipping: {0}", file); continue;