From 593b943cb09104f79408f094a285ffed33a12086 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 2 Sep 2024 13:26:35 -0700 Subject: [PATCH] New: Except language option for Language Custom Formats (cherry picked from commit 1584311914eed697fdd0f143951f4adfe3403351) Closes #10388 --- .../MultiLanguageFixture.cs | 30 +++++++++++++++++++ .../SingleLanguageFixture.cs | 10 +++++++ .../Specifications/LanguageSpecification.cs | 15 +++++++++- src/NzbDrone.Core/Localization/Core/en.json | 2 ++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs index dd2e3757f..afba2281b 100644 --- a/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs +++ b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/MultiLanguageFixture.cs @@ -42,6 +42,26 @@ namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification Subject.IsSatisfiedBy(_input).Should().BeTrue(); } + [Test] + public void should_match_language_if_other_languages_are_present() + { + Subject.Value = Language.French.Id; + Subject.ExceptLanguage = true; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + + [Test] + public void should_match_language_if_not_original_language_is_present() + { + Subject.Value = Language.Original.Id; + Subject.ExceptLanguage = true; + Subject.Negate = false; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } + [Test] public void should_not_match_different_language() { @@ -68,5 +88,15 @@ namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification Subject.IsSatisfiedBy(_input).Should().BeTrue(); } + + [Test] + public void should_not_match_negate_language_if_other_languages_are_present() + { + Subject.Value = Language.Spanish.Id; + Subject.ExceptLanguage = true; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeFalse(); + } } } diff --git a/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs index 4c7783716..eea793c82 100644 --- a/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs +++ b/src/NzbDrone.Core.Test/CustomFormats/Specifications/LanguageSpecification/SingleLanguageFixture.cs @@ -67,5 +67,15 @@ namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification Subject.IsSatisfiedBy(_input).Should().BeTrue(); } + + [Test] + public void should_match_negated_except_language_if_language_is_only_present_language() + { + Subject.Value = Language.French.Id; + Subject.ExceptLanguage = true; + Subject.Negate = true; + + Subject.IsSatisfiedBy(_input).Should().BeTrue(); + } } } diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs index bc42661b5..516c8196c 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs @@ -30,6 +30,9 @@ namespace NzbDrone.Core.CustomFormats [FieldDefinition(1, Label = "Language", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))] public int Value { get; set; } + [FieldDefinition(1, Label = "CustomFormatsSpecificationExceptLanguage", HelpText = "CustomFormatsSpecificationExceptLanguageHelpText", Type = FieldType.Checkbox)] + public bool ExceptLanguage { get; set; } + public override bool IsSatisfiedBy(CustomFormatInput input) { if (Negate) @@ -46,7 +49,12 @@ namespace NzbDrone.Core.CustomFormats ? input.Movie.MovieMetadata.Value.OriginalLanguage : (Language)Value; - return input?.Languages?.Contains(comparedLanguage) ?? false; + if (ExceptLanguage) + { + return input.Languages?.Any(l => l != comparedLanguage) ?? false; + } + + return input.Languages?.Contains(comparedLanguage) ?? false; } private bool IsSatisfiedByWithNegate(CustomFormatInput input) @@ -55,6 +63,11 @@ namespace NzbDrone.Core.CustomFormats ? input.Movie.MovieMetadata.Value.OriginalLanguage : (Language)Value; + if (ExceptLanguage) + { + return !input.Languages?.Any(l => l != comparedLanguage) ?? false; + } + return !input.Languages?.Contains(comparedLanguage) ?? false; } diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 7b68840d6..3ad1dfdab 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -264,6 +264,8 @@ "CustomFormatsSettings": "Custom Formats Settings", "CustomFormatsSettingsSummary": "Custom Formats and Settings", "CustomFormatsSettingsTriggerInfo": "A Custom Format will be applied to a release or file when it matches at least one of each of the different condition types chosen.", + "CustomFormatsSpecificationExceptLanguage": "Except Language", + "CustomFormatsSpecificationExceptLanguageHelpText": "Matches if any language other than the selected language is present", "CustomFormatsSpecificationFlag": "Flag", "CustomFormatsSpecificationRegularExpression": "Regular Expression", "CustomFormatsSpecificationRegularExpressionHelpText": "Custom Format RegEx is Case Insensitive",