diff --git a/src/actions.rs b/src/actions.rs index ad17e97..b42c34a 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -1,4 +1,4 @@ -use std::{fmt::Debug, process::exit}; +use std::{borrow::Borrow, fmt::Debug, process::exit}; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use reqwest::Url; @@ -28,7 +28,7 @@ impl Action { Self { client, base_url, - action: ActionCommands::Sync, + action: ActionCommands::OCRFixes, offset: 0, limit: None, pb, @@ -61,12 +61,18 @@ impl Action { async fn perform( &self, - payload: ActionPayload, + mut payload: ActionPayload, ) -> Result { let mut url = self.base_url.clone(); url.path_segments_mut().unwrap().push("subtitles"); let action_string: String = self.action.to_string(); url.query_pairs_mut().append_pair("action", &action_string); + if let ActionCommands::Sync(sync_options) = &self.action.borrow() { + payload.reference = sync_options.reference.clone(); + payload.max_offset_seconds = sync_options.max_offset_seconds; + payload.no_fix_framerate = Some(sync_options.no_fix_framerate); + payload.gss = Some(sync_options.gss); + } self.client.patch(url).json(&payload).send().await } @@ -82,12 +88,8 @@ impl Action { subtitle.audio_language_item.name, episode.title, )); - let payload = ActionPayload { - id: episode.sonarr_episode_id, - media_type: String::from("episode"), - language: subtitle.audio_language_item.code2.unwrap(), - path: subtitle.path.unwrap(), - }; + + let payload = ActionPayload::new(episode.sonarr_episode_id, "episode", &subtitle); match self.perform(payload).await { Ok(res) => match res.error_for_status() { Ok(_) => { @@ -128,12 +130,7 @@ impl Action { subtitle.audio_language_item.name, movie.title, )); - let payload = ActionPayload { - id: movie.radarr_id, - media_type: String::from("movie"), - language: subtitle.audio_language_item.code2.unwrap(), - path: subtitle.path.unwrap(), - }; + let payload = ActionPayload::new(movie.radarr_id, "movie", &subtitle); match self.perform(payload).await { Ok(res) => match res.error_for_status() { Ok(_) => { diff --git a/src/cli.rs b/src/cli.rs index f756484..1f1f6c7 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use clap::{Parser, Subcommand, ValueEnum}; +use clap::{Parser, Subcommand}; use reqwest::{header, Client, Url}; use reqwest_middleware::ClientBuilder; use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware}; @@ -101,10 +101,10 @@ impl Commands { } } -#[derive(Subcommand, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, ValueEnum)] +#[derive(Subcommand, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum ActionCommands { /// Sync all - Sync, + Sync(SyncOptions), /// Perform OCR fixes OCRFixes, /// Perform common fixes @@ -122,7 +122,7 @@ pub enum ActionCommands { impl ToString for ActionCommands { fn to_string(&self) -> String { match self { - ActionCommands::Sync => "sync".to_string(), + ActionCommands::Sync(_) => "sync".to_string(), ActionCommands::OCRFixes => "OCR_fixes".to_string(), ActionCommands::CommonFixes => "common".to_string(), ActionCommands::RemoveHearingImpaired => "remove_HI".to_string(), @@ -132,3 +132,18 @@ impl ToString for ActionCommands { } } } +#[derive(clap::Args, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SyncOptions { + /// Reference for sync from video file track number (a:0), subtitle (s:0), or some subtitles file path + #[arg(short)] + pub reference: Option, + /// Seconds of offset allowed when syncing [default: null] + #[arg(short, value_name = "MAX OFFSET")] + pub max_offset_seconds: Option, + /// Do not attempt to fix framerate [default: false] + #[arg(short, default_value_t = false)] + pub no_fix_framerate: bool, + /// Use Golden-Section search [default: false] + #[arg(short, default_value_t = false)] + pub gss: bool, +} diff --git a/src/data_types/request.rs b/src/data_types/request.rs index cfc9a12..6d2bd76 100644 --- a/src/data_types/request.rs +++ b/src/data_types/request.rs @@ -2,6 +2,8 @@ use clap::ValueEnum; use serde::{Deserialize, Serialize}; use std::str::FromStr; +use super::response::Subtitle; + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, ValueEnum)] pub enum MediaType { Movie, @@ -27,4 +29,29 @@ pub struct ActionPayload { pub media_type: String, pub language: String, pub path: String, + + // used only for sync action + #[serde(skip_serializing_if = "Option::is_none")] + pub reference: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub max_offset_seconds: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub no_fix_framerate: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub gss: Option, +} + +impl ActionPayload { + pub fn new(id: u32, media_type: &str, subtitle: &Subtitle) -> Self { + ActionPayload { + id, + media_type: String::from(media_type), + language: subtitle.audio_language_item.code2.clone().unwrap(), + path: subtitle.path.clone().unwrap(), + reference: None, + max_offset_seconds: None, + no_fix_framerate: None, + gss: None, + } + } }