fix(notify): use album title in music batch notifications

This commit is contained in:
jxxghp
2026-08-10 14:04:19 +08:00
parent d72ed5ed8e
commit 1d75826549
2 changed files with 73 additions and 7 deletions
+19 -6
View File
@@ -15,7 +15,7 @@ from jinja2 import Template
from app.core.cache import TTLCache from app.core.cache import TTLCache
from app.core.config import global_vars from app.core.config import global_vars
from app.core.context import MediaInfo, MusicInfo, TorrentInfo from app.core.context import MUSIC_ENTITY_ALBUM, MediaInfo, MusicInfo, TorrentInfo
from app.core.meta import MetaBase, MetaMusic from app.core.meta import MetaBase, MetaMusic
from app.db.systemconfig_oper import SystemConfigOper from app.db.systemconfig_oper import SystemConfigOper
from app.log import logger from app.log import logger
@@ -93,8 +93,13 @@ class TemplateContextBuilder:
if not mediainfo: if not mediainfo:
return return
if isinstance(mediainfo, MusicInfo): if isinstance(mediainfo, MusicInfo):
# 专辑识别结果会被同一批次的所有曲目复用,不能覆盖每个文件自己的曲名和曲序。 # 专辑实体的下载/整理是整批曲目共享一次通知:标题应以专辑为主
title = context.get("title") or cls.__convert_invalid_characters(mediainfo.title) # 题,且不展示单曲序号;单曲场景继续使用每个文件自己的曲名和曲序。
is_album_context = mediainfo.music_type == MUSIC_ENTITY_ALBUM
if is_album_context and mediainfo.album:
title = cls.__convert_invalid_characters(mediainfo.album)
else:
title = context.get("title") or cls.__convert_invalid_characters(mediainfo.title)
artists = context.get("artists") or [ artists = context.get("artists") or [
cls.__convert_invalid_characters(item) for item in mediainfo.artists cls.__convert_invalid_characters(item) for item in mediainfo.artists
] ]
@@ -103,13 +108,21 @@ class TemplateContextBuilder:
album_artist = context.get("album_artist") or cls.__convert_invalid_characters( album_artist = context.get("album_artist") or cls.__convert_invalid_characters(
mediainfo.album_artist mediainfo.album_artist
) )
year = context.get("year") or mediainfo.year year = (
mediainfo.year
if (is_album_context and mediainfo.year)
else (context.get("year") or mediainfo.year)
)
disc_number = context.get("disc_number") or mediainfo.disc_number disc_number = context.get("disc_number") or mediainfo.disc_number
track_number = context.get("track_number") or mediainfo.track_number track_number = (
None
if is_album_context
else (context.get("track_number") or mediainfo.track_number)
)
context.update({ context.update({
"type": mediainfo.type.value, "type": mediainfo.type.value,
"title": title, "title": title,
"name": context.get("name") or title, "name": title if is_album_context else (context.get("name") or title),
"artists": artists, "artists": artists,
"artist": artist, "artist": artist,
"album": album, "album": album,
+54 -1
View File
@@ -17,8 +17,10 @@ import importlib.util
import pytest import pytest
from app.core.context import MUSIC_ENTITY_ALBUM, MusicInfo
from app.core.meta import MetaMusic
from app.db.systemconfig_oper import SystemConfigOper from app.db.systemconfig_oper import SystemConfigOper
from app.helper.message import MessageTemplateHelper, TemplateHelper from app.helper.message import MessageTemplateHelper, TemplateContextBuilder, TemplateHelper
from app.schemas.message import Notification from app.schemas.message import Notification
from app.schemas.types import ContentType, SystemConfigKey from app.schemas.types import ContentType, SystemConfigKey
@@ -56,6 +58,57 @@ def notification_templates() -> SystemConfigOper:
config_oper.set(SystemConfigKey.NotificationTemplates, original) config_oper.set(SystemConfigKey.NotificationTemplates, original)
def test_album_batch_context_uses_album_title_for_notification() -> 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["title_year"] == "叶惠美 (2003)"
assert context.get("track_number") is None
rendered = TemplateHelper().render(
template_content=MUSIC_ORGANIZE_TEMPLATE,
**dict(context, file_count=11, total_size="1.2 GB"),
)
assert isinstance(rendered, dict)
assert rendered["title"] == "叶惠美 (2003) 已入库"
assert "艺术家:周杰伦" in rendered["text"]
assert "#3" not in rendered["title"]
def test_single_track_context_keeps_track_title_and_number() -> None:
"""
单曲下载/整理的通知上下文应继续使用曲目标题和曲序,
不受专辑场景调整的影响。
"""
context = MUSIC_CONTEXT.copy()
rendered = TemplateHelper().render(
template_content=MUSIC_ORGANIZE_TEMPLATE, **context
)
assert isinstance(rendered, dict)
assert rendered["title"] == "晴天 (2003) #3 已入库"
def test_literal_template_with_quoted_condition_renders_music() -> None: def test_literal_template_with_quoted_condition_renders_music() -> None:
""" """
带 ``{% if type == "音乐" %}`` 双引号条件的模板应能正常渲染, 带 ``{% if type == "音乐" %}`` 双引号条件的模板应能正常渲染,