diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index f2be2a3e4b..cce5acb15d 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -430,5 +430,35 @@ public void should_parse_subtitle_language_unknown(string fileName) var result = LanguageParser.ParseSubtitleLanguage(fileName); result.Should().Be(Language.Unknown); } + + [TestCase("The.Movie.Name.2016.German.DTS.DL.720p.BluRay.x264-RlsGrp")] + public void should_add_original_language_to_german_release_with_dl_tag(string postTitle) + { + var result = Parser.Parser.ParseMovieTitle(postTitle); + result.Languages.Count.Should().Be(2); + result.Languages.Should().Contain(Language.German); + result.Languages.Should().Contain(Language.Original); + } + + [TestCase("The.Movie.Name.2016.GERMAN.WEB-DL.h264-RlsGrp")] + [TestCase("The.Movie.Name.2016.GERMAN.WEB.DL.h264-RlsGrp")] + [TestCase("The Movie Name 2016 GERMAN WEB DL h264-RlsGrp")] + [TestCase("The.Movie.Name.2016.GERMAN.WEBDL.h264-RlsGrp")] + public void should_not_add_original_language_to_german_release_when_title_contains_web_dl(string postTitle) + { + var result = Parser.Parser.ParseMovieTitle(postTitle); + result.Languages.Count.Should().Be(1); + result.Languages.Should().Contain(Language.German); + } + + [TestCase("The.Movie.Name.2023.German.ML.EAC3.720p.NF.WEB.H264-RlsGrp")] + public void should_add_original_language_and_english_to_german_release_with_ml_tag(string postTitle) + { + var result = Parser.Parser.ParseMovieTitle(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 942f27df48..b53017abe1 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -42,6 +42,9 @@ public static class LanguageParser (?\bSK\b)", RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); + 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) @@ -220,31 +223,31 @@ public static List ParseLanguages(string title) } // Case sensitive - var caseSensitiveMatchs = CaseSensitiveLanguageRegex.Matches(title); + var caseSensitiveMatches = CaseSensitiveLanguageRegex.Matches(title); - foreach (Match match in caseSensitiveMatchs) + foreach (Match match in caseSensitiveMatches) { - if (match.Groups["lithuanian"].Captures.Cast().Any()) + if (match.Groups["lithuanian"].Captures.Any()) { languages.Add(Language.Lithuanian); } - if (match.Groups["czech"].Captures.Cast().Any()) + if (match.Groups["czech"].Captures.Any()) { languages.Add(Language.Czech); } - if (match.Groups["polish"].Captures.Cast().Any()) + if (match.Groups["polish"].Captures.Any()) { languages.Add(Language.Polish); } - if (match.Groups["bulgarian"].Captures.Cast().Any()) + if (match.Groups["bulgarian"].Captures.Any()) { languages.Add(Language.Bulgarian); } - if (match.Groups["slovak"].Captures.Cast().Any()) + if (match.Groups["slovak"].Captures.Any()) { languages.Add(Language.Slovak); } @@ -254,22 +257,22 @@ public static List ParseLanguages(string title) foreach (Match match in matches) { - 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); } @@ -360,6 +363,21 @@ public static List ParseLanguages(string title) 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(); } @@ -369,7 +387,7 @@ public static List ParseLanguageTags(string fileName) { 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();