//! HTTP-клиент grabber-ai (путь А: сервис `python -m src.service`). //! //! Запуск: //! cargo run -- --text "Перевод: Дублированный | MovieDalen" //! cargo run -- --html page.html //! DUB_URL=http://host:8000 cargo run -- --text "..." use serde::Deserialize; #[derive(Debug, Deserialize)] struct Track { segment: String, translation_type: String, #[serde(default)] type_confidence: Option, #[serde(default)] studio_span: Option, #[serde(default)] studio: Option, #[serde(default)] studio_confidence: Option, #[serde(default)] is_18plus: bool, #[serde(default)] age_confidence: Option, } #[derive(Debug, Deserialize)] struct PredictResponse { tracks: Vec, } #[tokio::main] async fn main() -> Result<(), Box> { let base_url = std::env::var("DUB_URL").unwrap_or_else(|_| "http://127.0.0.1:8000".into()); let args: Vec = std::env::args().collect(); let body = if let Some(i) = args.iter().position(|a| a == "--text") { serde_json::json!({ "text": args.get(i + 1).ok_or("--text требует значение")? }) } else if let Some(i) = args.iter().position(|a| a == "--html") { let path = args.get(i + 1).ok_or("--html требует путь к файлу")?; let html = std::fs::read_to_string(path)?; serde_json::json!({ "html": html }) } else { eprintln!("использование: cargo run -- --text \"...\" | --html файл.html"); std::process::exit(1); }; let client = reqwest::Client::new(); let resp: PredictResponse = client .post(format!("{base_url}/predict")) .json(&body) .send() .await? .error_for_status()? .json() .await?; for t in &resp.tracks { let age = if t.is_18plus { " 18+" } else { "" }; println!( "{} — {}{} (conf {:.2})", t.translation_type, t.studio.clone().unwrap_or_else(|| "—".into()), age, t.type_confidence.unwrap_or(0.0) ); println!(" текст: {}", t.segment); if let Some(span) = &t.studio_span { println!(" спан: «{span}»"); } } Ok(()) }