Add the arr-subs crate with the provider trait #184
Notifications
Due Date
No due date set.
Blocks
Depends on
#188 Fetch subtitles from Podnapisi
yolo/arr
#194 Sync subtitles with alass
yolo/arr
Reference: yolo/arr#184
Reference in New Issue
Block a user
Create
crates/arr-subs, the crate that owns everything subtitle-shaped thattouches the outside world: providers, extraction, translation backends and the
alasswrapper. Selection and ranking rules stay pure inarr-core(#185),the same way
arr-probeshells out toffprobewhile the policy engine thatconsumes its output does not.
Scope for this issue is the skeleton the rest of the milestone builds on:
[lints] workspace = true, dependencies referenced by namefrom
[workspace.dependencies]perCLAUDE.md.pt-PT / pt-BR distinction
arr-probe'slanguagemodule already resolves),a candidate with the fields ranking needs — provider, hash match, release
name, group, source, rating, download count, forced flag, SDH flag — and the
fetched result.
Providertrait: search for candidates for a media file, download one byid. Async, error type per the crate's own
error.rs, no providerimplementations yet.
declared and no backend behind them yet.
Non-goals: any provider implementation, any translation code, any ranking
logic. Those are separate issues and this one must not anticipate their
interfaces beyond the trait above.
See DESIGN.md §15 (added by #183) for the wanted-set and provider decisions.
Depends on: #183
Added
crates/arr-subsas a workspace member with[lints] workspace = trueand dependencies referenced by name from[workspace.dependencies]. The crate carries the domain types a provider deals in —ProviderIdandCandidateIdnewtypes,MediaRef/MediaFile/SearchRequestfor the file being searched for,Candidatewith the facts §15's ranking needs (hash match, release name, group, source, rating, download count, forced, SDH), andFetchedwith aSubtitleFormat. Language isarr_core::Language, so the pt-PT / pt-BR distinctionarr-probe'slanguagemodule already resolves is reused rather than duplicated. TheProvidertrait hasid,searchanddownload, using boxed futures likearr-daemon'sActiontrait so it stays object safe — the enabled provider set is a database setting (#198), not a compile-time fact. Errors live inerror.rs, each variant naming the provider, withRateLimitedsplit out so #197 can render a cap as a queue state rather than a failure. The four translation-backend cargo features (translate-openai,translate-deepl,translate-google,translate-command) are declared with no backend behind them. No provider implementation, no translation code, no ranking.Branch:
subtitles/184-subs-cratejust cipassed: 473 tests, clippy clean,cargo macheteclean, web-check clean.Findings
Fetched.contentinstead. Bytes were chosen because what happens next is not the provider's call —alassruns over it (#194) before it gets a name and a place in the title folder (#195), and a provider that writes temp files also owns cleaning them up. If the temp-path shape is wanted, it should change here rather than in one provider.arr_core::SubtitleTrackcannot express a forced embedded track. It carries onlylanguage. §15 says a forced track never satisfies a want, so #186 and #189 will record a forced embedded track as satisfying its language and the reconcile loop will stop looking. #189 already covers adding the codec to that struct (text versus bitmap); theforceddisposition flag is not in any issue I can find and probably belongs to the same probe change.