fix(download): remove deleted source from matching downloader

This commit is contained in:
jxxghp
2026-10-10 06:58:04 +08:00
parent e9f0c693e2
commit 1ed458eda7
2 changed files with 44 additions and 4 deletions

View File

@@ -100,7 +100,9 @@ class DownloadTaskOwner(_DownloadOwnerBase):
def _download_file_deleted(self, event: Event) -> None:
"""
下载文件删除时,同步删除下载任务
下载文件删除时,按查询到的下载器实例同步删除任务并通知下游。
旧 provider 未返回实例名时保留默认实例调用,兼容既有插件实现。
"""
if not event:
return
@@ -111,7 +113,18 @@ class DownloadTaskOwner(_DownloadOwnerBase):
# 先查询种子
torrents: List[_SchemaDownloaderTorrent] = self.list_torrents(hashs=[hash_str]) or []
if torrents:
self.remove_torrents(hashs=[hash_str], delete_file=False)
downloaders = list(dict.fromkeys(
torrent.downloader for torrent in torrents if torrent.downloader
))
if downloaders:
for downloader in downloaders:
self.remove_torrents(
hashs=[hash_str],
delete_file=False,
downloader=downloader,
)
else:
self.remove_torrents(hashs=[hash_str], delete_file=False)
# 发出下载任务删除事件,如需处理辅种,可监听该事件
self.eventmanager.send_event(EventType.DownloadDeleted, {
"hash": hash_str,

View File

@@ -4,7 +4,7 @@ import importlib
import inspect
import pickle
from typing import Optional
from unittest.mock import MagicMock
from unittest.mock import MagicMock, call
import pytest
@@ -103,7 +103,7 @@ def test_download_file_deleted_removes_task_without_deleting_files() -> None:
"""源文件删除后按 hash 清理任务并发布删除前快照。"""
hash_string = "download-hash"
torrent = DownloaderTorrent(
downloader="qbittorrent",
downloader="tr",
hash=hash_string,
title="Demo.Release",
)
@@ -120,6 +120,7 @@ def test_download_file_deleted_removes_task_without_deleting_files() -> None:
chain.remove_torrents.assert_called_once_with(
hashs=[hash_string],
delete_file=False,
downloader="tr",
)
chain.eventmanager.send_event.assert_called_once_with(
EventType.DownloadDeleted,
@@ -127,6 +128,32 @@ def test_download_file_deleted_removes_task_without_deleting_files() -> None:
)
def test_download_file_deleted_removes_task_from_each_matching_downloader() -> None:
"""同一 hash 命中多个下载器实例时,应逐个指定实例清理。"""
hash_string = "download-hash"
torrents = [
DownloaderTorrent(downloader="qb", hash=hash_string),
DownloaderTorrent(downloader="tr", hash=hash_string),
]
chain = DownloadChain.__new__(DownloadChain)
chain.list_torrents = MagicMock(return_value=torrents)
chain.remove_torrents = MagicMock()
chain.eventmanager = MagicMock()
chain.download_file_deleted(
Event(EventType.DownloadFileDeleted, {"hash": hash_string})
)
assert chain.remove_torrents.call_args_list == [
call(hashs=[hash_string], delete_file=False, downloader="qb"),
call(hashs=[hash_string], delete_file=False, downloader="tr"),
]
chain.eventmanager.send_event.assert_called_once_with(
EventType.DownloadDeleted,
{"hash": hash_string, "torrents": [torrent.model_dump() for torrent in torrents]},
)
@pytest.mark.parametrize(
("event", "expected_query"),
[