Autorise la configuration des noms UPNP.
This commit is contained in:
31
.claude/CLAUDE.md
Normal file
31
.claude/CLAUDE.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# PMOMusic Project Configuration
|
||||
|
||||
## Version Control
|
||||
Ce projet utilise **Jujutsu (jj)** pour le contrôle de version, PAS git.
|
||||
- Utiliser les commandes `jj` au lieu des commandes `git`
|
||||
- Bookmark principal : `main`
|
||||
- Ne jamais suggérer de commandes git
|
||||
|
||||
## Environnement
|
||||
Le PATH et les variables d'environnement sont configurés dans `.claude-env` à la racine du projet.
|
||||
|
||||
## Configuration de l'application
|
||||
- Fichier de configuration principal : `.pmomusic/config.yaml`
|
||||
- Configuration UPNP personnalisable pour différencier les instances en développement
|
||||
|
||||
## Développement
|
||||
Pendant le développement, plusieurs serveurs PMOMusic peuvent tourner en parallèle. Utiliser la configuration UPNP dans `.pmomusic/config.yaml` pour différencier les instances :
|
||||
|
||||
```yaml
|
||||
host:
|
||||
upnp:
|
||||
manufacturer: "PMOMusic-Dev1"
|
||||
udn_prefix: "pmomusic-dev1"
|
||||
model_name_prefix: "PMOMusic-Dev1"
|
||||
friendly_name_prefix: "PMOMusic-Dev1"
|
||||
```
|
||||
|
||||
## Architecture
|
||||
- Projet Rust multi-crates avec workspaces
|
||||
- Crates principales : pmoupnp, pmomediaserver, pmomediarenderer, pmoconfig
|
||||
- Pattern d'extension de configuration via traits (voir pmocache/src/config_ext.rs)
|
||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -4021,6 +4021,7 @@ dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"socket2 0.5.10",
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
host:
|
||||
http_port: "8080"
|
||||
upnp:
|
||||
manufacturer: "PMOMusic"
|
||||
udn_prefix: "pmomusic"
|
||||
model_name_prefix: "PMOMusic"
|
||||
friendly_name_prefix: "PMOMusic"
|
||||
cover_cache:
|
||||
directory: "cache_covers"
|
||||
size: 2000
|
||||
|
||||
@@ -41,16 +41,13 @@ use pmoupnp::devices::Device;
|
||||
/// }
|
||||
/// ```
|
||||
pub static MEDIA_RENDERER: Lazy<Arc<Device>> = Lazy::new(|| {
|
||||
let mut device = Device::new(
|
||||
let mut device = Device::new_from_config(
|
||||
"PMO_MediaRenderer".to_string(),
|
||||
"MediaRenderer".to_string(),
|
||||
"PMOMusic Audio Renderer".to_string(),
|
||||
"Audio Renderer".to_string(),
|
||||
);
|
||||
|
||||
device.set_manufacturer("PMOMusic".to_string());
|
||||
device.set_model_name("PMOMusic Audio Renderer".to_string());
|
||||
device.set_model_description("UPnP AV MediaRenderer for audio streaming".to_string());
|
||||
device.set_udn_prefix("pmomusic".to_string());
|
||||
|
||||
// Ajouter les trois services obligatoires
|
||||
device
|
||||
|
||||
@@ -37,16 +37,13 @@ use pmoupnp::devices::Device;
|
||||
/// }
|
||||
/// ```
|
||||
pub static MEDIA_SERVER: Lazy<Arc<Device>> = Lazy::new(|| {
|
||||
let mut device = Device::new(
|
||||
let mut device = Device::new_from_config(
|
||||
"PMO_MediaServer".to_string(),
|
||||
"MediaServer".to_string(),
|
||||
"PMOMusic Media Server".to_string(),
|
||||
"Media Server".to_string(),
|
||||
);
|
||||
|
||||
device.set_manufacturer("PMOMusic".to_string());
|
||||
device.set_model_name("PMOMusic Media Server".to_string());
|
||||
device.set_model_description("UPnP AV MediaServer for audio streaming".to_string());
|
||||
device.set_udn_prefix("pmomusic".to_string());
|
||||
|
||||
// Ajouter les deux services obligatoires
|
||||
device
|
||||
|
||||
@@ -36,6 +36,7 @@ reqwest = "0.12.23"
|
||||
utoipa = { version = "5.3", features = ["axum_extras"] }
|
||||
socket2 = "0.5"
|
||||
get_if_addrs = "0.5"
|
||||
serde_yaml = "0.9"
|
||||
|
||||
[features]
|
||||
default = ["server"]
|
||||
|
||||
@@ -122,6 +122,84 @@ impl Device {
|
||||
}
|
||||
}
|
||||
|
||||
/// Crée un nouveau modèle de device en utilisant la configuration.
|
||||
///
|
||||
/// Cette factory method charge les préfixes depuis pmoconfig et construit
|
||||
/// automatiquement les noms finaux en combinant les préfixes avec les suffixes.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `name` - Nom unique du device
|
||||
/// * `device_type` - Type UPnP du device (ex: "MediaServer", "MediaRenderer")
|
||||
/// * `friendly_name_suffix` - Suffixe pour le nom convivial (sera combiné avec le préfixe)
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```ignore
|
||||
/// use pmoupnp::devices::Device;
|
||||
///
|
||||
/// let device = Device::new_from_config(
|
||||
/// "PMO_MediaServer".to_string(),
|
||||
/// "MediaServer".to_string(),
|
||||
/// "Media Server".to_string(),
|
||||
/// );
|
||||
/// // Avec config par défaut :
|
||||
/// // - manufacturer = "PMOMusic"
|
||||
/// // - udn_prefix = "pmomusic"
|
||||
/// // - model_name = "PMOMusic Media Server"
|
||||
/// // - friendly_name = "PMOMusic Media Server"
|
||||
/// ```
|
||||
pub fn new_from_config(
|
||||
name: String,
|
||||
device_type: String,
|
||||
friendly_name_suffix: String,
|
||||
) -> Self {
|
||||
use crate::config_ext::UpnpConfigExt;
|
||||
|
||||
let config = pmoconfig::get_config();
|
||||
|
||||
// Charger les valeurs depuis la config (avec fallback aux defaults)
|
||||
let manufacturer = config
|
||||
.get_upnp_manufacturer()
|
||||
.unwrap_or_else(|_| "PMOMusic".to_string());
|
||||
let udn_prefix = config
|
||||
.get_upnp_udn_prefix()
|
||||
.unwrap_or_else(|_| "pmomusic".to_string());
|
||||
let model_name_prefix = config
|
||||
.get_upnp_model_name_prefix()
|
||||
.unwrap_or_else(|_| "PMOMusic".to_string());
|
||||
let friendly_name_prefix = config
|
||||
.get_upnp_friendly_name_prefix()
|
||||
.unwrap_or_else(|_| "PMOMusic".to_string());
|
||||
|
||||
// Construire les noms finaux
|
||||
let model_name = format!("{} {}", model_name_prefix, device_type);
|
||||
let friendly_name = format!("{} {}", friendly_name_prefix, friendly_name_suffix);
|
||||
|
||||
Self {
|
||||
object: UpnpObjectType {
|
||||
name: name.clone(),
|
||||
object_type: "Device".to_string(),
|
||||
},
|
||||
device_type,
|
||||
version: 1,
|
||||
friendly_name,
|
||||
manufacturer,
|
||||
manufacturer_url: None,
|
||||
model_description: None,
|
||||
model_name,
|
||||
model_number: None,
|
||||
model_url: None,
|
||||
serial_number: None,
|
||||
udn_prefix,
|
||||
upc: None,
|
||||
icon_url: None,
|
||||
presentation_url: None,
|
||||
services: RwLock::new(HashMap::new()),
|
||||
devices: RwLock::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Retourne le type de device UPnP.
|
||||
///
|
||||
/// Format: `urn:schemas-upnp-org:device:{type}:{version}`
|
||||
|
||||
@@ -261,7 +261,12 @@ impl UpnpServerExt for Server {
|
||||
if self.ssdp_enabled() {
|
||||
let ssdp_opt = SSDP_SERVER.read().unwrap();
|
||||
if let Some(ref ssdp) = *ssdp_opt {
|
||||
let ssdp_device = di.to_ssdp_device("PMOMusic", "1.0");
|
||||
use crate::config_ext::UpnpConfigExt;
|
||||
let config = pmoconfig::get_config();
|
||||
let manufacturer = config
|
||||
.get_upnp_manufacturer()
|
||||
.unwrap_or_else(|_| "PMOMusic".to_string());
|
||||
let ssdp_device = di.to_ssdp_device(&manufacturer, "1.0");
|
||||
ssdp.add_device(ssdp_device);
|
||||
info!("✅ SSDP announcement for {}", di.udn());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user