refactoring des caches
This commit is contained in:
@@ -48,4 +48,5 @@ tracing-subscriber = "0.3"
|
||||
|
||||
[features]
|
||||
default = ["pmoserver"]
|
||||
pmoserver = ["dep:pmoserver", "dep:pmoconfig", "dep:axum", "dep:utoipa", "pmocache/pmoserver", "pmocache/openapi"]
|
||||
pmoconfig = ["dep:pmoconfig", "pmocache/pmoconfig"]
|
||||
pmoserver = ["pmoconfig", "dep:pmoserver", "dep:axum", "dep:utoipa", "pmocache/pmoserver", "pmocache/openapi"]
|
||||
|
||||
106
pmoaudiocache/src/config_ext.rs
Normal file
106
pmoaudiocache/src/config_ext.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
//! Extension pour intégrer le cache audio dans pmoconfig
|
||||
//!
|
||||
//! Ce module fournit le trait `AudioCacheConfigExt` qui permet d'ajouter facilement
|
||||
//! des méthodes de gestion du cache audio à pmoconfig::Config.
|
||||
|
||||
use anyhow::Result;
|
||||
use pmoconfig::Config;
|
||||
use pmocache::CacheConfigExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
const DEFAULT_AUDIO_CACHE_DIR: &str = "cache_audio";
|
||||
const DEFAULT_AUDIO_CACHE_SIZE: usize = 500;
|
||||
|
||||
/// Trait d'extension pour gérer le cache audio dans pmoconfig
|
||||
///
|
||||
/// Ce trait étend `pmoconfig::Config` avec des méthodes spécifiques
|
||||
/// au cache audio avec conversion FLAC.
|
||||
///
|
||||
/// # Exemple
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use pmoconfig::get_config;
|
||||
/// use pmoaudiocache::AudioCacheConfigExt;
|
||||
///
|
||||
/// let config = get_config();
|
||||
/// let cache = config.create_audio_cache()?;
|
||||
///
|
||||
/// // Utiliser le cache
|
||||
/// let pk = cache.add_from_url("http://example.com/track.mp3", Some("album:123")).await?;
|
||||
/// ```
|
||||
pub trait AudioCacheConfigExt {
|
||||
/// Récupère le répertoire du cache audio
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Le chemin absolu du répertoire du cache audio (default: "cache_audio")
|
||||
fn get_audiocache_dir(&self) -> Result<String>;
|
||||
|
||||
/// Définit le répertoire du cache audio
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `directory` - Chemin du répertoire (absolu ou relatif au config_dir)
|
||||
fn set_audiocache_dir(&self, directory: String) -> Result<()>;
|
||||
|
||||
/// Récupère la taille maximale du cache audio
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Le nombre maximal de pistes audio dans le cache (default: 500)
|
||||
fn get_audiocache_size(&self) -> Result<usize>;
|
||||
|
||||
/// Définit la taille maximale du cache audio
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `size` - Nombre maximal de pistes audio
|
||||
fn set_audiocache_size(&self, size: usize) -> Result<()>;
|
||||
|
||||
/// Crée une instance du cache audio configurée avec conversion FLAC
|
||||
///
|
||||
/// Cette méthode factory crée un cache audio en utilisant les paramètres
|
||||
/// de configuration (répertoire et taille) et active la conversion FLAC
|
||||
/// automatique pour tous les fichiers audio téléchargés.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Une instance Arc du cache audio configuré
|
||||
///
|
||||
/// # Exemple
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// use pmoconfig::get_config;
|
||||
/// use pmoaudiocache::AudioCacheConfigExt;
|
||||
///
|
||||
/// let config = get_config();
|
||||
/// let cache = config.create_audio_cache()?;
|
||||
///
|
||||
/// // Le cache est prêt à être utilisé avec conversion FLAC automatique
|
||||
/// ```
|
||||
fn create_audio_cache(&self) -> Result<Arc<crate::Cache>>;
|
||||
}
|
||||
|
||||
impl AudioCacheConfigExt for Config {
|
||||
fn get_audiocache_dir(&self) -> Result<String> {
|
||||
self.get_cache_dir("audio_cache", DEFAULT_AUDIO_CACHE_DIR)
|
||||
}
|
||||
|
||||
fn set_audiocache_dir(&self, directory: String) -> Result<()> {
|
||||
self.set_cache_dir("audio_cache", directory)
|
||||
}
|
||||
|
||||
fn get_audiocache_size(&self) -> Result<usize> {
|
||||
self.get_cache_size("audio_cache", DEFAULT_AUDIO_CACHE_SIZE)
|
||||
}
|
||||
|
||||
fn set_audiocache_size(&self, size: usize) -> Result<()> {
|
||||
self.set_cache_size("audio_cache", size)
|
||||
}
|
||||
|
||||
fn create_audio_cache(&self) -> Result<Arc<crate::Cache>> {
|
||||
let dir = self.get_audiocache_dir()?;
|
||||
let size = self.get_audiocache_size()?;
|
||||
Ok(Arc::new(crate::cache::new_cache(&dir, size)?))
|
||||
}
|
||||
}
|
||||
@@ -137,10 +137,16 @@ pub mod metadata;
|
||||
#[cfg(feature = "pmoserver")]
|
||||
pub mod openapi;
|
||||
|
||||
#[cfg(feature = "pmoconfig")]
|
||||
pub mod config_ext;
|
||||
|
||||
// Re-exports principaux
|
||||
pub use cache::{add_with_metadata_extraction, get_metadata, new_cache, AudioConfig, Cache};
|
||||
pub use metadata::AudioMetadata;
|
||||
|
||||
#[cfg(feature = "pmoconfig")]
|
||||
pub use config_ext::AudioCacheConfigExt;
|
||||
|
||||
#[cfg(feature = "pmoserver")]
|
||||
pub use openapi::ApiDoc;
|
||||
|
||||
@@ -207,9 +213,10 @@ impl AudioCacheExt for pmoserver::Server {
|
||||
}
|
||||
|
||||
async fn init_audio_cache_configured(&mut self) -> anyhow::Result<Arc<Cache>> {
|
||||
use crate::AudioCacheConfigExt;
|
||||
let config = pmoconfig::get_config();
|
||||
let cache_dir = config.get_audio_cache_dir()?;
|
||||
let limit = config.get_audio_cache_size()?;
|
||||
let cache_dir = config.get_audiocache_dir()?;
|
||||
let limit = config.get_audiocache_size()?;
|
||||
self.init_audio_cache(&cache_dir, limit).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,46 @@ pub struct AudioMetadata {
|
||||
}
|
||||
|
||||
impl AudioMetadata {
|
||||
/// Extrait les métadonnées depuis un fichier audio taggé
|
||||
///
|
||||
/// Fonction interne commune pour extraire les métadonnées depuis un TaggedFile
|
||||
fn from_tagged_file(tagged_file: lofty::file::TaggedFile) -> Self {
|
||||
let properties = tagged_file.properties();
|
||||
let tag = tagged_file
|
||||
.primary_tag()
|
||||
.or_else(|| tagged_file.first_tag());
|
||||
|
||||
let mut metadata = Self {
|
||||
title: None,
|
||||
artist: None,
|
||||
album: None,
|
||||
year: None,
|
||||
track_number: None,
|
||||
track_total: None,
|
||||
disc_number: None,
|
||||
disc_total: None,
|
||||
genre: None,
|
||||
duration_secs: Some(properties.duration().as_secs()),
|
||||
sample_rate: properties.sample_rate(),
|
||||
channels: properties.channels(),
|
||||
bitrate: properties.audio_bitrate(),
|
||||
};
|
||||
|
||||
if let Some(tag) = tag {
|
||||
metadata.title = tag.title().map(|s| s.to_string());
|
||||
metadata.artist = tag.artist().map(|s| s.to_string());
|
||||
metadata.album = tag.album().map(|s| s.to_string());
|
||||
metadata.year = tag.year();
|
||||
metadata.track_number = tag.track();
|
||||
metadata.track_total = tag.track_total();
|
||||
metadata.disc_number = tag.disk();
|
||||
metadata.disc_total = tag.disk_total();
|
||||
metadata.genre = tag.genre().map(|s| s.to_string());
|
||||
}
|
||||
|
||||
metadata
|
||||
}
|
||||
|
||||
/// Extrait les métadonnées d'un fichier audio
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -88,41 +128,7 @@ impl AudioMetadata {
|
||||
/// ```
|
||||
pub fn from_file(path: &Path) -> Result<Self> {
|
||||
let tagged_file = Probe::open(path)?.options(ParseOptions::new()).read()?;
|
||||
|
||||
let properties = tagged_file.properties();
|
||||
let tag = tagged_file
|
||||
.primary_tag()
|
||||
.or_else(|| tagged_file.first_tag());
|
||||
|
||||
let mut metadata = Self {
|
||||
title: None,
|
||||
artist: None,
|
||||
album: None,
|
||||
year: None,
|
||||
track_number: None,
|
||||
track_total: None,
|
||||
disc_number: None,
|
||||
disc_total: None,
|
||||
genre: None,
|
||||
duration_secs: Some(properties.duration().as_secs()),
|
||||
sample_rate: properties.sample_rate(),
|
||||
channels: properties.channels(),
|
||||
bitrate: properties.audio_bitrate(),
|
||||
};
|
||||
|
||||
if let Some(tag) = tag {
|
||||
metadata.title = tag.title().map(|s| s.to_string());
|
||||
metadata.artist = tag.artist().map(|s| s.to_string());
|
||||
metadata.album = tag.album().map(|s| s.to_string());
|
||||
metadata.year = tag.year();
|
||||
metadata.track_number = tag.track();
|
||||
metadata.track_total = tag.track_total();
|
||||
metadata.disc_number = tag.disk();
|
||||
metadata.disc_total = tag.disk_total();
|
||||
metadata.genre = tag.genre().map(|s| s.to_string());
|
||||
}
|
||||
|
||||
Ok(metadata)
|
||||
Ok(Self::from_tagged_file(tagged_file))
|
||||
}
|
||||
|
||||
/// Crée des métadonnées depuis des données brutes audio
|
||||
@@ -136,41 +142,7 @@ impl AudioMetadata {
|
||||
.guess_file_type()?
|
||||
.options(ParseOptions::new())
|
||||
.read()?;
|
||||
|
||||
let properties = tagged_file.properties();
|
||||
let tag = tagged_file
|
||||
.primary_tag()
|
||||
.or_else(|| tagged_file.first_tag());
|
||||
|
||||
let mut metadata = Self {
|
||||
title: None,
|
||||
artist: None,
|
||||
album: None,
|
||||
year: None,
|
||||
track_number: None,
|
||||
track_total: None,
|
||||
disc_number: None,
|
||||
disc_total: None,
|
||||
genre: None,
|
||||
duration_secs: Some(properties.duration().as_secs()),
|
||||
sample_rate: properties.sample_rate(),
|
||||
channels: properties.channels(),
|
||||
bitrate: properties.audio_bitrate(),
|
||||
};
|
||||
|
||||
if let Some(tag) = tag {
|
||||
metadata.title = tag.title().map(|s| s.to_string());
|
||||
metadata.artist = tag.artist().map(|s| s.to_string());
|
||||
metadata.album = tag.album().map(|s| s.to_string());
|
||||
metadata.year = tag.year();
|
||||
metadata.track_number = tag.track();
|
||||
metadata.track_total = tag.track_total();
|
||||
metadata.disc_number = tag.disk();
|
||||
metadata.disc_total = tag.disk_total();
|
||||
metadata.genre = tag.genre().map(|s| s.to_string());
|
||||
}
|
||||
|
||||
Ok(metadata)
|
||||
Ok(Self::from_tagged_file(tagged_file))
|
||||
}
|
||||
|
||||
/// Génère une clé de collection basée sur l'artiste et l'album
|
||||
|
||||
Reference in New Issue
Block a user