Browse and listen to thousands of radio stations across the globe right from your terminal 🌎 📻 🎵✨
radio rust tokio web-radio command-line-tool tui
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 477ec0f87e203ee6889e61d434b1b19460a77215 135 lines 4.8 kB view raw
1use anyhow::Error; 2use app::CurrentDisplayMode; 3use clap::{arg, Command}; 4 5mod app; 6mod browse; 7mod cfg; 8mod decoder; 9mod extract; 10mod input; 11mod music; 12mod play; 13mod player; 14mod provider; 15mod search; 16mod server; 17mod service; 18mod tags; 19mod tui; 20mod types; 21mod visualization; 22 23fn cli() -> Command<'static> { 24 const VESRION: &str = env!("CARGO_PKG_VERSION"); 25 Command::new("tunein") 26 .version(VESRION) 27 .author("Tsiry Sandratraina <tsiry.sndr@fluentci.io>") 28 .about( 29 r#" 30 ______ ____ _______ ____ 31 /_ __/_ _____ ___ / _/__ / ___/ / / _/ 32 / / / // / _ \/ -_)/ // _ \ / /__/ /___/ / 33 /_/ \_,_/_//_/\__/___/_//_/ \___/____/___/ 34 35A simple CLI to listen to radio stations"#, 36 ) 37 .arg( 38 arg!(-p --provider "The radio provider to use, can be 'tunein' or 'radiobrowser'. Default is 'tunein'").default_value("tunein") 39 ) 40 .subcommand_required(true) 41 .subcommand( 42 Command::new("search") 43 .about("Search for a radio station") 44 .arg(arg!(<query> "The query to search for")), 45 ) 46 .subcommand( 47 Command::new("play") 48 .about("Play a radio station") 49 .arg(arg!(<station> "The station to play")) 50 .arg(arg!(--volume "Set the initial volume (as a percent)").default_value("100")) 51 .arg(clap::Arg::new("display-mode").long("display-mode").help("Set the display mode to start with").default_value("Spectroscope")), 52 ) 53 .subcommand( 54 Command::new("browse") 55 .about("Browse radio stations") 56 .arg(arg!([category] "The category (category name or id) to browse")) 57 .arg(arg!(--offset "The offset to start from").default_value("0")) 58 .arg(arg!(--limit "The number of results to show").default_value("100")), 59 ) 60 .subcommand( 61 Command::new("server") 62 .about("Start the server") 63 .arg(arg!([port] "The port to listen on").default_value("8090")), 64 ) 65 .subcommand( 66 Command::new("service") 67 .about("Manage systemd service for tunein-cli server") 68 .subcommand( 69 Command::new("install") 70 .about("Install systemd service for tunein-cli server") 71 ) 72 .subcommand( 73 Command::new("uninstall") 74 .about("Uninstall systemd service for tunein-cli server") 75 ) 76 .subcommand( 77 Command::new("status") 78 .about("Check status of tunein-cli systemd service") 79 ) 80 ) 81} 82 83#[tokio::main] 84async fn main() -> Result<(), Error> { 85 let matches = cli().get_matches(); 86 87 match matches.subcommand() { 88 Some(("search", args)) => { 89 let query = args.value_of("query").unwrap(); 90 let provider = matches.value_of("provider").unwrap(); 91 search::exec(query, provider).await?; 92 } 93 Some(("play", args)) => { 94 let station = args.value_of("station").unwrap(); 95 let provider = matches.value_of("provider").unwrap(); 96 let volume = args.value_of("volume").unwrap().parse::<f32>().unwrap(); 97 let display_mode = args 98 .value_of("display-mode") 99 .unwrap() 100 .parse::<CurrentDisplayMode>() 101 .unwrap(); 102 play::exec(station, provider, volume, display_mode).await?; 103 } 104 Some(("browse", args)) => { 105 let category = args.value_of("category"); 106 let offset = args.value_of("offset").unwrap(); 107 let limit = args.value_of("limit").unwrap(); 108 let provider = matches.value_of("provider").unwrap(); 109 browse::exec( 110 category, 111 offset.parse::<u32>()?, 112 limit.parse::<u32>()?, 113 provider, 114 ) 115 .await?; 116 } 117 Some(("server", args)) => { 118 let port = args.value_of("port").unwrap(); 119 let port = port.parse::<u16>().unwrap(); 120 server::exec(port).await?; 121 } 122 Some(("service", sub_m)) => match sub_m.subcommand() { 123 Some(("install", _)) => service::install()?, 124 Some(("uninstall", _)) => service::uninstall()?, 125 Some(("status", _)) => service::status()?, 126 _ => { 127 println!("Invalid subcommand. Use `tunein service --help` for more information"); 128 std::process::exit(1); 129 } 130 }, 131 _ => unreachable!(), 132 } 133 134 Ok(()) 135}