diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index c7210e6e5..4af5215aa 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -11,7 +11,7 @@ - + @@ -63,4 +63,4 @@ - \ No newline at end of file + diff --git a/src/NzbDrone.Common/Extensions/UrlExtensions.cs b/src/NzbDrone.Common/Extensions/UrlExtensions.cs index e44843838..d71cfec15 100644 --- a/src/NzbDrone.Common/Extensions/UrlExtensions.cs +++ b/src/NzbDrone.Common/Extensions/UrlExtensions.cs @@ -16,18 +16,7 @@ namespace NzbDrone.Common.Extensions return false; } - Uri uri; - if (!Uri.TryCreate(path, UriKind.Absolute, out uri)) - { - return false; - } - - if (!uri.IsWellFormedOriginalString()) - { - return false; - } - - return true; + return Uri.TryCreate(path, UriKind.Absolute, out var uri) && uri.IsWellFormedOriginalString(); } } } diff --git a/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs index 13ba44089..c76a08191 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs @@ -61,7 +61,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("readarr")] - [TestCase("readarr@readarr")] [TestCase("readarr.com")] public void should_not_be_valid_if_to_is_invalid(string email) { @@ -71,7 +70,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("readarr")] - [TestCase("readarr@readarr")] [TestCase("readarr.com")] public void should_not_be_valid_if_cc_is_invalid(string email) { @@ -81,7 +79,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests } [TestCase("readarr")] - [TestCase("readarr@readarr")] [TestCase("readarr.com")] public void should_not_be_valid_if_bcc_is_invalid(string email) { diff --git a/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs b/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs index e3c548ec9..30e2e9640 100644 --- a/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs +++ b/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs @@ -19,7 +19,7 @@ namespace NzbDrone.Core.Books QualityProfileExistsValidator qualityProfileExistsValidator, MetadataProfileExistsValidator metadataProfileExistsValidator) { - RuleFor(c => c.Path).Cascade(CascadeMode.StopOnFirstFailure) + RuleFor(c => c.Path).Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(recycleBinValidator) diff --git a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs index cc652c7f8..f62dfdba9 100644 --- a/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs +++ b/src/NzbDrone.Core/Download/Clients/rTorrent/RTorrentDirectoryValidator.cs @@ -17,7 +17,7 @@ namespace NzbDrone.Core.Download.Clients.rTorrent PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator) { - RuleFor(c => c.MusicDirectory).Cascade(CascadeMode.StopOnFirstFailure) + RuleFor(c => c.MusicDirectory).Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) diff --git a/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs b/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs index 7911eb713..2883f473a 100644 --- a/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs +++ b/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionExistsValidator.cs @@ -7,11 +7,12 @@ namespace NzbDrone.Core.ImportLists.Exclusions private readonly IImportListExclusionService _importListExclusionService; public ImportListExclusionExistsValidator(IImportListExclusionService importListExclusionService) - : base("This exclusion has already been added.") { _importListExclusionService = importListExclusionService; } + protected override string GetDefaultMessageTemplate() => "This exclusion has already been added."; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Organizer/FileNameValidation.cs b/src/NzbDrone.Core/Organizer/FileNameValidation.cs index 10b47513c..a346e01f9 100644 --- a/src/NzbDrone.Core/Organizer/FileNameValidation.cs +++ b/src/NzbDrone.Core/Organizer/FileNameValidation.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; @@ -32,22 +31,17 @@ namespace NzbDrone.Core.Organizer public class ValidStandardTrackFormatValidator : PropertyValidator { - public ValidStandardTrackFormatValidator() - : base("Must contain Book Title AND PartNumber, OR Original Title") - { - } + protected override string GetDefaultMessageTemplate() => "Must contain Book Title AND PartNumber, OR Original Title"; protected override bool IsValid(PropertyValidatorContext context) { - var value = context.PropertyValue as string; - - if (!(FileNameBuilder.BookTitleRegex.IsMatch(value) && FileNameBuilder.PartRegex.IsMatch(value)) && - !FileNameValidation.OriginalTokenRegex.IsMatch(value)) + if (context.PropertyValue is not string value) { return false; } - return true; + return (FileNameBuilder.BookTitleRegex.IsMatch(value) && FileNameBuilder.PartRegex.IsMatch(value)) || + FileNameValidation.OriginalTokenRegex.IsMatch(value); } } @@ -55,29 +49,18 @@ namespace NzbDrone.Core.Organizer { private readonly char[] _invalidPathChars = Path.GetInvalidPathChars(); - public IllegalCharactersValidator() - : base("Contains illegal characters: {InvalidCharacters}") - { - } + protected override string GetDefaultMessageTemplate() => "Contains illegal characters: {InvalidCharacters}"; protected override bool IsValid(PropertyValidatorContext context) { var value = context.PropertyValue as string; - var invalidCharacters = new List(); if (value.IsNullOrWhiteSpace()) { return true; } - foreach (var i in _invalidPathChars) - { - if (value.IndexOf(i) >= 0) - { - invalidCharacters.Add(i); - } - } - + var invalidCharacters = _invalidPathChars.Where(i => value!.IndexOf(i) >= 0).ToList(); if (invalidCharacters.Any()) { context.MessageFormatter.AppendArgument("InvalidCharacters", string.Join("", invalidCharacters)); diff --git a/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs b/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs index cfd08a2f4..124d75e54 100644 --- a/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs +++ b/src/NzbDrone.Core/Profiles/Delay/DelayProfileTagInUseValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Profiles.Delay private readonly IDelayProfileService _delayProfileService; public DelayProfileTagInUseValidator(IDelayProfileService delayProfileService) - : base("One or more tags is used in another profile") { _delayProfileService = delayProfileService; } + protected override string GetDefaultMessageTemplate() => "One or more tags is used in another profile"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) @@ -25,9 +26,7 @@ namespace NzbDrone.Core.Profiles.Delay dynamic instance = context.ParentContext.InstanceToValidate; var instanceId = (int)instance.Id; - var collection = context.PropertyValue as HashSet; - - if (collection == null || collection.Empty()) + if (context.PropertyValue is not HashSet collection || collection.Empty()) { return true; } diff --git a/src/NzbDrone.Core/Validation/FolderChmodValidator.cs b/src/NzbDrone.Core/Validation/FolderChmodValidator.cs index 3e90bf9fa..5677526af 100644 --- a/src/NzbDrone.Core/Validation/FolderChmodValidator.cs +++ b/src/NzbDrone.Core/Validation/FolderChmodValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation private readonly IDiskProvider _diskProvider; public FolderChmodValidator(IDiskProvider diskProvider) - : base("Must contain a valid Unix permissions octal") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "Must contain a valid Unix permissions octal"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/FolderValidator.cs b/src/NzbDrone.Core/Validation/FolderValidator.cs index 9d327b9c6..405fe14bd 100644 --- a/src/NzbDrone.Core/Validation/FolderValidator.cs +++ b/src/NzbDrone.Core/Validation/FolderValidator.cs @@ -6,10 +6,7 @@ namespace NzbDrone.Core.Validation { public class FolderValidator : PropertyValidator { - public FolderValidator() - : base("Invalid Path") - { - } + protected override string GetDefaultMessageTemplate() => "Invalid Path"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Core/Validation/GuidValidator.cs b/src/NzbDrone.Core/Validation/GuidValidator.cs index 92fd53ad3..19956a2fd 100644 --- a/src/NzbDrone.Core/Validation/GuidValidator.cs +++ b/src/NzbDrone.Core/Validation/GuidValidator.cs @@ -5,10 +5,7 @@ namespace NzbDrone.Core.Validation { public class GuidValidator : PropertyValidator { - public GuidValidator() - : base("String is not a valid Guid") - { - } + protected override string GetDefaultMessageTemplate() => "String is not a valid Guid"; protected override bool IsValid(PropertyValidatorContext context) { @@ -17,7 +14,7 @@ namespace NzbDrone.Core.Validation return false; } - return Guid.TryParse(context.PropertyValue.ToString(), out Guid guidOutput); + return Guid.TryParse(context.PropertyValue.ToString(), out _); } } } diff --git a/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs b/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs index 8fd3e96d4..328d7f8c3 100644 --- a/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/MetadataProfileExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation private readonly IMetadataProfileService _profileService; public MetadataProfileExistsValidator(IMetadataProfileService profileService) - : base("Metadata profile does not exist") { _profileService = profileService; } + protected override string GetDefaultMessageTemplate() => "Metadata profile does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs index 472f0e9bf..4beb46606 100644 --- a/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/AuthorAncestorValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IAuthorService _authorService; public AuthorAncestorValidator(IAuthorService authorService) - : base("Path is an ancestor of an existing author") { _authorService = authorService; } + protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing author"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/AuthorExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorExistsValidator.cs index 6a9b1958f..6f28ff199 100644 --- a/src/NzbDrone.Core/Validation/Paths/AuthorExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/AuthorExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IAuthorService _authorService; public AuthorExistsValidator(IAuthorService authorService) - : base("This author has already been added.") { _authorService = authorService; } + protected override string GetDefaultMessageTemplate() => "This author has already been added"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs b/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs index 1105afecb..2d4f2eef1 100644 --- a/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/AuthorPathValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IAuthorService _authorService; public AuthorPathValidator(IAuthorService authorService) - : base("Path is already configured for another author") { _authorService = authorService; } + protected override string GetDefaultMessageTemplate() => "Path is already configured for another author"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs index 9adb200aa..02e2aef81 100644 --- a/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/FileExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IDiskProvider _diskProvider; public FileExistsValidator(IDiskProvider diskProvider) - : base("File does not exist") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "File does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs b/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs index c58b5a273..6838b3ea6 100644 --- a/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/FolderWritableValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IDiskProvider _diskProvider; public FolderWritableValidator(IDiskProvider diskProvider) - : base($"Folder is not writable by user {Environment.UserName}") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => $"Folder is not writable by user {Environment.UserName}"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs b/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs index 48e3da21e..2476800ce 100644 --- a/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/MappedNetworkDriveValidator.cs @@ -14,12 +14,13 @@ namespace NzbDrone.Core.Validation.Paths private static readonly Regex DriveRegex = new Regex(@"[a-z]\:\\", RegexOptions.Compiled | RegexOptions.IgnoreCase); public MappedNetworkDriveValidator(IRuntimeInfo runtimeInfo, IDiskProvider diskProvider) - : base("Mapped Network Drive and Windows Service") { _runtimeInfo = runtimeInfo; _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "Mapped Network Drive and Windows Service"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) @@ -46,12 +47,7 @@ namespace NzbDrone.Core.Validation.Paths var mount = _diskProvider.GetMount(path); - if (mount != null && mount.DriveType == DriveType.Network) - { - return false; - } - - return true; + return mount is not { DriveType: DriveType.Network }; } } } diff --git a/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs index 77398b5e8..91493482f 100644 --- a/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/PathExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IDiskProvider _diskProvider; public PathExistsValidator(IDiskProvider diskProvider) - : base("Path does not exist") { _diskProvider = diskProvider; } + protected override string GetDefaultMessageTemplate() => "Path does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/PathValidator.cs b/src/NzbDrone.Core/Validation/Paths/PathValidator.cs index 40ca0579f..831d0e2a7 100644 --- a/src/NzbDrone.Core/Validation/Paths/PathValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/PathValidator.cs @@ -15,10 +15,7 @@ namespace NzbDrone.Core.Validation.Paths public class PathValidator : PropertyValidator { - public PathValidator() - : base("Invalid Path") - { - } + protected override string GetDefaultMessageTemplate() => "Invalid Path"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs index a8a714fe6..1299b72ac 100644 --- a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IConfigService _configService; public RecycleBinValidator(IConfigService configService) - : base("Path is {relationship} configured recycle bin folder") { _configService = configService; } + protected override string GetDefaultMessageTemplate() => "Path is {relationship} configured recycle bin folder"; + protected override bool IsValid(PropertyValidatorContext context) { var recycleBin = _configService.RecycleBin; diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs index 19f0800b5..1b7dd0bfa 100644 --- a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs @@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IRootFolderService _rootFolderService; public RootFolderAncestorValidator(IRootFolderService rootFolderService) - : base("Path is an ancestor of an existing root folder") { _rootFolderService = rootFolderService; } + protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing root folder"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs index 8494ac28b..7ceffdd7a 100644 --- a/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IRootFolderService _rootFolderService; public RootFolderValidator(IRootFolderService rootFolderService) - : base("Path is already configured as a root folder") { _rootFolderService = rootFolderService; } + protected override string GetDefaultMessageTemplate() => "Path is already configured as a root folder"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs index 9f097f8d2..0243923f1 100644 --- a/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/StartupFolderValidator.cs @@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths private readonly IAppFolderInfo _appFolderInfo; public StartupFolderValidator(IAppFolderInfo appFolderInfo) - : base("Path cannot be {relationship} the start up folder") { _appFolderInfo = appFolderInfo; } + protected override string GetDefaultMessageTemplate() => "Path cannot be {relationship} the start up folder"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs b/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs index d8f3a7f15..6b891394e 100644 --- a/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs +++ b/src/NzbDrone.Core/Validation/Paths/SystemFolderValidator.cs @@ -6,10 +6,7 @@ namespace NzbDrone.Core.Validation.Paths { public class SystemFolderValidator : PropertyValidator { - public SystemFolderValidator() - : base("Is {relationship} system folder {systemFolder}") - { - } + protected override string GetDefaultMessageTemplate() => "Is {relationship} system folder {systemFolder}"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs b/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs index 657260dd4..f8321f960 100644 --- a/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs +++ b/src/NzbDrone.Core/Validation/QualityProfileExistsValidator.cs @@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation private readonly IProfileService _profileService; public QualityProfileExistsValidator(IProfileService profileService) - : base("Quality Profile does not exist") { _profileService = profileService; } + protected override string GetDefaultMessageTemplate() => "Quality Profile does not exist"; + protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) diff --git a/src/NzbDrone.Core/Validation/UrlValidator.cs b/src/NzbDrone.Core/Validation/UrlValidator.cs index 844ab80f2..8588b4848 100644 --- a/src/NzbDrone.Core/Validation/UrlValidator.cs +++ b/src/NzbDrone.Core/Validation/UrlValidator.cs @@ -14,10 +14,7 @@ namespace NzbDrone.Core.Validation public class UrlValidator : PropertyValidator { - public UrlValidator() - : base("Invalid Url") - { - } + protected override string GetDefaultMessageTemplate() => "Invalid Url"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/Readarr.Api.V1/Author/AuthorController.cs b/src/Readarr.Api.V1/Author/AuthorController.cs index 0d58356c0..b20d976f0 100644 --- a/src/Readarr.Api.V1/Author/AuthorController.cs +++ b/src/Readarr.Api.V1/Author/AuthorController.cs @@ -76,7 +76,7 @@ namespace Readarr.Api.V1.Author Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.MetadataProfileId)); SharedValidator.RuleFor(s => s.Path) - .Cascade(CascadeMode.StopOnFirstFailure) + .Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) diff --git a/src/Readarr.Api.V1/Config/HostConfigController.cs b/src/Readarr.Api.V1/Config/HostConfigController.cs index b82efbda8..57a5875a0 100644 --- a/src/Readarr.Api.V1/Config/HostConfigController.cs +++ b/src/Readarr.Api.V1/Config/HostConfigController.cs @@ -51,7 +51,7 @@ namespace Readarr.Api.V1.Config SharedValidator.RuleFor(c => c.SslPort).NotEqual(c => c.Port).When(c => c.EnableSsl); SharedValidator.RuleFor(c => c.SslCertPath) - .Cascade(CascadeMode.StopOnFirstFailure) + .Cascade(CascadeMode.Stop) .NotEmpty() .IsValidPath() .SetValidator(fileExistsValidator) diff --git a/src/Readarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs b/src/Readarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs index 2cd3485b7..e8ca2bd51 100644 --- a/src/Readarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs +++ b/src/Readarr.Api.V1/Profiles/Quality/QualityCutoffValidator.cs @@ -15,30 +15,17 @@ namespace Readarr.Api.V1.Profiles.Quality public class ValidCutoffValidator : PropertyValidator { - public ValidCutoffValidator() - : base("Cutoff must be an allowed quality or group") - { - } + protected override string GetDefaultMessageTemplate() => "Cutoff must be an allowed quality or group"; protected override bool IsValid(PropertyValidatorContext context) { - int cutoff = (int)context.PropertyValue; + var cutoff = (int)context.PropertyValue; dynamic instance = context.ParentContext.InstanceToValidate; var items = instance.Items as IList; - QualityProfileQualityItemResource cutoffItem = items.SingleOrDefault(i => (i.Quality == null && i.Id == cutoff) || i.Quality?.Id == cutoff); - - if (cutoffItem == null) - { - return false; - } - - if (!cutoffItem.Allowed) - { - return false; - } + var cutoffItem = items?.SingleOrDefault(i => (i.Quality == null && i.Id == cutoff) || i.Quality?.Id == cutoff); - return true; + return cutoffItem is { Allowed: true }; } } } diff --git a/src/Readarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs b/src/Readarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs index a510e92f6..c957df257 100644 --- a/src/Readarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs +++ b/src/Readarr.Api.V1/Profiles/Quality/QualityItemsValidator.cs @@ -23,139 +23,104 @@ namespace Readarr.Api.V1.Profiles.Quality public class AllowedValidator : PropertyValidator { - public AllowedValidator() - : base("Must contain at least one allowed quality") - { - } + protected override string GetDefaultMessageTemplate() => "Must contain at least one allowed quality"; protected override bool IsValid(PropertyValidatorContext context) { - var list = context.PropertyValue as IList; - - if (list == null) - { - return false; - } - - if (!list.Any(c => c.Allowed)) - { - return false; - } - - return true; + return context.PropertyValue is IList list && + list.Any(c => c.Allowed); } } public class GroupItemValidator : PropertyValidator { - public GroupItemValidator() - : base("Groups must contain multiple qualities") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must contain multiple qualities"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Items.Count <= 1)) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Items.Count <= 1); } } public class QualityNameValidator : PropertyValidator { - public QualityNameValidator() - : base("Individual qualities should not be named") - { - } + protected override string GetDefaultMessageTemplate() => "Individual qualities should not be named"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Quality != null)) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Quality != null); } } public class ItemGroupNameValidator : PropertyValidator { - public ItemGroupNameValidator() - : base("Groups must have a name") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must have a name"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Quality == null && i.Name.IsNullOrWhiteSpace())) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Quality == null && i.Name.IsNullOrWhiteSpace()); } } public class ItemGroupIdValidator : PropertyValidator { - public ItemGroupIdValidator() - : base("Groups must have an ID") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must have an ID"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Any(i => i.Quality == null && i.Id == 0)) + if (context.PropertyValue is not IList items) { return false; } - return true; + return !items.Any(i => i.Quality == null && i.Id == 0); } } public class UniqueIdValidator : PropertyValidator { - public UniqueIdValidator() - : base("Groups must have a unique ID") - { - } + protected override string GetDefaultMessageTemplate() => "Groups must have a unique ID"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; - - if (items.Where(i => i.Id > 0).Select(i => i.Id).GroupBy(i => i).Any(g => g.Count() > 1)) + if (context.PropertyValue is not IList items) { return false; } - return true; + var ids = items.Where(i => i.Id > 0).Select(i => i.Id); + var groupedIds = ids.GroupBy(i => i); + + return groupedIds.All(g => g.Count() == 1); } } public class UniqueQualityIdValidator : PropertyValidator { - public UniqueQualityIdValidator() - : base("Qualities can only be used once") - { - } + protected override string GetDefaultMessageTemplate() => "Qualities can only be used once"; protected override bool IsValid(PropertyValidatorContext context) { - var items = context.PropertyValue as IList; + if (context.PropertyValue is not IList items) + { + return false; + } + var qualityIds = new HashSet(); foreach (var item in items) diff --git a/src/Readarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs b/src/Readarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs index 9289b50b8..20bd2079c 100644 --- a/src/Readarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs +++ b/src/Readarr.Api.V1/RemotePathMappings/RemotePathMappingController.cs @@ -28,8 +28,8 @@ namespace Readarr.Api.V1.RemotePathMappings .NotEmpty(); SharedValidator.RuleFor(c => c.LocalPath) - .Cascade(CascadeMode.StopOnFirstFailure) - .IsValidPath() + .Cascade(CascadeMode.Stop) + .IsValidPath() .SetValidator(mappedNetworkDriveValidator) .SetValidator(pathExistsValidator); } diff --git a/src/Readarr.Api.V1/RootFolders/RootFolderController.cs b/src/Readarr.Api.V1/RootFolders/RootFolderController.cs index 0974b1c26..d49466c9f 100644 --- a/src/Readarr.Api.V1/RootFolders/RootFolderController.cs +++ b/src/Readarr.Api.V1/RootFolders/RootFolderController.cs @@ -40,7 +40,7 @@ namespace Readarr.Api.V1.RootFolders _calibreProxy = calibreProxy; SharedValidator.RuleFor(c => c.Path) - .Cascade(CascadeMode.StopOnFirstFailure) + .Cascade(CascadeMode.Stop) .IsValidPath() .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) diff --git a/src/Readarr.Http/REST/ResourceValidator.cs b/src/Readarr.Http/REST/ResourceValidator.cs index 9fb37233f..dbabcd2ba 100644 --- a/src/Readarr.Http/REST/ResourceValidator.cs +++ b/src/Readarr.Http/REST/ResourceValidator.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Linq.Expressions; using FluentValidation; using FluentValidation.Internal; -using FluentValidation.Resources; using Readarr.Http.ClientSchema; namespace Readarr.Http.REST @@ -15,7 +14,7 @@ namespace Readarr.Http.REST { var rule = new PropertyRule(fieldListAccessor.GetMember(), c => GetValue(c, fieldListAccessor.Compile(), fieldName), null, () => CascadeMode.Continue, typeof(TProperty), typeof(TResource)); rule.PropertyName = fieldName; - rule.DisplayName = new StaticStringSource(fieldName); + rule.SetDisplayName(fieldName); AddRule(rule); return new RuleBuilder(rule, this); @@ -25,12 +24,7 @@ namespace Readarr.Http.REST { var resource = fieldListAccessor((TResource)container).SingleOrDefault(c => c.Name == fieldName); - if (resource == null) - { - return null; - } - - return resource.Value; + return resource?.Value; } } } diff --git a/src/Readarr.Http/Validation/EmptyCollectionValidator.cs b/src/Readarr.Http/Validation/EmptyCollectionValidator.cs index a1424be5d..1873f8ba1 100644 --- a/src/Readarr.Http/Validation/EmptyCollectionValidator.cs +++ b/src/Readarr.Http/Validation/EmptyCollectionValidator.cs @@ -6,10 +6,7 @@ namespace Readarr.Http.Validation { public class EmptyCollectionValidator : PropertyValidator { - public EmptyCollectionValidator() - : base("Collection Must Be Empty") - { - } + protected override string GetDefaultMessageTemplate() => "Collection Must Be Empty"; protected override bool IsValid(PropertyValidatorContext context) { diff --git a/src/Readarr.Http/Validation/RssSyncIntervalValidator.cs b/src/Readarr.Http/Validation/RssSyncIntervalValidator.cs index b9cf35a77..b3a0e494f 100644 --- a/src/Readarr.Http/Validation/RssSyncIntervalValidator.cs +++ b/src/Readarr.Http/Validation/RssSyncIntervalValidator.cs @@ -4,10 +4,7 @@ namespace Readarr.Http.Validation { public class RssSyncIntervalValidator : PropertyValidator { - public RssSyncIntervalValidator() - : base("Must be between 10 and 120 or 0 to disable") - { - } + protected override string GetDefaultMessageTemplate() => "Must be between 10 and 120 or 0 to disable"; protected override bool IsValid(PropertyValidatorContext context) { @@ -23,12 +20,7 @@ namespace Readarr.Http.Validation return true; } - if (value >= 10 && value <= 120) - { - return true; - } - - return false; + return value is >= 10 and <= 120; } } } diff --git a/src/Readarr.sln.DotSettings b/src/Readarr.sln.DotSettings new file mode 100644 index 000000000..df756d4d1 --- /dev/null +++ b/src/Readarr.sln.DotSettings @@ -0,0 +1,2 @@ + + True