fix(notify): scope album title aggregation to notifications only

This commit is contained in:
jxxghp
2026-08-10 14:34:58 +08:00
parent 1d75826549
commit 5acd8ab514
2 changed files with 49 additions and 8 deletions
+20 -7
View File
@@ -49,6 +49,7 @@ class TemplateContextBuilder:
file_extension: Optional[str] = None, file_extension: Optional[str] = None,
episodes_info: Optional[List[TmdbEpisode]] = None, episodes_info: Optional[List[TmdbEpisode]] = None,
include_raw_objects: bool = True, include_raw_objects: bool = True,
aggregate_music_album: bool = False,
**kwargs **kwargs
) -> Dict[str, Any]: ) -> Dict[str, Any]:
""" """
@@ -64,11 +65,14 @@ class TemplateContextBuilder:
:param file_extension: 文件扩展名 :param file_extension: 文件扩展名
:param episodes_info: 当前季的全部集信息 :param episodes_info: 当前季的全部集信息
:param include_raw_objects: 是否在 dict 里附带原始对象引用(``__meta__`` 等) :param include_raw_objects: 是否在 dict 里附带原始对象引用(``__meta__`` 等)
:param aggregate_music_album: 是否按整专聚合(通知场景):专辑实体
批量下载/入库只发一条通知,标题取专辑名且不展示单曲序号;
重命名等逐文件场景必须为 False 以保留每个文件的曲名和曲序
:return: 渲染上下文字典 :return: 渲染上下文字典
""" """
context: Dict[str, Any] = {} context: Dict[str, Any] = {}
self._add_episode_details(context, meta, episodes_info) self._add_episode_details(context, meta, episodes_info)
self._add_media_info(context, mediainfo) self._add_media_info(context, mediainfo, aggregate_music_album)
self._add_transfer_info(context, transferinfo) self._add_transfer_info(context, transferinfo)
self._add_torrent_info(context, torrentinfo) self._add_torrent_info(context, torrentinfo)
self._add_file_info(context, file_extension) self._add_file_info(context, file_extension)
@@ -82,20 +86,29 @@ class TemplateContextBuilder:
return {k: v for k, v in context.items() if v is not None} return {k: v for k, v in context.items() if v is not None}
@classmethod @classmethod
def _add_media_info(cls, context: Dict[str, Any], mediainfo: Optional[MediaInfo]) -> None: def _add_media_info(
cls,
context: Dict[str, Any],
mediainfo: Optional[MediaInfo],
aggregate_music_album: bool = False,
) -> None:
""" """
将 MediaInfo 中的标题、季年份、海报等业务字段就地写入 ``context``。 将 MediaInfo 中的标题、季年份、海报等业务字段就地写入 ``context``。
会读取 ``context`` 中由 ``_add_episode_details`` 先填好的 ``season`` / 会读取 ``context`` 中由 ``_add_episode_details`` 先填好的 ``season`` /
``year`` / ``title_year`` 占位,保证电视剧场景下季/年优先沿用 meta 解析值; ``year`` / ``title_year`` 占位,保证电视剧场景下季/年优先沿用 meta 解析值;
音乐场景保留文件标签解析出的曲目级字段,仅用识别结果补齐专辑级字段 音乐场景保留文件标签解析出的曲目级字段,仅用识别结果补齐专辑级字段
通知场景(``aggregate_music_album=True``)下整专批量以专辑为标题主体。
""" """
if not mediainfo: if not mediainfo:
return return
if isinstance(mediainfo, MusicInfo): if isinstance(mediainfo, MusicInfo):
# 专辑实体下载/整理是整批曲目共享一次通知:标题应以专辑为主 # 专辑实体批量下载/入库只发一条通知:标题取专辑名、不展示单曲
# 题,且不展示单曲序号;单曲场景继续使用每个文件自己的曲名和曲序。 # 序号;重命名等逐文件场景保持 False,继续使用文件自己的曲名和曲序。
is_album_context = mediainfo.music_type == MUSIC_ENTITY_ALBUM is_album_context = (
aggregate_music_album
and mediainfo.music_type == MUSIC_ENTITY_ALBUM
)
if is_album_context and mediainfo.album: if is_album_context and mediainfo.album:
title = cls.__convert_invalid_characters(mediainfo.album) title = cls.__convert_invalid_characters(mediainfo.album)
else: else:
@@ -502,7 +515,7 @@ class TemplateHelper(metaclass=SingletonClass):
if not parsed: if not parsed:
raise ValueError("模板解析失败") raise ValueError("模板解析失败")
context = self.builder.build(**kwargs) context = self.builder.build(aggregate_music_album=True, **kwargs)
if not context: if not context:
raise ValueError("上下文构建失败") raise ValueError("上下文构建失败")
+29 -1
View File
@@ -78,7 +78,9 @@ def test_album_batch_context_uses_album_title_for_notification() -> None:
year=2003, year=2003,
) )
context = TemplateContextBuilder().build(meta=meta, mediainfo=mediainfo) context = TemplateContextBuilder().build(
meta=meta, mediainfo=mediainfo, aggregate_music_album=True
)
assert context["title"] == "叶惠美" assert context["title"] == "叶惠美"
assert context["title_year"] == "叶惠美 (2003)" assert context["title_year"] == "叶惠美 (2003)"
@@ -94,6 +96,32 @@ def test_album_batch_context_uses_album_title_for_notification() -> None:
assert "#3" not in rendered["title"] assert "#3" not in rendered["title"]
def test_album_batch_context_keeps_track_identity_for_rename() -> None:
"""
重命名等逐文件场景(未开启整专聚合)应继续使用每个文件的曲名和曲序,
不能把专辑名写成所有目标文件名。
"""
meta = MetaMusic(
title="晴天",
artists=["周杰伦"],
album="叶惠美",
track_number=3,
year=2003,
)
mediainfo = MusicInfo(
music_type=MUSIC_ENTITY_ALBUM,
title="晴天",
album="叶惠美",
artists=["周杰伦"],
year=2003,
)
context = TemplateContextBuilder().build(meta=meta, mediainfo=mediainfo)
assert context["title"] == "晴天"
assert context["track"] == "03"
def test_single_track_context_keeps_track_title_and_number() -> None: def test_single_track_context_keeps_track_title_and_number() -> None:
""" """
单曲下载/整理的通知上下文应继续使用曲目标题和曲序, 单曲下载/整理的通知上下文应继续使用曲目标题和曲序,