from fastapi import APIRouter, UploadFile, Form, HTTPException, Depends from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from app.database import get_db from app.models import VideoUpload from .utils.s3 import upload_to_s3, delete_s3_key, key_from_url from app.auth import get_current_user from app.models import User from sqlalchemy import delete as sqldelete import uuid import os router = APIRouter() # Accept any video file ALLOWED_VIDEO_MIME_TYPES = { "video/mp4", "video/x-matroska", # mkv "video/quicktime", # mov "video/x-msvideo", # avi "video/webm", "video/mpeg", } @router.post("/upload") async def upload_video( user_id: int = Form(...), file: UploadFile = Form(...), db: AsyncSession = Depends(get_db), ): if file.content_type not in ALLOWED_VIDEO_MIME_TYPES: raise HTTPException( status_code=400, detail=f"Unsupported file type: {file.content_type}" ) try: uid = str(uuid.uuid4()) s3_key = f"videos/{uid}/{file.filename}" video_url = upload_to_s3(file, s3_key) new_video = VideoUpload( user_id=user_id, video_url=video_url, pdf_url="", # will be set after analysis status="pending", ) db.add(new_video) await db.commit() await db.refresh(new_video) return {"status": "uploaded", "video_url": video_url, "video_id": new_video.id} except Exception as e: await db.rollback() raise HTTPException(status_code=500, detail=str(e)) @router.delete("/uploads/{video_id}") async def delete_uploaded_video(video_id: int, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)): result = await db.execute(select(VideoUpload).where(VideoUpload.id == video_id)) video: VideoUpload | None = result.scalar_one_or_none() if not video: raise HTTPException(status_code=404, detail="Video not found") if video.user_id != current_user.id: raise HTTPException(status_code=403, detail="Not allowed") # Delete from S3 if present v_key = key_from_url(video.video_url) p_key = key_from_url(video.pdf_url) try: if v_key: delete_s3_key(v_key) if p_key: delete_s3_key(p_key) except Exception: pass # Delete DB row try: await db.delete(video) await db.commit() return {"message": "Upload deleted"} except Exception as e: await db.rollback() raise HTTPException(status_code=500, detail=str(e)) @router.delete("/uploads/{video_id}/pdf") async def delete_uploaded_pdf(video_id: int, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)): result = await db.execute(select(VideoUpload).where(VideoUpload.id == video_id)) video: VideoUpload | None = result.scalar_one_or_none() if not video: raise HTTPException(status_code=404, detail="Upload not found") if video.user_id != current_user.id: raise HTTPException(status_code=403, detail="Not allowed") p_key = key_from_url(video.pdf_url) if not p_key: return {"message": "No PDF to delete"} try: delete_s3_key(p_key) except Exception: pass # Clear pdf_url field video.pdf_url = "" try: await db.commit() await db.refresh(video) return {"message": "PDF deleted", "video_id": video.id} except Exception as e: await db.rollback() raise HTTPException(status_code=500, detail=str(e))