diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-26 16:24:18 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-26 16:24:18 +0200 |
| commit | bc94dc672d142e989fa4f483f643d4b43f66b02f (patch) | |
| tree | bf0cf9b60a79cc3ff607668c928bf88c76511e0d /packages | |
| parent | c81eaa0bd07e360ec03406dfc63267c3013a0319 (diff) | |
| download | meshbay-bc94dc672d142e989fa4f483f643d4b43f66b02f.tar.gz | |
fix(video): recognize "S1"/"S2"-style season folders, not just full words
Found live: a real show organized its first season as "House.of.the.Dragon.
S01E01...mkv" inside a folder named "S1" (the show name embedded in every
filename, so grouping worked by guessit's own title alone), but its later
seasons as "S02E01. Episode's Own Title.mkv" inside "S2"/"S3" — no show
name in any filename at all, relying entirely on the folder. Those seasons
showed up as loose individual entries instead of grouped under the show:
season_from_folder_name only recognized "season"/"saison"/"livre" as full
words, so "S2" didn't register as a season folder at all, and the
ancestor-based show-grouping fix (previous commits) never triggered for
those seasons.
A bare "S" + 1-2 digits as the *whole* folder name is now recognized too —
anchored to the entire name so it can't match some unrelated folder that
merely starts with "s" followed by digits.
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/indexer/title_parse.py | 9 | ||||
| -rw-r--r-- | packages/meshbay-node/tests/test_title_parse.py | 18 |
2 files changed, 27 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py b/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py index 985bd7a..24b423e 100644 --- a/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py +++ b/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py @@ -45,6 +45,12 @@ _SEASON_RE = re.compile( re.IGNORECASE, ) _SPECIALS_RE = re.compile(r"\b(?:bonus|extras?|specials?)\b", re.IGNORECASE) +# A bare "S" + number as the *whole* folder name — "S1", "S2", "S02" — a +# common abbreviated convention distinct from SEASON_WORDS' full words. +# Anchored to the entire name, not just `\b`-bounded within a longer +# string, so it only matches a folder actually named just that — never +# some other word that merely starts with "s" followed by digits. +_SEASON_ABBREV_RE = re.compile(r"^s(\d{1,2})$", re.IGNORECASE) _ROMAN_NUMERALS = { 2: "II", 3: "III", 4: "IV", 5: "V", 6: "VI", @@ -110,6 +116,9 @@ def season_from_folder_name(name: str) -> int | None: """ if _SPECIALS_RE.search(name): return 0 + m = _SEASON_ABBREV_RE.match(name.strip()) + if m: + return int(m.group(1)) m = _SEASON_RE.search(name) if not m: return None diff --git a/packages/meshbay-node/tests/test_title_parse.py b/packages/meshbay-node/tests/test_title_parse.py index cf51646..5f0977c 100644 --- a/packages/meshbay-node/tests/test_title_parse.py +++ b/packages/meshbay-node/tests/test_title_parse.py @@ -119,6 +119,24 @@ def test_season_folder_book_word_roman_numeral(): assert season_from_folder_name("Livre VI") == 6 +def test_season_folder_bare_s_abbreviation(): + # A common abbreviated convention distinct from SEASON_WORDS' full + # words — found live: a show with "S1"/"S2"/"S3" folders instead of + # "Season 1" etc, exactly the shape that grouped its later seasons as + # loose individual entries rather than under the show. + assert season_from_folder_name("S1") == 1 + assert season_from_folder_name("S2") == 2 + assert season_from_folder_name("S02") == 2 + + +def test_season_folder_bare_s_abbreviation_does_not_match_inside_a_longer_name(): + # Anchored to the whole folder name — a real folder that merely starts + # with "S" followed by digits somewhere in a longer, unrelated name + # must not be read as a season abbreviation. + assert season_from_folder_name("S1 Extended Cut") is None + assert season_from_folder_name("Something2") is None + + def test_specials_folder_maps_to_season_zero(): assert season_from_folder_name("Specials") == 0 assert season_from_folder_name("Bonus") == 0 |