diff --git a/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs b/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs index 43fb40963..8441f8f5c 100644 --- a/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs +++ b/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs @@ -8,11 +8,27 @@ namespace NzbDrone.Api.Config { public class MediaManagementConfigModule : NzbDroneConfigModule { - public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator, FolderChmodValidator folderChmodValidator) + public MediaManagementConfigModule(IConfigService configService, + PathExistsValidator pathExistsValidator, + FolderChmodValidator folderChmodValidator, + FolderWritableValidator folderWritableValidator, + MoviePathValidator moviePathValidator, + StartupFolderValidator startupFolderValidator, + SystemFolderValidator systemFolderValidator, + RootFolderAncestorValidator rootFolderAncestorValidator, + RootFolderValidator rootFolderValidator) : base(configService) { SharedValidator.RuleFor(c => c.ChmodFolder).SetValidator(folderChmodValidator).When(c => !string.IsNullOrEmpty(c.ChmodFolder) && PlatformInfo.IsMono); - SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); + SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath() + .SetValidator(folderWritableValidator) + .SetValidator(rootFolderValidator) + .SetValidator(pathExistsValidator) + .SetValidator(moviePathValidator) + .SetValidator(rootFolderAncestorValidator) + .SetValidator(startupFolderValidator) + .SetValidator(systemFolderValidator) + .When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); } protected override MediaManagementConfigResource ToResource(IConfigService model) diff --git a/src/NzbDrone.Api/Movies/MovieModule.cs b/src/NzbDrone.Api/Movies/MovieModule.cs index 319174b80..c9efffaa2 100644 --- a/src/NzbDrone.Api/Movies/MovieModule.cs +++ b/src/NzbDrone.Api/Movies/MovieModule.cs @@ -37,6 +37,7 @@ namespace NzbDrone.Api.Movies IAddMovieService addMovieService, IMapCoversToLocal coverMapper, RootFolderValidator rootFolderValidator, + RecycleBinValidator recycleBinValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, MoviePathValidator moviesPathValidator, MovieExistsValidator moviesExistsValidator, @@ -66,6 +67,7 @@ namespace NzbDrone.Api.Movies .SetValidator(mappedNetworkDriveValidator) .SetValidator(moviesPathValidator) .SetValidator(moviesAncestorValidator) + .SetValidator(recycleBinValidator) .SetValidator(systemFolderValidator) .When(s => !s.Path.IsNullOrWhiteSpace()); diff --git a/src/NzbDrone.Api/RootFolders/RootFolderModule.cs b/src/NzbDrone.Api/RootFolders/RootFolderModule.cs index c392af27a..7984c2dc6 100644 --- a/src/NzbDrone.Api/RootFolders/RootFolderModule.cs +++ b/src/NzbDrone.Api/RootFolders/RootFolderModule.cs @@ -16,6 +16,7 @@ namespace NzbDrone.Api.RootFolders RootFolderValidator rootFolderValidator, PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, + RecycleBinValidator recycleBinValidator, StartupFolderValidator startupFolderValidator, SystemFolderValidator systemFolderValidator, FolderWritableValidator folderWritableValidator) @@ -34,6 +35,7 @@ namespace NzbDrone.Api.RootFolders .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(pathExistsValidator) .SetValidator(systemFolderValidator) .SetValidator(folderWritableValidator); diff --git a/src/NzbDrone.Core/Movies/AddMovieValidator.cs b/src/NzbDrone.Core/Movies/AddMovieValidator.cs index a143a7446..57da73e8d 100644 --- a/src/NzbDrone.Core/Movies/AddMovieValidator.cs +++ b/src/NzbDrone.Core/Movies/AddMovieValidator.cs @@ -12,13 +12,15 @@ namespace NzbDrone.Core.Movies public class AddMovieValidator : AbstractValidator, IAddMovieValidator { public AddMovieValidator(RootFolderValidator rootFolderValidator, - MoviePathValidator moviePathValidator, - MovieAncestorValidator movieAncestorValidator, - MovieTitleSlugValidator movieTitleSlugValidator) + RecycleBinValidator recycleBinValidator, + MoviePathValidator moviePathValidator, + MovieAncestorValidator movieAncestorValidator, + MovieTitleSlugValidator movieTitleSlugValidator) { RuleFor(c => c.Path).Cascade(CascadeMode.StopOnFirstFailure) .IsValidPath() .SetValidator(rootFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(moviePathValidator) .SetValidator(movieAncestorValidator); diff --git a/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs b/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs index 0e24f1bf7..e613c8127 100644 --- a/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs +++ b/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs @@ -10,7 +10,7 @@ namespace NzbDrone.Core.Validation.Paths private readonly IMovieService _moviesService; public MoviePathValidator(IMovieService moviesService) - : base("Path is already configured for another movie: {moviePath}") + : base("Path is already configured for an existing movie: {moviePath}") { _moviesService = moviesService; } diff --git a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs new file mode 100644 index 000000000..a8a714fe6 --- /dev/null +++ b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs @@ -0,0 +1,44 @@ +using FluentValidation.Validators; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; + +namespace NzbDrone.Core.Validation.Paths +{ + public class RecycleBinValidator : PropertyValidator + { + private readonly IConfigService _configService; + + public RecycleBinValidator(IConfigService configService) + : base("Path is {relationship} configured recycle bin folder") + { + _configService = configService; + } + + protected override bool IsValid(PropertyValidatorContext context) + { + var recycleBin = _configService.RecycleBin; + var folder = context.PropertyValue.ToString(); + + if (context.PropertyValue == null || recycleBin.IsNullOrWhiteSpace()) + { + return true; + } + + if (recycleBin.PathEquals(folder)) + { + context.MessageFormatter.AppendArgument("relationship", "set to"); + + return false; + } + + if (recycleBin.IsParentPath(folder)) + { + context.MessageFormatter.AppendArgument("relationship", "child of"); + + return false; + } + + return true; + } + } +} diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs new file mode 100644 index 000000000..19f0800b5 --- /dev/null +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs @@ -0,0 +1,28 @@ +using System.Linq; +using FluentValidation.Validators; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.RootFolders; + +namespace NzbDrone.Core.Validation.Paths +{ + public class RootFolderAncestorValidator : PropertyValidator + { + private readonly IRootFolderService _rootFolderService; + + public RootFolderAncestorValidator(IRootFolderService rootFolderService) + : base("Path is an ancestor of an existing root folder") + { + _rootFolderService = rootFolderService; + } + + protected override bool IsValid(PropertyValidatorContext context) + { + if (context.PropertyValue == null) + { + return true; + } + + return !_rootFolderService.All().Any(s => context.PropertyValue.ToString().IsParentPath(s.Path)); + } + } +} diff --git a/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs b/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs index fffedc515..cad1aea7b 100644 --- a/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs +++ b/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs @@ -8,12 +8,30 @@ namespace Radarr.Api.V3.Config { public class MediaManagementConfigModule : RadarrConfigModule { - public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator, FolderChmodValidator folderChmodValidator) + public MediaManagementConfigModule(IConfigService configService, + PathExistsValidator pathExistsValidator, + FolderChmodValidator folderChmodValidator, + FolderWritableValidator folderWritableValidator, + MoviePathValidator moviePathValidator, + StartupFolderValidator startupFolderValidator, + SystemFolderValidator systemFolderValidator, + RootFolderAncestorValidator rootFolderAncestorValidator, + RootFolderValidator rootFolderValidator) : base(configService) { SharedValidator.RuleFor(c => c.RecycleBinCleanupDays).GreaterThanOrEqualTo(0); SharedValidator.RuleFor(c => c.ChmodFolder).SetValidator(folderChmodValidator).When(c => !string.IsNullOrEmpty(c.ChmodFolder) && (OsInfo.IsLinux || OsInfo.IsOsx)); - SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); + + SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath() + .SetValidator(folderWritableValidator) + .SetValidator(rootFolderValidator) + .SetValidator(pathExistsValidator) + .SetValidator(rootFolderAncestorValidator) + .SetValidator(startupFolderValidator) + .SetValidator(systemFolderValidator) + .SetValidator(moviePathValidator) + .When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); + SharedValidator.RuleFor(c => c.MinimumFreeSpaceWhenImporting).GreaterThanOrEqualTo(100); } diff --git a/src/Radarr.Api.V3/Movies/MovieModule.cs b/src/Radarr.Api.V3/Movies/MovieModule.cs index 9c646ef1f..23efbc875 100644 --- a/src/Radarr.Api.V3/Movies/MovieModule.cs +++ b/src/Radarr.Api.V3/Movies/MovieModule.cs @@ -56,6 +56,7 @@ namespace Radarr.Api.V3.Movies MoviePathValidator moviesPathValidator, MovieExistsValidator moviesExistsValidator, MovieAncestorValidator moviesAncestorValidator, + RecycleBinValidator recycleBinValidator, SystemFolderValidator systemFolderValidator, ProfileExistsValidator profileExistsValidator, MovieFolderAsRootFolderValidator movieFolderAsRootFolderValidator) @@ -84,6 +85,7 @@ namespace Radarr.Api.V3.Movies .SetValidator(mappedNetworkDriveValidator) .SetValidator(moviesPathValidator) .SetValidator(moviesAncestorValidator) + .SetValidator(recycleBinValidator) .SetValidator(systemFolderValidator) .When(s => !s.Path.IsNullOrWhiteSpace()); diff --git a/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs b/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs index 950186624..ff7c8f4ca 100644 --- a/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs +++ b/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs @@ -17,6 +17,7 @@ namespace Radarr.Api.V3.RootFolders RootFolderValidator rootFolderValidator, PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, + RecycleBinValidator recycleBinValidator, StartupFolderValidator startupFolderValidator, SystemFolderValidator systemFolderValidator, FolderWritableValidator folderWritableValidator) @@ -35,6 +36,7 @@ namespace Radarr.Api.V3.RootFolders .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(pathExistsValidator) .SetValidator(systemFolderValidator) .SetValidator(folderWritableValidator);