import uuid from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form, BackgroundTasks from sqlalchemy.orm import Session from pydantic import BaseModel from typing import List, Optional from app.db.session import get_db from app.models.user import User from app.models.video import Video from app.utils.auth import get_current_user from app.services.s3_service import upload_file_to_s3 from app.services.language_detection_service import detect_language_from_video router = APIRouter() ALLOWED_VIDEO_TYPES = ["video/mp4", "video/quicktime"] MAX_FILE_SIZE = 200 * 1024 * 1024 # 200MB class VideoResponse(BaseModel): id: int user_id: int original_s3_url: str language_from: str language_to: str source_language: Optional[str] = None status: str created_at: str class Config: orm_mode = True class VideoUploadResponse(BaseModel): video_id: int message: str s3_url: str detected_language: Optional[str] = None class LanguageDetectionResponse(BaseModel): video_id: int detected_language: Optional[str] @router.post("/upload", response_model=VideoUploadResponse) async def upload_video( background_tasks: BackgroundTasks, video: UploadFile = File(...), language_from: str = Form(...), language_to: str = Form(...), current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): # Validate file type if video.content_type not in ALLOWED_VIDEO_TYPES: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid file type. Only MP4 and MOV files are allowed." ) # Read file content file_content = await video.read() # Validate file size if len(file_content) > MAX_FILE_SIZE: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="File too large. Maximum size is 200MB." ) # Generate unique filename file_extension = video.filename.split('.')[-1] if video.filename else 'mp4' unique_filename = f"videos/{uuid.uuid4()}.{file_extension}" # Upload to S3 s3_url = await upload_file_to_s3(file_content, unique_filename, video.content_type) if not s3_url: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to upload video to S3" ) # Detect language from video detected_language = await detect_language_from_video(file_content) # Save video metadata to database db_video = Video( user_id=current_user.id, original_s3_url=s3_url, language_from=language_from, language_to=language_to, source_language=detected_language, status="uploaded" ) db.add(db_video) db.commit() db.refresh(db_video) return VideoUploadResponse( video_id=db_video.id, message="Video uploaded successfully", s3_url=s3_url, detected_language=detected_language ) @router.get("/", response_model=List[VideoResponse]) async def get_user_videos( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): videos = db.query(Video).filter(Video.user_id == current_user.id).all() return [VideoResponse( id=video.id, user_id=video.user_id, original_s3_url=video.original_s3_url, language_from=video.language_from, language_to=video.language_to, source_language=video.source_language, status=video.status, created_at=str(video.created_at) ) for video in videos] @router.get("/{video_id}", response_model=VideoResponse) async def get_video( video_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): video = db.query(Video).filter( Video.id == video_id, Video.user_id == current_user.id ).first() if not video: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Video not found" ) return VideoResponse( id=video.id, user_id=video.user_id, original_s3_url=video.original_s3_url, language_from=video.language_from, language_to=video.language_to, source_language=video.source_language, status=video.status, created_at=str(video.created_at) ) @router.get("/{video_id}/language", response_model=LanguageDetectionResponse) async def get_video_language( video_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): video = db.query(Video).filter( Video.id == video_id, Video.user_id == current_user.id ).first() if not video: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Video not found" ) return LanguageDetectionResponse( video_id=video.id, detected_language=video.source_language )