fix(github): improve ux when downloading cable channels

This commit is contained in:
alexandre pasmantier 2025-06-13 19:57:40 +02:00 committed by Alex Pasmantier
parent e76a3df776
commit 3e98475e35
5 changed files with 76 additions and 34 deletions

10
Cargo.lock generated
View File

@ -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",

View File

@ -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

View File

@ -1,3 +1,4 @@
use colored::Colorize;
use std::{
ops::Deref,
path::{Path, PathBuf},
@ -136,11 +137,21 @@ pub fn load_cable() -> Option<Cable> {
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;
}

View File

@ -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<Vec<ChannelPrototype>> {
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<Vec<ChannelPrototype>> {
})
.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(())
}

View File

@ -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);
}
}