···11-use std::str::FromStr;
22-31use anyhow::Error;
42use owo_colors::OwoColorize;
55-use tunein::{types::Category, TuneInClient};
33+44+use crate::provider::radiobrowser::Radiobrowser;
55+use crate::provider::tunein::Tunein;
66+use crate::provider::Provider;
6777-pub async fn exec(category: Option<&str>) -> Result<(), Error> {
88- let client = TuneInClient::new();
88+pub async fn exec(
99+ category: Option<&str>,
1010+ offset: u32,
1111+ limit: u32,
1212+ provider: &str,
1313+) -> Result<(), Error> {
1414+ let provider: Box<dyn Provider> = match provider {
1515+ "tunein" => Box::new(Tunein::new()),
1616+ "radiobrowser" => Box::new(Radiobrowser::new().await),
1717+ _ => {
1818+ return Err(anyhow::anyhow!(format!(
1919+ "Unsupported provider '{}'",
2020+ provider
2121+ )))
2222+ }
2323+ };
9241010- if category.is_some() && Category::from_str(category.unwrap_or_default()).is_err() {
1111- let id = category.unwrap_or_default();
1212- let results = client
1313- .browse_by_id(id)
1414- .await
1515- .map_err(|e| Error::msg(e.to_string()))?;
1616- for result in results {
1717- println!("{}", result.text);
1818- if let Some(children) = result.children {
1919- for child in children {
2020- match child.playing {
2525+ match category {
2626+ Some(category) => {
2727+ let results = provider.browse(category.to_string(), offset, limit).await?;
2828+ for result in results {
2929+ match result.id.is_empty() {
3030+ false => match result.playing {
2131 Some(playing) => println!(
2232 " {} | {} | id: {}",
2323- child.text.magenta(),
3333+ result.name.magenta(),
2434 playing,
2525- child.guide_id.unwrap()
3535+ result.id
2636 ),
2727- None => {
2828- if let Some(guide_id) = child.guide_id {
2929- println!(" {} | {}", child.text.magenta(), guide_id);
3030- }
3131- }
3232- }
3333- }
3434- }
3535- }
3636- return Ok(());
3737- }
3737+ None => println!(" {} | id: {}", result.name.magenta(), result.id),
3838+ },
38393939- let results = match category {
4040- Some(category) => match Category::from_str(category) {
4141- Ok(category) => client
4242- .browse(Some(category))
4343- .await
4444- .map_err(|e| Error::msg(e.to_string()))?,
4545- Err(_) => {
4646- println!("Invalid category");
4747- return Ok(());
4040+ true => println!("{}", result.name),
4141+ }
4842 }
4949- },
5050- None => client
5151- .browse(None)
5252- .await
5353- .map_err(|e| Error::msg(e.to_string()))?,
5454- };
5555-5656- for result in results {
5757- match result.guide_id {
5858- Some(_) => println!(
5959- "{} | id: {}",
6060- result.text.magenta(),
6161- result.guide_id.unwrap()
6262- ),
6363- None => println!("{}", result.text),
6443 }
6565- if let Some(children) = result.children {
6666- for child in children {
6767- match child.playing {
6868- Some(playing) => println!(
6969- " {} | {} | id: {}",
7070- child.text.magenta(),
7171- playing,
7272- child.guide_id.unwrap()
7373- ),
7474- None => println!(
7575- " {} | id: {}",
7676- child.text.magenta(),
7777- child.guide_id.unwrap()
7878- ),
7979- }
4444+ None => {
4545+ let results = provider.categories(offset, limit).await?;
4646+ for result in results {
4747+ println!("{}", result.magenta());
8048 }
8149 }
8282- }
5050+ };
8351 Ok(())
8452}
+16-2
src/main.rs
···32323333A simple CLI to listen to radio stations"#,
3434 )
3535+ .arg(
3636+ arg!(-p --provider "The radio provider to use, can be 'tunein' or 'radiobrowser'. Default is 'tunein'").default_value("tunein")
3737+ )
3538 .subcommand_required(true)
3639 .subcommand(
3740 Command::new("search")
···4649 .subcommand(
4750 Command::new("browse")
4851 .about("Browse radio stations")
4949- .arg(arg!([category] "The category (category name or id) to browse")),
5252+ .arg(arg!([category] "The category (category name or id) to browse"))
5353+ .arg(arg!(--offset "The offset to start from").default_value("0"))
5454+ .arg(arg!(--limit "The number of results to show").default_value("100")),
5055 )
5156 .subcommand(
5257 Command::new("server")
···7075 }
7176 Some(("browse", args)) => {
7277 let category = args.value_of("category");
7373- browse::exec(category).await?;
7878+ let offset = args.value_of("offset").unwrap();
7979+ let limit = args.value_of("limit").unwrap();
8080+ let provider = matches.value_of("provider").unwrap();
8181+ browse::exec(
8282+ category,
8383+ offset.parse::<u32>()?,
8484+ limit.parse::<u32>()?,
8585+ provider,
8686+ )
8787+ .await?;
7488 }
7589 Some(("server", args)) => {
7690 let port = args.value_of("port").unwrap();