From ee9b32bdbdfd64006ca7932cd6d0cfa32d7ca1f0 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 26 Sep 2026 11:47:24 +0800 Subject: [PATCH] fix(transfer): honor download history media type --- app/chain/transfer/execution.py | 9 ++- tests/test_transfer_history_identity_type.py | 72 ++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 tests/test_transfer_history_identity_type.py diff --git a/app/chain/transfer/execution.py b/app/chain/transfer/execution.py index 951591d7e..3e5aeefee 100644 --- a/app/chain/transfer/execution.py +++ b/app/chain/transfer/execution.py @@ -453,11 +453,18 @@ class TransferExecutionOwner(_TransferOwnerBase): and download_history.media_id and not history_year_conflict ): + # 下载历史类型与原生 ID 成对保存;目录类型只在快照缺少有效类型时兜底。 + try: + history_mtype = MediaType(download_history.type) + except (TypeError, ValueError): + history_mtype = None + if history_mtype in (None, MediaType.UNKNOWN): + history_mtype = task.mtype # 下载记录中已存在识别信息。这里不再重复标注类型:函数开头 # 已把 mediainfo 声明为 MediaInfo | MusicInfo | None,重复 # 声明会遮蔽它,把音乐识别结果判成类型错误 mediainfo = MediaChain().recognize_media( - mtype=task.mtype or MediaType(download_history.type), + mtype=history_mtype, media_source=download_history.media_source, media_id=download_history.media_id, music_type=self._download_history_music_type(download_history), diff --git a/tests/test_transfer_history_identity_type.py b/tests/test_transfer_history_identity_type.py new file mode 100644 index 000000000..f1454fd73 --- /dev/null +++ b/tests/test_transfer_history_identity_type.py @@ -0,0 +1,72 @@ +"""下载历史媒体身份类型的整理回归测试。""" + +from types import SimpleNamespace + +from app.application.history import DownloadHistorySnapshot +from app.application.transfer.workflow import TransferTask +from app.chain.transfer import TransferChain # pylint: disable=no-name-in-module +from app.domain.context import MediaInfo +from app.domain.meta.metabase import MetaBase +from app.schemas.file import FileItem +from app.schemas.types import MediaSource, MediaType + + +def test_download_history_type_wins_over_monitor_type_hint(monkeypatch): + """TMDB 影视 ID 冲突时,按下载历史保存的类型查询,不被目录提示改写。""" + recognized_media = MediaInfo(type=MediaType.TV, title="兰香如故", year="2026") + recognition_calls = [] + + def recognize_media(**kwargs): + """记录持久身份的实际识别类型。""" + recognition_calls.append(kwargs) + return recognized_media + + media_chain = SimpleNamespace( + recognize_media=recognize_media, + supplement_tmdb_info=lambda media, _meta: media, + ) + monkeypatch.setattr( + "app.chain.transfer.execution.MediaChain", + lambda: media_chain, + ) + + chain = object.__new__(TransferChain) + chain.transfer_history_repository = SimpleNamespace( + get_by_media_identity=lambda **_kwargs: None, + ) + chain.runtime_config = SimpleNamespace(scrape_follow_tmdb=True) + chain.jobview = SimpleNamespace( + migrate_task=lambda _task: False, + try_remove_job=lambda _task: None, + ) + chain.obtain_images = lambda **_kwargs: None + + task = TransferTask( + fileitem=FileItem( + storage="local", + path="/downloads/兰香如故.S01E32.mkv", + type="file", + name="兰香如故.S01E32.mkv", + extension="mkv", + size=1024, + ), + meta=MetaBase("兰香如故 S01E32"), + mtype=MediaType.MOVIE, + download_history=DownloadHistorySnapshot( + id=1, + path="/downloads/兰香如故.S01E32.mkv", + type=MediaType.TV.value, + title="兰香如故", + media_source=MediaSource.TMDB, + media_id="282326", + ), + preview=True, + ) + + state, message = chain._TransferChain__handle_transfer(task) + + assert not state + assert "已在整理队列中" in message + assert recognition_calls[0]["mtype"] == MediaType.TV + assert recognition_calls[0]["media_source"] == MediaSource.TMDB + assert recognition_calls[0]["media_id"] == "282326"