diff --git a/breadarrd/src/parser/mod.rs b/breadarrd/src/parser/mod.rs index 888a959..97780e1 100644 --- a/breadarrd/src/parser/mod.rs +++ b/breadarrd/src/parser/mod.rs @@ -181,6 +181,34 @@ mod tests { assert_eq!(p.resolution, Some(1080)); } + #[test] + fn parses_season_pack_shapes_without_literal_parens() { + // Real review-queue entries that all failed to resolve at all + // before this fix — season came back None, not just unmatched + // episode — because SEASON_PACK_RE required a literal + // "(S?N Complete)" shape. + assert_eq!( + parse("Modern.Family.S10.COMPLETE.720p.AMZN.WEBRip.x264-GalaxyTV").season, + Some(10) + ); + assert_eq!( + parse("Modern Family 2009 Season 8 Complete 720p AMZN WEBRip x264 [i_c]").season, + Some(8) + ); + assert_eq!( + parse("Red.Dwarf.S04.1080p.BluRay.x264-LATENCY [Season 4 Four Complete]").season, + Some(4) + ); + assert_eq!( + parse("Red.Dwarf.S11.1080p.BluRay.x264-SHORTBREHD [Season 11 Eleven]").season, + Some(11) + ); + assert_eq!( + parse("Game of Thrones - Season 8 S08 - 2019 1080p Bluray AAC5.1 x264-R").season, + Some(8) + ); + } + #[test] fn parses_yameii_dash_sxxexx_with_english_dub_tag() { let p = parse("[Yameii] Ascendance of a Bookworm - S04E11 [English Dub] [CR WEB-DL 1080p H264 AAC] [8ACE7B72] (Honzuki no Gekokujou)"); diff --git a/breadarrd/src/parser/tokens.rs b/breadarrd/src/parser/tokens.rs index f052603..1215930 100644 --- a/breadarrd/src/parser/tokens.rs +++ b/breadarrd/src/parser/tokens.rs @@ -50,8 +50,21 @@ static SXXEXX_RE: LazyLock = LazyLock::new(|| Regex::new(r"(?i)\bS(\d{1,2})E(\d{1,3})(?:v\d+)?\b").unwrap()); static SXX_DASH_EP_RE: LazyLock = LazyLock::new(|| Regex::new(r"(?i)\bS(\d{1,2})\s*-\s*(\d{1,3})\b").unwrap()); +// A bare season marker with no episode number attached — "S01", "Season 8", +// "Season.1", optionally with a trailing "Complete"/spelled-out season word +// (e.g. "[Season 4 Four Complete]") that's irrelevant to the number itself. +// Previously required literal parens around an explicit "S?N Complete)" +// shape, matching only one specific release-group convention; real +// releases routinely drop the parens, drop "Complete" entirely (e.g. +// "Game of Thrones - Season 8 S08 - 2019"), or spell "Season" out with a +// dot instead of a space (verified live: several real review-queue entries +// failed to resolve at all — season came back `None` — because none of +// these shapes matched the old pattern). Only reached after +// `SXXEXX_RE`/`SXX_DASH_EP_RE` have already failed to find an actual +// episode number, so treating a bare season marker as a pack signal here is +// safe. static SEASON_PACK_RE: LazyLock = - LazyLock::new(|| Regex::new(r"(?i)\(S?(\d{1,2})\s*Complete\)").unwrap()); + LazyLock::new(|| Regex::new(r"(?i)\bS(?:eason)?\.?\s*(\d{1,2})\b").unwrap()); static DASH_EPISODE_RE: LazyLock = LazyLock::new(|| Regex::new(r"-\s*(\d{1,3})\b").unwrap()); // A batch/season-pack release covering many episodes in one torrent.