diff --git a/Cargo.lock b/Cargo.lock index 396acf6..6e20081 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -332,6 +332,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "compact_str" version = "0.8.1" @@ -1723,6 +1732,7 @@ dependencies = [ "clap", "clap_mangen", "clipboard-win", + "colored", "criterion", "crossterm", "devicons", diff --git a/Cargo.toml b/Cargo.toml index 60b6466..ae2deef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ walkdir = "2.5.0" string_pipeline = "0.11.1" ureq = "3.0.11" serde_json = "1.0.140" +colored = "3.0.0" # target specific dependencies diff --git a/television/cable.rs b/television/cable.rs index ecc6aad..6543ffa 100644 --- a/television/cable.rs +++ b/television/cable.rs @@ -1,3 +1,4 @@ +use colored::Colorize; use std::{ ops::Deref, path::{Path, PathBuf}, @@ -136,11 +137,21 @@ pub fn load_cable() -> Option { if cable_files.is_empty() { println!( - "It seems you don't have any cable channels configured yet. -Run `tv update-channels` to get the latest default cable channels and/or add your own in `{}`. - -More info: https://github.com/alexpasmantier/television/blob/main/README.md", - cable_dir.to_string_lossy() + "{}", + "It seems you don't have any cable channels configured yet.\n" + .blue() + .bold() + ); + println!( + "Run {} to get the latest default cable channels and/or add your own in `{}`.\n", + "`tv update-channels`".green().bold(), + cable_dir.to_string_lossy().yellow().bold() + ); + println!( + "More info: {}", + "https://github.com/alexpasmantier/television/blob/main/README.md" + .blue() + .bold() ); return None; } diff --git a/television/gh.rs b/television/gh.rs index 62da7ef..156f41d 100644 --- a/television/gh.rs +++ b/television/gh.rs @@ -1,9 +1,14 @@ use anyhow::Result; +use colored::Colorize; use std::path::Path; use tracing::debug; use ureq::get; -use crate::channels::prototypes::ChannelPrototype; +use crate::{ + cable::{CABLE_DIR_NAME, CHANNEL_FILE_FORMAT, Cable}, + channels::prototypes::ChannelPrototype, + config::get_config_dir, +}; #[derive(Debug, Clone, serde::Deserialize)] struct GhNode { @@ -69,9 +74,9 @@ pub fn get_default_prototypes_from_repo() -> Result> { let nodes = make_gh_content_request(Path::new(DEFAULT_CABLE_DIR_PATH))?; for node in &nodes { println!( - "Discovered channel: \x1b[31m{}\x1b[0m\t\tdownload url: {}", - node.name, - node.download_url.as_deref().unwrap_or("N/A") + " Discovered channel: {}\t\tdownload url: {}", + node.name.blue().bold(), + node.download_url.as_deref().unwrap_or("N/A").blue().bold() ); } Ok(nodes @@ -89,3 +94,39 @@ pub fn get_default_prototypes_from_repo() -> Result> { }) .collect()) } + +pub fn update_local_channels() -> Result<()> { + println!("{}", "Fetching latest cable channels...".bold()); + let cable = Cable::from_prototypes(get_default_prototypes_from_repo()?); + println!("{}", "\nSaving channels locally...".bold()); + let cable_path = get_config_dir().join(CABLE_DIR_NAME); + if !cable_path.exists() { + println!(" Creating cable directory at {}", cable_path.display()); + std::fs::create_dir_all(&cable_path)?; + } + for (name, prototype) in cable.iter() { + let file_path = + cable_path.join(name).with_extension(CHANNEL_FILE_FORMAT); + let content = toml::to_string(&prototype)?; + // if the file already exists, don't overwrite it + if file_path.exists() { + println!( + " Channel {} already exists at {}, SKIPPING...", + name.blue().bold(), + file_path.display().to_string().yellow().bold() + ); + continue; + } + std::fs::write(&file_path, content)?; + println!( + " Saved channel {} to {}", + name.blue().bold(), + file_path.display().to_string().yellow().bold() + ); + } + println!( + "{}", + "\nCable channels updated successfully.".green().bold() + ); + Ok(()) +} diff --git a/television/main.rs b/television/main.rs index 656d7e5..ac0d4ba 100644 --- a/television/main.rs +++ b/television/main.rs @@ -5,9 +5,9 @@ use std::process::exit; use anyhow::Result; use clap::Parser; -use television::cable::{CABLE_DIR_NAME, CHANNEL_FILE_FORMAT, load_cable}; +use television::cable::load_cable; use television::cli::post_process; -use television::gh::get_default_prototypes_from_repo; +use television::gh::update_local_channels; use television::{ cable::Cable, channels::prototypes::ChannelPrototype, utils::clipboard::CLIPBOARD, @@ -21,9 +21,7 @@ use television::cli::{ guess_channel_from_prompt, list_channels, }; -use television::config::{ - Config, ConfigEnv, get_config_dir, merge_keybindings, -}; +use television::config::{Config, ConfigEnv, merge_keybindings}; use television::utils::shell::render_autocomplete_script_template; use television::utils::{ shell::{Shell, completion_script}, @@ -156,26 +154,7 @@ pub fn handle_subcommand(command: &Command, config: &Config) -> Result<()> { exit(0); } Command::UpdateChannels => { - println!("\x1b[1mFetching latest cable channels...\x1b[0m"); - let cable = - Cable::from_prototypes(get_default_prototypes_from_repo()?); - println!("\n\x1b[1mWriting channels locally...\x1b[0m"); - let cable_path = get_config_dir().join(CABLE_DIR_NAME); - if !cable_path.exists() { - println!( - "Creating cable directory at {}", - cable_path.display() - ); - std::fs::create_dir_all(&cable_path)?; - } - for (name, prototype) in cable.iter() { - let file_path = - cable_path.join(name).with_extension(CHANNEL_FILE_FORMAT); - let content = toml::to_string(&prototype)?; - std::fs::write(&file_path, content)?; - println!("Saved channel {} to {}", name, file_path.display()); - } - println!("\n\x1b[1mCable channels updated successfully.\x1b[0m"); + update_local_channels()?; exit(0); } }