mirror of
https://github.com/Radarr/Radarr
synced 2025-12-09 09:56:04 +01:00
parent
098a893083
commit
16ed68d5de
10 changed files with 183 additions and 1 deletions
|
|
@ -1,4 +1,5 @@
|
|||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
|
|
@ -18,6 +19,8 @@ public ICustomFormatSpecification Clone()
|
|||
return (ICustomFormatSpecification)MemberwiseClone();
|
||||
}
|
||||
|
||||
public abstract NzbDroneValidationResult Validate();
|
||||
|
||||
public bool IsSatisfiedBy(ParsedMovieInfo movieInfo)
|
||||
{
|
||||
var match = IsSatisfiedByWithoutNegate(movieInfo);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
|
|
@ -11,6 +12,8 @@ public interface ICustomFormatSpecification
|
|||
bool Negate { get; set; }
|
||||
bool Required { get; set; }
|
||||
|
||||
NzbDroneValidationResult Validate();
|
||||
|
||||
ICustomFormatSpecification Clone();
|
||||
bool IsSatisfiedBy(ParsedMovieInfo movieInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class IndexerFlagSpecificationValidator : AbstractValidator<IndexerFlagSpecification>
|
||||
{
|
||||
public IndexerFlagSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty();
|
||||
RuleFor(c => c.Value).Custom((qualityValue, context) =>
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(IndexerFlags), qualityValue))
|
||||
{
|
||||
context.AddFailure(string.Format("Invalid indexer flag condition value: {0}", qualityValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class IndexerFlagSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly IndexerFlagSpecificationValidator Validator = new IndexerFlagSpecificationValidator();
|
||||
|
||||
public override int Order => 4;
|
||||
public override string ImplementationName => "Indexer Flag";
|
||||
|
||||
|
|
@ -17,5 +37,10 @@ protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
|||
var flags = movieInfo?.ExtraInfo?.GetValueOrDefault("IndexerFlags") as IndexerFlags?;
|
||||
return flags?.HasFlag((IndexerFlags)Value) == true;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,31 @@
|
|||
using System.Linq;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class LanguageSpecificationValidator : AbstractValidator<LanguageSpecification>
|
||||
{
|
||||
public LanguageSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty();
|
||||
RuleFor(c => c.Value).Custom((value, context) =>
|
||||
{
|
||||
if (!Language.All.Any(o => o.Id == value))
|
||||
{
|
||||
context.AddFailure(string.Format("Invalid Language condition value: {0}", value));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class LanguageSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly LanguageSpecificationValidator Validator = new LanguageSpecificationValidator();
|
||||
|
||||
public override int Order => 3;
|
||||
public override string ImplementationName => "Language";
|
||||
|
||||
|
|
@ -19,5 +39,10 @@ protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
|||
: (Language)Value;
|
||||
return movieInfo?.Languages?.Contains(comparedLanguage) ?? false;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,31 @@
|
|||
using System;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class QualityModifierSpecificationValidator : AbstractValidator<QualityModifierSpecification>
|
||||
{
|
||||
public QualityModifierSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty();
|
||||
RuleFor(c => c.Value).Custom((qualityValue, context) =>
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(Modifier), qualityValue))
|
||||
{
|
||||
context.AddFailure(string.Format("Invalid quality modifier condition value: {0}", qualityValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class QualityModifierSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly QualityModifierSpecificationValidator Validator = new QualityModifierSpecificationValidator();
|
||||
|
||||
public override int Order => 7;
|
||||
public override string ImplementationName => "Quality Modifier";
|
||||
|
||||
|
|
@ -16,5 +36,10 @@ protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
|||
{
|
||||
return (movieInfo?.Quality?.Quality?.Modifier ?? (int)Modifier.NONE) == (Modifier)Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,23 @@
|
|||
using System.Text.RegularExpressions;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class RegexSpecificationBaseValidator : AbstractValidator<RegexSpecificationBase>
|
||||
{
|
||||
public RegexSpecificationBaseValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty().WithMessage("Regex Pattern must not be empty");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class RegexSpecificationBase : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly RegexSpecificationBaseValidator Validator = new RegexSpecificationBaseValidator();
|
||||
|
||||
protected Regex _regex;
|
||||
protected string _raw;
|
||||
|
||||
|
|
@ -15,7 +28,11 @@ public string Value
|
|||
set
|
||||
{
|
||||
_raw = value;
|
||||
_regex = new Regex(value, RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
if (value.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_regex = new Regex(value, RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -28,5 +45,10 @@ protected bool MatchString(string compared)
|
|||
|
||||
return _regex.IsMatch(compared);
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,23 @@
|
|||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class ResolutionSpecificationValidator : AbstractValidator<ResolutionSpecification>
|
||||
{
|
||||
public ResolutionSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public class ResolutionSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly ResolutionSpecificationValidator Validator = new ResolutionSpecificationValidator();
|
||||
|
||||
public override int Order => 6;
|
||||
public override string ImplementationName => "Resolution";
|
||||
|
||||
|
|
@ -16,5 +28,10 @@ protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
|||
{
|
||||
return (movieInfo?.Quality?.Quality?.Resolution ?? (int)Resolution.Unknown) == Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,24 @@
|
|||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class SizeSpecificationValidator : AbstractValidator<SizeSpecification>
|
||||
{
|
||||
public SizeSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Min).GreaterThan(0);
|
||||
RuleFor(c => c.Max).GreaterThan(c => c.Min);
|
||||
}
|
||||
}
|
||||
|
||||
public class SizeSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly SizeSpecificationValidator Validator = new SizeSpecificationValidator();
|
||||
|
||||
public override int Order => 8;
|
||||
public override string ImplementationName => "Size";
|
||||
|
||||
|
|
@ -21,5 +34,10 @@ protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
|||
|
||||
return size > Min.Gigabytes() && size <= Max.Gigabytes();
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,23 @@
|
|||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public class SourceSpecificationValidator : AbstractValidator<SourceSpecification>
|
||||
{
|
||||
public SourceSpecificationValidator()
|
||||
{
|
||||
RuleFor(c => c.Value).NotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public class SourceSpecification : CustomFormatSpecificationBase
|
||||
{
|
||||
private static readonly SourceSpecificationValidator Validator = new SourceSpecificationValidator();
|
||||
|
||||
public override int Order => 5;
|
||||
public override string ImplementationName => "Source";
|
||||
|
||||
|
|
@ -16,5 +28,10 @@ protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
|||
{
|
||||
return (movieInfo?.Quality?.Quality?.Source ?? (int)Source.UNKNOWN) == (Source)Value;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.Validation;
|
||||
using Radarr.Http;
|
||||
using Radarr.Http.REST;
|
||||
using Radarr.Http.REST.Attributes;
|
||||
|
|
@ -50,6 +52,9 @@ protected override CustomFormatResource GetResourceById(int id)
|
|||
public ActionResult<CustomFormatResource> Create(CustomFormatResource customFormatResource)
|
||||
{
|
||||
var model = customFormatResource.ToModel(_specifications);
|
||||
|
||||
Validate(model);
|
||||
|
||||
return Created(_formatService.Insert(model).Id);
|
||||
}
|
||||
|
||||
|
|
@ -57,6 +62,9 @@ public ActionResult<CustomFormatResource> Create(CustomFormatResource customForm
|
|||
public ActionResult<CustomFormatResource> Update(CustomFormatResource resource)
|
||||
{
|
||||
var model = resource.ToModel(_specifications);
|
||||
|
||||
Validate(model);
|
||||
|
||||
_formatService.Update(model);
|
||||
|
||||
return Accepted(model.Id);
|
||||
|
|
@ -89,6 +97,25 @@ public object GetTemplates()
|
|||
return schema;
|
||||
}
|
||||
|
||||
private void Validate(CustomFormat definition)
|
||||
{
|
||||
foreach (var spec in definition.Specifications)
|
||||
{
|
||||
var validationResult = spec.Validate();
|
||||
VerifyValidationResult(validationResult);
|
||||
}
|
||||
}
|
||||
|
||||
protected void VerifyValidationResult(ValidationResult validationResult)
|
||||
{
|
||||
var result = new NzbDroneValidationResult(validationResult.Errors);
|
||||
|
||||
if (!result.IsValid)
|
||||
{
|
||||
throw new ValidationException(result.Errors);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<ICustomFormatSpecification> GetPresets()
|
||||
{
|
||||
yield return new ReleaseTitleSpecification
|
||||
|
|
|
|||
Loading…
Reference in a new issue