feat: implement transcode settings repository and integrate with local-files provider

This commit is contained in:
2026-03-16 04:24:39 +01:00
parent 50df852416
commit 9d792249c9
12 changed files with 269 additions and 177 deletions

View File

@@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::db::DatabasePool;
use domain::{ActivityLogRepository, ChannelRepository, ProviderConfigRepository, ScheduleRepository, UserRepository};
use domain::{ActivityLogRepository, ChannelRepository, ProviderConfigRepository, ScheduleRepository, TranscodeSettingsRepository, UserRepository};
#[derive(Debug, thiserror::Error)]
pub enum FactoryError {
@@ -103,3 +103,57 @@ pub async fn build_schedule_repository(
)),
}
}
pub async fn build_transcode_settings_repository(
pool: &DatabasePool,
) -> FactoryResult<Arc<dyn TranscodeSettingsRepository>> {
match pool {
#[cfg(feature = "sqlite")]
DatabasePool::Sqlite(p) => Ok(Arc::new(
crate::transcode_settings_repository::SqliteTranscodeSettingsRepository::new(p.clone()),
)),
#[allow(unreachable_patterns)]
_ => Err(FactoryError::NotImplemented(
"TranscodeSettingsRepository not implemented for this database".to_string(),
)),
}
}
#[cfg(feature = "local-files")]
pub struct LocalFilesBundle {
pub provider: Arc<crate::LocalFilesProvider>,
pub local_index: Arc<crate::LocalIndex>,
pub transcode_manager: Option<Arc<crate::TranscodeManager>>,
}
#[cfg(feature = "local-files")]
pub async fn build_local_files_bundle(
pool: &DatabasePool,
root_dir: std::path::PathBuf,
transcode_dir: Option<std::path::PathBuf>,
cleanup_ttl_hours: u32,
base_url: String,
) -> FactoryResult<LocalFilesBundle> {
match pool {
#[cfg(feature = "sqlite")]
DatabasePool::Sqlite(sqlite_pool) => {
let cfg = crate::LocalFilesConfig {
root_dir,
base_url,
transcode_dir: transcode_dir.clone(),
cleanup_ttl_hours,
};
let idx = Arc::new(crate::LocalIndex::new(&cfg, sqlite_pool.clone()).await);
let tm = transcode_dir.as_ref().map(|td| {
std::fs::create_dir_all(td).ok();
crate::TranscodeManager::new(td.clone(), cleanup_ttl_hours)
});
let provider = Arc::new(crate::LocalFilesProvider::new(Arc::clone(&idx), cfg, tm.clone()));
Ok(LocalFilesBundle { provider, local_index: idx, transcode_manager: tm })
}
#[allow(unreachable_patterns)]
_ => Err(FactoryError::NotImplemented(
"local-files requires SQLite".to_string(),
)),
}
}

View File

@@ -22,6 +22,7 @@ mod activity_log_repository;
mod channel_repository;
mod provider_config_repository;
mod schedule_repository;
mod transcode_settings_repository;
mod user_repository;
#[cfg(feature = "local-files")]
@@ -41,6 +42,10 @@ pub use channel_repository::SqliteChannelRepository;
pub use provider_config_repository::SqliteProviderConfigRepository;
#[cfg(feature = "sqlite")]
pub use schedule_repository::SqliteScheduleRepository;
#[cfg(feature = "sqlite")]
pub use transcode_settings_repository::SqliteTranscodeSettingsRepository;
pub use domain::TranscodeSettingsRepository;
#[cfg(feature = "jellyfin")]
pub use jellyfin::{JellyfinConfig, JellyfinMediaProvider};

View File

@@ -0,0 +1,4 @@
#[cfg(feature = "sqlite")]
mod sqlite;
#[cfg(feature = "sqlite")]
pub use sqlite::SqliteTranscodeSettingsRepository;

View File

@@ -0,0 +1,34 @@
use async_trait::async_trait;
use domain::{DomainError, DomainResult, TranscodeSettingsRepository};
use sqlx::SqlitePool;
pub struct SqliteTranscodeSettingsRepository {
pool: SqlitePool,
}
impl SqliteTranscodeSettingsRepository {
pub fn new(pool: SqlitePool) -> Self {
Self { pool }
}
}
#[async_trait]
impl TranscodeSettingsRepository for SqliteTranscodeSettingsRepository {
async fn load_cleanup_ttl(&self) -> DomainResult<Option<u32>> {
let row: Option<(i64,)> =
sqlx::query_as("SELECT cleanup_ttl_hours FROM transcode_settings WHERE id = 1")
.fetch_optional(&self.pool)
.await
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
Ok(row.map(|(h,)| h as u32))
}
async fn save_cleanup_ttl(&self, hours: u32) -> DomainResult<()> {
sqlx::query("UPDATE transcode_settings SET cleanup_ttl_hours = ? WHERE id = 1")
.bind(hours as i64)
.execute(&self.pool)
.await
.map_err(|e| DomainError::InfrastructureError(e.to_string()))?;
Ok(())
}
}