feat: Add transcription worker and state management

Introduce an `AppState` struct to hold shared application state,
including configuration and the transcription sender.
Modify `create_router` and `create_router_with_state` to use `AppState`.
Update `main.rs` to initialize the transcription worker and pass the
`AppState` to the router.
Implement the transcription worker logic in
`server/src/transcribe/worker.rs`, handling job queues, FFmpeg remuxing,
and Whisper transcription.
Update `server/src/auth.rs` to use `Arc<Config>` from the shared state.
Modify `server/src/routes/upload.rs` to enqueue transcription jobs and
handle potential errors.
Add `TranscribeJob` and channel types in `server/src/transcribe/mod.rs`.
This commit is contained in:
2026-04-13 16:45:24 +02:00
parent 84f8df2bf4
commit bcae4e5466
7 changed files with 158 additions and 19 deletions
+12 -9
View File
@@ -1,7 +1,7 @@
use std::path::PathBuf;
use std::sync::Arc;
use axum::extract::FromRequestParts;
use axum::extract::{FromRef, FromRequestParts};
use axum::http::request::Parts;
use crate::config::Config;
@@ -14,31 +14,34 @@ pub struct AuthenticatedUser {
pub data_dir: PathBuf,
}
impl FromRequestParts<Arc<Config>> for AuthenticatedUser {
impl<S> FromRequestParts<S> for AuthenticatedUser
where
S: Send + Sync,
Arc<Config>: FromRef<S>,
{
type Rejection = AppError;
async fn from_request_parts(
parts: &mut Parts,
state: &Arc<Config>,
) -> Result<Self, Self::Rejection> {
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let config = Arc::<Config>::from_ref(state);
let api_key = parts
.headers
.get("X-API-Key")
.and_then(|v| v.to_str().ok())
.ok_or(AppError::Unauthorized)?;
let slug = state
let slug = config
.api_keys
.get(api_key)
.ok_or(AppError::Unauthorized)?;
let user = state
let user = config
.users
.iter()
.find(|u| u.slug == *slug)
.ok_or(AppError::Unauthorized)?;
let data_dir = state.data_path.join(slug);
let data_dir = config.data_path.join(slug);
tokio::fs::create_dir_all(data_dir.join("open")).await?;
tokio::fs::create_dir_all(data_dir.join("done")).await?;