aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/indexer/title_parse.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/title_parse.py20
1 files changed, 20 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 018746b..def947f 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/title_parse.py
@@ -288,6 +288,26 @@ def strip_track_prefix(text: str) -> str:
return re.sub(r"^[\s-]+", "", text[m.end():]).strip() if m else text
+# An *explicit* season/episode marker: SxxExx, 1x08, "Episode 8", "Ep 8",
+# "Season 1"/"Saison 1". guessit will also invent a season+episode from a
+# bare 3-4 digit run ("1080p" truncated to "108" -> S01E08; "1280" ->
+# S12E80), which is how a plain movie ends up shelved as a series
+# (§10.1/V14). The indexer uses this to tell a real flat-library episode
+# from that hallucination.
+_EPISODE_MARKER_RE = re.compile(
+ r"s\d{1,2}[\s._-]*e\d{1,3}"
+ r"|\b\d{1,2}x\d{1,3}\b"
+ r"|\bepisode[\s._-]*\d{1,3}\b"
+ r"|\bep[\s._-]*\d{1,3}\b"
+ r"|\b(?:season|saison)[\s._-]*\d{1,2}\b",
+ re.IGNORECASE,
+)
+
+
+def has_episode_marker(filename: str) -> bool:
+ return bool(_EPISODE_MARKER_RE.search(filename))
+
+
def parse_episode_filename(filename: str) -> ParsedName:
"""
Parse an episode filename. `display_title` may come back None (e.g.