diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-02-14 16:39:45 +0100 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2025-02-14 16:39:45 +0100 |
commit | e30b69dd4c2ebfb4ae77b38037b66f3e6fcb17bc (patch) | |
tree | 3f68362bf4b0a1ea097d3b584f52b2da4c00ff71 | |
parent | fix(yt/cli): Make most of the arguments to `yt select <cmd> <hash>` optional (diff) | |
download | yt-e30b69dd4c2ebfb4ae77b38037b66f3e6fcb17bc.zip |
feat(yt): Make colorization of the output configurable
-rw-r--r-- | contrib/config.toml | 3 | ||||
-rw-r--r-- | yt/src/cli.rs | 4 | ||||
-rw-r--r-- | yt/src/config/default.rs | 7 | ||||
-rw-r--r-- | yt/src/config/definitions.rs | 7 | ||||
-rw-r--r-- | yt/src/config/file_system.rs | 12 | ||||
-rw-r--r-- | yt/src/config/mod.rs | 10 | ||||
-rw-r--r-- | yt/src/main.rs | 4 | ||||
-rw-r--r-- | yt/src/update/mod.rs | 2 | ||||
-rw-r--r-- | yt/src/videos/display/mod.rs | 72 | ||||
-rw-r--r-- | yt/src/videos/mod.rs | 2 |
10 files changed, 81 insertions, 42 deletions
diff --git a/contrib/config.toml b/contrib/config.toml index ffd91a1..ac06959 100644 --- a/contrib/config.toml +++ b/contrib/config.toml @@ -8,6 +8,9 @@ # You should have received a copy of the License along with this program. # If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. +[global] +display_colors = true + [select] playback_speed = 2.7 subtitle_langs = "" diff --git a/yt/src/cli.rs b/yt/src/cli.rs index e95b93f..6e6dd3a 100644 --- a/yt/src/cli.rs +++ b/yt/src/cli.rs @@ -38,6 +38,10 @@ pub struct CliArgs { #[arg(long="verbose", short = 'v', action = ArgAction::Count)] pub verbosity: u8, + /// Display colors [defaults to true, if the config file has no value] + #[arg(long, short = 'C')] + pub color: Option<bool>, + /// Set the path to the videos.db. This overrides the default and the config file. #[arg(long, short)] pub db_path: Option<PathBuf>, diff --git a/yt/src/config/default.rs b/yt/src/config/default.rs index 926f422..9189545 100644 --- a/yt/src/config/default.rs +++ b/yt/src/config/default.rs @@ -44,6 +44,13 @@ pub(super) fn create_path(path: PathBuf) -> Result<PathBuf> { pub(crate) const PREFIX: &str = "yt"; +pub(crate) mod global { + pub(crate) fn display_colors() -> bool { + // TODO: This should probably check if the output is a tty and otherwise return `false` <2025-02-14> + true + } +} + pub(crate) mod select { pub(crate) fn playback_speed() -> f64 { 2.7 diff --git a/yt/src/config/definitions.rs b/yt/src/config/definitions.rs index 3d025b3..9f8b971 100644 --- a/yt/src/config/definitions.rs +++ b/yt/src/config/definitions.rs @@ -15,6 +15,7 @@ use serde::Deserialize; #[derive(Debug, Deserialize, PartialEq)] #[serde(deny_unknown_fields)] pub(crate) struct ConfigFile { + pub global: Option<GlobalConfig>, pub select: Option<SelectConfig>, pub watch: Option<WatchConfig>, pub paths: Option<PathsConfig>, @@ -24,6 +25,12 @@ pub(crate) struct ConfigFile { #[derive(Debug, Deserialize, PartialEq, Clone, Copy)] #[serde(deny_unknown_fields)] +pub(crate) struct GlobalConfig { + pub display_colors: Option<bool>, +} + +#[derive(Debug, Deserialize, PartialEq, Clone, Copy)] +#[serde(deny_unknown_fields)] pub(crate) struct UpdateConfig { pub max_backlog: Option<u32>, } diff --git a/yt/src/config/file_system.rs b/yt/src/config/file_system.rs index 6709a2b..49e02fe 100644 --- a/yt/src/config/file_system.rs +++ b/yt/src/config/file_system.rs @@ -11,8 +11,8 @@ use crate::config::{DownloadConfig, PathsConfig, SelectConfig, WatchConfig}; use super::{ - default::{create_path, download, paths, select, update, watch}, - Config, UpdateConfig, + default::{create_path, download, global, paths, select, update, watch}, + Config, GlobalConfig, UpdateConfig, }; use std::{fs::read_to_string, path::PathBuf}; @@ -70,6 +70,7 @@ impl Config { pub fn from_config_file( db_path: Option<PathBuf>, config_path: Option<PathBuf>, + display_colors: Option<bool>, ) -> Result<Self> { let config_file_path = config_path.map_or_else(|| -> Result<_> { paths::config_path() }, Ok)?; @@ -79,6 +80,13 @@ impl Config { .context("Failed to parse the config file as toml")?; Ok(Self { + global: GlobalConfig { + display_colors: { + let config_value: Option<bool> = get! {@option config, global, display_colors}; + + display_colors.unwrap_or(config_value.unwrap_or_else(global::display_colors)) + }, + }, select: SelectConfig { playback_speed: get! {select::playback_speed, config, select, playback_speed}, subtitle_langs: get! {select::subtitle_langs, config, select, subtitle_langs}, diff --git a/yt/src/config/mod.rs b/yt/src/config/mod.rs index 36dd3fc..be99caa 100644 --- a/yt/src/config/mod.rs +++ b/yt/src/config/mod.rs @@ -21,15 +21,21 @@ pub mod file_system; #[derive(Serialize, Debug)] pub struct Config { + pub global: GlobalConfig, pub select: SelectConfig, pub watch: WatchConfig, pub paths: PathsConfig, pub download: DownloadConfig, pub update: UpdateConfig, } +// These structures could get non-copy fields in the future. + +#[derive(Serialize, Debug)] +#[allow(missing_copy_implementations)] +pub struct GlobalConfig { + pub display_colors: bool, +} #[derive(Serialize, Debug)] -// This structure could get non-copy fields in the future. -// The same thing applies to all the other structures here. #[allow(missing_copy_implementations)] pub struct UpdateConfig { pub max_backlog: u32, diff --git a/yt/src/main.rs b/yt/src/main.rs index 3097eea..4378346 100644 --- a/yt/src/main.rs +++ b/yt/src/main.rs @@ -90,7 +90,7 @@ async fn main() -> Result<()> { }); let app = { - let config = Config::from_config_file(args.db_path, args.config_path)?; + let config = Config::from_config_file(args.db_path, args.config_path, args.color)?; App::new(config).await? }; @@ -151,7 +151,7 @@ async fn main() -> Result<()> { .to_formatted_video(&app) .await .context("Failed to format video")? - .colorize()) + .colorize(&app)) .to_info_display() ); } diff --git a/yt/src/update/mod.rs b/yt/src/update/mod.rs index e3ab54e..3cdc61b 100644 --- a/yt/src/update/mod.rs +++ b/yt/src/update/mod.rs @@ -253,7 +253,7 @@ async fn process_subscription( .to_formatted_video(app) .await .with_context(|| format!("Failed to format video: '{}'", video.title))? - .colorize()) + .colorize(app)) .to_line_display() ); Ok(()) diff --git a/yt/src/videos/display/mod.rs b/yt/src/videos/display/mod.rs index 4e5ee50..4a32e52 100644 --- a/yt/src/videos/display/mod.rs +++ b/yt/src/videos/display/mod.rs @@ -41,40 +41,44 @@ pub struct ColorizedFormattedVideo(FormattedVideo); impl FormattedVideo { #[must_use] - pub fn colorize(self) -> ColorizedFormattedVideo { - let Self { - cache_path, - description, - duration, - extractor_hash, - last_status_change, - parent_subscription_name, - priority, - publish_date, - status, - status_change, - thumbnail_url, - title, - url, - video_options, - } = self; - - ColorizedFormattedVideo(Self { - cache_path: cache_path.blue().bold().to_string(), - description, - duration: duration.cyan().bold().to_string(), - extractor_hash: extractor_hash.bright_purple().italic().to_string(), - last_status_change: last_status_change.bright_cyan().to_string(), - parent_subscription_name: parent_subscription_name.bright_magenta().to_string(), - priority, - publish_date: publish_date.bright_white().bold().to_string(), - status: status.red().bold().to_string(), - status_change, - thumbnail_url, - title: title.green().bold().to_string(), - url: url.italic().to_string(), - video_options: video_options.bright_green().to_string(), - }) + pub fn colorize(self, app: &App) -> ColorizedFormattedVideo { + if app.config.global.display_colors { + let Self { + cache_path, + description, + duration, + extractor_hash, + last_status_change, + parent_subscription_name, + priority, + publish_date, + status, + status_change, + thumbnail_url, + title, + url, + video_options, + } = self; + + ColorizedFormattedVideo(Self { + cache_path: cache_path.blue().bold().to_string(), + description, + duration: duration.cyan().bold().to_string(), + extractor_hash: extractor_hash.bright_purple().italic().to_string(), + last_status_change: last_status_change.bright_cyan().to_string(), + parent_subscription_name: parent_subscription_name.bright_magenta().to_string(), + priority, + publish_date: publish_date.bright_white().bold().to_string(), + status: status.red().bold().to_string(), + status_change, + thumbnail_url, + title: title.green().bold().to_string(), + url: url.italic().to_string(), + video_options: video_options.bright_green().to_string(), + }) + } else { + ColorizedFormattedVideo(self) + } } } diff --git a/yt/src/videos/mod.rs b/yt/src/videos/mod.rs index 9704f73..156d01d 100644 --- a/yt/src/videos/mod.rs +++ b/yt/src/videos/mod.rs @@ -41,7 +41,7 @@ pub async fn query(app: &App, limit: Option<usize>, search_query: Option<String> .try_collect::<Vec<FormattedVideo>>() .await? .into_iter() - .map(|vid| (&vid.colorize()).to_line_display()) + .map(|vid| (&vid.colorize(app)).to_line_display()) .collect(); if let Some(query) = search_query { |