From fefc6f87bad6d8d51e52574306c5a4aaf67c5360 Mon Sep 17 00:00:00 2001 From: Elia Petrachi Date: Tue, 4 Feb 2025 23:27:51 +0100 Subject: [PATCH 1/6] add new parameter to ParsedMovieInfo in order to store any extra release title parameters --- src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs b/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs index fc649c607..671a73ac8 100644 --- a/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs @@ -16,6 +16,7 @@ namespace NzbDrone.Core.Parser.Model public string OriginalTitle { get; set; } public string ReleaseTitle { get; set; } public string SimpleReleaseTitle { get; set; } + public string TitleExtraParameters { get; set; } public QualityModel Quality { get; set; } public List Languages { get; set; } public string ReleaseGroup { get; set; } From 799fdef7703f56c6fac0751155ec6dccd0fd8d06 Mon Sep 17 00:00:00 2001 From: Elia Petrachi Date: Tue, 4 Feb 2025 23:40:05 +0100 Subject: [PATCH 2/6] fix if nesting --- src/NzbDrone.Core/Parser/Parser.cs | 132 +++++++++++++++-------------- 1 file changed, 68 insertions(+), 64 deletions(-) diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index e943feb6b..b681a8c9c 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -269,78 +269,82 @@ namespace NzbDrone.Core.Parser { var match = regex.Matches(simpleTitle); - if (match.Count != 0) + if (match.Count == 0) { - Logger.Trace(regex); - try + continue; + } + + Logger.Trace(regex); + try + { + var result = ParseMovieMatchCollection(match); + + if (result == null) { - var result = ParseMovieMatchCollection(match); + continue; + } + + // TODO: Add tests for this! + var simpleReleaseTitle = SimpleReleaseTitleRegex.Replace(releaseTitle, string.Empty); + + var simpleTitleReplaceString = match[0].Groups["title"].Success ? match[0].Groups["title"].Value : result.PrimaryMovieTitle; - if (result != null) + if (simpleTitleReplaceString.IsNotNullOrWhiteSpace()) + { + if (match[0].Groups["title"].Success) + { + simpleReleaseTitle = simpleReleaseTitle.Remove(match[0].Groups["title"].Index, match[0].Groups["title"].Length) + .Insert(match[0].Groups["title"].Index, simpleTitleReplaceString.Contains('.') ? "A.Movie" : "A Movie"); + } + else { - // TODO: Add tests for this! - var simpleReleaseTitle = SimpleReleaseTitleRegex.Replace(releaseTitle, string.Empty); - - var simpleTitleReplaceString = match[0].Groups["title"].Success ? match[0].Groups["title"].Value : result.PrimaryMovieTitle; - - if (simpleTitleReplaceString.IsNotNullOrWhiteSpace()) - { - if (match[0].Groups["title"].Success) - { - simpleReleaseTitle = simpleReleaseTitle.Remove(match[0].Groups["title"].Index, match[0].Groups["title"].Length) - .Insert(match[0].Groups["title"].Index, simpleTitleReplaceString.Contains('.') ? "A.Movie" : "A Movie"); - } - else - { - simpleReleaseTitle = simpleReleaseTitle.Replace(simpleTitleReplaceString, simpleTitleReplaceString.Contains('.') ? "A.Movie" : "A Movie"); - } - } - - result.ReleaseGroup = ParseReleaseGroup(simpleReleaseTitle); - - var subGroup = GetSubGroup(match); - if (!subGroup.IsNullOrWhiteSpace()) - { - result.ReleaseGroup = subGroup; - } - - result.HardcodedSubs = ParseHardcodeSubs(title); - - Logger.Debug("Release Group parsed: {0}", result.ReleaseGroup); - - result.Languages = LanguageParser.ParseLanguages(result.ReleaseGroup.IsNotNullOrWhiteSpace() ? simpleReleaseTitle.Replace(result.ReleaseGroup, "RlsGrp") : simpleReleaseTitle); - Logger.Debug("Languages parsed: {0}", string.Join(", ", result.Languages)); - - result.Quality = QualityParser.ParseQuality(title); - Logger.Debug("Quality parsed: {0}", result.Quality); - - if (result.Edition.IsNullOrWhiteSpace()) - { - result.Edition = ParseEdition(simpleReleaseTitle); - Logger.Debug("Edition parsed: {0}", result.Edition); - } - - result.ReleaseHash = GetReleaseHash(match); - if (!result.ReleaseHash.IsNullOrWhiteSpace()) - { - Logger.Debug("Release Hash parsed: {0}", result.ReleaseHash); - } - - result.OriginalTitle = originalTitle; - result.ReleaseTitle = releaseTitle; - result.SimpleReleaseTitle = simpleReleaseTitle; - - result.ImdbId = ParseImdbId(simpleReleaseTitle); - result.TmdbId = ParseTmdbId(simpleReleaseTitle); - - return result; + simpleReleaseTitle = simpleReleaseTitle.Replace(simpleTitleReplaceString, simpleTitleReplaceString.Contains('.') ? "A.Movie" : "A Movie"); } } - catch (InvalidDateException ex) + + result.ReleaseGroup = ParseReleaseGroup(simpleReleaseTitle); + + var subGroup = GetSubGroup(match); + if (!subGroup.IsNullOrWhiteSpace()) { - Logger.Debug(ex, ex.Message); - break; + result.ReleaseGroup = subGroup; } + + result.HardcodedSubs = ParseHardcodeSubs(title); + + Logger.Debug("Release Group parsed: {0}", result.ReleaseGroup); + + result.Languages = LanguageParser.ParseLanguages(result.ReleaseGroup.IsNotNullOrWhiteSpace() ? simpleReleaseTitle.Replace(result.ReleaseGroup, "RlsGrp") : simpleReleaseTitle); + Logger.Debug("Languages parsed: {0}", string.Join(", ", result.Languages)); + + result.Quality = QualityParser.ParseQuality(title); + Logger.Debug("Quality parsed: {0}", result.Quality); + + if (result.Edition.IsNullOrWhiteSpace()) + { + result.Edition = ParseEdition(simpleReleaseTitle); + Logger.Debug("Edition parsed: {0}", result.Edition); + } + + result.ReleaseHash = GetReleaseHash(match); + if (!result.ReleaseHash.IsNullOrWhiteSpace()) + { + Logger.Debug("Release Hash parsed: {0}", result.ReleaseHash); + } + + result.OriginalTitle = originalTitle; + result.ReleaseTitle = releaseTitle; + result.SimpleReleaseTitle = simpleReleaseTitle; + + result.ImdbId = ParseImdbId(simpleReleaseTitle); + result.TmdbId = ParseTmdbId(simpleReleaseTitle); + + return result; + } + catch (InvalidDateException ex) + { + Logger.Debug(ex, ex.Message); + break; } } } From 97ff47a01dc78f8c91b91d353433162833526db2 Mon Sep 17 00:00:00 2001 From: Elia Petrachi Date: Tue, 4 Feb 2025 23:40:55 +0100 Subject: [PATCH 3/6] move title file extension removal after the matching the regex --- src/NzbDrone.Core/Parser/Parser.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index b681a8c9c..0000f9eb8 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -224,10 +224,8 @@ namespace NzbDrone.Core.Parser Logger.Debug("Reversed name detected. Converted to '{0}'", title); } - var releaseTitle = RemoveFileExtension(title); - // Trim dashes from end - releaseTitle = releaseTitle.Trim('-', '_'); + var releaseTitle = title.Trim('-', '_'); releaseTitle = releaseTitle.Replace("【", "[").Replace("】", "]"); @@ -284,6 +282,8 @@ namespace NzbDrone.Core.Parser continue; } + releaseTitle = RemoveFileExtension(releaseTitle); + // TODO: Add tests for this! var simpleReleaseTitle = SimpleReleaseTitleRegex.Replace(releaseTitle, string.Empty); From 48079c6dc1aa39b96f64b1dc7ddd3af9b2fdfafe Mon Sep 17 00:00:00 2001 From: Elia Petrachi Date: Tue, 4 Feb 2025 23:42:07 +0100 Subject: [PATCH 4/6] add new release title extra parameters regex and assign the values to the TitleExtraParameters field of the ParsedMovieInfo --- src/NzbDrone.Core/Parser/Parser.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 0000f9eb8..2137a8b8c 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -23,6 +23,8 @@ namespace NzbDrone.Core.Parser private static readonly RegexReplace[] PreSubstitutionRegex = Array.Empty(); + private static readonly Regex ExtraParametersRegex = new Regex(@"(?.+)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + private static readonly Regex[] ReportMovieTitleRegex = new[] { // Anime [Subgroup] and Year @@ -49,7 +51,7 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled),*/ // Normal movie format, e.g: Mission.Impossible.3.2011 - new Regex(@"^(?(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|(1(8|9)|20)\d{2}|\]|\W(1(8|9)|20)\d{2})))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), + new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|(1(8|9)|20)\d{2}|\]|\W(1(8|9)|20)\d{2})))+(\W+|_|$)(?!\\)" + ExtraParametersRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled), // PassThePopcorn Torrent names: Star.Wars[PassThePopcorn] new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), @@ -667,6 +669,11 @@ namespace NzbDrone.Core.Parser result.Edition = matchCollection[0].Groups["edition"].Value.Replace(".", " "); } + if (matchCollection[0].Groups["extra"].Success) + { + result.TitleExtraParameters = matchCollection[0].Groups["extra"].Value.Replace(".", " "); + } + var movieTitles = new List<string>(); movieTitles.Add(movieName); From b48cdc804d9d0199a2c19e3f55984271bfce4646 Mon Sep 17 00:00:00 2001 From: Elia Petrachi <eliapetrachi@tuta.io> Date: Tue, 4 Feb 2025 23:43:05 +0100 Subject: [PATCH 5/6] match custom formats on the extra parameters extracted from the release title --- .../CustomFormats/Specifications/ReleaseTitleSpecification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs index 1c59b9294..993a8d7f3 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.CustomFormats protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) { - return MatchString(input.MovieInfo?.SimpleReleaseTitle) || MatchString(input.Filename); + return MatchString(input.MovieInfo?.SimpleReleaseTitle) || MatchString(input.Filename) || MatchString(input.MovieInfo?.TitleExtraParameters); } } } From 81c190b610e1b1f99c848b78279e5b10df8b32a4 Mon Sep 17 00:00:00 2001 From: Elia Petrachi <eliapetrachi@tuta.io> Date: Thu, 6 Feb 2025 21:30:45 +0100 Subject: [PATCH 6/6] rename additional release title parameters from extra to post --- .../Specifications/ReleaseTitleSpecification.cs | 2 +- src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs | 2 +- src/NzbDrone.Core/Parser/Parser.cs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs index 993a8d7f3..4859b9053 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/ReleaseTitleSpecification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.CustomFormats protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) { - return MatchString(input.MovieInfo?.SimpleReleaseTitle) || MatchString(input.Filename) || MatchString(input.MovieInfo?.TitleExtraParameters); + return MatchString(input.MovieInfo?.SimpleReleaseTitle) || MatchString(input.Filename) || MatchString(input.MovieInfo?.PostTitleParameters); } } } diff --git a/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs b/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs index 671a73ac8..839c24998 100644 --- a/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ParsedMovieInfo.cs @@ -16,7 +16,7 @@ namespace NzbDrone.Core.Parser.Model public string OriginalTitle { get; set; } public string ReleaseTitle { get; set; } public string SimpleReleaseTitle { get; set; } - public string TitleExtraParameters { get; set; } + public string PostTitleParameters { get; set; } public QualityModel Quality { get; set; } public List<Language> Languages { get; set; } public string ReleaseGroup { get; set; } diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 2137a8b8c..fc0818f41 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -23,7 +23,7 @@ namespace NzbDrone.Core.Parser private static readonly RegexReplace[] PreSubstitutionRegex = Array.Empty<RegexReplace>(); - private static readonly Regex ExtraParametersRegex = new Regex(@"(?<extra>.+)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); + private static readonly Regex PostTitleParametersRegex = new Regex(@"(?<additional>.+)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); private static readonly Regex[] ReportMovieTitleRegex = new[] { @@ -51,7 +51,7 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled),*/ // Normal movie format, e.g: Mission.Impossible.3.2011 - new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|(1(8|9)|20)\d{2}|\]|\W(1(8|9)|20)\d{2})))+(\W+|_|$)(?!\\)" + ExtraParametersRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled), + new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|(1(8|9)|20)\d{2}|\]|\W(1(8|9)|20)\d{2})))+(\W+|_|$)(?!\\)" + PostTitleParametersRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled), // PassThePopcorn Torrent names: Star.Wars[PassThePopcorn] new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![()\[!]))*(?<year>(\[\w *\])))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), @@ -669,9 +669,9 @@ namespace NzbDrone.Core.Parser result.Edition = matchCollection[0].Groups["edition"].Value.Replace(".", " "); } - if (matchCollection[0].Groups["extra"].Success) + if (matchCollection[0].Groups["additional"].Success) { - result.TitleExtraParameters = matchCollection[0].Groups["extra"].Value.Replace(".", " "); + result.PostTitleParameters = matchCollection[0].Groups["additional"].Value.Replace(".", " "); } var movieTitles = new List<string>();