diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/yt/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/yt/src/commands/comments/implm/mod.rs | 15 | ||||
-rw-r--r-- | crates/yt/src/commands/comments/mod.rs | 6 | ||||
-rw-r--r-- | crates/yt/src/commands/description/implm.rs | 16 | ||||
-rw-r--r-- | crates/yt/src/commands/description/mod.rs | 6 | ||||
-rw-r--r-- | crates/yt/src/commands/mod.rs | 29 | ||||
-rw-r--r-- | crates/yt/src/commands/show/implm/mod.rs | 100 |
7 files changed, 112 insertions, 61 deletions
diff --git a/crates/yt/Cargo.toml b/crates/yt/Cargo.toml index 12456fe..95f8270 100644 --- a/crates/yt/Cargo.toml +++ b/crates/yt/Cargo.toml @@ -50,6 +50,7 @@ url.workspace = true uu_fmt.workspace = true xdg = "3.0.0" yt_dlp.workspace = true +reqwest = "0.12.22" [[bin]] name = "yt" diff --git a/crates/yt/src/commands/comments/implm/mod.rs b/crates/yt/src/commands/comments/implm/mod.rs deleted file mode 100644 index 1c02718..0000000 --- a/crates/yt/src/commands/comments/implm/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::{ - app::App, commands::comments::CommentsCommand, output::display_less, storage::db::video::Video, -}; - -use anyhow::Result; - -impl CommentsCommand { - pub(crate) async fn implm(self, app: &App) -> Result<()> { - let comments = Video::get_current_comments(app).await?; - - display_less(comments.render(app.config.global.display_colors))?; - - Ok(()) - } -} diff --git a/crates/yt/src/commands/comments/mod.rs b/crates/yt/src/commands/comments/mod.rs deleted file mode 100644 index d87c75d..0000000 --- a/crates/yt/src/commands/comments/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -use clap::Parser; - -mod implm; - -#[derive(Parser, Debug)] -pub(crate) struct CommentsCommand {} diff --git a/crates/yt/src/commands/description/implm.rs b/crates/yt/src/commands/description/implm.rs deleted file mode 100644 index 7c39b1c..0000000 --- a/crates/yt/src/commands/description/implm.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::{ - app::App, commands::description::DescriptionCommand, output::display_fmt_and_less, - storage::db::video::Video, -}; - -use anyhow::Result; - -impl DescriptionCommand { - pub(crate) async fn implm(self, app: &App) -> Result<()> { - let description = Video::get_current_description(app).await?; - - display_fmt_and_less(&description)?; - - Ok(()) - } -} diff --git a/crates/yt/src/commands/description/mod.rs b/crates/yt/src/commands/description/mod.rs deleted file mode 100644 index b5b2a10..0000000 --- a/crates/yt/src/commands/description/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -use clap::Parser; - -mod implm; - -#[derive(Parser, Debug)] -pub(crate) struct DescriptionCommand {} diff --git a/crates/yt/src/commands/mod.rs b/crates/yt/src/commands/mod.rs index a6aa2af..ee8b29c 100644 --- a/crates/yt/src/commands/mod.rs +++ b/crates/yt/src/commands/mod.rs @@ -7,10 +7,10 @@ use tokio::runtime::Runtime; use crate::{ app::App, commands::{ - comments::CommentsCommand, config::ConfigCommand, database::DatabaseCommand, - description::DescriptionCommand, download::DownloadCommand, playlist::PlaylistCommand, - select::SelectCommand, status::StatusCommand, subscriptions::SubscriptionCommand, - update::UpdateCommand, videos::VideosCommand, watch::WatchCommand, + config::ConfigCommand, database::DatabaseCommand, download::DownloadCommand, + playlist::PlaylistCommand, select::SelectCommand, show::ShowCommand, status::StatusCommand, + subscriptions::SubscriptionCommand, update::UpdateCommand, videos::VideosCommand, + watch::WatchCommand, }, config::Config, storage::db::subscription::Subscriptions, @@ -18,13 +18,12 @@ use crate::{ pub(crate) mod implm; -mod comments; mod config; mod database; -mod description; mod download; mod playlist; mod select; +mod show; mod status; mod subscriptions; mod update; @@ -33,12 +32,6 @@ mod watch; #[derive(Subcommand, Debug)] pub(crate) enum Command { - /// Display the comments of the currently playing video. - Comments { - #[command(flatten)] - cmd: CommentsCommand, - }, - /// Show, the configuration options in effect. Config { #[command(flatten)] @@ -52,12 +45,6 @@ pub(crate) enum Command { cmd: DatabaseCommand, }, - /// Display the description of the currently playing video - Description { - #[command(flatten)] - cmd: DescriptionCommand, - }, - /// Download and cache URLs Download { #[command(flatten)] @@ -76,6 +63,12 @@ pub(crate) enum Command { cmd: Option<SelectCommand>, }, + /// Show things about the currently playing video. + Show { + #[command(subcommand)] + cmd: ShowCommand, + }, + /// Show, which videos have been selected to be watched (and their cache status) Status { #[command(flatten)] diff --git a/crates/yt/src/commands/show/implm/mod.rs b/crates/yt/src/commands/show/implm/mod.rs new file mode 100644 index 0000000..158a25b --- /dev/null +++ b/crates/yt/src/commands/show/implm/mod.rs @@ -0,0 +1,100 @@ +use std::{ + fs::{self, OpenOptions}, + io, + process::Command, +}; + +use crate::{ + app::App, + commands::ShowCommand, + output::{display_fmt_and_less, display_less}, + storage::db::video::Video, +}; + +use anyhow::{Context, Result, anyhow, bail}; +use tempfile::Builder; +use tokio_util::bytes::Buf; + +impl ShowCommand { + pub(crate) async fn implm(&self, app: &App) -> Result<()> { + match self { + ShowCommand::Description {} => { + let description = Video::get_current_description(app).await?; + + display_fmt_and_less(&description)?; + } + ShowCommand::Comments {} => { + let comments = Video::get_current_comments(app).await?; + + display_less(comments.render(app.config.global.display_colors))?; + } + ShowCommand::Thumbnail {} => { + let video = Video::currently_focused(app).await?.ok_or(anyhow!( + "You need to have a current video to display its info" + ))?; + + if let Some(url) = video.thumbnail_url { + let response = reqwest::get(url.clone()) + .await + .with_context(|| format!("Failed to download thumbnail from url: {url}"))?; + let response = response + .error_for_status() + .context("Failed to download thumbnail")?; + + let (tmp_path, mut tmp) = { + let file = Builder::new().prefix("yt-thumbnail-download").tempfile()?; + let (_, path) = file.keep()?; + let new_file = OpenOptions::new() + .write(true) + .read(false) + .create(false) + .truncate(true) + .open(&path)?; + + (path, new_file) + }; + + let mut content = response.bytes().await?.reader(); + io::copy(&mut content, &mut tmp)?; + + let status = Command::new(app.config.commands.image_show.first()) + .args(app.config.commands.image_show.tail()) + .arg(tmp_path.as_os_str()) + .status() + .context("Failed to spawn image show command")?; + + if !status.success() { + bail!( + "{:?} failed with status: {}", + &app.config.commands.image_show.join(" "), + status + ); + } + + fs::remove_file(&tmp_path).with_context(|| { + format!( + "Failed to cleanup downloaded thumbnail image at: {}", + tmp_path.display() + ) + })?; + } else { + eprintln!("Current video does not have a thumbnail."); + } + } + ShowCommand::Info {} => { + let video = Video::currently_focused(app).await?.ok_or(anyhow!( + "You need to have a current video to display its info" + ))?; + + display_less( + video + .to_info_display(app, None) + .await + .context("Failed to format video")?, + )?; + } + } + + Ok(()) + } +} |