完善 qBittorrent 临时标签清理 (#6093)

This commit is contained in:
jxxghp
2026-07-12 16:51:46 +08:00
parent 476dfef7d9
commit 51a7120c79
3 changed files with 32 additions and 9 deletions
+6 -5
View File
@@ -195,9 +195,6 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
ignore_category_check=False ignore_category_check=False
) )
# 获取种子内容布局: `Original: 原始, Subfolder: 创建子文件夹, NoSubfolder: 不创建子文件夹`
torrent_layout = server.get_content_layout()
if not state: if not state:
# 查询所有下载器的种子 # 查询所有下载器的种子
torrents, error = server.get_torrents() torrents, error = server.get_torrents()
@@ -210,7 +207,8 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
if torrent.get("name") == getattr(torrent_from_file, 'name', '') \ if torrent.get("name") == getattr(torrent_from_file, 'name', '') \
and torrent.get("total_size") == getattr(torrent_from_file, 'total_size', 0): and torrent.get("total_size") == getattr(torrent_from_file, 'total_size', 0):
torrent_hash = torrent.get("hash") torrent_hash = torrent.get("hash")
torrent_tags = [str(tag).strip() for tag in torrent.get("tags").split(',')] server.delete_torrents_tag(torrent_hash, tag)
torrent_tags = [str(tag).strip() for tag in (torrent.get("tags") or "").split(',')]
logger.warn(f"下载器中已存在该种子任务:{torrent_hash} - {torrent.get('name')}") logger.warn(f"下载器中已存在该种子任务:{torrent_hash} - {torrent.get('name')}")
# 给种子打上标签 # 给种子打上标签
if "已整理" in torrent_tags: if "已整理" in torrent_tags:
@@ -218,7 +216,8 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
if settings.TORRENT_TAG and settings.TORRENT_TAG not in torrent_tags: if settings.TORRENT_TAG and settings.TORRENT_TAG not in torrent_tags:
logger.info(f"给种子 {torrent_hash} 打上标签:{settings.TORRENT_TAG}") logger.info(f"给种子 {torrent_hash} 打上标签:{settings.TORRENT_TAG}")
server.set_torrents_tag(ids=torrent_hash, tags=[settings.TORRENT_TAG]) server.set_torrents_tag(ids=torrent_hash, tags=[settings.TORRENT_TAG])
server.delete_torrents_tag(torrent_hash, tag) # 获取种子内容布局: `Original: 原始, Subfolder: 创建子文件夹, NoSubfolder: 不创建子文件夹`
torrent_layout = server.get_content_layout()
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, f"下载任务已存在" return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, f"下载任务已存在"
finally: finally:
torrents.clear() torrents.clear()
@@ -234,6 +233,8 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
if not torrent_hash: if not torrent_hash:
return None, None, None, f"下载任务添加成功,但获取Qbittorrent任务信息失败:{content}" return None, None, None, f"下载任务添加成功,但获取Qbittorrent任务信息失败:{content}"
else: else:
# 获取种子内容布局: `Original: 原始, Subfolder: 创建子文件夹, NoSubfolder: 不创建子文件夹`
torrent_layout = server.get_content_layout()
if is_paused: if is_paused:
# 种子文件 # 种子文件
torrent_files = server.get_files( torrent_files = server.get_files(
+4 -2
View File
@@ -303,14 +303,16 @@ class Qbittorrent:
def delete_torrents_tag(self, ids: Union[str, list], tag: Union[str, list]) -> bool: def delete_torrents_tag(self, ids: Union[str, list], tag: Union[str, list]) -> bool:
""" """
删除Tag 从指定种子移除标签,并删除全局标签定义
:param ids: 种子Hash列表 :param ids: 种子Hash列表
:param tag: 标签内容 :param tag: 标签内容
:return: 是否删除成功
""" """
if not self.qbc: if not self.qbc:
return False return False
try: try:
self.qbc.torrents_delete_tags(torrent_hashes=ids, tags=tag) self.qbc.torrents_remove_tags(torrent_hashes=ids, tags=tag)
self.qbc.torrents_delete_tags(tags=tag)
return True return True
except Exception as err: except Exception as err:
logger.error(f"删除种子Tag出错:{str(err)}") logger.error(f"删除种子Tag出错:{str(err)}")
+22 -2
View File
@@ -3,7 +3,7 @@ import sys
import types import types
from enum import Enum from enum import Enum
from pathlib import Path from pathlib import Path
from unittest.mock import MagicMock, patch from unittest.mock import call, MagicMock, patch
def _load_qbittorrent_modules(): def _load_qbittorrent_modules():
@@ -518,6 +518,9 @@ def test_download_prefers_added_torrent_ids_before_tag_lookup():
fake_server.delete_torrents_tag.assert_called_once_with("abc123", "tmp-tag-01") fake_server.delete_torrents_tag.assert_called_once_with("abc123", "tmp-tag-01")
fake_server.get_torrent_id_by_tag.assert_not_called() fake_server.get_torrent_id_by_tag.assert_not_called()
assert fake_server.add_torrent.call_args.kwargs["tag"] == ["tmp-tag-01", "moviepilot-tag"] assert fake_server.add_torrent.call_args.kwargs["tag"] == ["tmp-tag-01", "moviepilot-tag"]
assert fake_server.mock_calls.index(
call.delete_torrents_tag("abc123", "tmp-tag-01")
) < fake_server.mock_calls.index(call.get_content_layout())
def test_download_falls_back_to_tag_lookup_when_added_ids_missing(): def test_download_falls_back_to_tag_lookup_when_added_ids_missing():
@@ -550,7 +553,7 @@ def test_download_removes_temporary_tag_from_existing_torrent():
"name": "test", "name": "test",
"total_size": len(b"torrent-content"), "total_size": len(b"torrent-content"),
"hash": "existing123", "hash": "existing123",
"tags": "tmp-tag-01,moviepilot-tag", "tags": None,
}], None) }], None)
module = _build_module(fake_server) module = _build_module(fake_server)
@@ -563,6 +566,23 @@ def test_download_removes_temporary_tag_from_existing_torrent():
assert result == ("qb", "existing123", "Original", "下载任务已存在") assert result == ("qb", "existing123", "Original", "下载任务已存在")
fake_server.delete_torrents_tag.assert_called_once_with("existing123", "tmp-tag-01") fake_server.delete_torrents_tag.assert_called_once_with("existing123", "tmp-tag-01")
assert fake_server.mock_calls.index(
call.delete_torrents_tag("existing123", "tmp-tag-01")
) < fake_server.mock_calls.index(call.get_content_layout())
def test_delete_torrents_tag_uses_supported_qbittorrent_api_arguments():
"""删除标签时应分别调用任务移除接口和全局标签删除接口。"""
fake_client = MagicMock()
downloader = Qbittorrent.__new__(Qbittorrent)
downloader.qbc = fake_client
assert downloader.delete_torrents_tag("abc123", "tmp-tag-01")
fake_client.torrents_remove_tags.assert_called_once_with(
torrent_hashes="abc123",
tags="tmp-tag-01",
)
fake_client.torrents_delete_tags.assert_called_once_with(tags="tmp-tag-01")
def test_get_files_retries_until_qbittorrent_files_available(): def test_get_files_retries_until_qbittorrent_files_available():