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:
Roman
2026-09-22 12:17:27 +00:00
parent affc97c527
commit 9500a84a5e
7 changed files with 283 additions and 58 deletions
+30
View File
@@ -102,3 +102,33 @@ async def test_cancel(file_server, manager):
await dm.cancel(d["id"])
data = await dm.get(d["id"])
assert data["status"] in ("cancelled", "done") # course possible si déjà fini
async def test_delete_keeps_file(file_server, manager):
d = await dm.enqueue(f"{file_server}/video.mp4", "http://page", "Anime X - E1 (VOSTFR)")
data = await _wait_status(d["id"], {"done", "failed"})
assert data["status"] == "done", data.get("error")
path = get_settings().download_dir / data["file_path"]
assert path.is_file()
assert await dm.delete(d["id"]) is True
assert await dm.get(d["id"]) is None
assert path.is_file() # le fichier vidéo est conservé
async def test_delete_with_file(file_server, manager):
d = await dm.enqueue(f"{file_server}/video.mp4", "http://page", "Anime X - E2 (VOSTFR)")
data = await _wait_status(d["id"], {"done", "failed"})
path = get_settings().download_dir / data["file_path"]
assert await dm.delete(d["id"], delete_file=True) is True
assert await dm.get(d["id"]) is None
assert not path.exists()
assert await dm.delete(d["id"]) is False # déjà supprimé → introuvable
async def test_delete_active(file_server, manager):
d = await dm.enqueue(f"{file_server}/video.mp4", "http://page", "Anime X - E3")
filename = d["file_path"]
assert await dm.delete(d["id"]) is True
assert await dm.get(d["id"]) is None
download_dir = get_settings().download_dir
assert not (download_dir / filename).exists()
assert not (download_dir / (filename + ".part")).exists()