From 5a1808592a719ebdd7615032c35c367a2c63a1cd Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 15 Aug 2026 11:14:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(transfer):=20=E4=BF=AE=E5=A4=8D=E6=9C=AA?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E9=9F=B3=E4=B9=90=E4=BB=BB=E5=8A=A1=E7=99=BB?= =?UTF-8?q?=E8=AE=B0=E4=BD=9C=E4=B8=9A=E5=9B=A0=E5=B9=B4=E4=BB=BD=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=A0=A1=E9=AA=8C=E5=A4=B1=E8=B4=A5=20(#6325)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/chain/transfer.py | 14 ++++++ tests/test_transfer_music_job_media.py | 60 ++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/test_transfer_music_job_media.py diff --git a/app/chain/transfer.py b/app/chain/transfer.py index dfa761468..f43e888a0 100755 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -238,6 +238,20 @@ class JobManager: else: # 没有媒体信息 meta: MetaBase = task.meta + if isinstance(meta, MetaMusic): + # 未识别的音乐按已解析元数据兜底展示;音乐年份为 int, + # 不能复用 MediaInfo(year 为 str),否则触发 pydantic 校验异常 + return schemas.MusicInfo( + title=meta.name, + artists=list(meta.artists or []), + artist=meta.artist, + album=meta.album, + album_artist=meta.album_artist, + year=meta.year, + title_year=f"{meta.name} ({meta.year})" if meta.year else meta.name, + media_source=meta.media_source, + media_id=meta.media_id, + ) return schemas.MediaInfo( title=meta.name, year=meta.year, diff --git a/tests/test_transfer_music_job_media.py b/tests/test_transfer_music_job_media.py new file mode 100644 index 000000000..c15f3eb54 --- /dev/null +++ b/tests/test_transfer_music_job_media.py @@ -0,0 +1,60 @@ +from app import schemas +from app.application.transfer import TransferTask +from app.chain.transfer import JobManager +from app.domain.meta.metamusic import MetaMusic +from app.schemas import FileItem + + +def _music_task() -> TransferTask: + """构造未识别出媒体信息的音乐整理任务,复现 #6325 场景。""" + meta = MetaMusic( + org_string="歌手 - 歌曲名 (1998) [FLAC]", + title="歌曲名", + artists=["歌手"], + album="专辑名", + year=1998, + track_number=3, + ) + fileitem = FileItem( + storage="local", + path="/music/歌手/歌曲名.flac", + type="file", + name="歌曲名.flac", + basename="歌曲名", + extension="flac", + ) + return TransferTask(fileitem=fileitem, meta=meta) + + +def test_add_music_task_without_mediainfo_builds_music_info(): + """音乐任务识别失败登记作业时应按 MusicInfo 兜底,而不是把 int 年份塞进 MediaInfo。""" + jobview = JobManager() + task = _music_task() + + # 修复前这里会抛 pydantic 校验异常:MediaInfo.year 期望 str 而音乐年份是 int + assert jobview.add_task(task) + + jobs = list(jobview._job_view.values()) + assert len(jobs) == 1 + media = jobs[0].media + assert isinstance(media, schemas.MusicInfo) + # MetaMusic.name 优先返回专辑名,作为作业展示标题 + assert media.title == "专辑名" + assert media.year == 1998 + assert media.artists == ["歌手"] + assert media.album == "专辑名" + assert media.title_year == "专辑名 (1998)" + + +def test_add_music_task_without_year_keeps_title(): + """无年份的音乐兜底展示不应拼接空年份。""" + task = _music_task() + task.meta = MetaMusic(org_string="歌曲名", title="歌曲名") + + jobview = JobManager() + assert jobview.add_task(task) + + media = next(iter(jobview._job_view.values())).media + assert isinstance(media, schemas.MusicInfo) + assert media.year is None + assert media.title_year == "歌曲名"