From a698d5504a5344c73ba1d8e1c044fcf2a0a531d0 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 26 Sep 2026 11:58:08 +0800 Subject: [PATCH] fix(transfer): keep history type resolution within ratchet --- app/chain/transfer/execution.py | 21 ++++++++++++-------- tests/test_transfer_history_identity_type.py | 20 +++++++++++++++---- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/app/chain/transfer/execution.py b/app/chain/transfer/execution.py index 3e5aeefee..858b8a984 100644 --- a/app/chain/transfer/execution.py +++ b/app/chain/transfer/execution.py @@ -58,6 +58,18 @@ class _TransferRetryExhausted(RuntimeError): self.snapshot = snapshot +def _download_history_media_type( + history_type: Optional[str], + fallback: Optional[MediaType], +) -> Optional[MediaType]: + """使用下载历史身份类型;缺少有效类型时回退到整理调用提示。""" + try: + media_type = MediaType(history_type) + except (TypeError, ValueError): + return fallback + return fallback if media_type == MediaType.UNKNOWN else media_type + + class _DurableTransferStepRunner: """以稳定顺序、lease 和 attempt fencing 执行整理外部步骤。""" @@ -453,18 +465,11 @@ 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=history_mtype, + mtype=_download_history_media_type(download_history.type, task.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 index f1454fd73..e9b7d9f03 100644 --- a/tests/test_transfer_history_identity_type.py +++ b/tests/test_transfer_history_identity_type.py @@ -2,6 +2,8 @@ from types import SimpleNamespace +import pytest + 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 @@ -11,8 +13,18 @@ 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 冲突时,按下载历史保存的类型查询,不被目录提示改写。""" +@pytest.mark.parametrize( + ("history_type", "expected_type"), + [ + (MediaType.TV.value, MediaType.TV), + (MediaType.UNKNOWN.value, MediaType.MOVIE), + ("invalid", MediaType.MOVIE), + ], +) +def test_download_history_type_wins_over_monitor_type_hint( + monkeypatch, history_type: str, expected_type: MediaType +): + """TMDB 影视 ID 冲突时优先使用下载历史类型,并为无效类型保留调用提示。""" recognized_media = MediaInfo(type=MediaType.TV, title="兰香如故", year="2026") recognition_calls = [] @@ -55,7 +67,7 @@ def test_download_history_type_wins_over_monitor_type_hint(monkeypatch): download_history=DownloadHistorySnapshot( id=1, path="/downloads/兰香如故.S01E32.mkv", - type=MediaType.TV.value, + type=history_type, title="兰香如故", media_source=MediaSource.TMDB, media_id="282326", @@ -67,6 +79,6 @@ def test_download_history_type_wins_over_monitor_type_hint(monkeypatch): assert not state assert "已在整理队列中" in message - assert recognition_calls[0]["mtype"] == MediaType.TV + assert recognition_calls[0]["mtype"] == expected_type assert recognition_calls[0]["media_source"] == MediaSource.TMDB assert recognition_calls[0]["media_id"] == "282326"