import os import uuid import aiofiles from fastapi import APIRouter, Depends, HTTPException, UploadFile from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps import get_current_user from app.config import settings from app.database import get_db from app.models.recording import RecordingSource from app.models.user import User from app.schemas.recording import RecordingList, RecordingResponse from app.services.recording import ( create_recording, get_format_from_filename, get_media_duration, get_recording_by_id, get_recordings, get_upload_path, ) from app.tasks.transcription import transcribe_recording router = APIRouter(prefix="/api/recordings", tags=["recordings"]) ALLOWED_FORMATS = {"mp4", "webm", "mp3", "wav", "ogg", "m4a", "flac"} @router.post("/upload", response_model=RecordingResponse, status_code=201) async def upload_recording( file: UploadFile, title: str = "", db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): fmt = get_format_from_filename(file.filename or "unknown.mp4") if fmt not in ALLOWED_FORMATS: raise HTTPException(400, f"Unsupported format: {fmt}") os.makedirs(settings.upload_dir, exist_ok=True) file_path = get_upload_path(file.filename or "recording.mp4") async with aiofiles.open(file_path, "wb") as f: while chunk := await file.read(1024 * 1024): await f.write(chunk) file_size = os.path.getsize(file_path) duration = get_media_duration(file_path) final_title = title or file.filename or "Untitled" recording = await create_recording( db=db, user_id=user.id, title=final_title, file_path=file_path, file_size=file_size, format=fmt, source=RecordingSource.web, duration=duration, ) transcribe_recording.delay(str(recording.id)) return recording @router.get("", response_model=RecordingList) async def list_recordings( skip: int = 0, limit: int = 50, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): items, total = await get_recordings(db, skip=skip, limit=limit) return RecordingList(items=items, total=total) @router.get("/{recording_id}", response_model=RecordingResponse) async def get_recording( recording_id: uuid.UUID, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): recording = await get_recording_by_id(db, recording_id) if not recording: raise HTTPException(404, "Recording not found") return recording @router.delete("/{recording_id}", status_code=204) async def delete_recording( recording_id: uuid.UUID, db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): recording = await get_recording_by_id(db, recording_id) if not recording: raise HTTPException(404, "Recording not found") if os.path.exists(recording.file_path): os.remove(recording.file_path) await db.delete(recording) await db.commit()