amélioration de la webapp
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::connectionmanager::variables::{
|
||||
A_ARG_TYPE_CONNECTIONID, A_ARG_TYPE_RCSID, A_ARG_TYPE_AVTRANSPORTID,
|
||||
A_ARG_TYPE_PROTOCOLINFO, A_ARG_TYPE_DIRECTION, A_ARG_TYPE_CONNECTIONSTATUS,
|
||||
A_ARG_TYPE_AVTRANSPORTID, A_ARG_TYPE_CONNECTIONID, A_ARG_TYPE_CONNECTIONSTATUS,
|
||||
A_ARG_TYPE_DIRECTION, A_ARG_TYPE_PROTOCOLINFO, A_ARG_TYPE_RCSID,
|
||||
};
|
||||
use pmoupnp::define_action;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::connectionmanager::variables::{SOURCEPROTOCOLINFO, SINKPROTOCOLINFO};
|
||||
use crate::connectionmanager::variables::{SINKPROTOCOLINFO, SOURCEPROTOCOLINFO};
|
||||
use pmoupnp::define_action;
|
||||
|
||||
define_action! {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod getprotocolinfo;
|
||||
mod getcurrentconnectionids;
|
||||
mod getcurrentconnectioninfo;
|
||||
mod getprotocolinfo;
|
||||
|
||||
pub use getprotocolinfo::GETPROTOCOLINFO;
|
||||
pub use getcurrentconnectionids::GETCURRENTCONNECTIONIDS;
|
||||
pub use getcurrentconnectioninfo::GETCURRENTCONNECTIONINFO;
|
||||
pub use getprotocolinfo::GETPROTOCOLINFO;
|
||||
|
||||
@@ -65,14 +65,14 @@
|
||||
|
||||
use pmoupnp::define_service;
|
||||
|
||||
pub mod variables;
|
||||
pub mod actions;
|
||||
pub mod variables;
|
||||
|
||||
use actions::{GETCURRENTCONNECTIONIDS, GETCURRENTCONNECTIONINFO, GETPROTOCOLINFO};
|
||||
use variables::{
|
||||
A_ARG_TYPE_AVTRANSPORTID, A_ARG_TYPE_CONNECTIONID, A_ARG_TYPE_CONNECTIONSTATUS,
|
||||
A_ARG_TYPE_DIRECTION, A_ARG_TYPE_PROTOCOLINFO, A_ARG_TYPE_RCSID,
|
||||
CURRENTCONNECTIONIDS, SINKPROTOCOLINFO, SOURCEPROTOCOLINFO
|
||||
A_ARG_TYPE_DIRECTION, A_ARG_TYPE_PROTOCOLINFO, A_ARG_TYPE_RCSID, CURRENTCONNECTIONIDS,
|
||||
SINKPROTOCOLINFO, SOURCEPROTOCOLINFO,
|
||||
};
|
||||
|
||||
// Service ConnectionManager:1 conforme à la spécification UPnP AV pour MediaServer
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
mod a_arg_type_avtransportid;
|
||||
mod a_arg_type_connectionid;
|
||||
mod a_arg_type_connectionstatus;
|
||||
mod a_arg_type_direction;
|
||||
mod a_arg_type_protocolinfo;
|
||||
mod a_arg_type_rcsid;
|
||||
mod a_arg_type_avtransportid;
|
||||
mod currentconnectionids;
|
||||
mod sourceprotocolinfo;
|
||||
mod sinkprotocolinfo;
|
||||
mod sourceprotocolinfo;
|
||||
|
||||
pub use a_arg_type_avtransportid::A_ARG_TYPE_AVTRANSPORTID;
|
||||
pub use a_arg_type_connectionid::A_ARG_TYPE_CONNECTIONID;
|
||||
pub use a_arg_type_connectionstatus::A_ARG_TYPE_CONNECTIONSTATUS;
|
||||
pub use a_arg_type_direction::A_ARG_TYPE_DIRECTION;
|
||||
pub use a_arg_type_protocolinfo::A_ARG_TYPE_PROTOCOLINFO;
|
||||
pub use a_arg_type_rcsid::A_ARG_TYPE_RCSID;
|
||||
pub use a_arg_type_avtransportid::A_ARG_TYPE_AVTRANSPORTID;
|
||||
pub use currentconnectionids::CURRENTCONNECTIONIDS;
|
||||
pub use sourceprotocolinfo::SOURCEPROTOCOLINFO;
|
||||
pub use sinkprotocolinfo::SINKPROTOCOLINFO;
|
||||
pub use sourceprotocolinfo::SOURCEPROTOCOLINFO;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
//! - **Search** : Recherche dans les sources qui le supportent
|
||||
//! - **Update ID** : Suivi des changements pour les notifications UPnP
|
||||
|
||||
use pmosource::api::{list_all_sources, get_source as get_source_from_registry};
|
||||
use pmodidl::{Container, DIDLLite};
|
||||
use pmosource::api::{get_source as get_source_from_registry, list_all_sources};
|
||||
use pmosource::{BrowseResult, MusicSource};
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -28,8 +28,7 @@ fn to_didl_lite(containers: &[Container], items: &[pmodidl::Item]) -> Result<Str
|
||||
items: items.to_vec(),
|
||||
};
|
||||
|
||||
quick_xml::se::to_string(&didl)
|
||||
.map_err(|e| format!("Failed to serialize DIDL-Lite: {}", e))
|
||||
quick_xml::se::to_string(&didl).map_err(|e| format!("Failed to serialize DIDL-Lite: {}", e))
|
||||
}
|
||||
|
||||
/// Handler pour le service ContentDirectory
|
||||
@@ -208,11 +207,7 @@ impl ContentHandler {
|
||||
requested_count as usize
|
||||
};
|
||||
|
||||
let paginated: Vec<Container> = containers
|
||||
.into_iter()
|
||||
.skip(start)
|
||||
.take(count)
|
||||
.collect();
|
||||
let paginated: Vec<Container> = containers.into_iter().skip(start).take(count).collect();
|
||||
|
||||
let returned = paginated.len();
|
||||
let didl = to_didl_lite(&paginated, &[])?;
|
||||
@@ -278,11 +273,7 @@ impl ContentHandler {
|
||||
// On commence dans les items
|
||||
containers.clear();
|
||||
let item_start = start - total_containers;
|
||||
items = items
|
||||
.into_iter()
|
||||
.skip(item_start)
|
||||
.take(count)
|
||||
.collect();
|
||||
items = items.into_iter().skip(item_start).take(count).collect();
|
||||
}
|
||||
|
||||
let returned = (containers.len() + items.len()) as u32;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use crate::contentdirectory::handlers;
|
||||
use crate::contentdirectory::variables::{
|
||||
A_ARG_TYPE_OBJECTID, A_ARG_TYPE_BROWSEFLAG, A_ARG_TYPE_FILTER,
|
||||
A_ARG_TYPE_SORTCRITERIA, A_ARG_TYPE_INDEX, A_ARG_TYPE_COUNT,
|
||||
A_ARG_TYPE_RESULT, A_ARG_TYPE_UPDATEID,
|
||||
A_ARG_TYPE_BROWSEFLAG, A_ARG_TYPE_COUNT, A_ARG_TYPE_FILTER, A_ARG_TYPE_INDEX,
|
||||
A_ARG_TYPE_OBJECTID, A_ARG_TYPE_RESULT, A_ARG_TYPE_SORTCRITERIA, A_ARG_TYPE_UPDATEID,
|
||||
};
|
||||
use pmoupnp::define_action;
|
||||
use crate::contentdirectory::handlers;
|
||||
|
||||
define_action! {
|
||||
pub static BROWSE = "Browse" stateless {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::contentdirectory::handlers;
|
||||
use crate::contentdirectory::variables::SEARCHCAPABILITIES;
|
||||
use pmoupnp::define_action;
|
||||
use crate::contentdirectory::handlers;
|
||||
|
||||
define_action! {
|
||||
pub static GETSEARCHCAPABILITIES = "GetSearchCapabilities" stateless {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::contentdirectory::handlers;
|
||||
use crate::contentdirectory::variables::SORTCAPABILITIES;
|
||||
use pmoupnp::define_action;
|
||||
use crate::contentdirectory::handlers;
|
||||
|
||||
define_action! {
|
||||
pub static GETSORTCAPABILITIES = "GetSortCapabilities" stateless {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::contentdirectory::handlers;
|
||||
use crate::contentdirectory::variables::SYSTEMUPDATEID;
|
||||
use pmoupnp::define_action;
|
||||
use crate::contentdirectory::handlers;
|
||||
|
||||
define_action! {
|
||||
pub static GETSYSTEMUPDATEID = "GetSystemUpdateID" stateless {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
mod browse;
|
||||
mod search;
|
||||
mod getsearchcapabilities;
|
||||
mod getsortcapabilities;
|
||||
mod getsystemupdateid;
|
||||
mod search;
|
||||
|
||||
pub use browse::BROWSE;
|
||||
pub use search::SEARCH;
|
||||
pub use getsearchcapabilities::GETSEARCHCAPABILITIES;
|
||||
pub use getsortcapabilities::GETSORTCAPABILITIES;
|
||||
pub use getsystemupdateid::GETSYSTEMUPDATEID;
|
||||
pub use search::SEARCH;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use crate::contentdirectory::handlers;
|
||||
use crate::contentdirectory::variables::{
|
||||
A_ARG_TYPE_OBJECTID, A_ARG_TYPE_SEARCHCRITERIA, A_ARG_TYPE_FILTER,
|
||||
A_ARG_TYPE_SORTCRITERIA, A_ARG_TYPE_INDEX, A_ARG_TYPE_COUNT,
|
||||
A_ARG_TYPE_RESULT, A_ARG_TYPE_UPDATEID,
|
||||
A_ARG_TYPE_COUNT, A_ARG_TYPE_FILTER, A_ARG_TYPE_INDEX, A_ARG_TYPE_OBJECTID, A_ARG_TYPE_RESULT,
|
||||
A_ARG_TYPE_SEARCHCRITERIA, A_ARG_TYPE_SORTCRITERIA, A_ARG_TYPE_UPDATEID,
|
||||
};
|
||||
use pmoupnp::define_action;
|
||||
use crate::contentdirectory::handlers;
|
||||
|
||||
define_action! {
|
||||
pub static SEARCH = "Search" stateless {
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
//! - [`get_sort_capabilities_handler`] : Capacités de tri supportées
|
||||
//! - [`get_system_update_id_handler`] : ID de mise à jour du système
|
||||
|
||||
use pmoupnp::{action_handler, get, set};
|
||||
use pmoupnp::actions::{ActionError, ActionHandler};
|
||||
use crate::content_handler::ContentHandler;
|
||||
use pmoupnp::actions::{ActionError, ActionHandler};
|
||||
use pmoupnp::{action_handler, get, set};
|
||||
use tracing::{debug, error};
|
||||
|
||||
/// Handler pour l'action Browse.
|
||||
@@ -76,7 +76,10 @@ pub fn browse_handler() -> ActionHandler {
|
||||
set!(&mut data, "TotalMatches", total);
|
||||
set!(&mut data, "UpdateID", update_id);
|
||||
|
||||
debug!("✅ Browse completed: returned={}, total={}", returned, total);
|
||||
debug!(
|
||||
"✅ Browse completed: returned={}, total={}",
|
||||
returned, total
|
||||
);
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
@@ -128,7 +131,10 @@ pub fn search_handler() -> ActionHandler {
|
||||
set!(&mut data, "TotalMatches", total);
|
||||
set!(&mut data, "UpdateID", update_id);
|
||||
|
||||
debug!("✅ Search completed: returned={}, total={}", returned, total);
|
||||
debug!(
|
||||
"✅ Search completed: returned={}, total={}",
|
||||
returned, total
|
||||
);
|
||||
Ok(data)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,18 +74,15 @@
|
||||
|
||||
use pmoupnp::define_service;
|
||||
|
||||
pub mod variables;
|
||||
pub mod actions;
|
||||
pub mod handlers;
|
||||
pub mod variables;
|
||||
|
||||
use actions::{
|
||||
BROWSE, SEARCH, GETSEARCHCAPABILITIES, GETSORTCAPABILITIES, GETSYSTEMUPDATEID
|
||||
};
|
||||
use actions::{BROWSE, GETSEARCHCAPABILITIES, GETSORTCAPABILITIES, GETSYSTEMUPDATEID, SEARCH};
|
||||
use variables::{
|
||||
A_ARG_TYPE_OBJECTID, A_ARG_TYPE_BROWSEFLAG, A_ARG_TYPE_FILTER,
|
||||
A_ARG_TYPE_SORTCRITERIA, A_ARG_TYPE_INDEX, A_ARG_TYPE_COUNT,
|
||||
A_ARG_TYPE_UPDATEID, A_ARG_TYPE_RESULT, A_ARG_TYPE_SEARCHCRITERIA,
|
||||
SEARCHCAPABILITIES, SORTCAPABILITIES, SYSTEMUPDATEID
|
||||
A_ARG_TYPE_BROWSEFLAG, A_ARG_TYPE_COUNT, A_ARG_TYPE_FILTER, A_ARG_TYPE_INDEX,
|
||||
A_ARG_TYPE_OBJECTID, A_ARG_TYPE_RESULT, A_ARG_TYPE_SEARCHCRITERIA, A_ARG_TYPE_SORTCRITERIA,
|
||||
A_ARG_TYPE_UPDATEID, SEARCHCAPABILITIES, SORTCAPABILITIES, SYSTEMUPDATEID,
|
||||
};
|
||||
|
||||
// Service ContentDirectory:1 conforme à la spécification UPnP AV pour MediaServer
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
mod a_arg_type_objectid;
|
||||
mod a_arg_type_browseflag;
|
||||
mod a_arg_type_filter;
|
||||
mod a_arg_type_sortcriteria;
|
||||
mod a_arg_type_index;
|
||||
mod a_arg_type_count;
|
||||
mod a_arg_type_updateid;
|
||||
mod a_arg_type_filter;
|
||||
mod a_arg_type_index;
|
||||
mod a_arg_type_objectid;
|
||||
mod a_arg_type_result;
|
||||
mod a_arg_type_searchcriteria;
|
||||
mod a_arg_type_sortcriteria;
|
||||
mod a_arg_type_updateid;
|
||||
mod searchcapabilities;
|
||||
mod sortcapabilities;
|
||||
mod systemupdateid;
|
||||
|
||||
pub use a_arg_type_objectid::A_ARG_TYPE_OBJECTID;
|
||||
pub use a_arg_type_browseflag::A_ARG_TYPE_BROWSEFLAG;
|
||||
pub use a_arg_type_filter::A_ARG_TYPE_FILTER;
|
||||
pub use a_arg_type_sortcriteria::A_ARG_TYPE_SORTCRITERIA;
|
||||
pub use a_arg_type_index::A_ARG_TYPE_INDEX;
|
||||
pub use a_arg_type_count::A_ARG_TYPE_COUNT;
|
||||
pub use a_arg_type_updateid::A_ARG_TYPE_UPDATEID;
|
||||
pub use a_arg_type_filter::A_ARG_TYPE_FILTER;
|
||||
pub use a_arg_type_index::A_ARG_TYPE_INDEX;
|
||||
pub use a_arg_type_objectid::A_ARG_TYPE_OBJECTID;
|
||||
pub use a_arg_type_result::A_ARG_TYPE_RESULT;
|
||||
pub use a_arg_type_searchcriteria::A_ARG_TYPE_SEARCHCRITERIA;
|
||||
pub use a_arg_type_sortcriteria::A_ARG_TYPE_SORTCRITERIA;
|
||||
pub use a_arg_type_updateid::A_ARG_TYPE_UPDATEID;
|
||||
pub use searchcapabilities::SEARCHCAPABILITIES;
|
||||
pub use sortcapabilities::SORTCAPABILITIES;
|
||||
pub use systemupdateid::SYSTEMUPDATEID;
|
||||
|
||||
@@ -3,11 +3,8 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{connectionmanager::CONNECTIONMANAGER, contentdirectory::CONTENTDIRECTORY};
|
||||
use pmoupnp::devices::Device;
|
||||
use crate::{
|
||||
contentdirectory::CONTENTDIRECTORY,
|
||||
connectionmanager::CONNECTIONMANAGER,
|
||||
};
|
||||
|
||||
/// Device MediaServer UPnP.
|
||||
///
|
||||
@@ -52,10 +49,12 @@ pub static MEDIA_SERVER: Lazy<Arc<Device>> = Lazy::new(|| {
|
||||
device.set_udn_prefix("pmomusic".to_string());
|
||||
|
||||
// Ajouter les deux services obligatoires
|
||||
device.add_service(Arc::clone(&CONTENTDIRECTORY))
|
||||
device
|
||||
.add_service(Arc::clone(&CONTENTDIRECTORY))
|
||||
.expect("Failed to add ContentDirectory service");
|
||||
|
||||
device.add_service(Arc::clone(&CONNECTIONMANAGER))
|
||||
device
|
||||
.add_service(Arc::clone(&CONNECTIONMANAGER))
|
||||
.expect("Failed to add ConnectionManager service");
|
||||
|
||||
Arc::new(device)
|
||||
|
||||
@@ -63,23 +63,23 @@
|
||||
//! server.register_qobuz_from_config().await?;
|
||||
//! ```
|
||||
|
||||
pub mod contentdirectory;
|
||||
pub mod connectionmanager;
|
||||
pub mod device;
|
||||
pub mod source_registry;
|
||||
pub mod server_ext;
|
||||
pub mod content_handler;
|
||||
pub mod contentdirectory;
|
||||
pub mod device;
|
||||
pub mod server_ext;
|
||||
pub mod source_registry;
|
||||
pub mod sources;
|
||||
|
||||
// API REST pour l'enregistrement des sources (requires features qobuz/paradise)
|
||||
#[cfg(any(feature = "qobuz", feature = "paradise"))]
|
||||
pub mod sources_api;
|
||||
|
||||
pub use device::MEDIA_SERVER;
|
||||
pub use source_registry::SourceRegistry;
|
||||
pub use server_ext::{MediaServerExt, get_source_registry, MusicSourceExt};
|
||||
pub use content_handler::ContentHandler;
|
||||
pub use sources::{SourcesExt, SourceInitError};
|
||||
pub use device::MEDIA_SERVER;
|
||||
pub use server_ext::{MediaServerExt, MusicSourceExt, get_source_registry};
|
||||
pub use source_registry::SourceRegistry;
|
||||
pub use sources::{SourceInitError, SourcesExt};
|
||||
|
||||
// Re-export sources when features are enabled
|
||||
#[cfg(feature = "qobuz")]
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
//! méthodes spécifiques au MediaServer UPnP.
|
||||
|
||||
use async_trait::async_trait;
|
||||
use pmosource::MusicSource;
|
||||
use pmoserver::Server;
|
||||
use pmosource::MusicSource;
|
||||
use std::sync::Arc;
|
||||
|
||||
// Réexporter le trait de base de pmosource
|
||||
@@ -23,7 +23,10 @@ pub use pmosource::MusicSourceExt;
|
||||
///
|
||||
/// let sources = pmosource::api::list_all_sources().await;
|
||||
/// ```
|
||||
#[deprecated(since = "0.2.0", note = "Use pmosource::api::list_all_sources() directly")]
|
||||
#[deprecated(
|
||||
since = "0.2.0",
|
||||
note = "Use pmosource::api::list_all_sources() directly"
|
||||
)]
|
||||
pub async fn get_source_registry() -> Vec<Arc<dyn MusicSource>> {
|
||||
pmosource::api::list_all_sources().await
|
||||
}
|
||||
|
||||
@@ -210,8 +210,8 @@ impl Default for SourceRegistry {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pmosource::{MusicSource, Result, BrowseResult};
|
||||
use pmodidl::{Container, Item};
|
||||
use pmosource::{BrowseResult, MusicSource, Result};
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -308,9 +308,15 @@ mod tests {
|
||||
async fn test_list_all() {
|
||||
let registry = SourceRegistry::new();
|
||||
|
||||
registry.register(Arc::new(TestSource::new("test-1", "Test 1"))).await;
|
||||
registry.register(Arc::new(TestSource::new("test-2", "Test 2"))).await;
|
||||
registry.register(Arc::new(TestSource::new("test-3", "Test 3"))).await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-1", "Test 1")))
|
||||
.await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-2", "Test 2")))
|
||||
.await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-3", "Test 3")))
|
||||
.await;
|
||||
|
||||
let sources = registry.list_all().await;
|
||||
assert_eq!(sources.len(), 3);
|
||||
@@ -321,17 +327,23 @@ mod tests {
|
||||
let registry = SourceRegistry::new();
|
||||
assert_eq!(registry.count().await, 0);
|
||||
|
||||
registry.register(Arc::new(TestSource::new("test-1", "Test 1"))).await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-1", "Test 1")))
|
||||
.await;
|
||||
assert_eq!(registry.count().await, 1);
|
||||
|
||||
registry.register(Arc::new(TestSource::new("test-2", "Test 2"))).await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-2", "Test 2")))
|
||||
.await;
|
||||
assert_eq!(registry.count().await, 2);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_remove() {
|
||||
let registry = SourceRegistry::new();
|
||||
registry.register(Arc::new(TestSource::new("test-1", "Test 1"))).await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-1", "Test 1")))
|
||||
.await;
|
||||
|
||||
assert!(registry.contains("test-1").await);
|
||||
assert!(registry.remove("test-1").await);
|
||||
@@ -345,7 +357,9 @@ mod tests {
|
||||
|
||||
assert!(!registry.contains("test-1").await);
|
||||
|
||||
registry.register(Arc::new(TestSource::new("test-1", "Test 1"))).await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-1", "Test 1")))
|
||||
.await;
|
||||
|
||||
assert!(registry.contains("test-1").await);
|
||||
assert!(!registry.contains("test-2").await);
|
||||
@@ -355,11 +369,15 @@ mod tests {
|
||||
async fn test_replace_source() {
|
||||
let registry = SourceRegistry::new();
|
||||
|
||||
registry.register(Arc::new(TestSource::new("test-1", "Old Name"))).await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-1", "Old Name")))
|
||||
.await;
|
||||
let old = registry.get("test-1").await.unwrap();
|
||||
assert_eq!(old.name(), "Old Name");
|
||||
|
||||
registry.register(Arc::new(TestSource::new("test-1", "New Name"))).await;
|
||||
registry
|
||||
.register(Arc::new(TestSource::new("test-1", "New Name")))
|
||||
.await;
|
||||
let new = registry.get("test-1").await.unwrap();
|
||||
assert_eq!(new.name(), "New Name");
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
//! Ce module fournit des helpers pour créer et enregistrer facilement des sources
|
||||
//! musicales préconfigurées à partir de la configuration système.
|
||||
|
||||
use pmosource::MusicSourceExt;
|
||||
use pmoserver::Server;
|
||||
use pmosource::MusicSourceExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Erreur lors de l'initialisation d'une source
|
||||
@@ -93,7 +93,11 @@ pub trait SourcesExt {
|
||||
/// server.register_qobuz_with_credentials("user@example.com", "password").await?;
|
||||
/// ```
|
||||
#[cfg(feature = "qobuz")]
|
||||
async fn register_qobuz_with_credentials(&mut self, username: &str, password: &str) -> Result<()>;
|
||||
async fn register_qobuz_with_credentials(
|
||||
&mut self,
|
||||
username: &str,
|
||||
password: &str,
|
||||
) -> Result<()>;
|
||||
|
||||
/// Enregistre la source Radio Paradise
|
||||
///
|
||||
@@ -141,7 +145,11 @@ impl SourcesExt for Server {
|
||||
}
|
||||
|
||||
#[cfg(feature = "qobuz")]
|
||||
async fn register_qobuz_with_credentials(&mut self, username: &str, password: &str) -> Result<()> {
|
||||
async fn register_qobuz_with_credentials(
|
||||
&mut self,
|
||||
username: &str,
|
||||
password: &str,
|
||||
) -> Result<()> {
|
||||
use pmoqobuz::{QobuzClient, QobuzSource};
|
||||
|
||||
tracing::info!("Initializing Qobuz source with explicit credentials...");
|
||||
@@ -165,18 +173,19 @@ impl SourcesExt for Server {
|
||||
|
||||
#[cfg(feature = "paradise")]
|
||||
async fn register_paradise(&mut self) -> Result<()> {
|
||||
use pmoparadise::{RadioParadiseClient, RadioParadiseSource, RadioParadiseExt};
|
||||
use pmoparadise::{RadioParadiseClient, RadioParadiseExt, RadioParadiseSource};
|
||||
|
||||
tracing::info!("Initializing Radio Paradise source...");
|
||||
|
||||
// Créer le client (Radio Paradise ne nécessite pas d'authentification)
|
||||
let client = RadioParadiseClient::new()
|
||||
.await
|
||||
.map_err(|e| SourceInitError::ParadiseError(format!("Failed to create client: {}", e)))?;
|
||||
let client = RadioParadiseClient::new().await.map_err(|e| {
|
||||
SourceInitError::ParadiseError(format!("Failed to create client: {}", e))
|
||||
})?;
|
||||
|
||||
// Créer la source depuis le registry avec capacité FIFO par défaut
|
||||
let source = RadioParadiseSource::from_registry_default(client)
|
||||
.map_err(|e| SourceInitError::ParadiseError(format!("Failed to create source: {}", e)))?;
|
||||
let source = RadioParadiseSource::from_registry_default(client).map_err(|e| {
|
||||
SourceInitError::ParadiseError(format!("Failed to create source: {}", e))
|
||||
})?;
|
||||
|
||||
// Enregistrer la source
|
||||
// Note: La FIFO sera peuplée automatiquement lors du premier browse
|
||||
|
||||
@@ -13,13 +13,7 @@
|
||||
//! Ces endpoints sont définis ici plutôt que dans `pmosource` pour éviter les
|
||||
//! dépendances circulaires (pmoqobuz et pmoparadise dépendent de pmosource).
|
||||
|
||||
use axum::{
|
||||
extract::Json,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::post,
|
||||
Router,
|
||||
};
|
||||
use axum::{Router, extract::Json, http::StatusCode, response::IntoResponse, routing::post};
|
||||
use pmosource::MusicSource;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
Reference in New Issue
Block a user