from typing import Any from app.auth import AuthenticatedUser, get_current_user from app.core.storage import OSSStorageService, get_storage_service from app.dependencies import get_generated_video_repository, get_project_repository from app.schemas.generated_video import ( GeneratedVideoDownloadUrlResponse, GeneratedVideoResponse, ListGeneratedVideosResponse, UpdateGeneratedVideoReviewRequest, ) from fastapi import APIRouter, Depends, HTTPException, Query from packages.application import ( GetGeneratedVideoDownloadUrlUseCase, GetGeneratedVideoUseCase, ListGeneratedVideosUseCase, ) router = APIRouter() def _to_generated_video_response(item, download_url: str | None = None) -> GeneratedVideoResponse: return GeneratedVideoResponse( id=item.id, project_id=item.project_id, generation_task_id=item.generation_task_id, name=item.name, file_url=item.file_url, file_size=item.file_size, duration=item.duration, thumbnail_url=item.thumbnail_url, width=item.width, height=item.height, fps=item.fps, status=item.status, review_status=item.review_status, generation_params=item.generation_params, download_url=download_url, ) @router.get("", response_model=ListGeneratedVideosResponse) def list_generated_videos( project_id: str | None = Query(None), authenticated_user: AuthenticatedUser = Depends(get_current_user), generated_video_repository: Any = Depends(get_generated_video_repository), project_repository: Any = Depends(get_project_repository), storage_service: OSSStorageService = Depends(get_storage_service), ) -> ListGeneratedVideosResponse: user_id = authenticated_user.user.id use_case = ListGeneratedVideosUseCase(generated_video_repository) if project_id: # If project_id provided, check access and filter by project project = project_repository.find_by_id(project_id) if project is None: raise HTTPException(status_code=404, detail=f"Project {project_id} not found") items = use_case.execute(project_id) else: # If no project_id, list all videos from accessible projects accessible_projects = project_repository.find_accessible_projects(user_id) all_items = [] for proj in accessible_projects: all_items.extend(use_case.execute(proj.id)) items = all_items # Generate download URLs for each video responses = [] for item in items: download_url = storage_service.get_download_url(item.file_url) responses.append(_to_generated_video_response(item, download_url=download_url)) return ListGeneratedVideosResponse(items=responses) @router.get("/{video_id}", response_model=GeneratedVideoResponse) def get_generated_video( video_id: str, authenticated_user: AuthenticatedUser = Depends(get_current_user), generated_video_repository: Any = Depends(get_generated_video_repository), storage_service: OSSStorageService = Depends(get_storage_service), ) -> GeneratedVideoResponse: use_case = GetGeneratedVideoUseCase(generated_video_repository) item = use_case.execute(video_id) if item is None: raise HTTPException(status_code=404, detail=f"GeneratedVideo {video_id} not found") download_url = storage_service.get_download_url(item.file_url) return _to_generated_video_response(item, download_url=download_url) @router.patch("/{video_id}/review", response_model=GeneratedVideoResponse) def update_generated_video_review_status( video_id: str, request: UpdateGeneratedVideoReviewRequest, authenticated_user: AuthenticatedUser = Depends(get_current_user), generated_video_repository: Any = Depends(get_generated_video_repository), storage_service: OSSStorageService = Depends(get_storage_service), ) -> GeneratedVideoResponse: video = generated_video_repository.get(video_id) if video is None: raise HTTPException(status_code=404, detail=f"GeneratedVideo {video_id} not found") video.review_status = request.review_status updated = generated_video_repository.update(video) download_url = storage_service.get_download_url(updated.file_url) return _to_generated_video_response(updated, download_url=download_url) @router.get("/{video_id}/download-url", response_model=GeneratedVideoDownloadUrlResponse) def get_generated_video_download_url( video_id: str, authenticated_user: AuthenticatedUser = Depends(get_current_user), generated_video_repository: Any = Depends(get_generated_video_repository), storage_service: OSSStorageService = Depends(get_storage_service), ) -> GeneratedVideoDownloadUrlResponse: video = generated_video_repository.get(video_id) if video is None: raise HTTPException(status_code=404, detail=f"GeneratedVideo {video_id} not found") use_case = GetGeneratedVideoDownloadUrlUseCase(generated_video_repository) file_url = use_case.execute(video_id) if file_url is None: raise HTTPException(status_code=404, detail=f"GeneratedVideo {video_id} not found") download_url = storage_service.get_download_url(file_url) return GeneratedVideoDownloadUrlResponse(video_id=video_id, download_url=download_url)