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

feat(api): add provider to request parameters

Changed files
+112 -28
proto
tunein
src
+10 -1
proto/tunein/v1alpha1/browse.proto
··· 5 5 import "objects/v1alpha1/category.proto"; 6 6 import "objects/v1alpha1/station.proto"; 7 7 8 - message GetCategoriesRequest {} 8 + message GetCategoriesRequest { 9 + optional string provider = 1; 10 + optional uint32 offset = 2; 11 + optional uint32 limit = 3; 12 + } 9 13 10 14 message GetCategoriesResponse { 11 15 repeated objects.v1alpha1.Category categories = 1; ··· 13 17 14 18 message BrowseCategoryRequest { 15 19 string category_id = 1; 20 + optional string provider = 2; 21 + optional uint32 offset = 3; 22 + optional uint32 limit = 4; 16 23 } 17 24 18 25 message BrowseCategoryResponse { ··· 21 28 22 29 message GetStationDetailsRequest { 23 30 string id = 1; 31 + optional string provider = 2; 24 32 } 25 33 26 34 message GetStationDetailsResponse { ··· 29 37 30 38 message SearchRequest { 31 39 string query = 1; 40 + optional string provider = 2; 32 41 } 33 42 34 43 message SearchResponse {
+2 -1
proto/tunein/v1alpha1/playback.proto
··· 12 12 13 13 message PlayRequest { 14 14 string station_name_or_id = 1; 15 + optional string provider = 2; 15 16 } 16 17 17 18 message PlayResponse {} ··· 20 21 rpc Play(PlayRequest) returns (PlayResponse) {} 21 22 rpc Stop(StopRequest) returns (StopResponse) {} 22 23 rpc PlayOrPause(PlayOrPauseRequest) returns (PlayOrPauseResponse) {} 23 - } 24 + }
src/api/descriptor.bin

This is a binary file and will not be displayed.

+21 -2
src/api/tunein.v1alpha1.rs
··· 1 1 // This file is @generated by prost-build. 2 - #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3 - pub struct GetCategoriesRequest {} 2 + #[derive(Clone, PartialEq, ::prost::Message)] 3 + pub struct GetCategoriesRequest { 4 + #[prost(string, optional, tag = "1")] 5 + pub provider: ::core::option::Option<::prost::alloc::string::String>, 6 + #[prost(uint32, optional, tag = "2")] 7 + pub offset: ::core::option::Option<u32>, 8 + #[prost(uint32, optional, tag = "3")] 9 + pub limit: ::core::option::Option<u32>, 10 + } 4 11 #[derive(Clone, PartialEq, ::prost::Message)] 5 12 pub struct GetCategoriesResponse { 6 13 #[prost(message, repeated, tag = "1")] ··· 10 17 pub struct BrowseCategoryRequest { 11 18 #[prost(string, tag = "1")] 12 19 pub category_id: ::prost::alloc::string::String, 20 + #[prost(string, optional, tag = "2")] 21 + pub provider: ::core::option::Option<::prost::alloc::string::String>, 22 + #[prost(uint32, optional, tag = "3")] 23 + pub offset: ::core::option::Option<u32>, 24 + #[prost(uint32, optional, tag = "4")] 25 + pub limit: ::core::option::Option<u32>, 13 26 } 14 27 #[derive(Clone, PartialEq, ::prost::Message)] 15 28 pub struct BrowseCategoryResponse { ··· 20 33 pub struct GetStationDetailsRequest { 21 34 #[prost(string, tag = "1")] 22 35 pub id: ::prost::alloc::string::String, 36 + #[prost(string, optional, tag = "2")] 37 + pub provider: ::core::option::Option<::prost::alloc::string::String>, 23 38 } 24 39 #[derive(Clone, PartialEq, ::prost::Message)] 25 40 pub struct GetStationDetailsResponse { ··· 32 47 pub struct SearchRequest { 33 48 #[prost(string, tag = "1")] 34 49 pub query: ::prost::alloc::string::String, 50 + #[prost(string, optional, tag = "2")] 51 + pub provider: ::core::option::Option<::prost::alloc::string::String>, 35 52 } 36 53 #[derive(Clone, PartialEq, ::prost::Message)] 37 54 pub struct SearchResponse { ··· 576 593 pub struct PlayRequest { 577 594 #[prost(string, tag = "1")] 578 595 pub station_name_or_id: ::prost::alloc::string::String, 596 + #[prost(string, optional, tag = "2")] 597 + pub provider: ::core::option::Option<::prost::alloc::string::String>, 579 598 } 580 599 #[derive(Clone, Copy, PartialEq, ::prost::Message)] 581 600 pub struct PlayResponse {}
+60 -15
src/server/browse.rs
··· 1 - use tunein_cli::api::{ 2 - objects::v1alpha1::{Category, Station, StationLinkDetails}, 3 - tunein::v1alpha1::{ 4 - browse_service_server::BrowseService, BrowseCategoryRequest, BrowseCategoryResponse, 5 - GetCategoriesRequest, GetCategoriesResponse, GetStationDetailsRequest, 6 - GetStationDetailsResponse, SearchRequest, SearchResponse, 1 + use tunein_cli::{ 2 + api::{ 3 + objects::v1alpha1::{Category, Station, StationLinkDetails}, 4 + tunein::v1alpha1::{ 5 + browse_service_server::BrowseService, BrowseCategoryRequest, BrowseCategoryResponse, 6 + GetCategoriesRequest, GetCategoriesResponse, GetStationDetailsRequest, 7 + GetStationDetailsResponse, SearchRequest, SearchResponse, 8 + }, 7 9 }, 10 + provider::radiobrowser::Radiobrowser, 8 11 }; 9 12 10 13 use tunein_cli::provider::{tunein::Tunein, Provider}; ··· 16 19 impl BrowseService for Browse { 17 20 async fn get_categories( 18 21 &self, 19 - _request: tonic::Request<GetCategoriesRequest>, 22 + request: tonic::Request<GetCategoriesRequest>, 20 23 ) -> Result<tonic::Response<GetCategoriesResponse>, tonic::Status> { 21 - let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 22 - let offset = 0; 23 - let limit = 100; 24 + let req = request.into_inner(); 25 + let provider = req.provider.as_deref(); 26 + 27 + let client: Box<dyn Provider + Send + Sync> = match provider { 28 + Some("tunein") => Box::new(Tunein::new()), 29 + Some("radiobrowser") => Box::new(Radiobrowser::new().await), 30 + None => Box::new(Tunein::new()), 31 + _ => { 32 + return Err(tonic::Status::internal("Unsupported provider")); 33 + } 34 + }; 35 + 36 + let offset = req.offset.unwrap_or(0); 37 + let limit = req.limit.unwrap_or(100); 24 38 let result = client 25 39 .categories(offset, limit) 26 40 .await ··· 38 52 let req = request.into_inner(); 39 53 let category_id = req.category_id; 40 54 41 - let offset = 0; 42 - let limit = 100; 55 + let offset = req.offset.unwrap_or(0); 56 + let limit = req.limit.unwrap_or(100); 57 + 58 + let provider = req.provider.as_deref(); 59 + 60 + let client: Box<dyn Provider + Send + Sync> = match provider { 61 + Some("tunein") => Box::new(Tunein::new()), 62 + Some("radiobrowser") => Box::new(Radiobrowser::new().await), 63 + None => Box::new(Tunein::new()), 64 + _ => { 65 + return Err(tonic::Status::internal("Unsupported provider")); 66 + } 67 + }; 43 68 44 - let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 45 69 let results = client 46 70 .browse(category_id, offset, limit) 47 71 .await ··· 57 81 ) -> Result<tonic::Response<GetStationDetailsResponse>, tonic::Status> { 58 82 let req = request.into_inner(); 59 83 let station_id = req.id; 60 - let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 84 + 85 + let provider = req.provider.as_deref(); 86 + 87 + let client: Box<dyn Provider + Send + Sync> = match provider { 88 + Some("tunein") => Box::new(Tunein::new()), 89 + Some("radiobrowser") => Box::new(Radiobrowser::new().await), 90 + None => Box::new(Tunein::new()), 91 + _ => { 92 + return Err(tonic::Status::internal("Unsupported provider")); 93 + } 94 + }; 95 + 61 96 let result = client 62 97 .get_station(station_id) 63 98 .await ··· 77 112 request: tonic::Request<SearchRequest>, 78 113 ) -> Result<tonic::Response<SearchResponse>, tonic::Status> { 79 114 let req = request.into_inner(); 80 - let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 115 + let provider = req.provider.as_deref(); 116 + 117 + let client: Box<dyn Provider + Send + Sync> = match provider { 118 + Some("tunein") => Box::new(Tunein::new()), 119 + Some("radiobrowser") => Box::new(Radiobrowser::new().await), 120 + None => Box::new(Tunein::new()), 121 + _ => { 122 + return Err(tonic::Status::internal("Unsupported provider")); 123 + } 124 + }; 125 + 81 126 let results = client 82 127 .search(req.query) 83 128 .await
+19 -9
src/server/playback.rs
··· 1 1 use std::sync::{Arc, Mutex}; 2 2 3 + use crate::player::{Player, PlayerCommand}; 3 4 use tokio::sync::mpsc; 4 - use tunein_cli::api::tunein::v1alpha1::{ 5 - playback_service_server::PlaybackService, PlayOrPauseRequest, PlayOrPauseResponse, PlayRequest, 6 - PlayResponse, StopRequest, StopResponse, 7 - }; 8 - 9 - use crate::{ 10 - player::{Player, PlayerCommand}, 11 - provider::{tunein::Tunein, Provider}, 5 + use tunein_cli::provider::{tunein::Tunein, Provider}; 6 + use tunein_cli::{ 7 + api::tunein::v1alpha1::{ 8 + playback_service_server::PlaybackService, PlayOrPauseRequest, PlayOrPauseResponse, 9 + PlayRequest, PlayResponse, StopRequest, StopResponse, 10 + }, 11 + provider::radiobrowser::Radiobrowser, 12 12 }; 13 13 14 14 pub struct Playback { ··· 33 33 ) -> Result<tonic::Response<PlayResponse>, tonic::Status> { 34 34 let req = request.into_inner(); 35 35 36 - let client: Box<dyn Provider + Send + Sync> = Box::new(Tunein::new()); 36 + let provider = req.provider.as_deref(); 37 + 38 + let client: Box<dyn Provider + Send + Sync> = match provider { 39 + Some("tunein") => Box::new(Tunein::new()), 40 + Some("radiobrowser") => Box::new(Radiobrowser::new().await), 41 + None => Box::new(Tunein::new()), 42 + _ => { 43 + return Err(tonic::Status::internal("Unsupported provider")); 44 + } 45 + }; 46 + 37 47 let station = client 38 48 .get_station(req.station_name_or_id.clone()) 39 49 .await