fix(downloader): make torrent deletion actually delete and report failures (#1046)

torrents_delete received a Python list, which httpx form-encodes as repeated
'hashes' fields that qBittorrent ignores — pipe-join it as the API expects.
Check the response status instead of logging success unconditionally, and
propagate the failure up through delete_torrent to the API ResponseModel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014w1Z6Nxy6XTRgkFXqPr9Zh
This commit is contained in:
Estrella Pan
2026-07-02 11:39:10 +02:00
parent 930dd01220
commit e6aac59954
3 changed files with 22 additions and 6 deletions

View File

@@ -110,13 +110,19 @@ class MockDownloader:
)
return True
async def torrents_delete(self, hash: str, delete_files: bool = True):
hashes = hash.split("|") if "|" in hash else [hash]
async def torrents_delete(
self, hash: str | list, delete_files: bool = True
) -> bool:
if isinstance(hash, (list, tuple)):
hashes = list(hash)
else:
hashes = hash.split("|") if "|" in hash else [hash]
for h in hashes:
self._torrents.pop(h, None)
logger.debug(
"[MockDownloader] torrents_delete(%s, delete_files=%s)", hash, delete_files
)
return True
async def torrents_pause(self, hashes: str):
for h in hashes.split("|"):

View File

@@ -144,9 +144,13 @@ class DownloadClient(TorrentPath):
logger.debug("[Downloader] Rename failed: %s >> %s", old_path, new_path)
return result
async def delete_torrent(self, hashes, delete_files: bool = True):
await self.client.torrents_delete(hashes, delete_files=delete_files)
logger.info("[Downloader] Remove torrents.")
async def delete_torrent(self, hashes, delete_files: bool = True) -> bool:
ok = await self.client.torrents_delete(hashes, delete_files=delete_files)
if ok:
logger.info("[Downloader] Remove torrents.")
else:
logger.error("[Downloader] Failed to remove torrents.")
return ok
async def pause_torrent(self, hashes: str):
await self.client.torrents_pause(hashes)

View File

@@ -25,7 +25,13 @@ class TorrentManager(Database):
async def delete_torrents(self, data: Bangumi, client: DownloadClient):
hash_list = await self.__match_torrents_list(data)
if hash_list:
await client.delete_torrent(hash_list)
if not await client.delete_torrent(hash_list):
return ResponseModel(
status_code=500,
status=False,
msg_en=f"Failed to delete torrents for {data.official_title}",
msg_zh=f"删除 {data.official_title} 种子失败",
)
logger.info(f"Delete rule and torrents for {data.official_title}")
return ResponseModel(
status_code=200,