Migrate to FluentValidation 9
This commit is contained in:
parent
dec6e14036
commit
40e54685b9
|
@ -16,18 +16,7 @@ namespace NzbDrone.Common.Extensions
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri uri;
|
return Uri.TryCreate(path, UriKind.Absolute, out var uri) && uri.IsWellFormedOriginalString();
|
||||||
if (!Uri.TryCreate(path, UriKind.Absolute, out uri))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uri.IsWellFormedOriginalString())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("sonarr")]
|
[TestCase("sonarr")]
|
||||||
[TestCase("sonarr@sonarr")]
|
|
||||||
[TestCase("email.me")]
|
[TestCase("email.me")]
|
||||||
[Ignore("Allowed coz some email servers allow arbitrary source, we probably need to support 'Name <email>' syntax")]
|
[Ignore("Allowed coz some email servers allow arbitrary source, we probably need to support 'Name <email>' syntax")]
|
||||||
public void should_not_be_valid_if_from_is_invalid(string email)
|
public void should_not_be_valid_if_from_is_invalid(string email)
|
||||||
|
@ -73,7 +72,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("sonarr")]
|
[TestCase("sonarr")]
|
||||||
[TestCase("sonarr@sonarr")]
|
|
||||||
[TestCase("email.me")]
|
[TestCase("email.me")]
|
||||||
public void should_not_be_valid_if_to_is_invalid(string email)
|
public void should_not_be_valid_if_to_is_invalid(string email)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +81,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("sonarr")]
|
[TestCase("sonarr")]
|
||||||
[TestCase("sonarr@sonarr")]
|
|
||||||
[TestCase("email.me")]
|
[TestCase("email.me")]
|
||||||
public void should_not_be_valid_if_cc_is_invalid(string email)
|
public void should_not_be_valid_if_cc_is_invalid(string email)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +90,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("sonarr")]
|
[TestCase("sonarr")]
|
||||||
[TestCase("sonarr@sonarr")]
|
|
||||||
[TestCase("email.me")]
|
[TestCase("email.me")]
|
||||||
public void should_not_be_valid_if_bcc_is_invalid(string email)
|
public void should_not_be_valid_if_bcc_is_invalid(string email)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,8 +17,8 @@ namespace NzbDrone.Core.Download.Clients.rTorrent
|
||||||
PathExistsValidator pathExistsValidator,
|
PathExistsValidator pathExistsValidator,
|
||||||
MappedNetworkDriveValidator mappedNetworkDriveValidator)
|
MappedNetworkDriveValidator mappedNetworkDriveValidator)
|
||||||
{
|
{
|
||||||
RuleFor(c => c.TvDirectory).Cascade(CascadeMode.StopOnFirstFailure)
|
RuleFor(c => c.TvDirectory).Cascade(CascadeMode.Stop)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(rootFolderValidator)
|
.SetValidator(rootFolderValidator)
|
||||||
.SetValidator(mappedNetworkDriveValidator)
|
.SetValidator(mappedNetworkDriveValidator)
|
||||||
.SetValidator(pathExistsValidator)
|
.SetValidator(pathExistsValidator)
|
||||||
|
|
|
@ -7,11 +7,12 @@ namespace NzbDrone.Core.ImportLists.Exclusions
|
||||||
private readonly IImportListExclusionService _importListExclusionService;
|
private readonly IImportListExclusionService _importListExclusionService;
|
||||||
|
|
||||||
public ImportListExclusionExistsValidator(IImportListExclusionService importListExclusionService)
|
public ImportListExclusionExistsValidator(IImportListExclusionService importListExclusionService)
|
||||||
: base("This exclusion has already been added.")
|
|
||||||
{
|
{
|
||||||
_importListExclusionService = importListExclusionService;
|
_importListExclusionService = importListExclusionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "This exclusion has already been added.";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
@ -66,96 +65,70 @@ namespace NzbDrone.Core.Organizer
|
||||||
|
|
||||||
public class ValidStandardEpisodeFormatValidator : PropertyValidator
|
public class ValidStandardEpisodeFormatValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public ValidStandardEpisodeFormatValidator()
|
protected override string GetDefaultMessageTemplate() => "Must contain season and episode numbers OR Original Title";
|
||||||
: base("Must contain season and episode numbers OR Original Title")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var value = context.PropertyValue as string;
|
if (context.PropertyValue is not string value)
|
||||||
|
|
||||||
if (!FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) &&
|
|
||||||
!FileNameValidation.OriginalTokenRegex.IsMatch(value))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) ||
|
||||||
|
FileNameValidation.OriginalTokenRegex.IsMatch(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ValidDailyEpisodeFormatValidator : PropertyValidator
|
public class ValidDailyEpisodeFormatValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public ValidDailyEpisodeFormatValidator()
|
protected override string GetDefaultMessageTemplate() => "Must contain Air Date OR Season and Episode OR Original Title";
|
||||||
: base("Must contain Air Date OR Season and Episode OR Original Title")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var value = context.PropertyValue as string;
|
if (context.PropertyValue is not string value)
|
||||||
|
|
||||||
if (!FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) &&
|
|
||||||
!FileNameBuilder.AirDateRegex.IsMatch(value) &&
|
|
||||||
!FileNameValidation.OriginalTokenRegex.IsMatch(value))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) ||
|
||||||
|
FileNameBuilder.AirDateRegex.IsMatch(value) ||
|
||||||
|
FileNameValidation.OriginalTokenRegex.IsMatch(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ValidAnimeEpisodeFormatValidator : PropertyValidator
|
public class ValidAnimeEpisodeFormatValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public ValidAnimeEpisodeFormatValidator()
|
protected override string GetDefaultMessageTemplate() =>
|
||||||
: base("Must contain Absolute Episode number OR Season and Episode OR Original Title")
|
"Must contain Absolute Episode number OR Season and Episode OR Original Title";
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var value = context.PropertyValue as string;
|
if (context.PropertyValue is not string value)
|
||||||
|
|
||||||
if (!FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) &&
|
|
||||||
!FileNameBuilder.AbsoluteEpisodePatternRegex.IsMatch(value) &&
|
|
||||||
!FileNameValidation.OriginalTokenRegex.IsMatch(value))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return FileNameBuilder.SeasonEpisodePatternRegex.IsMatch(value) ||
|
||||||
|
FileNameBuilder.AbsoluteEpisodePatternRegex.IsMatch(value) ||
|
||||||
|
FileNameValidation.OriginalTokenRegex.IsMatch(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IllegalCharactersValidator : PropertyValidator
|
public class IllegalCharactersValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
private readonly char[] _invalidPathChars = Path.GetInvalidPathChars();
|
private static readonly char[] InvalidPathChars = Path.GetInvalidPathChars();
|
||||||
|
|
||||||
public IllegalCharactersValidator()
|
protected override string GetDefaultMessageTemplate() => "Contains illegal characters: {InvalidCharacters}";
|
||||||
: base("Contains illegal characters: {InvalidCharacters}")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var value = context.PropertyValue as string;
|
var value = context.PropertyValue as string;
|
||||||
var invalidCharacters = new List<char>();
|
|
||||||
|
|
||||||
if (value.IsNullOrWhiteSpace())
|
if (value.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var i in _invalidPathChars)
|
var invalidCharacters = InvalidPathChars.Where(i => value!.IndexOf(i) >= 0).ToList();
|
||||||
{
|
|
||||||
if (value.IndexOf(i) >= 0)
|
|
||||||
{
|
|
||||||
invalidCharacters.Add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invalidCharacters.Any())
|
if (invalidCharacters.Any())
|
||||||
{
|
{
|
||||||
context.MessageFormatter.AppendArgument("InvalidCharacters", string.Join("", invalidCharacters));
|
context.MessageFormatter.AppendArgument("InvalidCharacters", string.Join("", invalidCharacters));
|
||||||
|
|
|
@ -10,11 +10,12 @@ namespace NzbDrone.Core.Profiles.Delay
|
||||||
private readonly IDelayProfileService _delayProfileService;
|
private readonly IDelayProfileService _delayProfileService;
|
||||||
|
|
||||||
public DelayProfileTagInUseValidator(IDelayProfileService delayProfileService)
|
public DelayProfileTagInUseValidator(IDelayProfileService delayProfileService)
|
||||||
: base("One or more tags is used in another profile")
|
|
||||||
{
|
{
|
||||||
_delayProfileService = delayProfileService;
|
_delayProfileService = delayProfileService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "One or more tags is used in another profile";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
@ -25,9 +26,7 @@ namespace NzbDrone.Core.Profiles.Delay
|
||||||
dynamic instance = context.ParentContext.InstanceToValidate;
|
dynamic instance = context.ParentContext.InstanceToValidate;
|
||||||
var instanceId = (int)instance.Id;
|
var instanceId = (int)instance.Id;
|
||||||
|
|
||||||
var collection = context.PropertyValue as HashSet<int>;
|
if (context.PropertyValue is not HashSet<int> collection || collection.Empty())
|
||||||
|
|
||||||
if (collection == null || collection.Empty())
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
||||||
<PackageReference Include="FluentMigrator.Runner" Version="3.3.2" />
|
<PackageReference Include="FluentMigrator.Runner" Version="3.3.2" />
|
||||||
<PackageReference Include="FluentMigrator.Runner.SQLite" Version="3.3.2" />
|
<PackageReference Include="FluentMigrator.Runner.SQLite" Version="3.3.2" />
|
||||||
<PackageReference Include="FluentValidation" Version="8.6.2" />
|
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="NLog" Version="4.7.14" />
|
<PackageReference Include="NLog" Version="4.7.14" />
|
||||||
|
|
|
@ -16,8 +16,8 @@ namespace NzbDrone.Core.Tv
|
||||||
SeriesAncestorValidator seriesAncestorValidator,
|
SeriesAncestorValidator seriesAncestorValidator,
|
||||||
SeriesTitleSlugValidator seriesTitleSlugValidator)
|
SeriesTitleSlugValidator seriesTitleSlugValidator)
|
||||||
{
|
{
|
||||||
RuleFor(c => c.Path).Cascade(CascadeMode.StopOnFirstFailure)
|
RuleFor(c => c.Path).Cascade(CascadeMode.Stop)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(rootFolderValidator)
|
.SetValidator(rootFolderValidator)
|
||||||
.SetValidator(seriesPathValidator)
|
.SetValidator(seriesPathValidator)
|
||||||
.SetValidator(seriesAncestorValidator);
|
.SetValidator(seriesAncestorValidator);
|
||||||
|
|
|
@ -9,11 +9,13 @@ namespace NzbDrone.Core.Tv
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
|
|
||||||
public SeriesTitleSlugValidator(ISeriesService seriesService)
|
public SeriesTitleSlugValidator(ISeriesService seriesService)
|
||||||
: base("Title slug '{slug}' is in use by series '{seriesTitle}'. Check the FAQ for more information")
|
|
||||||
{
|
{
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() =>
|
||||||
|
"Title slug '{slug}' is in use by series '{seriesTitle}'. Check the FAQ for more information";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
public FolderChmodValidator(IDiskProvider diskProvider)
|
public FolderChmodValidator(IDiskProvider diskProvider)
|
||||||
: base("Must contain a valid Unix permissions octal")
|
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Must contain a valid Unix permissions octal";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -6,10 +6,7 @@ namespace NzbDrone.Core.Validation
|
||||||
{
|
{
|
||||||
public class FolderValidator : PropertyValidator
|
public class FolderValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public FolderValidator()
|
protected override string GetDefaultMessageTemplate() => "Invalid Path";
|
||||||
: base("Invalid Path")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
public FileExistsValidator(IDiskProvider diskProvider)
|
public FileExistsValidator(IDiskProvider diskProvider)
|
||||||
: base("File does not exist")
|
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "File does not exist";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
public FolderWritableValidator(IDiskProvider diskProvider)
|
public FolderWritableValidator(IDiskProvider diskProvider)
|
||||||
: base($"Folder is not writable by user {Environment.UserName}")
|
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => $"Folder is not writable by user {Environment.UserName}";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -14,12 +14,13 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private static readonly Regex DriveRegex = new Regex(@"[a-z]\:\\", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
private static readonly Regex DriveRegex = new Regex(@"[a-z]\:\\", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
public MappedNetworkDriveValidator(IRuntimeInfo runtimeInfo, IDiskProvider diskProvider)
|
public MappedNetworkDriveValidator(IRuntimeInfo runtimeInfo, IDiskProvider diskProvider)
|
||||||
: base("Mapped Network Drive and Windows Service")
|
|
||||||
{
|
{
|
||||||
_runtimeInfo = runtimeInfo;
|
_runtimeInfo = runtimeInfo;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Mapped Network Drive and Windows Service";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
@ -46,12 +47,7 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
|
|
||||||
var mount = _diskProvider.GetMount(path);
|
var mount = _diskProvider.GetMount(path);
|
||||||
|
|
||||||
if (mount != null && mount.DriveType == DriveType.Network)
|
return mount is not { DriveType: DriveType.Network };
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly IDiskProvider _diskProvider;
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
|
||||||
public PathExistsValidator(IDiskProvider diskProvider)
|
public PathExistsValidator(IDiskProvider diskProvider)
|
||||||
: base("Path does not exist")
|
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Path does not exist";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -15,10 +15,7 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
|
|
||||||
public class PathValidator : PropertyValidator
|
public class PathValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public PathValidator()
|
protected override string GetDefaultMessageTemplate() => "Invalid Path";
|
||||||
: base("Invalid Path")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
|
|
||||||
public RecycleBinValidator(IConfigService configService)
|
public RecycleBinValidator(IConfigService configService)
|
||||||
: base("Path is {relationship} configured recycle bin folder")
|
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Path is {relationship} configured recycle bin folder";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var recycleBin = _configService.RecycleBin;
|
var recycleBin = _configService.RecycleBin;
|
||||||
|
|
|
@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly IRootFolderService _rootFolderService;
|
private readonly IRootFolderService _rootFolderService;
|
||||||
|
|
||||||
public RootFolderAncestorValidator(IRootFolderService rootFolderService)
|
public RootFolderAncestorValidator(IRootFolderService rootFolderService)
|
||||||
: base("Path is an ancestor of an existing root folder")
|
|
||||||
{
|
{
|
||||||
_rootFolderService = rootFolderService;
|
_rootFolderService = rootFolderService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing root folder";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly IRootFolderService _rootFolderService;
|
private readonly IRootFolderService _rootFolderService;
|
||||||
|
|
||||||
public RootFolderValidator(IRootFolderService rootFolderService)
|
public RootFolderValidator(IRootFolderService rootFolderService)
|
||||||
: base("Path is already configured as a root folder")
|
|
||||||
{
|
{
|
||||||
_rootFolderService = rootFolderService;
|
_rootFolderService = rootFolderService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Path is already configured as a root folder";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -10,11 +10,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
|
|
||||||
public SeriesAncestorValidator(ISeriesService seriesService)
|
public SeriesAncestorValidator(ISeriesService seriesService)
|
||||||
: base("Path is an ancestor of an existing series")
|
|
||||||
{
|
{
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Path is an ancestor of an existing series";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
|
|
||||||
public SeriesExistsValidator(ISeriesService seriesService)
|
public SeriesExistsValidator(ISeriesService seriesService)
|
||||||
: base("This series has already been added")
|
|
||||||
{
|
{
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "This series has already been added";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly ISeriesService _seriesService;
|
private readonly ISeriesService _seriesService;
|
||||||
|
|
||||||
public SeriesPathValidator(ISeriesService seriesService)
|
public SeriesPathValidator(ISeriesService seriesService)
|
||||||
: base("Path is already configured for another series")
|
|
||||||
{
|
{
|
||||||
_seriesService = seriesService;
|
_seriesService = seriesService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Path is already configured for another series";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -9,11 +9,12 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
private readonly IAppFolderInfo _appFolderInfo;
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
|
|
||||||
public StartupFolderValidator(IAppFolderInfo appFolderInfo)
|
public StartupFolderValidator(IAppFolderInfo appFolderInfo)
|
||||||
: base("Path cannot be {relationship} the start up folder")
|
|
||||||
{
|
{
|
||||||
_appFolderInfo = appFolderInfo;
|
_appFolderInfo = appFolderInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Path cannot be {relationship} the start up folder";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -6,10 +6,7 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
{
|
{
|
||||||
public class SystemFolderValidator : PropertyValidator
|
public class SystemFolderValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public SystemFolderValidator()
|
protected override string GetDefaultMessageTemplate() => "Is {relationship} system folder {systemFolder}";
|
||||||
: base("Is {relationship} system folder {systemFolder}")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,11 +8,12 @@ namespace NzbDrone.Core.Validation
|
||||||
private readonly IQualityProfileService _qualityProfileService;
|
private readonly IQualityProfileService _qualityProfileService;
|
||||||
|
|
||||||
public ProfileExistsValidator(IQualityProfileService qualityProfileService)
|
public ProfileExistsValidator(IQualityProfileService qualityProfileService)
|
||||||
: base("QualityProfile does not exist")
|
|
||||||
{
|
{
|
||||||
_qualityProfileService = qualityProfileService;
|
_qualityProfileService = qualityProfileService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "QualityProfile does not exist";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
|
|
@ -14,10 +14,7 @@ namespace NzbDrone.Core.Validation
|
||||||
|
|
||||||
public class UrlValidator : PropertyValidator
|
public class UrlValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public UrlValidator()
|
protected override string GetDefaultMessageTemplate() => "Invalid Url";
|
||||||
: base("Invalid Url")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentAssertions" Version="6.10.0" />
|
<PackageReference Include="FluentAssertions" Version="6.10.0" />
|
||||||
<PackageReference Include="FluentValidation" Version="8.6.2" />
|
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
||||||
<PackageReference Include="Moq" Version="4.18.4" />
|
<PackageReference Include="Moq" Version="4.18.4" />
|
||||||
<PackageReference Include="NLog" Version="4.7.14" />
|
<PackageReference Include="NLog" Version="4.7.14" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Sonarr.Api.V3.Config
|
||||||
SharedValidator.RuleFor(c => c.SslPort).NotEqual(c => c.Port).When(c => c.EnableSsl);
|
SharedValidator.RuleFor(c => c.SslPort).NotEqual(c => c.Port).When(c => c.EnableSsl);
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.SslCertPath)
|
SharedValidator.RuleFor(c => c.SslCertPath)
|
||||||
.Cascade(CascadeMode.StopOnFirstFailure)
|
.Cascade(CascadeMode.Stop)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(fileExistsValidator)
|
.SetValidator(fileExistsValidator)
|
||||||
|
|
|
@ -15,10 +15,7 @@ namespace Sonarr.Api.V3.Profiles.Quality
|
||||||
|
|
||||||
public class ValidCutoffValidator<T> : PropertyValidator
|
public class ValidCutoffValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public ValidCutoffValidator()
|
protected override string GetDefaultMessageTemplate() => "Cutoff must be an allowed quality or group";
|
||||||
: base("Cutoff must be an allowed quality or group")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
|
@ -26,19 +23,9 @@ namespace Sonarr.Api.V3.Profiles.Quality
|
||||||
dynamic instance = context.ParentContext.InstanceToValidate;
|
dynamic instance = context.ParentContext.InstanceToValidate;
|
||||||
var items = instance.Items as IList<QualityProfileQualityItemResource>;
|
var items = instance.Items as IList<QualityProfileQualityItemResource>;
|
||||||
|
|
||||||
var cutoffItem = items.SingleOrDefault(i => (i.Quality == null && i.Id == cutoff) || i.Quality?.Id == cutoff);
|
var cutoffItem = items?.SingleOrDefault(i => (i.Quality == null && i.Id == cutoff) || i.Quality?.Id == cutoff);
|
||||||
|
|
||||||
if (cutoffItem == null)
|
return cutoffItem is { Allowed: true };
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cutoffItem.Allowed)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,139 +23,104 @@ namespace Sonarr.Api.V3.Profiles.Quality
|
||||||
|
|
||||||
public class AllowedValidator<T> : PropertyValidator
|
public class AllowedValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public AllowedValidator()
|
protected override string GetDefaultMessageTemplate() => "Must contain at least one allowed quality";
|
||||||
: base("Must contain at least one allowed quality")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var list = context.PropertyValue as IList<QualityProfileQualityItemResource>;
|
return context.PropertyValue is IList<QualityProfileQualityItemResource> list &&
|
||||||
|
list.Any(c => c.Allowed);
|
||||||
if (list == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!list.Any(c => c.Allowed))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GroupItemValidator<T> : PropertyValidator
|
public class GroupItemValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public GroupItemValidator()
|
protected override string GetDefaultMessageTemplate() => "Groups must contain multiple qualities";
|
||||||
: base("Groups must contain multiple qualities")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var items = context.PropertyValue as IList<QualityProfileQualityItemResource>;
|
if (context.PropertyValue is not IList<QualityProfileQualityItemResource> items)
|
||||||
|
|
||||||
if (items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Items.Count <= 1))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return !items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Items.Count <= 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class QualityNameValidator<T> : PropertyValidator
|
public class QualityNameValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public QualityNameValidator()
|
protected override string GetDefaultMessageTemplate() => "Individual qualities should not be named";
|
||||||
: base("Individual qualities should not be named")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var items = context.PropertyValue as IList<QualityProfileQualityItemResource>;
|
if (context.PropertyValue is not IList<QualityProfileQualityItemResource> items)
|
||||||
|
|
||||||
if (items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Quality != null))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return !items.Any(i => i.Name.IsNotNullOrWhiteSpace() && i.Quality != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ItemGroupNameValidator<T> : PropertyValidator
|
public class ItemGroupNameValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public ItemGroupNameValidator()
|
protected override string GetDefaultMessageTemplate() => "Groups must have a name";
|
||||||
: base("Groups must have a name")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var items = context.PropertyValue as IList<QualityProfileQualityItemResource>;
|
if (context.PropertyValue is not IList<QualityProfileQualityItemResource> items)
|
||||||
|
|
||||||
if (items.Any(i => i.Quality == null && i.Name.IsNullOrWhiteSpace()))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return !items.Any(i => i.Quality == null && i.Name.IsNullOrWhiteSpace());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ItemGroupIdValidator<T> : PropertyValidator
|
public class ItemGroupIdValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public ItemGroupIdValidator()
|
protected override string GetDefaultMessageTemplate() => "Groups must have an ID";
|
||||||
: base("Groups must have an ID")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var items = context.PropertyValue as IList<QualityProfileQualityItemResource>;
|
if (context.PropertyValue is not IList<QualityProfileQualityItemResource> items)
|
||||||
|
|
||||||
if (items.Any(i => i.Quality == null && i.Id == 0))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return !items.Any(i => i.Quality == null && i.Id == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UniqueIdValidator<T> : PropertyValidator
|
public class UniqueIdValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public UniqueIdValidator()
|
protected override string GetDefaultMessageTemplate() => "Groups must have a unique ID";
|
||||||
: base("Groups must have a unique ID")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var items = context.PropertyValue as IList<QualityProfileQualityItemResource>;
|
if (context.PropertyValue is not IList<QualityProfileQualityItemResource> items)
|
||||||
|
|
||||||
if (items.Where(i => i.Id > 0).Select(i => i.Id).GroupBy(i => i).Any(g => g.Count() > 1))
|
|
||||||
{
|
{
|
||||||
return false;
|
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<T> : PropertyValidator
|
public class UniqueQualityIdValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public UniqueQualityIdValidator()
|
protected override string GetDefaultMessageTemplate() => "Qualities can only be used once";
|
||||||
: base("Qualities can only be used once")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
var items = context.PropertyValue as IList<QualityProfileQualityItemResource>;
|
if (context.PropertyValue is not IList<QualityProfileQualityItemResource> items)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var qualityIds = new HashSet<int>();
|
var qualityIds = new HashSet<int>();
|
||||||
|
|
||||||
foreach (var item in items)
|
foreach (var item in items)
|
||||||
|
|
|
@ -28,8 +28,8 @@ namespace Sonarr.Api.V3.RemotePathMappings
|
||||||
.NotEmpty();
|
.NotEmpty();
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.LocalPath)
|
SharedValidator.RuleFor(c => c.LocalPath)
|
||||||
.Cascade(CascadeMode.StopOnFirstFailure)
|
.Cascade(CascadeMode.Stop)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(mappedNetworkDriveValidator)
|
.SetValidator(mappedNetworkDriveValidator)
|
||||||
.SetValidator(pathExistsValidator);
|
.SetValidator(pathExistsValidator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ namespace Sonarr.Api.V3.RootFolders
|
||||||
_rootFolderService = rootFolderService;
|
_rootFolderService = rootFolderService;
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Path)
|
SharedValidator.RuleFor(c => c.Path)
|
||||||
.Cascade(CascadeMode.StopOnFirstFailure)
|
.Cascade(CascadeMode.Stop)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(rootFolderValidator)
|
.SetValidator(rootFolderValidator)
|
||||||
.SetValidator(mappedNetworkDriveValidator)
|
.SetValidator(mappedNetworkDriveValidator)
|
||||||
.SetValidator(startupFolderValidator)
|
.SetValidator(startupFolderValidator)
|
||||||
|
|
|
@ -73,8 +73,8 @@ namespace Sonarr.Api.V3.Series
|
||||||
Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.QualityProfileId));
|
Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.QualityProfileId));
|
||||||
|
|
||||||
SharedValidator.RuleFor(s => s.Path)
|
SharedValidator.RuleFor(s => s.Path)
|
||||||
.Cascade(CascadeMode.StopOnFirstFailure)
|
.Cascade(CascadeMode.Stop)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(rootFolderValidator)
|
.SetValidator(rootFolderValidator)
|
||||||
.SetValidator(mappedNetworkDriveValidator)
|
.SetValidator(mappedNetworkDriveValidator)
|
||||||
.SetValidator(seriesPathValidator)
|
.SetValidator(seriesPathValidator)
|
||||||
|
|
|
@ -11,11 +11,12 @@ namespace Sonarr.Api.V3.Series
|
||||||
private readonly IBuildFileNames _fileNameBuilder;
|
private readonly IBuildFileNames _fileNameBuilder;
|
||||||
|
|
||||||
public SeriesFolderAsRootFolderValidator(IBuildFileNames fileNameBuilder)
|
public SeriesFolderAsRootFolderValidator(IBuildFileNames fileNameBuilder)
|
||||||
: base("Root folder path contains series folder")
|
|
||||||
{
|
{
|
||||||
_fileNameBuilder = fileNameBuilder;
|
_fileNameBuilder = fileNameBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override string GetDefaultMessageTemplate() => "Root folder path contains series folder";
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null)
|
if (context.PropertyValue == null)
|
||||||
|
@ -23,7 +24,7 @@ namespace Sonarr.Api.V3.Series
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var seriesResource = context.Instance as SeriesResource;
|
var seriesResource = context.InstanceToValidate as SeriesResource;
|
||||||
|
|
||||||
if (seriesResource == null)
|
if (seriesResource == null)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,7 @@ namespace Sonarr.Api.V3.Series
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rootFolder = new DirectoryInfo(rootFolderPath).Name;
|
var rootFolder = new DirectoryInfo(rootFolderPath!).Name;
|
||||||
var series = seriesResource.ToModel();
|
var series = seriesResource.ToModel();
|
||||||
var seriesFolder = _fileNameBuilder.GetSeriesFolder(series);
|
var seriesFolder = _fileNameBuilder.GetSeriesFolder(series);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentValidation" Version="8.6.2" />
|
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
||||||
<PackageReference Include="Ical.Net" Version="4.2.0" />
|
<PackageReference Include="Ical.Net" Version="4.2.0" />
|
||||||
<PackageReference Include="NLog" Version="4.7.14" />
|
<PackageReference Include="NLog" Version="4.7.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -4,7 +4,6 @@ using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using FluentValidation.Internal;
|
using FluentValidation.Internal;
|
||||||
using FluentValidation.Resources;
|
|
||||||
using Sonarr.Http.ClientSchema;
|
using Sonarr.Http.ClientSchema;
|
||||||
|
|
||||||
namespace Sonarr.Http.REST
|
namespace Sonarr.Http.REST
|
||||||
|
@ -15,7 +14,7 @@ namespace Sonarr.Http.REST
|
||||||
{
|
{
|
||||||
var rule = new PropertyRule(fieldListAccessor.GetMember(), c => GetValue(c, fieldListAccessor.Compile(), fieldName), null, () => CascadeMode.Continue, typeof(TProperty), typeof(TResource));
|
var rule = new PropertyRule(fieldListAccessor.GetMember(), c => GetValue(c, fieldListAccessor.Compile(), fieldName), null, () => CascadeMode.Continue, typeof(TProperty), typeof(TResource));
|
||||||
rule.PropertyName = fieldName;
|
rule.PropertyName = fieldName;
|
||||||
rule.DisplayName = new StaticStringSource(fieldName);
|
rule.SetDisplayName(fieldName);
|
||||||
|
|
||||||
AddRule(rule);
|
AddRule(rule);
|
||||||
return new RuleBuilder<TResource, TProperty>(rule, this);
|
return new RuleBuilder<TResource, TProperty>(rule, this);
|
||||||
|
@ -25,12 +24,7 @@ namespace Sonarr.Http.REST
|
||||||
{
|
{
|
||||||
var resource = fieldListAccessor((TResource)container).SingleOrDefault(c => c.Name == fieldName);
|
var resource = fieldListAccessor((TResource)container).SingleOrDefault(c => c.Name == fieldName);
|
||||||
|
|
||||||
if (resource == null)
|
return resource?.Value;
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.Value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<TargetFrameworks>net6.0</TargetFrameworks>
|
<TargetFrameworks>net6.0</TargetFrameworks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentValidation" Version="8.6.2" />
|
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
||||||
<PackageReference Include="ImpromptuInterface" Version="7.0.1" />
|
<PackageReference Include="ImpromptuInterface" Version="7.0.1" />
|
||||||
<PackageReference Include="NLog" Version="4.7.14" />
|
<PackageReference Include="NLog" Version="4.7.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -6,10 +6,7 @@ namespace Sonarr.Http.Validation
|
||||||
{
|
{
|
||||||
public class EmptyCollectionValidator<T> : PropertyValidator
|
public class EmptyCollectionValidator<T> : PropertyValidator
|
||||||
{
|
{
|
||||||
public EmptyCollectionValidator()
|
protected override string GetDefaultMessageTemplate() => "Collection Must Be Empty";
|
||||||
: base("Collection Must Be Empty")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,10 +4,7 @@ namespace Sonarr.Http.Validation
|
||||||
{
|
{
|
||||||
public class RssSyncIntervalValidator : PropertyValidator
|
public class RssSyncIntervalValidator : PropertyValidator
|
||||||
{
|
{
|
||||||
public RssSyncIntervalValidator()
|
protected override string GetDefaultMessageTemplate() => "Must be between 10 and 120 or 0 to disable";
|
||||||
: base("Must be between 10 and 120 or 0 to disable")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool IsValid(PropertyValidatorContext context)
|
protected override bool IsValid(PropertyValidatorContext context)
|
||||||
{
|
{
|
||||||
|
@ -23,12 +20,7 @@ namespace Sonarr.Http.Validation
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value >= 10 && value <= 120)
|
return value is >= 10 and <= 120;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sonarr/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sonarr/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=tvdb/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
Loading…
Reference in New Issue