From ad2e199b80f05020eaf11c4aa757b566a3cf454e Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sat, 26 Mar 2022 15:55:26 +0800 Subject: [PATCH] add new option use-progress-bar fix panic when artwork is 404 --- Language/pixiv_downloader.pot | 115 +++++++++++++++------------- Language/pixiv_downloader.zh_CN.po | 117 ++++++++++++++++------------- src/download.rs | 3 + src/ext/json.rs | 5 ++ src/ext/mod.rs | 1 + src/ext/use_or_not.rs | 82 ++++++++++++++++++++ src/main.rs | 1 + src/opt/mod.rs | 1 + src/opt/use_progress_bar.rs | 62 +++++++++++++++ src/opthelper.rs | 18 ++++- src/opts.rs | 20 +++++ src/settings_list.rs | 8 ++ 12 files changed, 329 insertions(+), 104 deletions(-) create mode 100644 src/ext/use_or_not.rs create mode 100644 src/opt/mod.rs create mode 100644 src/opt/use_progress_bar.rs diff --git a/Language/pixiv_downloader.pot b/Language/pixiv_downloader.pot index aa8a45c..2e5d5ed 100644 --- a/Language/pixiv_downloader.pot +++ b/Language/pixiv_downloader.pot @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: pixiv_downloader\n" -"POT-Creation-Date: 2022-03-25 22:17+0800\n" +"POT-Creation-Date: 2022-03-26 15:53+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,12 +17,13 @@ msgstr "" msgid "Failed to parse regex:" msgstr "" -#: author_name_filter.rs:46 retry_interval.rs:22 ugoira.rs:286 +#: author_name_filter.rs:46 ext/use_or_not.rs:73 retry_interval.rs:22 +#: ugoira.rs:286 msgid "Failed to get JSON object." msgstr "" -#: author_name_filter.rs:48 author_name_filter.rs:130 retry_interval.rs:61 -#: retry_interval.rs:65 ugoira.rs:288 ugoira.rs:293 +#: author_name_filter.rs:48 author_name_filter.rs:130 ext/use_or_not.rs:79 +#: retry_interval.rs:61 retry_interval.rs:65 ugoira.rs:288 ugoira.rs:293 msgid "Unsupported JSON type." msgstr "" @@ -138,76 +139,76 @@ msgstr "" msgid "Warning: Web api client not logined, some future may not work." msgstr "" -#: download.rs:70 +#: download.rs:73 msgid "Failed to get page count." msgstr "" -#: download.rs:79 +#: download.rs:82 msgid "Failed to get pages' data." msgstr "" -#: download.rs:92 +#: download.rs:95 msgid "Failed to save metadata to JSON file." msgstr "" -#: download.rs:107 +#: download.rs:110 msgid "Failed to get ugoira's data." msgstr "" -#: download.rs:113 +#: download.rs:116 msgid "Can not find source link for ugoira." msgstr "" -#: download.rs:119 download.rs:197 download.rs:271 +#: download.rs:122 download.rs:200 download.rs:274 msgid "Failed to get file name from url:" msgstr "" -#: download.rs:135 download.rs:141 +#: download.rs:138 download.rs:144 msgid "Failed to download ugoira:" msgstr "" -#: download.rs:146 +#: download.rs:149 msgid "Downloaded ugoira:" msgstr "" -#: download.rs:156 +#: download.rs:159 msgid "Warning: Failed to generate video's metadata:" msgstr "" -#: download.rs:166 +#: download.rs:169 msgid "Failed to convert from ugoira to mp4 video file:" msgstr "" -#: download.rs:169 +#: download.rs:172 msgid "Converted -> " msgstr "" -#: download.rs:172 +#: download.rs:175 msgid "Failed to parse frames:" msgstr "" -#: download.rs:179 +#: download.rs:182 msgid "Warning: Unknown illust type:" msgstr "" -#: download.rs:182 +#: download.rs:185 msgid "Warning: Failed to get illust's type." msgstr "" -#: download.rs:191 download.rs:265 +#: download.rs:194 download.rs:268 msgid "Failed to get original picture's link." msgstr "" -#: download.rs:212 download.rs:251 download.rs:291 download.rs:321 +#: download.rs:215 download.rs:254 download.rs:294 download.rs:324 msgid "Failed to add exif data to image:" msgstr "" -#: download.rs:231 download.rs:237 download.rs:301 download.rs:307 +#: download.rs:234 download.rs:240 download.rs:304 download.rs:310 #: pixiv_web.rs:153 msgid "Failed to download image:" msgstr "" -#: download.rs:242 download.rs:312 +#: download.rs:245 download.rs:315 msgid "Downloaded image:" msgstr "" @@ -215,98 +216,110 @@ msgstr "" msgid "Failed to parse duration from string." msgstr "" -#: opts.rs:93 +#: ext/use_or_not.rs:65 +msgid "Failed to parse value." +msgstr "" + +#: opts.rs:98 msgid "Warning: The specified config file not found." msgstr "" -#: opts.rs:117 +#: opts.rs:122 msgid "Usage:" msgstr "" -#: opts.rs:119 +#: opts.rs:124 msgid "Download an artwork" msgstr "" -#: opts.rs:121 +#: opts.rs:126 msgid "Fix the config file" msgstr "" -#: opts.rs:123 +#: opts.rs:128 msgid "Print all available settings" msgstr "" -#: opts.rs:131 +#: opts.rs:136 msgid "Print help message." msgstr "" -#: opts.rs:135 +#: opts.rs:140 msgid "The location of config file." msgstr "" -#: opts.rs:141 settings_list.rs:11 +#: opts.rs:146 settings_list.rs:13 msgid "The location of cookies file. Used for web API." msgstr "" -#: opts.rs:147 settings_list.rs:12 +#: opts.rs:152 settings_list.rs:14 msgid "The language of translated tags." msgstr "" -#: opts.rs:150 +#: opts.rs:155 msgid "Verbose logging." msgstr "" -#: opts.rs:151 +#: opts.rs:156 msgid "Overwrite existing file." msgstr "" -#: opts.rs:152 +#: opts.rs:157 msgid "Skip overwrite existing file." msgstr "" -#: opts.rs:156 settings_list.rs:13 +#: opts.rs:161 settings_list.rs:15 msgid "Max retry count if request failed." msgstr "" -#: opts.rs:162 settings_list.rs:14 +#: opts.rs:167 settings_list.rs:16 msgid "The interval (in seconds) between two retries." msgstr "" -#: opts.rs:165 settings_list.rs:15 +#: opts.rs:170 settings_list.rs:17 msgid "Use data from webpage first." msgstr "" -#: opts.rs:170 settings_list.rs:18 +#: opts.rs:175 settings_list.rs:20 msgid "Add/Update exif information to image files even when overwrite are disabled." msgstr "" -#: opts.rs:191 +#: opts.rs:180 settings_list.rs:22 +msgid "Whether to enable progress bar." +msgstr "" + +#: opts.rs:202 msgid "Unknown command." msgstr "" -#: opts.rs:201 +#: opts.rs:212 msgid "Failed to parse ID:" msgstr "" -#: opts.rs:207 +#: opts.rs:218 msgid "No URL or ID specified." msgstr "" -#: opts.rs:215 +#: opts.rs:226 msgid "No detailed command specified." msgstr "" -#: opts.rs:228 +#: opts.rs:239 msgid "Unknown config subcommand." msgstr "" -#: opts.rs:264 +#: opts.rs:275 msgid "Retry count must be an non-negative integer:" msgstr "" -#: opts.rs:273 +#: opts.rs:284 msgid "Failed to parse retry interval:" msgstr "" +#: opts.rs:298 +msgid "Failed to parse :" +msgstr "" + #: parser/description.rs:129 parser/metadata.rs:76 msgid "Failed to parse HTML:" msgstr "" @@ -407,15 +420,15 @@ msgstr "" msgid "Failed to flush file:" msgstr "" -#: settings_list.rs:10 +#: settings_list.rs:12 msgid "Pixiv's refresh tokens. Used to login." msgstr "" -#: settings_list.rs:16 +#: settings_list.rs:18 msgid "Remove the part which after these parttens." msgstr "" -#: settings_list.rs:19 +#: settings_list.rs:21 msgid "Progress bar's template. See for more informations." msgstr "" @@ -535,14 +548,14 @@ msgstr "" msgid "Error when downloading file:" msgstr "" -#: main.rs:84 +#: main.rs:85 msgid "Failed to save config file:" msgstr "" -#: main.rs:95 +#: main.rs:96 msgid "All available settings:" msgstr "" -#: main.rs:127 +#: main.rs:128 msgid "Can not read config file:" msgstr "" diff --git a/Language/pixiv_downloader.zh_CN.po b/Language/pixiv_downloader.zh_CN.po index ca0f4f4..6c5ec6f 100644 --- a/Language/pixiv_downloader.zh_CN.po +++ b/Language/pixiv_downloader.zh_CN.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: pixiv_downloader\n" -"POT-Creation-Date: 2022-03-25 22:17+0800\n" -"PO-Revision-Date: 2022-03-25 22:19+0800\n" +"POT-Creation-Date: 2022-03-26 15:53+0800\n" +"PO-Revision-Date: 2022-03-26 15:54+0800\n" "Last-Translator: lifegpc \n" "Language-Team: \n" "Language: zh_CN\n" @@ -18,12 +18,13 @@ msgstr "" msgid "Failed to parse regex:" msgstr "无法解析正则:" -#: author_name_filter.rs:46 retry_interval.rs:22 ugoira.rs:286 +#: author_name_filter.rs:46 ext/use_or_not.rs:73 retry_interval.rs:22 +#: ugoira.rs:286 msgid "Failed to get JSON object." msgstr "无法获取 JSON 对象。" -#: author_name_filter.rs:48 author_name_filter.rs:130 retry_interval.rs:61 -#: retry_interval.rs:65 ugoira.rs:288 ugoira.rs:293 +#: author_name_filter.rs:48 author_name_filter.rs:130 ext/use_or_not.rs:79 +#: retry_interval.rs:61 retry_interval.rs:65 ugoira.rs:288 ugoira.rs:293 msgid "Unsupported JSON type." msgstr "不支持的 JSON 类型。" @@ -139,76 +140,76 @@ msgstr "无法初始化 Pixiv 网页 API 客户端。" msgid "Warning: Web api client not logined, some future may not work." msgstr "警告:Web API 客户端未登录,一些功能可能无法工作。" -#: download.rs:70 +#: download.rs:73 msgid "Failed to get page count." msgstr "无法获取页数。" -#: download.rs:79 +#: download.rs:82 msgid "Failed to get pages' data." msgstr "无法获取每页数据。" -#: download.rs:92 +#: download.rs:95 msgid "Failed to save metadata to JSON file." msgstr "无法将元数据保存到 JSON 文件。" -#: download.rs:107 +#: download.rs:110 msgid "Failed to get ugoira's data." msgstr "无法获取动图数据。" -#: download.rs:113 +#: download.rs:116 msgid "Can not find source link for ugoira." msgstr "无法获取动图的链接。" -#: download.rs:119 download.rs:197 download.rs:271 +#: download.rs:122 download.rs:200 download.rs:274 msgid "Failed to get file name from url:" msgstr "无法从 URL 获取文件名:" -#: download.rs:135 download.rs:141 +#: download.rs:138 download.rs:144 msgid "Failed to download ugoira:" msgstr "无法下载动图:" -#: download.rs:146 +#: download.rs:149 msgid "Downloaded ugoira:" msgstr "已下载动图:" -#: download.rs:156 +#: download.rs:159 msgid "Warning: Failed to generate video's metadata:" msgstr "警告:无法生成视频元数据:" -#: download.rs:166 +#: download.rs:169 msgid "Failed to convert from ugoira to mp4 video file:" msgstr "无法将动图转换为 mp4 视频文件:" -#: download.rs:169 +#: download.rs:172 msgid "Converted -> " msgstr "已转换 -> " -#: download.rs:172 +#: download.rs:175 msgid "Failed to parse frames:" msgstr "无法解析帧数据:" -#: download.rs:179 +#: download.rs:182 msgid "Warning: Unknown illust type:" msgstr "警告:未知的插图类型:" -#: download.rs:182 +#: download.rs:185 msgid "Warning: Failed to get illust's type." msgstr "警告:无法获取插图类型。" -#: download.rs:191 download.rs:265 +#: download.rs:194 download.rs:268 msgid "Failed to get original picture's link." msgstr "无法获取原图链接。" -#: download.rs:212 download.rs:251 download.rs:291 download.rs:321 +#: download.rs:215 download.rs:254 download.rs:294 download.rs:324 msgid "Failed to add exif data to image:" msgstr "无法往图片增加 EXIF 数据:" -#: download.rs:231 download.rs:237 download.rs:301 download.rs:307 +#: download.rs:234 download.rs:240 download.rs:304 download.rs:310 #: pixiv_web.rs:153 msgid "Failed to download image:" msgstr "无法下载图片:" -#: download.rs:242 download.rs:312 +#: download.rs:245 download.rs:315 msgid "Downloaded image:" msgstr "已下载图片:" @@ -216,99 +217,111 @@ msgstr "已下载图片:" msgid "Failed to parse duration from string." msgstr "无法解析从字符串解析时长。" -#: opts.rs:93 +#: ext/use_or_not.rs:65 +msgid "Failed to parse value." +msgstr "无法解析值。" + +#: opts.rs:98 msgid "Warning: The specified config file not found." msgstr "警告:没有找到指定的设置文件。" -#: opts.rs:117 +#: opts.rs:122 msgid "Usage:" msgstr "使用方法:" -#: opts.rs:119 +#: opts.rs:124 msgid "Download an artwork" msgstr "下载一个作品" -#: opts.rs:121 +#: opts.rs:126 msgid "Fix the config file" msgstr "修复设置文件" -#: opts.rs:123 +#: opts.rs:128 msgid "Print all available settings" msgstr "打印所有可用的设置" -#: opts.rs:131 +#: opts.rs:136 msgid "Print help message." msgstr "打印帮助信息。" -#: opts.rs:135 +#: opts.rs:140 msgid "The location of config file." msgstr "设置文件的位置。" -#: opts.rs:141 settings_list.rs:11 +#: opts.rs:146 settings_list.rs:13 msgid "The location of cookies file. Used for web API." msgstr "cookies 文件的位置。用于网页 API。" -#: opts.rs:147 settings_list.rs:12 +#: opts.rs:152 settings_list.rs:14 msgid "The language of translated tags." msgstr "翻译后的标签语言。" -#: opts.rs:150 +#: opts.rs:155 msgid "Verbose logging." msgstr "启用详细内容输出。" -#: opts.rs:151 +#: opts.rs:156 msgid "Overwrite existing file." msgstr "覆盖已有文件。" -#: opts.rs:152 +#: opts.rs:157 msgid "Skip overwrite existing file." msgstr "跳过覆盖已有文件。" -#: opts.rs:156 settings_list.rs:13 +#: opts.rs:161 settings_list.rs:15 msgid "Max retry count if request failed." msgstr "请求失败时最大重试次数。" -#: opts.rs:162 settings_list.rs:14 +#: opts.rs:167 settings_list.rs:16 msgid "The interval (in seconds) between two retries." msgstr "两次尝试的间隔时间(单位:秒)。" -#: opts.rs:165 settings_list.rs:15 +#: opts.rs:170 settings_list.rs:17 msgid "Use data from webpage first." msgstr "优先使用来自网页的数据。" -#: opts.rs:170 settings_list.rs:18 +#: opts.rs:175 settings_list.rs:20 msgid "" "Add/Update exif information to image files even when overwrite are disabled." msgstr "添加或更新图片的 EXIF 信息,即使不覆盖图片文件。" -#: opts.rs:191 +#: opts.rs:180 settings_list.rs:22 +msgid "Whether to enable progress bar." +msgstr "是否启用进度条。" + +#: opts.rs:202 msgid "Unknown command." msgstr "未知指令。" -#: opts.rs:201 +#: opts.rs:212 msgid "Failed to parse ID:" msgstr "无法解析 ID:" -#: opts.rs:207 +#: opts.rs:218 msgid "No URL or ID specified." msgstr "没有指定网址或 ID。" -#: opts.rs:215 +#: opts.rs:226 msgid "No detailed command specified." msgstr "没有指定更详细的指令。" -#: opts.rs:228 +#: opts.rs:239 msgid "Unknown config subcommand." msgstr "未知的 config 子指令。" -#: opts.rs:264 +#: opts.rs:275 msgid "Retry count must be an non-negative integer:" msgstr "重试次数不能是负数:" -#: opts.rs:273 +#: opts.rs:284 msgid "Failed to parse retry interval:" msgstr "无法解析间隔时间:" +#: opts.rs:298 +msgid "Failed to parse :" +msgstr "无法解析 :" + #: parser/description.rs:129 parser/metadata.rs:76 msgid "Failed to parse HTML:" msgstr "无法解析 HTML:" @@ -413,15 +426,15 @@ msgstr "无法将设置转换为 JSON 对象。" msgid "Failed to flush file:" msgstr "无法刷新文件缓冲区:" -#: settings_list.rs:10 +#: settings_list.rs:12 msgid "Pixiv's refresh tokens. Used to login." msgstr "Pixiv 的 refresh tokens。用于登录。" -#: settings_list.rs:16 +#: settings_list.rs:18 msgid "Remove the part which after these parttens." msgstr "移除匹配的部分。" -#: settings_list.rs:19 +#: settings_list.rs:21 msgid "Progress bar's template. See for more informations." msgstr "进度条模板。更多信息见 。" @@ -541,14 +554,14 @@ msgstr "正在下载 \"\"。" msgid "Error when downloading file:" msgstr "下载文件时发生错误:" -#: main.rs:84 +#: main.rs:85 msgid "Failed to save config file:" msgstr "无法保存设置文件:" -#: main.rs:95 +#: main.rs:96 msgid "All available settings:" msgstr "所有可用的设置:" -#: main.rs:127 +#: main.rs:128 msgid "Can not read config file:" msgstr "无法读取设置文件:" diff --git a/src/download.rs b/src/download.rs index 3f27eef..ea43769 100644 --- a/src/download.rs +++ b/src/download.rs @@ -60,6 +60,9 @@ impl Main { if re.is_none() { re = pw.get_artwork_ajax(id); } + if re.is_none() { + return 1; + } let re = re.unwrap(); if ajax_ver { pages = (&re["pageCount"]).as_u64(); diff --git a/src/ext/json.rs b/src/ext/json.rs index 875359e..e7caaf2 100644 --- a/src/ext/json.rs +++ b/src/ext/json.rs @@ -33,3 +33,8 @@ impl ToJson for &JsonValue { Some((*self).clone()) } } + +pub trait FromJson where Self: Sized { + type Err; + fn from_json(v: T) -> Result; +} diff --git a/src/ext/mod.rs b/src/ext/mod.rs index 6f9d062..d9f5e71 100644 --- a/src/ext/mod.rs +++ b/src/ext/mod.rs @@ -4,3 +4,4 @@ pub mod flagset; pub mod json; #[cfg(any(feature = "exif", feature = "avdict", feature = "ugoira"))] pub mod rawhandle; +pub mod use_or_not; diff --git a/src/ext/use_or_not.rs b/src/ext/use_or_not.rs new file mode 100644 index 0000000..d604864 --- /dev/null +++ b/src/ext/use_or_not.rs @@ -0,0 +1,82 @@ +use crate::ext::json::FromJson; +use crate::ext::json::ToJson; +use crate::gettext; +use crate::stdext::TryErr; +use std::str::FromStr; + +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] +pub enum UseOrNot { + /// Auto Detect + Auto, + /// Enabled + Yes, + /// Disabled + No, +} + +/// Convert to bool (whether to enable some features) +pub trait ToBool where Self: AsRef { + /// Auto detect function. + fn detect(&self) -> bool; + /// Return whether to enable some features + fn to_bool(&self) -> bool { + match self.as_ref() { + UseOrNot::Auto => { self.detect() } + UseOrNot::Yes => { true } + UseOrNot::No => { false } + } + } +} + +impl AsRef for UseOrNot { + fn as_ref(&self) -> &Self { + self + } +} + +impl Default for UseOrNot { + fn default() -> Self { + Self::Auto + } +} + +impl From for UseOrNot { + fn from(v: bool) -> Self { + if v { + Self::Yes + } else { + Self::No + } + } +} + +impl FromStr for UseOrNot { + type Err = &'static str; + fn from_str(s: &str) -> Result { + let s = s.to_lowercase(); + let s = s.as_str(); + if s == "yes" || s == "true" { + Ok(Self::Yes) + } else if s == "no" || s == "false" { + Ok(Self::No) + } else if s == "auto" { + Ok(Self::Auto) + } else { + Err(gettext("Failed to parse value.")) + } + } +} + +impl FromJson for UseOrNot { + type Err = &'static str; + fn from_json(v: T) -> Result { + let v = v.to_json().try_err(gettext("Failed to get JSON object."))?; + if v.is_boolean() { + Ok(Self::from(v.as_bool().unwrap())) + } else if v.is_string() { + Self::from_json(v.as_str().unwrap()) + } else { + Err(gettext("Unsupported JSON type.")) + } + } +} diff --git a/src/main.rs b/src/main.rs index f737a2a..a006a45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,7 @@ mod ext; mod i18n; mod list; mod opthelper; +mod opt; mod opts; mod parser; mod pixiv_link; diff --git a/src/opt/mod.rs b/src/opt/mod.rs new file mode 100644 index 0000000..12b4b24 --- /dev/null +++ b/src/opt/mod.rs @@ -0,0 +1 @@ +pub mod use_progress_bar; diff --git a/src/opt/use_progress_bar.rs b/src/opt/use_progress_bar.rs new file mode 100644 index 0000000..fe98feb --- /dev/null +++ b/src/opt/use_progress_bar.rs @@ -0,0 +1,62 @@ +use crate::ext::use_or_not::ToBool; +use crate::ext::use_or_not::UseOrNot; + +#[derive(Clone, Copy, Debug)] +pub struct UseProgressBar { + v: UseOrNot, + stream: atty::Stream, +} + +impl AsRef for UseProgressBar { + fn as_ref(&self) -> &Self { + self + } +} + +impl AsRef for UseProgressBar { + fn as_ref(&self) -> &UseOrNot { + self.v.as_ref() + } +} + +impl Default for UseProgressBar { + fn default() -> Self { + Self { + v: UseOrNot::Auto, + stream: atty::Stream::Stdout, + } + } +} + +impl From for UseProgressBar { + fn from(v: bool) -> Self { + Self { + v: UseOrNot::from(v), + stream: atty::Stream::Stdout, + } + } +} + +impl From for UseProgressBar { + fn from(stream: atty::Stream) -> Self { + Self { + v: UseOrNot::Auto, + stream, + } + } +} + +impl From for UseProgressBar { + fn from(v: UseOrNot) -> Self { + Self { + v, + stream: atty::Stream::Stdout, + } + } +} + +impl ToBool for UseProgressBar { + fn detect(&self) -> bool { + atty::is(self.stream) + } +} diff --git a/src/opthelper.rs b/src/opthelper.rs index 0b259e2..4622d1f 100644 --- a/src/opthelper.rs +++ b/src/opthelper.rs @@ -1,4 +1,8 @@ use crate::author_name_filter::AuthorNameFilter; +use crate::ext::json::FromJson; +use crate::ext::use_or_not::ToBool; +use crate::ext::use_or_not::UseOrNot; +use crate::opt::use_progress_bar::UseProgressBar; use crate::opts::CommandOpts; use crate::list::NonTailList; use crate::retry_interval::parse_retry_interval_from_json; @@ -6,7 +10,7 @@ use crate::settings::SettingStore; use std::time::Duration; /// An sturct to access all available settings/command line switches -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct OptHelper<'a> { /// Command Line Options opt: &'a CommandOpts, @@ -14,6 +18,7 @@ pub struct OptHelper<'a> { settings: &'a SettingStore, default_retry_interval: NonTailList, _author_name_filters: Option>, + _use_progress_bar: Option, } impl<'a> OptHelper<'a> { @@ -54,11 +59,19 @@ impl<'a> OptHelper<'a> { } else { None }; + let _use_progress_bar = if opt.use_progress_bar.is_some() { + Some(UseProgressBar::from(opt.use_progress_bar.unwrap())) + } else if settings.have("use-progress-bar") { + Some(UseProgressBar::from(UseOrNot::from_json(settings.get("use-progress-bar").unwrap()).unwrap())) + } else { + None + }; Self { opt, settings, default_retry_interval: l, _author_name_filters: _author_name_filters, + _use_progress_bar: _use_progress_bar, } } @@ -120,6 +133,9 @@ impl<'a> OptHelper<'a> { /// Return whether to use progress bar. pub fn use_progress_bar(&self) -> bool { + if self._use_progress_bar.is_some() { + return self._use_progress_bar.as_ref().unwrap().to_bool(); + } atty::is(atty::Stream::Stdout) } diff --git a/src/opts.rs b/src/opts.rs index 919a46f..b901b3d 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -1,5 +1,6 @@ extern crate getopts; +use crate::ext::use_or_not::UseOrNot; use crate::gettext; use crate::list::NonTailList; use crate::pixiv_link::PixivID; @@ -8,6 +9,7 @@ use crate::utils::check_file_exists; use crate::utils::get_exe_path_else_current; use getopts::Options; use std::env; +use std::str::FromStr; use std::time::Duration; /// Command Line command @@ -62,6 +64,8 @@ pub struct CommandOpts { #[cfg(feature = "exif")] /// Add/Update exif information to image files even when overwrite are disabled pub update_exif: bool, + /// Whether to enable progress bar + pub use_progress_bar: Option, } impl CommandOpts { @@ -80,6 +84,7 @@ impl CommandOpts { use_webpage: false, #[cfg(feature = "exif")] update_exif: false, + use_progress_bar: None, } } @@ -169,6 +174,12 @@ pub fn parse_cmd() -> Option { "update-exif", gettext("Add/Update exif information to image files even when overwrite are disabled."), ); + opts.optopt( + "", + "use-progress-bar", + gettext("Whether to enable progress bar."), + "yes/no/auto", + ); let result = match opts.parse(&argv[1..]) { Ok(m) => m, Err(err) => { @@ -280,5 +291,14 @@ pub fn parse_cmd() -> Option { { re.as_mut().unwrap().update_exif = result.opt_present("update-exif"); } + if result.opt_present("use-progress-bar") { + let s = result.opt_str("use-progress-bar").unwrap(); + let r = UseOrNot::from_str(s.as_str()); + if r.is_err() { + println!("{} {}", gettext("Failed to parse :").replace("", "use-progress-bar").as_str(), r.unwrap_err()); + return None; + } + re.as_mut().unwrap().use_progress_bar = Some(r.unwrap()); + } re } diff --git a/src/settings_list.rs b/src/settings_list.rs index 8200cc8..6ad43b8 100644 --- a/src/settings_list.rs +++ b/src/settings_list.rs @@ -1,4 +1,6 @@ use crate::author_name_filter::check_author_name_filters; +use crate::ext::json::FromJson; +use crate::ext::use_or_not::UseOrNot; use crate::gettext; use crate::retry_interval::check_retry_interval; use crate::settings::SettingDes; @@ -17,6 +19,7 @@ pub fn get_settings_list() -> Vec { #[cfg(feature = "exif")] SettingDes::new("update-exif", gettext("Add/Update exif information to image files even when overwrite are disabled."), JsonValueType::Boolean, None).unwrap(), 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(), ] } @@ -29,3 +32,8 @@ fn check_nonempty_str(obj: &JsonValue) -> bool { let r = obj.as_str(); r.is_some() && r.unwrap().len() != 0 } + +fn check_user_or_not(obj: &JsonValue) -> bool { + let r = UseOrNot::from_json(obj); + r.is_ok() +}