From 8b60be1fdbb258bb0595e16f45efaa274a03f6e0 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Tue, 14 Jun 2022 12:25:34 +0000 Subject: [PATCH] Add new options --- src/downloader/downloader.rs | 4 +- src/opthelper.rs | 34 +++++++++++++++ src/opts.rs | 81 ++++++++++++++++++++++++++++++------ src/settings_list.rs | 2 + 4 files changed, 106 insertions(+), 15 deletions(-) diff --git a/src/downloader/downloader.rs b/src/downloader/downloader.rs index 3fd15fb..2247d3a 100644 --- a/src/downloader/downloader.rs +++ b/src/downloader/downloader.rs @@ -506,11 +506,11 @@ impl Do } else { self.disable_progress_bar(); } - match helper.retry() { + match helper.download_retry() { Some(u) => self.set_max_retry_count(u), None => {} } - self.set_retry_interval(helper.retry_interval()); + self.set_retry_interval(helper.download_retry_interval()); } #[inline] diff --git a/src/opthelper.rs b/src/opthelper.rs index 8257644..0d692d8 100644 --- a/src/opthelper.rs +++ b/src/opthelper.rs @@ -45,6 +45,40 @@ impl OptHelper { } } + /// Return retry count when downloading failed. + pub fn download_retry(&self) -> Option { + if self.opt.get_ref().download_retry.is_some() { + return Some(self.opt.get_ref().download_retry.unwrap()); + } + let re = self.settings.get_ref().get("download-retry"); + if re.is_some() { + return Some(re.unwrap().as_i64().unwrap()); + } + self.retry() + } + + /// Return retry interval when downloading files. + pub fn download_retry_interval(&self) -> NonTailList { + if self.opt.get_ref().download_retry_interval.is_some() { + return self + .opt + .get_ref() + .download_retry_interval + .as_ref() + .unwrap() + .clone(); + } + if self.settings.get_ref().have("download-retry-interval") { + let v = self + .settings + .get_ref() + .get("download-retry-interval") + .unwrap(); + return parse_retry_interval_from_json(v).unwrap(); + } + self.retry_interval() + } + /// return language pub fn language(&self) -> Option { if self.opt.get_ref().language.is_some() { diff --git a/src/opts.rs b/src/opts.rs index 80beddc..50b2d82 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -10,6 +10,7 @@ use crate::utils::get_exe_path_else_current; use getopts::HasArg; use getopts::Options; use std::env; +use std::num::ParseIntError; use std::str::FromStr; use std::time::Duration; @@ -71,6 +72,10 @@ pub struct CommandOpts { pub use_progress_bar: Option, /// Whether to download multiple images at the same time pub download_multiple_images: Option, + /// Max retry count when downloading failed. + pub download_retry: Option, + /// Retry interval when downloading files. + pub download_retry_interval: Option>, } impl CommandOpts { @@ -91,6 +96,8 @@ impl CommandOpts { update_exif: false, use_progress_bar: None, download_multiple_images: None, + download_retry: None, + download_retry_interval: None, } } @@ -136,7 +143,7 @@ pub fn print_usage(prog: &str, opts: &Options) { println!("{}", opts.usage(brief.as_str())); } -/// Prase bool string +/// Prase [bool] from string pub fn parse_bool>(s: Option) -> Result, String> { let tmp = match s { Some(s) => Some(s.as_ref().to_lowercase()), @@ -160,6 +167,19 @@ pub fn parse_bool>(s: Option) -> Result, String> { } } +/// Prase [i64] from string +pub fn parse_i64>(s: Option) -> Result, ParseIntError> { + match s { + Some(s) => { + let s = s.as_ref(); + let s = s.trim(); + let c = s.parse::()?; + Ok(Some(c)) + } + None => Ok(None), + } +} + /// Parse optional option /// * `opts` - The result of options. See [getopts::Matches]. /// * `key` - The key of the option. @@ -237,11 +257,29 @@ pub fn parse_cmd() -> Option { opts.opt( "", "download-multiple-images", - gettext("Download multiple images at the same time."), + format!( + "{} ({} {})", + gettext("Download multiple images at the same time."), + gettext("Default:"), + "yes" + ) + .as_str(), "yes/no", HasArg::Maybe, getopts::Occur::Optional, ); + opts.optopt( + "", + "download-retry", + gettext("Max retry count if download failed."), + "COUNT", + ); + opts.optopt( + "", + "download-retry-interval", + gettext("The interval (in seconds) between two retries when downloading files."), + "LIST", + ); let result = match opts.parse(&argv[1..]) { Ok(m) => m, Err(err) => { @@ -332,19 +370,14 @@ pub fn parse_cmd() -> Option { } else { None }; - if result.opt_present("retry") { - let s = result.opt_str("retry").unwrap(); - let s = s.trim(); - let c = s.parse::(); - if c.is_err() { - println!( - "{} {}", - gettext("Retry count must be an non-negative integer:"), - c.unwrap_err() - ); + match parse_i64(result.opt_str("retry")) { + Ok(r) => { + re.as_mut().unwrap().retry = r; + } + Err(e) => { + println!("{} {}", gettext("Failed to parse retry count:"), e); return None; } - re.as_mut().unwrap().retry = Some(c.unwrap()); } if result.opt_present("retry-interval") { let s = result.opt_str("retry-interval").unwrap(); @@ -392,6 +425,28 @@ pub fn parse_cmd() -> Option { return None; } } + match parse_i64(result.opt_str("download-retry")) { + Ok(r) => { + re.as_mut().unwrap().download_retry = r; + } + Err(e) => { + println!("{} {}", gettext("Failed to parse retry count:"), e); + return None; + } + } + if result.opt_present("download-retry-interval") { + let s = result.opt_str("download-retry-interval").unwrap(); + let r = parse_retry_interval_from_str(s.as_str()); + if r.is_err() { + println!( + "{} {}", + gettext("Failed to parse retry interval:"), + r.unwrap_err() + ); + return None; + } + re.as_mut().unwrap().download_retry_interval = Some(r.unwrap()); + } re } diff --git a/src/settings_list.rs b/src/settings_list.rs index 889e2bc..4e0eb74 100644 --- a/src/settings_list.rs +++ b/src/settings_list.rs @@ -21,6 +21,8 @@ pub fn get_settings_list() -> Vec { SettingDes::new("progress-bar-template", gettext("Progress bar's template. See for more informations.").replace("", "https://docs.rs/indicatif/latest/indicatif/#templates").as_str(), JsonValueType::Str, Some(check_nonempty_str)).unwrap(), SettingDes::new("use-progress-bar", gettext("Whether to enable progress bar."), JsonValueType::Multiple, Some(check_user_or_not)).unwrap(), SettingDes::new("download-multiple-images", gettext("Download multiple images at the same time."), JsonValueType::Boolean, None).unwrap(), + SettingDes::new("download-retry", gettext("Max retry count if download failed."), JsonValueType::Number, Some(check_i64)).unwrap(), + SettingDes::new("download-retry-interval", gettext("The interval (in seconds) between two retries when downloading files."), JsonValueType::Multiple, Some(check_retry_interval)).unwrap() ] }