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

View File

@@ -15,7 +15,7 @@ from jinja2 import Template
from app.core.cache import TTLCache
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.db.systemconfig_oper import SystemConfigOper
from app.log import logger
@@ -93,8 +93,13 @@ class TemplateContextBuilder:
if not mediainfo:
return
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 [
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(
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
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({
"type": mediainfo.type.value,
"title": title,
"name": context.get("name") or title,
"name": title if is_album_context else (context.get("name") or title),
"artists": artists,
"artist": artist,
"album": album,

View File

@@ -17,8 +17,10 @@ import importlib.util
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.helper.message import MessageTemplateHelper, TemplateHelper
from app.helper.message import MessageTemplateHelper, TemplateContextBuilder, TemplateHelper
from app.schemas.message import Notification
from app.schemas.types import ContentType, SystemConfigKey
@@ -56,6 +58,57 @@ def notification_templates() -> SystemConfigOper:
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:
"""
带 ``{% if type == "音乐" %}`` 双引号条件的模板应能正常渲染,