aboutsummaryrefslogtreecommitdiff
path: root/src/translation
diff options
context:
space:
mode:
Diffstat (limited to 'src/translation')
-rw-r--r--src/translation/deepl.rs65
1 files changed, 52 insertions, 13 deletions
diff --git a/src/translation/deepl.rs b/src/translation/deepl.rs
index f2e84d7..11510d5 100644
--- a/src/translation/deepl.rs
+++ b/src/translation/deepl.rs
@@ -1,6 +1,9 @@
-use std::{collections::BTreeMap, time::Duration};
+use std::{collections::BTreeMap, fmt::Display, time::Duration};
+use crate::util;
+use cached::proc_macro::io_cached;
use deepl::DeepLApi;
+use deepl::ModelType;
use relm4::prelude::*;
use crate::{
@@ -66,30 +69,28 @@ impl AsyncComponent for DeeplTranslator {
impl DeeplTranslator {
async fn do_translate(&mut self, sender: AsyncComponentSender<Self>) {
if let Some(stream_ix) = self.stream_ix {
- let deepl = DeepLApi::with(&Settings::default().deepl_api_key()).new();
-
let next_cue_to_translate = self.next_cues_to_translate.entry(stream_ix).or_insert(0);
- if let Some(cue) = {
+ while let Some(cue) = {
SUBTITLE_TRACKS
.read()
.get(&stream_ix)
- .unwrap()
- .texts
- .get(*next_cue_to_translate)
+ .and_then(|stream| stream.texts.get(*next_cue_to_translate))
.cloned()
} {
- match deepl
- .translate_text(cue, deepl::Lang::EN)
- .model_type(deepl::ModelType::PreferQualityOptimized)
- .await
+ match translate_text(TranslateRequest {
+ input: cue.clone(),
+ source_lang: None, // TODO
+ target_lang: deepl::Lang::EN, // TODO
+ })
+ .await
{
- Ok(mut resp) => {
+ Ok(translated) => {
TRANSLATIONS
.write()
.entry(stream_ix)
.or_insert(Vec::new())
- .push(resp.translations.pop().unwrap().text);
+ .push(translated);
*next_cue_to_translate = *next_cue_to_translate + 1;
}
@@ -100,7 +101,45 @@ impl DeeplTranslator {
}
}
+ // check every second for new cues to be translated
relm4::tokio::time::sleep(Duration::from_secs(1)).await;
sender.input(DeeplTranslatorMsg::DoTranslate);
}
}
+
+#[derive(Clone)]
+struct TranslateRequest {
+ input: String,
+ source_lang: Option<deepl::Lang>,
+ target_lang: deepl::Lang,
+}
+
+impl Display for TranslateRequest {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(
+ f,
+ "{:?}-{}:{}",
+ self.source_lang, self.target_lang, self.input
+ )
+ }
+}
+
+#[io_cached(
+ disk = true,
+ create = r#"{ util::make_cache("deepl_translations") }"#,
+ map_error = r#"|err| err"#
+)]
+async fn translate_text(req: TranslateRequest) -> anyhow::Result<String> {
+ let deepl = DeepLApi::with(&Settings::default().deepl_api_key()).new();
+ let mut requester = deepl.translate_text(req.input, req.target_lang);
+ requester.model_type(ModelType::PreferQualityOptimized);
+ if let Some(source_lang) = req.source_lang {
+ requester.source_lang(source_lang);
+ }
+ let translated = requester.await?.translations.pop().unwrap().text;
+
+ // try to respect deepl's rate-limit
+ relm4::tokio::time::sleep(Duration::from_millis(500)).await;
+
+ Ok(translated)
+}