diff --git a/src/NzbDrone.Core/Organizer/FileNameValidation.cs b/src/NzbDrone.Core/Organizer/FileNameValidation.cs index 0352e7ba7..b7682407b 100644 --- a/src/NzbDrone.Core/Organizer/FileNameValidation.cs +++ b/src/NzbDrone.Core/Organizer/FileNameValidation.cs @@ -1,5 +1,8 @@ +using System.IO; +using System.Linq; using FluentValidation; using FluentValidation.Validators; +using NzbDrone.Common.Extensions; namespace NzbDrone.Core.Organizer { @@ -8,13 +11,42 @@ public static class FileNameValidation public static IRuleBuilderOptions ValidMovieFolderFormat(this IRuleBuilder ruleBuilder) { ruleBuilder.SetValidator(new NotEmptyValidator(null)); + ruleBuilder.SetValidator(new IllegalCharactersValidator()); + return ruleBuilder.SetValidator(new RegularExpressionValidator(FileNameBuilder.MovieTitleRegex)).WithMessage("Must contain movie title"); } public static IRuleBuilderOptions ValidMovieFormat(this IRuleBuilder ruleBuilder) { ruleBuilder.SetValidator(new NotEmptyValidator(null)); + ruleBuilder.SetValidator(new IllegalCharactersValidator()); + return ruleBuilder.SetValidator(new RegularExpressionValidator(FileNameBuilder.MovieTitleRegex)).WithMessage("Must contain movie title"); } } + + public class IllegalCharactersValidator : PropertyValidator + { + private static readonly char[] InvalidPathChars = Path.GetInvalidPathChars(); + + protected override string GetDefaultMessageTemplate() => "Contains illegal characters: {InvalidCharacters}"; + + protected override bool IsValid(PropertyValidatorContext context) + { + var value = context.PropertyValue as string; + if (value.IsNullOrWhiteSpace()) + { + return true; + } + + var invalidCharacters = InvalidPathChars.Where(i => value!.IndexOf(i) >= 0).ToList(); + if (invalidCharacters.Any()) + { + context.MessageFormatter.AppendArgument("InvalidCharacters", string.Join("", invalidCharacters)); + return false; + } + + return true; + } + } }