diff --git a/k-tv-backend/api/src/main.rs b/k-tv-backend/api/src/main.rs index d487dd1..52d9840 100644 --- a/k-tv-backend/api/src/main.rs +++ b/k-tv-backend/api/src/main.rs @@ -121,6 +121,57 @@ async fn main() -> anyhow::Result<()> { registry.register("jellyfin", Arc::new(infra::JellyfinMediaProvider::new(cfg))); } } + #[cfg(feature = "local-files")] + "local_files" => { + if let k_core::db::DatabasePool::Sqlite(ref sqlite_pool) = db_pool { + if let Ok(cfg_map) = serde_json::from_str::>(&row.config_json) { + if let Some(files_dir) = cfg_map.get("files_dir") { + let transcode_dir = cfg_map.get("transcode_dir") + .filter(|s| !s.is_empty()) + .map(std::path::PathBuf::from); + let cleanup_ttl_hours: u32 = cfg_map.get("cleanup_ttl_hours") + .and_then(|s| s.parse().ok()) + .unwrap_or(24); + let lf_cfg = infra::LocalFilesConfig { + root_dir: std::path::PathBuf::from(files_dir), + base_url: config.base_url.clone(), + transcode_dir: transcode_dir.clone(), + cleanup_ttl_hours, + }; + tracing::info!("Loading local-files provider from DB config at {:?}", files_dir); + let idx = Arc::new(infra::LocalIndex::new(&lf_cfg, sqlite_pool.clone()).await); + local_index = Some(Arc::clone(&idx)); + let scan_idx = Arc::clone(&idx); + tokio::spawn(async move { scan_idx.rescan().await; }); + let tm = transcode_dir.as_ref().map(|td| { + std::fs::create_dir_all(td).ok(); + tracing::info!("Transcoding enabled; cache dir: {:?}", td); + let tm = infra::TranscodeManager::new(td.clone(), cleanup_ttl_hours); + // Load persisted TTL override from transcode_settings table. + let tm_clone = Arc::clone(&tm); + let pool_clone = sqlite_pool.clone(); + tokio::spawn(async move { + if let Ok(row) = sqlx::query_as::<_, (i64,)>( + "SELECT cleanup_ttl_hours FROM transcode_settings WHERE id = 1", + ) + .fetch_one(&pool_clone) + .await + { + tm_clone.set_cleanup_ttl(row.0 as u32); + } + }); + tm + }); + registry.register( + "local", + Arc::new(infra::LocalFilesProvider::new(Arc::clone(&idx), lf_cfg, tm.clone())), + ); + transcode_manager = tm; + sqlite_pool_for_state = Some(sqlite_pool.clone()); + } + } + } + } _ => {} } } diff --git a/k-tv-backend/api/src/routes/admin_providers.rs b/k-tv-backend/api/src/routes/admin_providers.rs index dc70371..16809c3 100644 --- a/k-tv-backend/api/src/routes/admin_providers.rs +++ b/k-tv-backend/api/src/routes/admin_providers.rs @@ -168,15 +168,6 @@ async fn rebuild_registry(state: &AppState) -> DomainResult<()> { Arc::new(infra::LocalFilesProvider::new(Arc::clone(&idx), lf_cfg, tm.clone())), ); - // Sync cleanup_ttl_hours to transcode_settings table so - // GET /files/transcode-settings returns the configured value. - let _ = sqlx::query( - "UPDATE transcode_settings SET cleanup_ttl_hours = ? WHERE id = 1", - ) - .bind(cleanup_ttl_hours as i64) - .execute(&sqlite_pool) - .await; - *state.local_index.write().await = Some(idx); *state.transcode_manager.write().await = tm; *state.sqlite_pool.write().await = Some(sqlite_pool); diff --git a/k-tv-backend/api/src/routes/files.rs b/k-tv-backend/api/src/routes/files.rs index 11b742e..4d3f595 100644 --- a/k-tv-backend/api/src/routes/files.rs +++ b/k-tv-backend/api/src/routes/files.rs @@ -256,17 +256,10 @@ async fn get_transcode_settings( State(state): State, CurrentUser(_user): CurrentUser, ) -> Result, ApiError> { - let pool = state.sqlite_pool.read().await.clone() - .ok_or_else(|| ApiError::not_implemented("sqlite not available"))?; - - let (ttl,): (i64,) = - sqlx::query_as("SELECT cleanup_ttl_hours FROM transcode_settings WHERE id = 1") - .fetch_one(&pool) - .await - .map_err(|e| ApiError::internal(e.to_string()))?; - + let tm = state.transcode_manager.read().await.clone() + .ok_or_else(|| ApiError::not_implemented("TRANSCODE_DIR not configured"))?; Ok(Json(TranscodeSettingsResponse { - cleanup_ttl_hours: ttl as u32, + cleanup_ttl_hours: tm.get_cleanup_ttl(), })) }