Browse and listen to thousands of radio stations across the globe right from your terminal ๐ŸŒŽ ๐Ÿ“ป ๐ŸŽตโœจ
radio rust tokio web-radio command-line-tool tui

update tunein provider

Changed files
+80 -11
src
provider
+32 -7
src/provider/tunein.rs
··· 42 42 } 43 43 44 44 async fn browse(&self, category: String) -> Result<Vec<Station>, Error> { 45 + let guide_id = category.clone(); 45 46 let category = match category.as_str() { 46 47 "by location" => Some(tunein::types::Category::ByLocation), 47 48 "by language" => Some(tunein::types::Category::ByLanguage), ··· 50 51 "music" => Some(tunein::types::Category::Music), 51 52 "local radio" => Some(tunein::types::Category::LocalRadio), 52 53 "podcasts" => Some(tunein::types::Category::Podcasts), 53 - _ => return Err(Error::msg("Invalid category")), 54 + _ => None, 54 55 }; 55 56 57 + if category.is_none() { 58 + let category_stations = self 59 + .client 60 + .browse_by_id(&guide_id) 61 + .await 62 + .map_err(|e| Error::msg(e.to_string()))?; 63 + 64 + let mut stations = vec![]; 65 + 66 + for st in category_stations { 67 + if let Some(children) = st.children { 68 + stations = [stations, children].concat(); 69 + } 70 + } 71 + 72 + let stations = stations.into_iter().map(|x| Station::from(x)).collect(); 73 + return Ok(stations); 74 + } 75 + 56 76 let stations = self 57 77 .client 58 78 .browse(category) 59 79 .await 60 80 .map_err(|e| Error::msg(e.to_string()))?; 61 81 62 - Ok(vec![]) 82 + let stations = stations.into_iter().map(|x| Station::from(x)).collect(); 83 + Ok(stations) 63 84 } 64 85 } 65 86 ··· 89 110 pub async fn test_browse() { 90 111 let provider = Tunein::new(); 91 112 let stations = provider.browse("music".to_string()).await.unwrap(); 92 - let stations = stations 93 - .into_iter() 94 - .map(|x| Station::from(x)) 95 - .collect::<Vec<Station>>(); 96 113 println!("Browse: {:#?}", stations); 97 - assert!(stations.len() == 0) 114 + assert!(stations.len() > 0) 115 + } 116 + 117 + #[tokio::test] 118 + pub async fn test_browse_by_id() { 119 + let provider = Tunein::new(); 120 + let stations = provider.browse("c57942".to_string()).await.unwrap(); 121 + println!("Browse by category id: {:#?}", stations); 122 + assert!(stations.len() > 0) 98 123 } 99 124 }
+48 -4
src/types.rs
··· 32 32 .unwrap_or("0".to_string()) 33 33 .parse() 34 34 .unwrap_or_default(), 35 - codec: "".to_string(), 36 - stream_url: "".to_string(), 35 + codec: Default::default(), 36 + stream_url: Default::default(), 37 37 } 38 38 } 39 39 } ··· 41 41 impl From<StationLinkDetails> for Station { 42 42 fn from(details: StationLinkDetails) -> Station { 43 43 Station { 44 - id: "".to_string(), 45 - name: "".to_string(), 44 + id: Default::default(), 45 + name: Default::default(), 46 46 bitrate: details.bitrate, 47 47 stream_url: details.url, 48 48 codec: details.media_type.to_uppercase(), 49 49 } 50 50 } 51 51 } 52 + 53 + impl From<tunein::types::Station> for Station { 54 + fn from(st: tunein::types::Station) -> Station { 55 + Station { 56 + id: st.guide_id.unwrap_or_default(), 57 + name: st.text, 58 + bitrate: st 59 + .bitrate 60 + .unwrap_or("0".to_string()) 61 + .parse() 62 + .unwrap_or_default(), 63 + stream_url: Default::default(), 64 + codec: st.formats.unwrap_or_default().to_uppercase(), 65 + } 66 + } 67 + } 68 + 69 + impl From<Box<tunein::types::Station>> for Station { 70 + fn from(st: Box<tunein::types::Station>) -> Station { 71 + Station { 72 + id: st.guide_id.unwrap_or_default(), 73 + name: st.text, 74 + bitrate: st 75 + .bitrate 76 + .unwrap_or("0".to_string()) 77 + .parse() 78 + .unwrap_or_default(), 79 + stream_url: Default::default(), 80 + codec: st.formats.unwrap_or_default().to_uppercase(), 81 + } 82 + } 83 + } 84 + 85 + impl From<tunein::types::CategoryDetails> for Station { 86 + fn from(ct: tunein::types::CategoryDetails) -> Station { 87 + Station { 88 + id: ct.guide_id.unwrap_or_default(), 89 + name: ct.text, 90 + bitrate: 0, 91 + stream_url: Default::default(), 92 + codec: Default::default(), 93 + } 94 + } 95 + }