From 5ea1fb9424ac5156d4f35627ac4be86dee8bd1b3 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 26 Mar 2023 21:39:01 -0700 Subject: [PATCH] New: Parsing of multi-episode files in brackets Closes #5501 --- .../FileNameBuilderTests/MultiEpisodeFixture.cs | 10 ++++++++++ .../ParserTests/MultiEpisodeParserFixture.cs | 1 + src/NzbDrone.Core/Parser/Parser.cs | 6 +++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/MultiEpisodeFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/MultiEpisodeFixture.cs index db9b13a02..a352f369b 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/MultiEpisodeFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/MultiEpisodeFixture.cs @@ -270,5 +270,15 @@ public void should_format_prefixed_range_multi_episode_using_episode_separator() Subject.BuildFileName(new List { _episode1, _episode2, _episode3 }, _series, _episodeFile) .Should().Be("South Park - 15x06-x08 - City Sushi"); } + + [Test] + public void should_format_range_multi_episode_wrapped_in_brackets() + { + _namingConfig.StandardEpisodeFormat = "{Series Title} (S{season:00}E{episode:00}) {Episode Title}"; + _namingConfig.MultiEpisodeStyle = 4; + + Subject.BuildFileName(new List { _episode1, _episode2, _episode3 }, _series, _episodeFile) + .Should().Be("South Park (S15E06-08) City Sushi"); + } } } diff --git a/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs index 8ae77273e..3fbd06f34 100644 --- a/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/MultiEpisodeParserFixture.cs @@ -74,6 +74,7 @@ public class MultiEpisodeParserFixture : CoreTest [TestCase("Series Title! (2013) - S04E44-E45 - Il 200 spettacolare episodio da narcisisti! [NetflixHD 720p HEVC] [ITA+ENG].mkv", "Series Title! (2013)", 4, new[] { 44, 45 })] [TestCase("13 Series Se.1 afl.2-3-4 [VTM]", "13 Series", 1, new[] { 2, 3, 4 })] [TestCase("Series T Se.3 afl.3 en 4", "Series T", 3, new[] { 3, 4 })] + [TestCase("Series Title (S15E06-08) City Sushi", "Series Title", 15, new[] { 6, 7, 8 })] // [TestCase("", "", , new [] { })] public void should_parse_multiple_episodes(string postTitle, string title, int season, int[] episodes) diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index d3fedc61e..ba02f179f 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -229,7 +229,11 @@ public static class Parser // Multi-episode with episodes in square brackets (Series Title [S01E11E12] or Series Title [S01E11-12]) new Regex(@"(?:.*(?:^))(?.*?)[-._ ]+\[S(?<season>(?<!\d+)\d{2}(?!\d+))(?:[E-]{1,2}(?<episode>(?<!\d+)\d{2}(?!\d+)))+\]", - RegexOptions.IgnoreCase | RegexOptions.Compiled), + RegexOptions.IgnoreCase | RegexOptions.Compiled), + + // Multi-episode with episodes in brackets (Series Title (S01E11E12) or Series Title (S01E11-12)) + new Regex(@"(?:.*(?:^))(?<title>.*?)[-._ ]+\(S(?<season>(?<!\d+)\d{2}(?!\d+))(?:[E-]{1,2}(?<episode>(?<!\d+)\d{2}(?!\d+)))+\)", + RegexOptions.IgnoreCase | RegexOptions.Compiled), // Multi-episode release with no space between series title and season (S01E11E12) new Regex(@"(?:.*(?:^))(?<title>.*?)S(?<season>(?<!\d+)\d{2}(?!\d+))(?:E(?<episode>(?<!\d+)\d{2}(?!\d+)))+",