"""Роуты управления загрузками: создание, список, удаление.""" from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, status from app.api.deps import get_events, get_queue, get_storage from app.core.events import EventBus from app.core.queue import DownloadQueue from app.core.storage import Storage from app.models import CreateDownloads, Download, DownloadEvent router = APIRouter(prefix="/api/downloads", tags=["downloads"]) @router.post("", status_code=status.HTTP_201_CREATED, response_model=list[Download]) async def create_downloads( payload: CreateDownloads, storage: Storage = Depends(get_storage), queue: DownloadQueue = Depends(get_queue), events: EventBus = Depends(get_events), ) -> list[Download]: """Принять ссылки (по одной на строку), создать задачи и поставить в очередь.""" urls = [u.strip() for u in payload.urls if u.strip()] if not urls: raise HTTPException(status.HTTP_400_BAD_REQUEST, "Список ссылок пуст") created: list[Download] = [] for url in urls: download = Download(url=url) await storage.create(download) await queue.add(download.id) await events.publish(DownloadEvent(type="created", download=download)) created.append(download) return created @router.get("", response_model=list[Download]) async def list_downloads(storage: Storage = Depends(get_storage)) -> list[Download]: """Список всех загрузок — для гидрации UI при загрузке страницы.""" return await storage.list() @router.delete("/{download_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_download( download_id: str, storage: Storage = Depends(get_storage), events: EventBus = Depends(get_events), ) -> None: deleted = await storage.delete(download_id) if not deleted: raise HTTPException(status.HTTP_404_NOT_FOUND, "Загрузка не найдена") await events.publish(DownloadEvent(type="deleted", id=download_id))