use arboard::Clipboard;
use clap::Args;
use crate::{
commands::{Runnable, trim::TrimCmd},
core::api::ApiClientManager,
youtube_utils::{get_youtube_api_key, get_youtube_id},
};
use anyhow::{Result, bail};
#[derive(Debug, Default, Args)]
pub struct YtCmd {
#[arg(short, long)]
link: Option<String>,
#[arg(short, long)]
multiplier: String,
#[arg(long)]
max_items: Option<usize>,
}
const YT_PLAYLIST_MAX_ITEMS: usize = 500;
impl Runnable for YtCmd {
fn run(self) -> Result<()> {
let key = match get_youtube_api_key() {
Some(key) => key,
None => bail!(
"Missing environment variable: TRIMSEC_YOUTUBE_KEY; read README.md for more information."
),
};
let link = if !self.link.is_some() {
let mut c = Clipboard::new().unwrap();
let l = c.get_text().ok();
if let Some(l) = l {
l
} else {
bail!("No content found in clipboard.")
}
} else if let Some(l) = self.link {
l
} else {
bail!("Could not find YouTube link in arguments. Aborting.")
};
let manager = ApiClientManager::new(&key);
let id = get_youtube_id(&link);
if let Some(id) = id {
match manager
.fetch_duration_from_id(&id, self.max_items.unwrap_or(YT_PLAYLIST_MAX_ITEMS))
{
Ok((duration, item_count)) => {
let cmd = TrimCmd {
duration,
multiplier: self.multiplier,
};
cmd.run()?;
if id.is_playlist {
println!("Trimmed for {item_count} item(s).")
}
}
Err(e) => bail!("Failed to fetch details from URL: {e}"),
}
} else {
bail!(
"Not a valid YouTube URL! Only videos/embeds/shorts URLs are supported in the `yt` command."
)
}
Ok(())
}
}