fix(media): a sidecar named "episode.mkv.srt" anchors, and loses the container word
The first run against the real library died in the anchor lookup: a subtitle whose own name carries the media extension matches BOTH prefix forms of its video, and the "keep the longest" comparison read the destination slot of the tuple instead of the length slot. The fixture only ever matched one prefix, so the seam was green over a crash. The tail the sidecar keeps is now stripped of that container word: Jellyfin and Plex both read "Show S01E01.forced.srt", not "Show S01E01.mkv.forced.srt", and an nfo still carries the media extension because that one is constructed, not parsed.
This commit is contained in:
1 parent
441b908937
commit
c0c77590b1
2 files changed
+16
-1
No files matched your search
@@ -112,6 +112,9 @@ VIDEO_EXT = {".mkv", ".mp4", ".avi", ".m4v", ".mov", ".ts", ".m2ts", ".mpg",
|
|||||||
SUB_EXT = {".srt", ".ass", ".ssa", ".sub", ".vtt"}
|
SUB_EXT = {".srt", ".ass", ".ssa", ".sub", ".vtt"}
|
||||||
IMG_EXT = {".jpg", ".jpeg", ".png", ".webp", ".bmp", ".gif", ".tbn"}
|
IMG_EXT = {".jpg", ".jpeg", ".png", ".webp", ".bmp", ".gif", ".tbn"}
|
||||||
NFO_EXT = {".nfo", ".xml"}
|
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.
|
# 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$")
|
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
|
# 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)
|
base = os.path.basename(src)
|
||||||
for prefix in (os.path.splitext(base)[0], base):
|
for prefix in (os.path.splitext(base)[0], base):
|
||||||
if stem == prefix or stem.startswith(prefix + "."):
|
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))
|
best = (src, dst, len(prefix))
|
||||||
if best:
|
if best:
|
||||||
return best[0], best[1]
|
return best[0], best[1]
|
||||||
@@ -568,6 +571,11 @@ def sidecar_name(r, src, dst):
|
|||||||
carry — hung on the video file's new base."""
|
carry — hung on the video file's new base."""
|
||||||
stem = os.path.splitext(os.path.basename(src))[0]
|
stem = os.path.splitext(os.path.basename(src))[0]
|
||||||
tail = os.path.splitext(r["base"])[0][len(stem):]
|
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:
|
if r["ext"] in NFO_EXT:
|
||||||
tail = os.path.splitext(os.path.basename(src))[1] + tail
|
tail = os.path.splitext(os.path.basename(src))[1] + tail
|
||||||
return clean(os.path.splitext(os.path.basename(dst))[0] + tail + r["ext"])
|
return clean(os.path.splitext(os.path.basename(dst))[0] + tail + r["ext"])
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ setup() {
|
|||||||
# trailer: four things that have to end up in four different places.
|
# 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.mkv" 9000
|
||||||
at "$SEASON/The.Examples.S01E01.Pilot.1080p.x265.en.srt" 200
|
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/folder.jpg" 300
|
||||||
at "$SEASON/Trailers/teaser.mkv" 1000
|
at "$SEASON/Trailers/teaser.mkv" 1000
|
||||||
at "$SEASON/tvshow.nfo" 400
|
at "$SEASON/tvshow.nfo" 400
|
||||||
@@ -143,6 +144,12 @@ PY
|
|||||||
= "$LIB/The Examples (2010)/Season 01/The Examples S01E01.en.srt" ]
|
= "$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" {
|
@test "a season image keeps its own name; a series nfo keeps the series folder" {
|
||||||
plan
|
plan
|
||||||
[ "$(dst "$SEASON/folder.jpg")" = "$LIB/The Examples (2010)/Season 01/folder.jpg" ]
|
[ "$(dst "$SEASON/folder.jpg")" = "$LIB/The Examples (2010)/Season 01/folder.jpg" ]
|
||||||
|
|||||||
Reference in new issue
Block a user