2a9cf9e224
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
2.9 KiB
Python
99 lines
2.9 KiB
Python
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,
|
|
)
|
|
|
|
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,
|
|
)
|
|
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()
|