From 1f7fac2b285bfd2fb968ea37217b9a9108d5fd4f Mon Sep 17 00:00:00 2001 From: jxxghp Date: Wed, 26 Aug 2026 21:53:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(qbittorrent):=20=E6=B8=85=E7=90=86=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E8=B6=85=E6=97=B6=E7=9A=84=E4=B8=B4=E6=97=B6=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=20(#6395)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/modules/qbittorrent/qbittorrent.py | 14 ++++++++++---- tests/test_qbittorrent_compat.py | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/app/modules/qbittorrent/qbittorrent.py b/app/modules/qbittorrent/qbittorrent.py index 466187ed4..1ec728c7a 100644 --- a/app/modules/qbittorrent/qbittorrent.py +++ b/app/modules/qbittorrent/qbittorrent.py @@ -302,17 +302,18 @@ class Qbittorrent: tags=tags) return None if error else torrents or [] - def delete_torrents_tag(self, ids: Union[str, list], tag: Union[str, list]) -> bool: + def delete_torrents_tag(self, ids: Optional[Union[str, list]], tag: Union[str, list]) -> bool: """ 从指定种子移除标签,并删除全局标签定义 - :param ids: 种子Hash列表 + :param ids: 种子Hash列表;未知种子Hash时传入None,仅删除全局标签定义 :param tag: 标签内容 :return: 是否删除成功 """ if not self.qbc: return False try: - self.qbc.torrents_remove_tags(torrent_hashes=ids, tags=tag) + if ids: + self.qbc.torrents_remove_tags(torrent_hashes=ids, tags=tag) self.qbc.torrents_delete_tags(tags=tag) return True except Exception as err: @@ -384,7 +385,10 @@ class Qbittorrent: def get_torrent_id_by_tag(self, tags: Union[str, list], status: Optional[str] = None) -> Optional[str]: """ - 通过标签多次尝试获取刚添加的种子ID,并移除标签 + 通过标签多次尝试获取刚添加的种子ID,并确保移除临时标签。 + + qBittorrent 可能已接受任务但暂时无法按标签查询到种子,此时仍需删除 + 全局临时标签,避免批量添加的部分失败路径留下随机标签。 """ torrent_id = None # QB添加下载后需要时间,重试10次每次等待3秒 @@ -397,6 +401,8 @@ class Qbittorrent: else: self.delete_torrents_tag(torrent_id, tags) break + if torrent_id is None: + self.delete_torrents_tag(None, tags) return torrent_id def add_torrent(self, diff --git a/tests/test_qbittorrent_compat.py b/tests/test_qbittorrent_compat.py index 888f1db83..89fcbff54 100644 --- a/tests/test_qbittorrent_compat.py +++ b/tests/test_qbittorrent_compat.py @@ -685,6 +685,26 @@ def test_delete_torrents_tag_uses_supported_qbittorrent_api_arguments(): fake_client.torrents_delete_tags.assert_called_once_with(tags="tmp-tag-01") +def test_get_torrent_id_by_tag_deletes_temporary_tag_after_lookup_timeout(): + """按标签查询超时时也应删除全局临时标签,避免随机标签残留。""" + fake_client = MagicMock() + downloader = Qbittorrent.__new__(Qbittorrent) + downloader.qbc = fake_client + + with patch.object( + downloader, + "_Qbittorrent__get_last_add_torrentid_by_tag", + return_value=None, + ) as lookup, patch.object(qbittorrent_module.time, "sleep") as sleep: + torrent_id = downloader.get_torrent_id_by_tag(tags="tmp-tag-01") + + assert torrent_id is None + assert lookup.call_count == 9 + assert sleep.call_count == 9 + fake_client.torrents_remove_tags.assert_not_called() + fake_client.torrents_delete_tags.assert_called_once_with(tags="tmp-tag-01") + + def test_get_files_retries_until_qbittorrent_files_available(): """qBittorrent 添加任务后文件列表短暂未就绪时应重试。""" torrent_files = [{"id": 12, "name": "Show.S01E12.mkv"}]