fix(transfer): keep history type resolution within ratchet

This commit is contained in:
jxxghp
2026-09-26 11:58:08 +08:00
parent ee9b32bdbd
commit a698d5504a
2 changed files with 29 additions and 12 deletions

View File

@@ -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),

View File

@@ -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"