2025-10-12 21:39:20 +02:00
|
|
|
//! # pmocache - Système de cache générique pour PMOMusic
|
|
|
|
|
//!
|
|
|
|
|
//! Cette crate fournit un système de cache générique avec support de base de données SQLite
|
|
|
|
|
//! et stockage sur disque. Elle est utilisée comme base pour des caches spécialisés comme
|
|
|
|
|
//! `pmocovers` (cache d'images) et `pmoaudiocache` (cache de pistes audio).
|
|
|
|
|
//!
|
|
|
|
|
//! ## Vue d'ensemble
|
|
|
|
|
//!
|
|
|
|
|
//! `pmocache` fournit les composants de base pour :
|
|
|
|
|
//! - Stocker des fichiers sur disque avec une base de données SQLite pour les métadonnées
|
|
|
|
|
//! - Gérer des collections d'éléments (albums, playlists, etc.)
|
|
|
|
|
//! - Suivre les statistiques d'utilisation (hits, dernière utilisation)
|
|
|
|
|
//! - Télécharger automatiquement depuis des URLs
|
|
|
|
|
//! - Consolider et purger le cache
|
|
|
|
|
//!
|
|
|
|
|
//! ## Architecture
|
|
|
|
|
//!
|
|
|
|
|
//! `pmocache` est conçu comme une base générique :
|
|
|
|
|
//!
|
|
|
|
|
//! ```text
|
|
|
|
|
//! pmocache (générique)
|
|
|
|
|
//! ├── db.rs - Base de données SQLite générique
|
|
|
|
|
//! └── cache.rs - Système de cache générique
|
|
|
|
|
//!
|
|
|
|
|
//! pmocovers (spécialisé pour les images)
|
|
|
|
|
//! └── Utilise pmocache + conversion WebP
|
|
|
|
|
//!
|
|
|
|
|
//! pmoaudiocache (spécialisé pour l'audio)
|
|
|
|
|
//! └── Utilise pmocache + métadonnées audio
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
|
|
|
|
//! ## Utilisation
|
|
|
|
|
//!
|
|
|
|
|
//! ### Exemple basique
|
|
|
|
|
//!
|
|
|
|
|
//! ```rust,no_run
|
2025-10-17 14:36:39 +02:00
|
|
|
//! use pmocache::{Cache, CacheConfig};
|
|
|
|
|
//!
|
|
|
|
|
//! // Définir la configuration du cache
|
|
|
|
|
//! struct MyConfig;
|
|
|
|
|
//! impl CacheConfig for MyConfig {
|
|
|
|
|
//! fn file_extension() -> &'static str { "dat" }
|
|
|
|
|
//! fn table_name() -> &'static str { "my_cache" }
|
|
|
|
|
//! fn cache_type() -> &'static str { "generic" }
|
|
|
|
|
//! }
|
2025-10-12 21:39:20 +02:00
|
|
|
//!
|
|
|
|
|
//! #[tokio::main]
|
|
|
|
|
//! async fn main() -> anyhow::Result<()> {
|
2025-10-17 14:36:39 +02:00
|
|
|
//! let cache = Cache::<MyConfig>::new("./cache", 1000, "http://localhost:8080")?;
|
2025-10-12 21:39:20 +02:00
|
|
|
//!
|
|
|
|
|
//! // Ajouter un fichier depuis une URL
|
|
|
|
|
//! let pk = cache.add_from_url("http://example.com/file.dat", None).await?;
|
|
|
|
|
//! println!("Fichier ajouté avec clé: {}", pk);
|
|
|
|
|
//!
|
|
|
|
|
//! // Récupérer le fichier
|
|
|
|
|
//! let path = cache.get(&pk).await?;
|
|
|
|
|
//! println!("Fichier stocké à: {:?}", path);
|
|
|
|
|
//!
|
|
|
|
|
//! Ok(())
|
|
|
|
|
//! }
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
|
|
|
|
//! ### Utilisation avec des collections
|
|
|
|
|
//!
|
|
|
|
|
//! ```rust,no_run
|
2025-10-17 14:36:39 +02:00
|
|
|
//! use pmocache::{Cache, CacheConfig};
|
|
|
|
|
//!
|
|
|
|
|
//! struct AudioConfig;
|
|
|
|
|
//! impl CacheConfig for AudioConfig {
|
|
|
|
|
//! fn file_extension() -> &'static str { "flac" }
|
|
|
|
|
//! fn table_name() -> &'static str { "audio" }
|
|
|
|
|
//! fn cache_type() -> &'static str { "audio" }
|
|
|
|
|
//! }
|
2025-10-12 21:39:20 +02:00
|
|
|
//!
|
|
|
|
|
//! #[tokio::main]
|
|
|
|
|
//! async fn main() -> anyhow::Result<()> {
|
2025-10-17 14:36:39 +02:00
|
|
|
//! let cache = Cache::<AudioConfig>::new("./cache", 1000, "http://localhost:8080")?;
|
2025-10-12 21:39:20 +02:00
|
|
|
//!
|
|
|
|
|
//! // Ajouter des pistes d'un album
|
|
|
|
|
//! let album_id = "album:the_wall";
|
|
|
|
|
//! cache.add_from_url("http://example.com/track1.flac", Some(album_id)).await?;
|
|
|
|
|
//! cache.add_from_url("http://example.com/track2.flac", Some(album_id)).await?;
|
|
|
|
|
//!
|
|
|
|
|
//! // Récupérer toutes les pistes de l'album
|
|
|
|
|
//! let tracks = cache.get_collection(album_id).await?;
|
|
|
|
|
//! println!("Album contient {} pistes", tracks.len());
|
|
|
|
|
//!
|
|
|
|
|
//! Ok(())
|
|
|
|
|
//! }
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
|
|
|
|
//! ## Structure des fichiers
|
|
|
|
|
//!
|
|
|
|
|
//! ```text
|
|
|
|
|
//! cache/
|
|
|
|
|
//! ├── cache.db # Base de données SQLite
|
|
|
|
|
//! ├── 1a2b3c4d.webp # Fichier 1
|
|
|
|
|
//! └── 5e6f7a8b.flac # Fichier 2
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
|
|
|
|
//! ## Schéma de base de données
|
|
|
|
|
//!
|
|
|
|
|
//! ```sql
|
|
|
|
|
//! CREATE TABLE {table_name} (
|
|
|
|
|
//! pk TEXT PRIMARY KEY, -- Clé unique (hash SHA1 de l'URL)
|
|
|
|
|
//! source_url TEXT, -- URL source
|
|
|
|
|
//! collection TEXT, -- Collection (album, playlist, etc.)
|
|
|
|
|
//! hits INTEGER DEFAULT 0, -- Nombre d'accès
|
|
|
|
|
//! last_used TEXT -- Dernière utilisation (RFC3339)
|
|
|
|
|
//! );
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
|
|
|
|
//! ## Dépendances principales
|
|
|
|
|
//!
|
|
|
|
|
//! - `rusqlite` : Base de données SQLite
|
|
|
|
|
//! - `reqwest` : Téléchargement HTTP
|
|
|
|
|
//! - `sha1` : Génération de clés
|
|
|
|
|
//! - `tokio` : Runtime asynchrone
|
|
|
|
|
//!
|
|
|
|
|
//! ## Voir aussi
|
|
|
|
|
//!
|
|
|
|
|
//! - [`pmocovers`] : Cache d'images avec conversion WebP
|
|
|
|
|
//! - [`pmoaudiocache`] : Cache de pistes audio
|
|
|
|
|
|
|
|
|
|
pub mod cache;
|
2025-10-17 14:36:39 +02:00
|
|
|
pub mod cache_trait;
|
2025-10-19 13:42:29 +02:00
|
|
|
pub mod db;
|
2025-10-17 19:48:53 +02:00
|
|
|
pub mod download;
|
2025-10-17 14:36:39 +02:00
|
|
|
|
|
|
|
|
#[cfg(feature = "pmoserver")]
|
|
|
|
|
pub mod pmoserver_ext;
|
2025-10-12 21:39:20 +02:00
|
|
|
|
2025-10-17 19:48:53 +02:00
|
|
|
#[cfg(feature = "pmoserver")]
|
|
|
|
|
pub mod api;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "openapi")]
|
|
|
|
|
pub mod openapi;
|
|
|
|
|
|
2025-10-25 17:14:24 +02:00
|
|
|
#[cfg(feature = "pmoconfig")]
|
|
|
|
|
pub mod config_ext;
|
|
|
|
|
|
2025-10-17 19:48:53 +02:00
|
|
|
pub use cache::{Cache, CacheConfig};
|
2025-10-25 17:14:24 +02:00
|
|
|
pub use cache_trait::{pk_from_content_header, pk_from_url, FileCache};
|
2025-10-19 13:42:29 +02:00
|
|
|
pub use db::{CacheEntry, DB};
|
2025-10-19 17:26:06 +02:00
|
|
|
pub use download::{
|
2025-10-25 17:14:24 +02:00
|
|
|
download, download_with_transformer, ingest_with_transformer, peek_header,
|
|
|
|
|
peek_reader_header, Download, StreamTransformer,
|
2025-10-19 17:26:06 +02:00
|
|
|
};
|
2025-10-17 19:48:53 +02:00
|
|
|
|
|
|
|
|
#[cfg(feature = "pmoserver")]
|
2025-10-19 13:42:29 +02:00
|
|
|
pub use pmoserver_ext::{create_api_router, create_file_router, GenericCacheExt};
|
2025-10-17 19:48:53 +02:00
|
|
|
|
|
|
|
|
#[cfg(all(feature = "pmoserver", feature = "openapi"))]
|
2025-10-19 13:42:29 +02:00
|
|
|
pub use api::{AddItemRequest, AddItemResponse, DeleteItemResponse, DownloadStatus, ErrorResponse};
|
2025-10-25 17:14:24 +02:00
|
|
|
|
|
|
|
|
#[cfg(feature = "pmoconfig")]
|
|
|
|
|
pub use config_ext::CacheConfigExt;
|