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 == "歌曲名"