diff --git a/scripts/media-shows.py b/scripts/media-shows.py index 44d52bb..ccee97c 100755 --- a/scripts/media-shows.py +++ b/scripts/media-shows.py @@ -112,6 +112,9 @@ VIDEO_EXT = {".mkv", ".mp4", ".avi", ".m4v", ".mov", ".ts", ".m2ts", ".mpg", SUB_EXT = {".srt", ".ass", ".ssa", ".sub", ".vtt"} IMG_EXT = {".jpg", ".jpeg", ".png", ".webp", ".bmp", ".gif", ".tbn"} NFO_EXT = {".nfo", ".xml"} +# The container's own word, for a sidecar named "episode.mkv.srt": that component +# is not a language flag, and both matchers read the plain form better. +CONTAINER = {e[1:] for e in VIDEO_EXT} # Files that are never anybody's business: hidden, forks, resume state, thumbnails. SKIP_NAME = re.compile(r"^(\.|#|dl_state|@eaDir|Thumbs\.db|desktop\.ini)|\.!q$") # Show-level metadata keeps its own name at the series root; season-level at the @@ -556,7 +559,7 @@ def anchor_of(path, stem): base = os.path.basename(src) for prefix in (os.path.splitext(base)[0], base): if stem == prefix or stem.startswith(prefix + "."): - if best is None or len(prefix) > best[1]: + if best is None or len(prefix) > best[2]: best = (src, dst, len(prefix)) if best: return best[0], best[1] @@ -568,6 +571,11 @@ def sidecar_name(r, src, dst): carry — hung on the video file's new base.""" stem = os.path.splitext(os.path.basename(src))[0] tail = os.path.splitext(r["base"])[0][len(stem):] + # "Show.S01E01.mkv.srt" carries the container's name, not a flag: Jellyfin and + # Plex both read "Show S01E01.srt", so the container word is dropped here. + parts = tail.split(".") + if len(parts) > 1 and parts[1].lower() in CONTAINER: + tail = "".join("." + p for p in parts[2:]) if r["ext"] in NFO_EXT: tail = os.path.splitext(os.path.basename(src))[1] + tail return clean(os.path.splitext(os.path.basename(dst))[0] + tail + r["ext"]) diff --git a/tests/media_shows.bats b/tests/media_shows.bats index fd4029b..db5e349 100755 --- a/tests/media_shows.bats +++ b/tests/media_shows.bats @@ -54,6 +54,7 @@ setup() { # trailer: four things that have to end up in four different places. at "$SEASON/The.Examples.S01E01.Pilot.1080p.x265.mkv" 9000 at "$SEASON/The.Examples.S01E01.Pilot.1080p.x265.en.srt" 200 + at "$SEASON/The.Examples.S01E01.Pilot.1080p.x265.mkv.forced.srt" 250 at "$SEASON/folder.jpg" 300 at "$SEASON/Trailers/teaser.mkv" 1000 at "$SEASON/tvshow.nfo" 400 @@ -143,6 +144,12 @@ PY = "$LIB/The Examples (2010)/Season 01/The Examples S01E01.en.srt" ] } +@test "a subtitle that carries the container's word in its own name still follows the episode" { + plan + [ "$(dst "$SEASON/The.Examples.S01E01.Pilot.1080p.x265.mkv.forced.srt")" \ + = "$LIB/The Examples (2010)/Season 01/The Examples S01E01.forced.srt" ] +} + @test "a season image keeps its own name; a series nfo keeps the series folder" { plan [ "$(dst "$SEASON/folder.jpg")" = "$LIB/The Examples (2010)/Season 01/folder.jpg" ]