Téléchargements : suppression par épisode et regroupement par animé
- DELETE /api/downloads/{id} (?delete_file=true pour effacer aussi le fichier)
- Événement SSE « removed » → toutes les pages ouvertes se synchronisent
- Page Téléchargements groupée par animé : groupes repliables (dépliés si
actifs), compteurs par statut, taille totale, tri par numéro d'épisode
- Actions par groupe : 🧹 retirer les terminés, ✖ annuler les actifs
- Limite de liste 200 → 2000 tâches
This commit is contained in:
@@ -64,6 +64,13 @@ async def cancel(download_id: int) -> dict:
|
||||
await download_manager.cancel(download_id)
|
||||
return {"ok": True}
|
||||
|
||||
@router.delete("/{download_id}")
|
||||
async def delete_download(download_id: int, delete_file: bool = False) -> dict:
|
||||
"""Retire une tâche de la file ; delete_file=true efface aussi le fichier."""
|
||||
if not await download_manager.delete(download_id, delete_file=delete_file):
|
||||
raise HTTPException(404, detail="Téléchargement introuvable")
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.post("/cancel-all")
|
||||
async def cancel_all() -> dict:
|
||||
@@ -81,7 +88,7 @@ async def events() -> EventSourceResponse:
|
||||
|
||||
async def stream() -> AsyncIterator[dict]:
|
||||
yield {"data": json.dumps({"type": "snapshot", "items": await download_manager.list_all()})}
|
||||
async for update in download_manager.subscribe():
|
||||
yield {"data": json.dumps({"type": "update", "item": update}, default=str)}
|
||||
async for message in download_manager.subscribe():
|
||||
yield {"data": json.dumps(message, default=str)}
|
||||
|
||||
return EventSourceResponse(stream())
|
||||
|
||||
Reference in New Issue
Block a user