Write subtitle sidecars into the title folder #195
Notifications
Due Date
No due date set.
Blocks
Depends on
Reference: yolo/arr#195
Reference in New Issue
Block a user
Write subtitles into the library, in the §7.4 title folder next to the video.
Naming, per DESIGN.md §15 (added by #183):
The
.mtsegment marks a machine translation, keeping §7.4's property thatlstells the truth with the app stopped.sidecar that Jellyfin picks up mid-write.
single call §7.5 already makes on import.
§7.4 deletes atomically. Confirm that holds for the season subfolders on the
TV side.
Verify against the live Jellyfin before closing: that it reads
….pt-PT.srtas Portuguese, and that….pt-PT.mt.srtis also read asPortuguese rather than as a subtitle titled "mt". If the extra segment breaks
the language read, fall back to a plain filename with the machine flag living
only on the database row, and amend §15 to match — do not ship a marker
Jellyfin misreads.
Depends on: #186, #194, #212, #213
Implemented the sidecar-write half of §15: naming and atomic write already existed from #199 (
layout::subtitle_name,subtitles.rs'swrite_sidecar/claim_path/finish), so the actual gap was the Jellyfin refresh call.JellyfinClientlived inarr-daemon, a binary crate arr-api cannot depend on, so I moved it intoarr-api(arr_api::jellyfin), attached an optional instance toAppStateviawith_jellyfin, and made the subtitle grab and translate handlers callrefresh()after a successful write — same single call §7.5 already makes on import, best-effort (a refresh failure logs and never fails the write).arr-daemonnow builds oneJellyfinClientinmain.rsand hands it to both the reconcile loop'sImportActionand the API'sAppState. Added tests covering the refresh call and its failure tolerance.Branch:
subtitles/195-write-sidecars.just cipassed in full (639/639 tests, fmt/lint/deps/web-check clean).Findings
Could not verify against a live Jellyfin. This worker's sandbox has no network reachability to the Jellyfin host (ICMP reaches it, TCP 8096 times out — looks firewalled from this segment). The issue asks to confirm
….pt-PT.srtreads as Portuguese and….pt-PT.mt.srtreads as Portuguese rather than a subtitle titled "mt" before closing. That check still needs to happen from a session with real LAN access before this can be considered validated; I did not add a fallback naming scheme since I have no evidence the current one is wrong.Season/episode deletion never removes subtitle sidecars from disk, and now silently orphans them.
remove_library_filesinarr-api/src/series.rsresolves targets frommedia_filesrows only; forFileScope::Season/FileScope::Episodeit deletes the exact video file, not the season folder (only a whole-series deleteremove_dir_alls the title folder).remove_scope_filesthen deletes themedia_filesrow in the same transaction, andsubtitle_files.media_file_idisON DELETE CASCADE, so the subtitle's database row disappears too — while the.srt/.mt.srtfile stays on disk, now with nothing in the database pointing at it. The doc comment onremove_library_files("Sidecars beside a removed episode therefore stay; they are not rows this service wrote") predates subtitles (#174/#175, phase/6, before #186) and is now stale — subtitle files are rows this service wrote. This is a real gap in area/api's removal path, not something #195's scope covers; worth its own issue.