""" Download management routes for Ohm Stream Downloader API. """ from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query, Request, Response from fastapi.templating import Jinja2Templates from fastapi.responses import HTMLResponse from app.download_manager import DownloadManager from app.models import DownloadRequest from app.models.auth import User from app.routers.router_auth import get_current_user_from_token, get_optional_user router = APIRouter(prefix="/api/downloads", tags=["downloads"]) templates = Jinja2Templates(directory="templates") def get_download_manager() -> DownloadManager: from main import download_manager return download_manager @router.get("") async def get_downloads( request: Request, html: bool = Query(False), download_manager: DownloadManager = Depends(get_download_manager), current_user: Optional[User] = Depends(get_optional_user), ): """Get list of all download tasks. Returns HTML for HTMX requests.""" is_htmx = request.headers.get("HX-Request") == "true" or request.headers.get("HX-Request") if current_user is None and (html or is_htmx): return templates.TemplateResponse( "components/login_prompt.html", {"request": request} ) if current_user is None: raise HTTPException(status_code=401, detail="Authentication required") tasks = download_manager.get_all_tasks() if html or is_htmx: print(f"[DOWNLOADS] HTML Request. Found {len(tasks)} tasks.") return templates.TemplateResponse( "components/downloads_list.html", {"request": request, "tasks": tasks} ) print(f"[DOWNLOADS] API Request. Returning JSON.") return {"downloads": tasks} @router.post("") async def create_download( download_request: DownloadRequest, download_manager: DownloadManager = Depends(get_download_manager), current_user=Depends(get_current_user_from_token), ): """Create a new download task""" return download_manager.create_task(download_request) @router.get("/{task_id}") async def get_download_status( task_id: str, download_manager: DownloadManager = Depends(get_download_manager), current_user: Optional[User] = Depends(get_optional_user), ): """Get status of a specific download task""" if current_user is None: raise HTTPException(status_code=401, detail="Authentication required") task = download_manager.get_task(task_id) if not task: raise HTTPException(status_code=404, detail="Task not found") return task @router.post("/{task_id}/pause") async def pause_download( task_id: str, download_manager: DownloadManager = Depends(get_download_manager), current_user=Depends(get_current_user_from_token), ): """Pause a download task""" if download_manager.pause_download(task_id): return {"status": "success", "message": "Download paused"} raise HTTPException(status_code=400, detail="Failed to pause download") @router.post("/{task_id}/resume") async def resume_download( task_id: str, download_manager: DownloadManager = Depends(get_download_manager), current_user=Depends(get_current_user_from_token), ): """Resume a paused download task""" if download_manager.resume_download(task_id): return {"status": "success", "message": "Download resumed"} raise HTTPException(status_code=400, detail="Failed to resume download") @router.delete("/{task_id}") async def cancel_download( task_id: str, download_manager: DownloadManager = Depends(get_download_manager), current_user=Depends(get_current_user_from_token), ): """Cancel and delete a download task""" if hasattr(download_manager, "cancel_download"): if download_manager.cancel_download(task_id): return {"status": "success", "message": "Download cancelled"} if task_id in download_manager.tasks: del download_manager.tasks[task_id] return {"status": "success", "message": "Download removed"} raise HTTPException(status_code=400, detail="Failed to cancel download") @router.post("/cleanup") async def cleanup_completed( download_manager: DownloadManager = Depends(get_download_manager), current_user=Depends(get_current_user_from_token), ): """Remove all completed tasks from the list""" if hasattr(download_manager, "cleanup_tasks"): count = download_manager.cleanup_tasks() return {"status": "success", "message": f"Cleaned up {count} tasks"} to_delete = [tid for tid, t in download_manager.tasks.items() if t.status == "completed"] for tid in to_delete: del download_manager.tasks[tid] return {"status": "success", "message": f"Cleaned up {len(to_delete)} tasks"}