Gestion des notifications

This commit is contained in:
2025-11-29 01:56:40 +01:00
parent a559375176
commit 6ae06b38e1
7 changed files with 147 additions and 7 deletions

View File

@@ -77,12 +77,13 @@ use pmoupnp::define_service;
pub mod actions;
pub mod handlers;
pub mod variables;
pub mod state;
use actions::{BROWSE, GETSEARCHCAPABILITIES, GETSORTCAPABILITIES, GETSYSTEMUPDATEID, SEARCH};
use variables::{
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,
A_ARG_TYPE_UPDATEID, SEARCHCAPABILITIES, SORTCAPABILITIES, SYSTEMUPDATEID, CONTAINERUPDATEIDS,
};
// Service ContentDirectory:1 conforme à la spécification UPnP AV pour MediaServer
@@ -102,6 +103,7 @@ define_service! {
SEARCHCAPABILITIES,
SORTCAPABILITIES,
SYSTEMUPDATEID,
CONTAINERUPDATEIDS,
],
actions: [
BROWSE,

View File

@@ -0,0 +1,58 @@
use once_cell::sync::OnceCell;
use pmoupnp::{services::ServiceInstance, variable_types::StateValue};
use std::sync::{atomic::{AtomicU32, Ordering}, Arc, Weak, Mutex};
static CONTENTDIR_INSTANCE: OnceCell<Weak<ServiceInstance>> = OnceCell::new();
static SYSTEM_UPDATE_ID: AtomicU32 = AtomicU32::new(1);
static CONTAINER_UPDATE_IDS: Mutex<String> = Mutex::new(String::new());
/// Enregistre l'instance ContentDirectory pour pouvoir pousser des notifications GENA.
pub fn register_instance(instance: &Arc<ServiceInstance>) {
let _ = CONTENTDIR_INSTANCE.set(Arc::downgrade(instance));
// Initialiser les valeurs
set_system_update_id(1);
set_container_update_ids("");
}
/// Notifie une mise à jour en incrémentant SystemUpdateID et ContainerUpdateIDs.
/// `container_ids` doit contenir les IDs des conteneurs impactés.
pub fn notify_containers_updated(container_ids: &[&str]) {
let new_id = SYSTEM_UPDATE_ID.fetch_add(1, Ordering::Relaxed).saturating_add(1);
set_system_update_id(new_id);
if !container_ids.is_empty() {
let mut buf = String::new();
for (idx, cid) in container_ids.iter().enumerate() {
if idx > 0 {
buf.push(',');
}
buf.push_str(cid);
buf.push(',');
buf.push_str(&new_id.to_string());
}
set_container_update_ids(&buf);
}
}
fn set_system_update_id(id: u32) {
tracing::info!("ContentDirectory: SystemUpdateID -> {}", id);
if let Some(service) = CONTENTDIR_INSTANCE.get().and_then(|w| w.upgrade()) {
if let Some(var) = service.get_variable("SystemUpdateID") {
let _ = var.set_value(StateValue::UI4(id));
}
}
}
fn set_container_update_ids(value: &str) {
tracing::info!("ContentDirectory: ContainerUpdateIDs -> {}", value);
{
let mut guard = CONTAINER_UPDATE_IDS.lock().unwrap();
*guard = value.to_string();
}
if let Some(service) = CONTENTDIR_INSTANCE.get().and_then(|w| w.upgrade()) {
if let Some(var) = service.get_variable("ContainerUpdateIDs") {
let _ = var.set_value(StateValue::String(value.to_string()));
}
}
}

View File

@@ -173,7 +173,8 @@ impl SourcesExt for Server {
#[cfg(feature = "paradise")]
async fn register_paradise(&mut self) -> Result<()> {
use pmoparadise::{RadioParadiseClient, RadioParadiseExt, RadioParadiseSource};
use pmoparadise::{RadioParadiseExt, RadioParadiseSource};
use crate::contentdirectory::state;
tracing::info!("Initializing Radio Paradise source...");
@@ -181,7 +182,13 @@ impl SourcesExt for Server {
let base_url = self.base_url();
// Créer la source Radio Paradise (utilise le singleton PlaylistManager)
let source = Arc::new(RadioParadiseSource::new(base_url.to_string()));
let notifier = Arc::new(|containers: &[String]| {
let refs: Vec<&str> = containers.iter().map(|s| s.as_str()).collect();
state::notify_containers_updated(&refs);
});
let source = Arc::new(
RadioParadiseSource::new(base_url.to_string()).with_container_notifier(notifier),
);
// Brancher les callbacks de playlists (live/history) pour signaler les updates
source.attach_playlist_callbacks();