diff --git a/crates/arr-api/src/subtitles.rs b/crates/arr-api/src/subtitles.rs index 93e6e29..a33ffef 100644 --- a/crates/arr-api/src/subtitles.rs +++ b/crates/arr-api/src/subtitles.rs @@ -993,12 +993,18 @@ pub async fn translate( write_sidecar(&destination, &arr_subs::srt::render(&translated)).await?; + let sync = state.syncer().settle(&target.path, &destination).await; + if let Some(synced) = &sync.content { + write_sidecar(&destination, synced).await?; + } + let record = arr_db::NewSubtitleFile::translated( target.media_file_id, &target_language.to_string(), &engine, &destination.to_string_lossy(), - ); + ) + .sync(db_sync_state(sync.state)); finish( &state, &record, @@ -1964,6 +1970,48 @@ mod tests { ); } + /// §15: `alass` runs on every translated subtitle too (#217), not just + /// fetched ones. + #[tokio::test] + async fn a_translation_writes_the_synced_content_when_alass_accepts_it() { + let dir = tempfile::tempdir().expect("tempdir"); + let binary = fake_alass( + dir.path(), + "printf '1\\n00:00:06,000 --> 00:00:07,000\\nOLA\\n' > \"$3\"\n", + ) + .await; + let fixture = build_fixture( + vec![Arc::new(StubProvider::new("opensubtitles"))], + vec![Arc::new(StubBackend)], + arr_subs::Syncer::new().with_binary(&binary), + ) + .await; + let (_, source) = grab(&fixture, pt()).await; + let source_id = source["id"].as_i64().expect("source id"); + + let response = reqwest::Client::new() + .post(format!( + "{}/api/media-files/1/subtitles/translate", + fixture.base + )) + .json(&serde_json::json!({ + "source_subtitle_id": source_id, + "target_language": "en", + "engine": "openai" + })) + .send() + .await + .expect("translate"); + assert_eq!(response.status(), StatusCode::CREATED); + let body: serde_json::Value = response.json().await.expect("json"); + assert_eq!(body["sync"], "synced"); + let sidecar = PathBuf::from(body["path"].as_str().expect("path")); + assert_eq!( + tokio::fs::read_to_string(&sidecar).await.expect("sidecar"), + "1\n00:00:06,000 --> 00:00:07,000\nOLA\n" + ); + } + /// §15 allows a machine translation as the source of another one. #[tokio::test] async fn a_machine_translation_is_itself_a_legal_source() {