feat(media): plan a TV relayout from the numbering Jellyfin already has #99
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