diff --git a/app/application/messaging/message.py b/app/application/messaging/message.py index cd5f83c36..e1857bb3a 100644 --- a/app/application/messaging/message.py +++ b/app/application/messaging/message.py @@ -165,7 +165,7 @@ class TemplateContextBuilder: 会读取 ``context`` 中由 ``_add_episode_details`` 先填好的 ``season`` / ``year`` / ``title_year`` 占位,保证电视剧场景下季/年优先沿用 meta 解析值; - 音乐场景保留文件标签解析出的曲目级字段,仅用识别结果补齐专辑级字段; + 音乐场景保留曲目级标签;已识别专辑实体时以所选数据源覆盖专辑级字段; 通知场景(``aggregate_music_album=True``)下整专批量以专辑为标题主体。 """ if not mediainfo: @@ -173,15 +173,14 @@ class TemplateContextBuilder: if isinstance(mediainfo, MusicInfo): # 专辑实体批量下载/入库只发一条通知:标题取专辑名、不展示单曲 # 序号;重命名等逐文件场景保持 False,继续使用文件自己的曲名和曲序。 - is_album_context = ( - aggregate_music_album - and mediainfo.music_type == MUSIC_ENTITY_ALBUM - ) + is_album_entity = mediainfo.music_type == MUSIC_ENTITY_ALBUM + is_album_context = aggregate_music_album and is_album_entity + has_album_identity = bool(is_album_entity and mediainfo.media_source and mediainfo.media_id) # 专辑场景以识别结果的专辑名为标题;整专年份以识别结果为准, # 逐文件场景沿用 meta 解析年份,保证文件级年份优先。 year = ( mediainfo.year - if (is_album_context and mediainfo.year) + if (has_album_identity and mediainfo.year) else (context.get("year") or mediainfo.year) ) if is_album_context and mediainfo.album: @@ -196,13 +195,14 @@ class TemplateContextBuilder: artist = context.get("artist") or cls.__convert_invalid_characters(mediainfo.artist) # 标签/目录名自带的尾部年份会被重命名模板的 `({{year}})` 再次追加, # 统一剥离避免生成 "专辑 (2018) (2018)" 这类重复年份目录(issue #6355) + album_value = mediainfo.album or mediainfo.title if has_album_identity else context.get("album") or mediainfo.album album = cls.__strip_album_trailing_year( - context.get("album") or cls.__convert_invalid_characters(mediainfo.album), + cls.__convert_invalid_characters(album_value), year, ) - album_artist = context.get("album_artist") or cls.__convert_invalid_characters( - mediainfo.album_artist - ) + album_artist_value = mediainfo.album_artist or mediainfo.artist \ + if has_album_identity else context.get("album_artist") or mediainfo.album_artist + album_artist = cls.__convert_invalid_characters(album_artist_value) disc_number = context.get("disc_number") or mediainfo.disc_number track_number = ( None diff --git a/tests/test_music_transfer.py b/tests/test_music_transfer.py index 2f872e738..624330c08 100644 --- a/tests/test_music_transfer.py +++ b/tests/test_music_transfer.py @@ -103,17 +103,17 @@ def test_music_rename_context_contains_audio_fields(): assert context["fileExt"] == ".flac" -def test_music_rename_prefers_track_meta_over_album_media(): - """专辑整理时应使用每个文件的曲名和曲序,不能把专辑名写成所有目标文件名。""" +def test_music_rename_uses_album_identity_and_track_meta(): + """专辑整理应采用所选专辑身份,同时保留每个文件的曲名和曲序。""" meta = MetaMusic( org_string="10. 明天晴天.m4a", title="明天晴天", artists=["孙燕姿"], - album="完美的一天", - album_artist="孙燕姿", - year=2005, + album="错误专辑·全精选集", + album_artist="错误艺术家(资源发布者)", + year=1999, track_number=10, - total_tracks=11, + total_tracks=99, ) album = MusicInfo( media_source="musicbrainz", @@ -137,6 +137,9 @@ def test_music_rename_prefers_track_meta_over_album_media(): assert context["title"] == "明天晴天" assert context["track"] == "10" + assert context["album"] == "完美的一天" + assert context["album_artist"] == "孙燕姿" + assert context["year"] == 2005 assert rendered == "孙燕姿/完美的一天 (2005)/10 - 明天晴天.m4a"