Sync manually grabbed subtitles with alass #214
Closed
opened 2026-08-25 00:41:21 +01:00 by naps62-yolo
·
1 comment
No Branch/Tag Specified
main
ui-mobile-first
codex/fix-action-button-reload
translation
qbit-2
docker
bugs
blitz/subtitles
fix/255-provider-reorder
blitz/feedback-3
subtitles/251-icon-vocab
subtitles/237-relocate-subs
fix/248-title-move-creates-root
blitz/feedback-2
issue/227-abandoned-pack-visible
issue/245-backoff-anchor
issue/240-design-coherence
issue/211-waived-rule
issue/232-plainer-words
issue/246-policy-reclassify
issue/244-root-slash-stored
issue/231-settings-rows
issue/241-reclassify-on-root-change
issue/239-failure-window
issue/230-icon-only
issue/243-root-path-edges
issue/238-attention-liveness
issue/229-back-button
issue/236-root-path-move
issue/226-attention-threshold
issue/228-root-move
blitz/size-bands
size-bands/209-runtime-scale
size-bands/210-size-waiver
size-bands/208-runtime-design
blitz/reliability
reliability/155-sqlx-migrations
reliability/176-refresh-on-add
removal-nav/175-removal-controls
removal-nav/174-season-file-removal
removal-nav/172-search-titles
removal-nav/173-homepage-library
removal-nav/171-untrack-clears
removal-nav/170-chip-align
removal-nav/169-design-amendment
feedback/167-deck-autosearch
feedback/165-chip-colour
feedback/166-header-rail
feedback/163-drop-cast
feedback/164-control-geometry
feedback/162-season-ordering
feedback/161-search-episodes
feedback/160-autotrack-seed
feedback/159-design-amend
blitz/rich-metadata
rich/151-grid
rich/148-search-rows
rich/150-series-meta
rich/149-movie-page
rich/147-search-art
rich/156-rating-null
rich/146-meta-api
rich/145-poster-cols
rich/144-trailer
rich/143-meta-detail
rich/142-design-amend
blitz/153-empty-episode-titles
blitz/152-deck-routes
blitz/141-season-vanished-api
blitz/129-series-detail-view
blitz/140-attention-episode-numbers
blitz/137-season-removals
blitz/133-attention-tv-lanes
blitz/139-movie-id-episode-guard
blitz/134-stale-attention-queue
blitz/124-rss-episode-matching
blitz/136-imdb-series-lookup
blitz/132-manual-commands
blitz/128-series-delete-files
blitz/131-status-seasons-input
blitz/138-plural-season-range
blitz/135-pack-name-parse
blitz/122-upstream-removals
blitz/130-add-series-search
blitz/121-series-refresh
blitz/127-unified-search-tv
blitz/123-episode-matching
blitz/126-tv-attention
blitz/119-tracked-rule
blitz/125-season-deck
blitz/120-tvdb-id
blitz/118-season-zero
blitz/117-design-amend
issue/115-avail-search
issue/112-name-truncate
issue/111-score-colors
No results found.
Labels
Clear labels
area/api
area/ci
area/compat
area/core
area/daemon
area/db
area/dl
area/indexer
area/infra
area/meta
area/parse
area/probe
area/subs
area/web
difficulty/easy
difficulty/hard
difficulty/moderate
difficulty/trivial
phase/1-skeleton
phase/2-logic
phase/3-sourcing
phase/4-movies
phase/5-ui
phase/6-tv
phase/7-people
phase/8-compat
phase/9-subtitles
type/bug
type/chore
type/feature
type/test
arr-api
CI and test harness
arr-compat
arr-core
arr-daemon
arr-db
arr-dl
arr-indexer
workspace and tooling
arr-meta
arr-parse
arr-probe
arr-subs crate: providers, extraction, translation, sync
web/
bounded, obvious approach, few files
subtle correctness or cross-cutting
multiple files, judgement, an interface to design
one file, mechanical, no design decisions
workspace, CI, config, database, empty API and SPA
parsing and policy engine, pure, no network
TMDB and Prowlarr, read-only
movies end to end
search, buckets, library views, queues
seasons, episodes, tracking, derived status
owner tags and notifications
Jellyseerr shim
build order: subtitles, DESIGN.md §15
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Reference: yolo/arr#214
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
#199 shipped the manual grab endpoint before the two things a grab has to do
to the bytes it fetched existed on the branch.
The conversion half is done —
srt_textincrates/arr-api/src/subtitles.rsnow calls
Fetched::to_srt(26bd25eonblitz/subtitles), so a providerserving VTT or ASS is converted rather than refused, and a format with no
parser fails before anything reaches the disk.
What remains is the sync half. A manually grabbed sidecar is still
recorded with
sync: "not_run". Once #194 lands, runalasson the fetchedsubtitle before the row is written, with the implausibility rules §15 states:
a shift beyond 60 seconds or lost cues keeps the unsynced original and flags
the file. #196 will call the same seam from the reconcile loop, so put it
somewhere both paths can reach rather than inline in the handler.
Depends on: #194, #199
Wire conversion and sync into the manual grabto Sync manually grabbed subtitles with alassImplemented the sync half of the manual grab:
POST /api/media-files/{id}/subtitles/grabnow runsalasson the fetched subtitle before the row is recorded, per §15's implausibility rules (a shift beyond 60s or lost cues keeps the unsynced original and flags the file).The seam lives in
arr-subs(Syncer::settle, newSyncState/Settledtypes), not inlined in the handler, so #196's reconcile loop can call the same function when it lands: it runsSyncer::sync, folds an accepted result into the content to write back, an implausible result into keeping the original with a warning logged, and — since alass has no health check yet (#200) — a spawn/timeout/non-zero failure degrades toNotRunwith a warning rather than failing the grab.AppStategained aSyncer(with_syncer, defaulting toalassonPATH); the daemon binary wires it fromconfig.alass_path, which already existed from #194 but was unused until now.Branch:
subtitles/214-grab-sync, based onblitz/subtitles.just ci: passed (642 tests).Findings
translate()(the/subtitles/translateendpoint) still records every machine translation withsync: "not_run". §15 says alass runs on "every fetched and every translated subtitle," but #214's issue body scoped this to the manual grab endpoint only ("A manually grabbed sidecar is still recorded with sync: not_run... run alass on the fetched subtitle"), so I left it out rather than widening scope. SameSyncer::settleseam applies there unchanged — it's a small follow-up.AppState::with_translation_backendsis never called inarr-daemon/src/main.rs. The daemon wiressubtitle_providersbut not translation backends, so/subtitles/translatecurrently 503s on every request in production regardless of compiled-in cargo features. Looks like a gap from #190/#191/#192, not something this issue touches.