From 06b86d4fad7b6f16d80a4abd122d36edb3ff8be7 Mon Sep 17 00:00:00 2001 From: Gabriel Patzleiner Date: Fri, 12 Jan 2024 01:32:40 +0100 Subject: [PATCH] New: Parse German Dual Language and Multi-language releases --- .../ParserTests/LanguageParserFixture.cs | 32 ++++++++++++++++ src/NzbDrone.Core/Parser/LanguageParser.cs | 38 ++++++++++++++----- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 4687778cb..3d1916b64 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -385,5 +385,37 @@ namespace NzbDrone.Core.Test.ParserTests var result = LanguageParser.ParseLanguages(postTitle); result.Should().BeEquivalentTo(new[] { Language.English, Language.Spanish, Language.Catalan }); } + + [TestCase("Series.Title.S01E01.German.DL.1080p.BluRay.x264-RlsGrp")] + [TestCase("Series.Title.S01E01.GERMAN.DL.1080P.WEB.H264-RlsGrp")] + [TestCase("Series.Title.2023.S01E01.German.DL.EAC3.1080p.DSNP.WEB.H264-RlsGrp")] + public void should_add_original_language_to_german_release_with_dl_tag(string postTitle) + { + var result = Parser.Parser.ParseTitle(postTitle); + result.Languages.Count.Should().Be(2); + result.Languages.Should().Contain(Language.German); + result.Languages.Should().Contain(Language.Original); + } + + [TestCase("Series.Title.2023.S01E01.GERMAN.1080P.WEB-DL.H264-RlsGrp")] + [TestCase("Series.Title.2023.S01E01.GERMAN.1080P.WEB.DL.H264-RlsGrp")] + [TestCase("Series Title 2023 S01E01 GERMAN 1080P WEB DL H264-RlsGrp")] + [TestCase("Series.Title.2023.S01E01.GERMAN.1080P.WEBDL.H264-RlsGrp")] + public void should_not_add_original_language_to_german_release_when_title_contains_web_dl(string postTitle) + { + var result = Parser.Parser.ParseTitle(postTitle); + result.Languages.Count.Should().Be(1); + result.Languages.Should().Contain(Language.German); + } + + [TestCase("Series.Title.2023.S01.German.ML.EAC3.1080p.NF.WEB.H264-RlsGrp")] + public void should_add_original_language_and_english_to_german_release_with_ml_tag(string postTitle) + { + var result = Parser.Parser.ParseTitle(postTitle); + result.Languages.Count.Should().Be(3); + result.Languages.Should().Contain(Language.German); + result.Languages.Should().Contain(Language.Original); + result.Languages.Should().Contain(Language.English); + } } } diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index e9390a766..00d92d5da 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -25,6 +25,9 @@ namespace NzbDrone.Core.Parser private static readonly Regex CaseSensitiveLanguageRegex = new Regex(@"(?:(?i)(?\bLT\b)|(?\bCZ\b)|(?\bPL\b)|(?\bBG\b)|(?\bSK\b))(?:(?i)(?![\W|_|^]SUB))", RegexOptions.Compiled); + private static readonly Regex GermanDualLanguageRegex = new (@"(?[a-z]{2,3})([-_. ](?full|forced|foreign|default|cc|psdh|sdh))*$", RegexOptions.Compiled | RegexOptions.IgnoreCase); public static List ParseLanguages(string title) @@ -188,6 +191,21 @@ namespace NzbDrone.Core.Parser languages.Add(Language.Unknown); } + if (languages.Count == 1 && languages.Single() == Language.German) + { + if (GermanDualLanguageRegex.IsMatch(title)) + { + Logger.Trace("Adding original language because the release title contains German DL tag"); + languages.Add(Language.Original); + } + else if (GermanMultiLanguageRegex.IsMatch(title)) + { + Logger.Trace("Adding original language and English because the release title contains German ML tag"); + languages.Add(Language.Original); + languages.Add(Language.English); + } + } + return languages.DistinctBy(l => (int)l).ToList(); } @@ -232,7 +250,7 @@ namespace NzbDrone.Core.Parser { var simpleFilename = Path.GetFileNameWithoutExtension(fileName); var match = SubtitleLanguageRegex.Match(simpleFilename); - var languageTags = match.Groups["tags"].Captures.Cast() + var languageTags = match.Groups["tags"].Captures .Where(tag => !tag.Value.Empty()) .Select(tag => tag.Value.ToLower()); return languageTags.ToList(); @@ -252,27 +270,27 @@ namespace NzbDrone.Core.Parser // Case sensitive var caseSensitiveMatch = CaseSensitiveLanguageRegex.Match(title); - if (caseSensitiveMatch.Groups["lithuanian"].Captures.Cast().Any()) + if (caseSensitiveMatch.Groups["lithuanian"].Captures.Any()) { languages.Add(Language.Lithuanian); } - if (caseSensitiveMatch.Groups["czech"].Captures.Cast().Any()) + if (caseSensitiveMatch.Groups["czech"].Captures.Any()) { languages.Add(Language.Czech); } - if (caseSensitiveMatch.Groups["polish"].Captures.Cast().Any()) + if (caseSensitiveMatch.Groups["polish"].Captures.Any()) { languages.Add(Language.Polish); } - if (caseSensitiveMatch.Groups["bulgarian"].Captures.Cast().Any()) + if (caseSensitiveMatch.Groups["bulgarian"].Captures.Any()) { languages.Add(Language.Bulgarian); } - if (caseSensitiveMatch.Groups["slovak"].Captures.Cast().Any()) + if (caseSensitiveMatch.Groups["slovak"].Captures.Any()) { languages.Add(Language.Slovak); } @@ -287,22 +305,22 @@ namespace NzbDrone.Core.Parser languages.Add(Language.English); } - if (match.Groups["italian"].Captures.Cast().Any()) + if (match.Groups["italian"].Captures.Any()) { languages.Add(Language.Italian); } - if (match.Groups["german"].Captures.Cast().Any()) + if (match.Groups["german"].Captures.Any()) { languages.Add(Language.German); } - if (match.Groups["flemish"].Captures.Cast().Any()) + if (match.Groups["flemish"].Captures.Any()) { languages.Add(Language.Flemish); } - if (match.Groups["greek"].Captures.Cast().Any()) + if (match.Groups["greek"].Captures.Any()) { languages.Add(Language.Greek); }