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:
@@ -223,7 +223,25 @@ class DownloadManager:
|
||||
)
|
||||
return cursor.rowcount or 0
|
||||
|
||||
async def list_all(self, limit: int = 200) -> list[dict]:
|
||||
async def delete(self, download_id: int, delete_file: bool = False) -> bool:
|
||||
"""Supprime une tâche de la file (annulée avant si active).
|
||||
|
||||
delete_file=True efface aussi le fichier téléchargé du disque.
|
||||
"""
|
||||
row = await db.fetchone("SELECT * FROM downloads WHERE id = ?", (download_id,))
|
||||
if row is None:
|
||||
return False
|
||||
if row["status"] in ACTIVE_STATUSES:
|
||||
await self.cancel(download_id)
|
||||
if delete_file and row["file_path"]:
|
||||
(get_settings().download_dir / row["file_path"]).unlink(missing_ok=True)
|
||||
self._part_path(row["file_path"]).unlink(missing_ok=True)
|
||||
await db.execute("DELETE FROM downloads WHERE id = ?", (download_id,))
|
||||
await self._emit_removed(download_id)
|
||||
logger.info("Téléchargement supprimé (id=%s, fichier=%s)", download_id, delete_file)
|
||||
return True
|
||||
|
||||
async def list_all(self, limit: int = 2000) -> list[dict]:
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM downloads ORDER BY "
|
||||
"CASE status WHEN 'downloading' THEN 0 WHEN 'pending' THEN 1 WHEN 'paused' THEN 2 "
|
||||
@@ -251,9 +269,15 @@ class DownloadManager:
|
||||
data = await self.get(download_id)
|
||||
if data is None:
|
||||
return
|
||||
self._publish({"type": "update", "item": data})
|
||||
|
||||
async def _emit_removed(self, download_id: int) -> None:
|
||||
self._publish({"type": "removed", "id": download_id})
|
||||
|
||||
def _publish(self, message: dict) -> None:
|
||||
for queue in self._listeners:
|
||||
with contextlib.suppress(asyncio.QueueFull):
|
||||
queue.put_nowait(data)
|
||||
queue.put_nowait(message)
|
||||
|
||||
# ------------------------------------------------------------ worker interne
|
||||
|
||||
|
||||
Reference in New Issue
Block a user