diff --git a/app/api/endpoints/transfer.py b/app/api/endpoints/transfer.py index c4cc2fd7..926001d8 100644 --- a/app/api/endpoints/transfer.py +++ b/app/api/endpoints/transfer.py @@ -93,6 +93,8 @@ def manual_transfer(transer_item: ManualTransferItem, :param _: Token校验 """ force = False + downloader = None + download_hash = None target_path = Path(transer_item.target_path) if transer_item.target_path else None if transer_item.logid: # 查询历史记录 @@ -101,6 +103,8 @@ def manual_transfer(transer_item: ManualTransferItem, return schemas.Response(success=False, message=f"整理记录不存在,ID:{transer_item.logid}") # 强制转移 force = True + downloader = history.downloader + download_hash = history.download_hash if history.status and ("move" in history.mode): # 重新整理成功的转移,则使用成功的 dest 做 in_path src_fileitem = FileItem(**history.dest_fileitem) @@ -121,6 +125,7 @@ def manual_transfer(transer_item: ManualTransferItem, transer_item.tmdbid = int(history.tmdbid) if history.tmdbid else transer_item.tmdbid transer_item.doubanid = str(history.doubanid) if history.doubanid else transer_item.doubanid transer_item.season = int(str(history.seasons).replace("S", "")) if history.seasons else transer_item.season + transer_item.episode_group = history.episode_group or transer_item.episode_group if history.episodes: if "-" in str(history.episodes): # E01-E03多集合并 @@ -173,7 +178,9 @@ def manual_transfer(transer_item: ManualTransferItem, library_type_folder=transer_item.library_type_folder, library_category_folder=transer_item.library_category_folder, force=force, - background=background + background=background, + downloader=downloader, + download_hash=download_hash ) # 失败 if not state: diff --git a/app/chain/transfer.py b/app/chain/transfer.py index 0453b8b7..781f9ab0 100755 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -1634,7 +1634,9 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): library_type_folder: Optional[bool] = None, library_category_folder: Optional[bool] = None, force: Optional[bool] = False, - background: Optional[bool] = False) -> Tuple[bool, Union[str, list]]: + background: Optional[bool] = False, + downloader: Optional[str] = None, + download_hash: Optional[str] = None) -> Tuple[bool, Union[str, list]]: """ 手动整理,支持复杂条件,带进度显示 :param fileitem: 文件项 @@ -1653,6 +1655,8 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): :param library_category_folder: 是否按类别建立目录 :param force: 是否强制整理 :param background: 是否后台运行 + :param downloader: 下载器名称 + :param download_hash: 下载任务哈希 """ logger.info(f"手动整理:{fileitem.path} ...") if tmdbid or doubanid: @@ -1682,7 +1686,9 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): library_category_folder=library_category_folder, force=force, background=background, - manual=True + manual=True, + downloader=downloader, + download_hash=download_hash ) if not state: return False, errmsg @@ -1703,7 +1709,9 @@ class TransferChain(ChainBase, ConfigReloadMixin, metaclass=Singleton): library_category_folder=library_category_folder, force=force, background=background, - manual=True) + manual=True, + downloader=downloader, + download_hash=download_hash) return state, errmsg def send_transfer_message(self, meta: MetaBase, mediainfo: MediaInfo, diff --git a/tests/test_transfer_history_retransfer.py b/tests/test_transfer_history_retransfer.py new file mode 100644 index 00000000..33c8bad8 --- /dev/null +++ b/tests/test_transfer_history_retransfer.py @@ -0,0 +1,54 @@ +from types import ModuleType, SimpleNamespace +import sys + +# The endpoint import pulls in a wide plugin/helper graph. Some optional modules are +# not present in this test environment, so stub them before importing the endpoint. +sys.modules.setdefault("app.helper.sites", ModuleType("app.helper.sites")) +setattr(sys.modules["app.helper.sites"], "SitesHelper", object) + +from app.api.endpoints.transfer import manual_transfer +from app.schemas import ManualTransferItem + + +def test_manual_transfer_from_history_preserves_download_context(monkeypatch): + history = SimpleNamespace( + status=0, + mode="copy", + src_fileitem={"storage": "local", "path": "/downloads/test.mkv", "name": "test.mkv", "type": "file"}, + dest_fileitem=None, + downloader="qbittorrent", + download_hash="abc123", + type="电视剧", + tmdbid="100", + doubanid="200", + seasons="S01", + episodes="E01-E02", + episode_group="WEB-DL", + ) + + captured = {} + + def fake_get(_db, logid): + assert logid == 1 + return history + + class FakeTransferChain: + def manual_transfer(self, **kwargs): + captured.update(kwargs) + return True, "" + + monkeypatch.setattr("app.api.endpoints.transfer.TransferHistory.get", fake_get) + monkeypatch.setattr("app.api.endpoints.transfer.TransferChain", FakeTransferChain) + + resp = manual_transfer( + transer_item=ManualTransferItem(logid=1, from_history=True), + background=True, + db=object(), + _="token", + ) + + assert resp.success is True + assert captured["downloader"] == "qbittorrent" + assert captured["download_hash"] == "abc123" + assert captured["episode_group"] == "WEB-DL" + assert captured["season"] == 1