mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-11-01 13:15:59 +08:00
fix(4.0): 更新规则时先在所有实例上匹配种子,任一实例不可用则不做任何修改
此前逐实例移动种子,后面的实例不可用时前面的实例已经移动,数据库仍记着旧目录。
This commit is contained in:
@@ -221,13 +221,33 @@ class TorrentManager:
|
||||
# 没换:规则的种子可能经订阅进了别的实例,逐个实例按各自的
|
||||
# 下载目录移动
|
||||
if new_instance == old_instance:
|
||||
for instance_id in await self._torrent_instances(old_data):
|
||||
root = settings.downloader_instance(instance_id).path
|
||||
moved_path = gen_save_path(data, root)
|
||||
old_paths = _save_paths(old_data, root)
|
||||
if old_paths == {normalize_save_path(moved_path)}:
|
||||
continue
|
||||
match_list = await self.__match_torrents_list(old_data, instance_id)
|
||||
# 先在所有实例上匹配种子:任一实例不可用就什么都不改,
|
||||
# 避免一部分实例已移动而规则仍记着旧目录
|
||||
moves = []
|
||||
try:
|
||||
for instance_id in await self._torrent_instances(old_data):
|
||||
root = settings.downloader_instance(instance_id).path
|
||||
moved_path = gen_save_path(data, root)
|
||||
old_paths = _save_paths(old_data, root)
|
||||
if old_paths == {normalize_save_path(moved_path)}:
|
||||
continue
|
||||
match_list = await self.__match_torrents_list(
|
||||
old_data, instance_id
|
||||
)
|
||||
moves.append((instance_id, moved_path, old_paths, match_list))
|
||||
except ConnectionError as e:
|
||||
logger.warning(
|
||||
"[Manager] Can't update rule %s: %s", old_data.rule_name, e
|
||||
)
|
||||
return ResponseModel(
|
||||
status_code=500,
|
||||
status=False,
|
||||
msg_en=f"Updating {old_data.official_title} failed: a "
|
||||
"downloader is unreachable; nothing was changed, retry later.",
|
||||
msg_zh=f"更新 {old_data.official_title} 失败:下载器不可用,"
|
||||
"规则未修改,请稍后重试。",
|
||||
)
|
||||
for instance_id, moved_path, old_paths, match_list in moves:
|
||||
async with DownloadClient(instance_id) as client:
|
||||
# Move existing torrents to new location if path changed
|
||||
if match_list:
|
||||
|
||||
@@ -448,6 +448,44 @@ class TestRuleOnAnotherInstance:
|
||||
moved = _mock("b")._torrents["hb"]["save_path"]
|
||||
assert moved == "/b/Bangumi/Test Anime (2024)/Season 2"
|
||||
|
||||
async def test_update_rule_unavailable_instance_changes_nothing_for_retry(
|
||||
self, two_instances
|
||||
):
|
||||
"""实例 b 不可用:a 上的种子不移动、规则不改,b 恢复后重试两边一起移动。"""
|
||||
from module.manager import TorrentManager
|
||||
from module.models import BangumiUpdate
|
||||
|
||||
bangumi_id = await self._rule_with_torrent_on_a()
|
||||
hb = _completed("B", "hb", "/b/Bangumi/Test Anime (2024)/Season 1")
|
||||
_mock("b")._torrents["hb"] = hb
|
||||
_mock("b").auth = AsyncMock(return_value=False) # type: ignore[method-assign]
|
||||
async with Database() as db:
|
||||
await db.torrent.add(
|
||||
Torrent(name="B", url="u-b", bangumi_id=1, downloader_id="b")
|
||||
)
|
||||
old = await db.bangumi.search_id(bangumi_id)
|
||||
assert old is not None
|
||||
update = BangumiUpdate(**old.model_dump(exclude={"id"}))
|
||||
update.season = 2
|
||||
resp = await TorrentManager(db).update_rule(bangumi_id, update)
|
||||
assert resp.status is False and resp.status_code == 500
|
||||
assert _mock("a")._torrents["old"]["save_path"] == old.save_path
|
||||
kept = await db.bangumi.search_id(bangumi_id)
|
||||
assert kept is not None and kept.save_path == old.save_path
|
||||
|
||||
# 登录失败会丢弃缓存的客户端,恢复后是新的客户端实例
|
||||
_mock("b")._torrents["hb"] = hb
|
||||
update = BangumiUpdate(**old.model_dump(exclude={"id"}))
|
||||
update.season = 2
|
||||
retry = await TorrentManager(db).update_rule(bangumi_id, update)
|
||||
assert retry.status is True
|
||||
new = await db.bangumi.search_id(bangumi_id)
|
||||
|
||||
season2 = "Bangumi/Test Anime (2024)/Season 2"
|
||||
assert new is not None and new.save_path == f"/a/{season2}"
|
||||
assert _mock("a")._torrents["old"]["save_path"] == f"/a/{season2}"
|
||||
assert _mock("b")._torrents["hb"]["save_path"] == f"/b/{season2}"
|
||||
|
||||
async def test_delete_rule_unavailable_instance_keeps_rule_for_retry(
|
||||
self, two_instances
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user