use anyhow::{bail, Context, Result}; use clap::Parser; use std::{ env, io::{BufRead, BufReader, Write}, process::Command as StdCmd, }; use tempfile::NamedTempFile; use yt::{constants::HELP_STR, ytcc_drop, Line, LineCommand, YtccListData}; use crate::args::{Args, Command, OrderCommand}; mod args; fn main() -> Result<()> { let args = Args::parse(); cli_log::init_cli_log!(); let ordering = match args.subcommand.unwrap_or(Command::Order { command: OrderCommand::Date { desc: true, asc: false, }, }) { Command::Order { command } => match command { OrderCommand::Date { desc, asc } => { if desc { vec!["--order-by".into(), "publish_date".into(), "desc".into()] } else if asc { vec!["--order-by".into(), "publish_date".into(), "asc".into()] } else { vec!["--order-by".into(), "publish_date".into(), "desc".into()] } } OrderCommand::Raw { value } => [vec!["--order-by".into()], value].concat(), }, }; let json_map = { let mut ytcc = StdCmd::new("ytcc"); ytcc.args(["--output", "json", "list"]); ytcc.args(ordering); serde_json::from_slice::>( &ytcc.output().context("Failed to json from ytcc")?.stdout, ) .context("Failed to deserialize json output")? }; let mut edit_file = NamedTempFile::new().context("Failed to get tempfile")?; let file: String = json_map .iter() .map(|line| { format!( "pick {} \"{}\" <{}> [{}]\n", line.id, line.title, line.playlists .iter() .map(|p| &p.name[..]) .collect::>() .join(", "), line.duration.trim() ) }) .collect(); for line in file.lines() { writeln!(&edit_file, "{}", line)?; } write!(&edit_file, "{}", HELP_STR)?; edit_file.flush().context("Failed to flush edit file")?; let read_file = edit_file.reopen()?; let mut nvim = StdCmd::new("nvim"); nvim.arg(edit_file.path()); let status = nvim.status().context("Falied to run nvim")?; if !status.success() { bail!("Nvim exited with error status: {}", status) } let mut watching = Vec::new(); let reader = BufReader::new(&read_file); for line in reader.lines() { let line = line.context("Failed to read line")?; if line.starts_with("#") { continue; } else if line.trim().len() == 0 { // empty line continue; } let line = Line::from(line.as_str()); match line.cmd { LineCommand::Pick => (), LineCommand::Drop => { ytcc_drop(line.id).with_context(|| format!("Failed to drop: {}", line.id))? } LineCommand::Watch => watching.push(line.id), } } dbg!(&watching); Ok(()) }