Merge pull request #6 from coissac/claude/fix-download-block-bug-clean-011CUpYvvxQzW5Hv2E4aL1nk
fix download block bug clean
This commit is contained in:
@@ -9,8 +9,8 @@ use url::Url;
|
||||
/// Default Radio Paradise API base URL
|
||||
pub const DEFAULT_API_BASE: &str = "https://api.radioparadise.com/api";
|
||||
|
||||
/// Default block base URL pattern
|
||||
pub const DEFAULT_BLOCK_BASE: &str = "https://apps.radioparadise.com/blocks/chan/0";
|
||||
/// Default block base URL (channel is appended)
|
||||
pub const DEFAULT_BLOCK_BASE: &str = "https://apps.radioparadise.com/blocks/chan";
|
||||
|
||||
/// Default image base URL
|
||||
pub const DEFAULT_IMAGE_BASE: &str = "https://img.radioparadise.com/";
|
||||
@@ -24,6 +24,9 @@ pub const DEFAULT_BLOCK_TIMEOUT_SECS: u64 = 180;
|
||||
/// Default User-Agent
|
||||
pub const DEFAULT_USER_AGENT: &str = "pmoparadise/0.1.0";
|
||||
|
||||
/// Default channel (0 = main mix)
|
||||
pub const DEFAULT_CHANNEL: u8 = 0;
|
||||
|
||||
/// Radio Paradise HTTP client
|
||||
///
|
||||
/// This client provides access to Radio Paradise's streaming API,
|
||||
@@ -48,7 +51,6 @@ pub const DEFAULT_USER_AGENT: &str = "pmoparadise/0.1.0";
|
||||
pub struct RadioParadiseClient {
|
||||
pub(crate) client: Client,
|
||||
api_base: String,
|
||||
block_base: String,
|
||||
channel: u8,
|
||||
pub(crate) request_timeout: Duration,
|
||||
pub(crate) block_timeout: Duration,
|
||||
@@ -71,12 +73,14 @@ impl RadioParadiseClient {
|
||||
/// Create a client with a custom reqwest::Client
|
||||
///
|
||||
/// Useful for sharing HTTP connection pools or custom proxy settings
|
||||
///
|
||||
/// Note: Uses default settings (channel 0, default timeouts).
|
||||
/// For more control, use `ClientBuilder::default().client(client).build()`.
|
||||
pub fn with_client(client: Client) -> Self {
|
||||
Self {
|
||||
client,
|
||||
api_base: DEFAULT_API_BASE.to_string(),
|
||||
block_base: DEFAULT_BLOCK_BASE.to_string(),
|
||||
channel: 0,
|
||||
channel: DEFAULT_CHANNEL,
|
||||
request_timeout: Duration::from_secs(DEFAULT_REQUEST_TIMEOUT_SECS),
|
||||
block_timeout: Duration::from_secs(DEFAULT_BLOCK_TIMEOUT_SECS),
|
||||
next_block_url: None,
|
||||
@@ -88,15 +92,15 @@ impl RadioParadiseClient {
|
||||
self.channel
|
||||
}
|
||||
|
||||
fn block_base_for_channel(channel: u8) -> String {
|
||||
format!("https://apps.radioparadise.com/blocks/chan/{}", channel)
|
||||
/// Get the block base URL for this client's channel
|
||||
pub fn block_base(&self) -> String {
|
||||
format!("{}/{}", DEFAULT_BLOCK_BASE, self.channel)
|
||||
}
|
||||
|
||||
/// Clone the client with a different channel while preserving other settings.
|
||||
pub fn clone_with_channel(&self, channel: u8) -> Self {
|
||||
let mut cloned = self.clone();
|
||||
cloned.channel = channel;
|
||||
cloned.block_base = Self::block_base_for_channel(channel);
|
||||
cloned.next_block_url = None;
|
||||
cloned
|
||||
}
|
||||
@@ -234,7 +238,6 @@ impl RadioParadiseClient {
|
||||
pub struct ClientBuilder {
|
||||
client: Option<Client>,
|
||||
api_base: String,
|
||||
block_base: String,
|
||||
channel: u8,
|
||||
request_timeout: Duration,
|
||||
block_timeout: Duration,
|
||||
@@ -247,8 +250,7 @@ impl Default for ClientBuilder {
|
||||
Self {
|
||||
client: None,
|
||||
api_base: DEFAULT_API_BASE.to_string(),
|
||||
block_base: DEFAULT_BLOCK_BASE.to_string(),
|
||||
channel: 0,
|
||||
channel: DEFAULT_CHANNEL,
|
||||
request_timeout: Duration::from_secs(DEFAULT_REQUEST_TIMEOUT_SECS),
|
||||
block_timeout: Duration::from_secs(DEFAULT_BLOCK_TIMEOUT_SECS),
|
||||
user_agent: DEFAULT_USER_AGENT.to_string(),
|
||||
@@ -275,12 +277,6 @@ impl ClientBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the block base URL
|
||||
pub fn block_base(mut self, url: impl Into<String>) -> Self {
|
||||
self.block_base = url.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the channel (0 = main mix, 1 = mellow, 2 = rock, 3 = world/etc)
|
||||
pub fn channel(mut self, channel: u8) -> Self {
|
||||
self.channel = channel;
|
||||
@@ -329,16 +325,9 @@ impl ClientBuilder {
|
||||
builder.build()?
|
||||
};
|
||||
|
||||
let block_base = if self.block_base == DEFAULT_BLOCK_BASE {
|
||||
RadioParadiseClient::block_base_for_channel(self.channel)
|
||||
} else {
|
||||
self.block_base.clone()
|
||||
};
|
||||
|
||||
Ok(RadioParadiseClient {
|
||||
client,
|
||||
api_base: self.api_base,
|
||||
block_base,
|
||||
channel: self.channel,
|
||||
request_timeout: self.request_timeout,
|
||||
block_timeout: self.block_timeout,
|
||||
@@ -355,6 +344,6 @@ mod tests {
|
||||
fn test_builder_defaults() {
|
||||
let builder = ClientBuilder::default();
|
||||
assert_eq!(builder.api_base, DEFAULT_API_BASE);
|
||||
assert_eq!(builder.channel, 0);
|
||||
assert_eq!(builder.channel, DEFAULT_CHANNEL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use crate::{channels::ParadiseChannelKind, client::DEFAULT_CHANNEL};
|
||||
use anyhow::Result;
|
||||
use pmoconfig::Config;
|
||||
use serde_yaml::Value;
|
||||
@@ -81,6 +82,60 @@ pub trait RadioParadiseConfigExt {
|
||||
/// config.set_paradise_enabled(false)?;
|
||||
/// ```
|
||||
fn set_paradise_enabled(&self, enabled: bool) -> Result<()>;
|
||||
|
||||
/// Récupère le channel par défaut
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Le channel par défaut (0 = Main Mix par défaut).
|
||||
///
|
||||
/// Si la valeur n'existe pas dans la configuration, elle est automatiquement
|
||||
/// définie à "main" et persistée.
|
||||
///
|
||||
/// # Channels disponibles
|
||||
///
|
||||
/// Peut être configuré comme chaîne de caractères ou nombre :
|
||||
/// - "main" ou 0 = Main Mix (eclectic, diverse mix)
|
||||
/// - "mellow" ou 1 = Mellow Mix (smooth, chilled music)
|
||||
/// - "rock" ou 2 = Rock Mix (classic & modern rock)
|
||||
/// - "eclectic" ou 3 = Eclectic Mix (global sounds)
|
||||
///
|
||||
/// # Exemple de configuration YAML
|
||||
///
|
||||
/// ```yaml
|
||||
/// sources:
|
||||
/// radio_paradise:
|
||||
/// default_channel: mellow # or 1
|
||||
/// ```
|
||||
///
|
||||
/// # Exemple d'utilisation
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// let channel = config.get_paradise_default_channel()?;
|
||||
/// let client = RadioParadiseClient::builder().channel(channel).build().await?;
|
||||
/// ```
|
||||
fn get_paradise_default_channel(&self) -> Result<u8>;
|
||||
|
||||
/// Définit le channel par défaut
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `channel` - Le channel (0-3)
|
||||
///
|
||||
/// La valeur est stockée sous forme de nom convivial ("main", "mellow", etc.)
|
||||
/// dans le fichier de configuration.
|
||||
///
|
||||
/// # Exemple
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use pmoparadise::channels::ParadiseChannelKind;
|
||||
///
|
||||
/// // Use Mellow Mix by default
|
||||
/// config.set_paradise_default_channel(ParadiseChannelKind::Mellow.id())?;
|
||||
/// // Or simply:
|
||||
/// config.set_paradise_default_channel(1)?;
|
||||
/// ```
|
||||
fn set_paradise_default_channel(&self, channel: u8) -> Result<()>;
|
||||
}
|
||||
|
||||
impl RadioParadiseConfigExt for Config {
|
||||
@@ -101,6 +156,62 @@ impl RadioParadiseConfigExt for Config {
|
||||
Value::Bool(enabled),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_paradise_default_channel(&self) -> Result<u8> {
|
||||
match self.get_value(&["sources", "radio_paradise", "default_channel"]) {
|
||||
Ok(Value::String(s)) => {
|
||||
// Try to parse as channel name (e.g., "main", "mellow", etc.)
|
||||
match s.parse::<ParadiseChannelKind>() {
|
||||
Ok(kind) => Ok(kind.id()),
|
||||
Err(_) => {
|
||||
// Invalid channel name, use default
|
||||
self.set_paradise_default_channel(DEFAULT_CHANNEL)?;
|
||||
Ok(DEFAULT_CHANNEL)
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Value::Number(n)) => {
|
||||
// Accept numeric channel ID (0-3)
|
||||
if let Some(ch) = n.as_u64() {
|
||||
if ch <= 3 {
|
||||
Ok(ch as u8)
|
||||
} else {
|
||||
// Invalid channel number, use default
|
||||
self.set_paradise_default_channel(DEFAULT_CHANNEL)?;
|
||||
Ok(DEFAULT_CHANNEL)
|
||||
}
|
||||
} else {
|
||||
// Not a valid number, use default
|
||||
self.set_paradise_default_channel(DEFAULT_CHANNEL)?;
|
||||
Ok(DEFAULT_CHANNEL)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Use default and persist it as "main" (user-friendly)
|
||||
self.set_value(
|
||||
&["sources", "radio_paradise", "default_channel"],
|
||||
Value::String("main".to_string()),
|
||||
)?;
|
||||
Ok(DEFAULT_CHANNEL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_paradise_default_channel(&self, channel: u8) -> Result<()> {
|
||||
// Convert channel ID to user-friendly string name
|
||||
let channel_name = match channel {
|
||||
0 => "main",
|
||||
1 => "mellow",
|
||||
2 => "rock",
|
||||
3 => "eclectic",
|
||||
_ => return Err(anyhow::anyhow!("Invalid channel ID: {}", channel)),
|
||||
};
|
||||
|
||||
self.set_value(
|
||||
&["sources", "radio_paradise", "default_channel"],
|
||||
Value::String(channel_name.to_string()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user