fix(messaging): show music resource titles in channel interactions

This commit is contained in:
jxxghp
2026-09-26 16:16:01 +08:00
parent 37bb17128f
commit d6fe5a87da
3 changed files with 104 additions and 0 deletions

View File

@@ -25,6 +25,7 @@ from app.chain.subscribe.facade import SubscribeChain
from app.domain import episode as episode_rules
from app.domain.context import Context, MediaInfo, MusicInfo
from app.domain.meta.metabase import MetaBase
from app.foundation import size as size_tools
from app.runtime.log import logger
from app.schemas.download import DownloadDirectory
from app.schemas.file import FileURI
@@ -1104,6 +1105,46 @@ class MediaInteractionChain(ChainBase):
)
request.page = page
total = len(request.items)
if isinstance(request.current_media, MusicInfo):
if self._supports_interactive_buttons(channel):
title = f"【{request.title}】共找到{total}条相关资源,请选择下载"
buttons = self._create_torrent_buttons(
channel=channel,
request=request,
items=page_items,
total=total,
total_pages=total_pages,
)
else:
page_hint = " p: 上一页 n: 下一页" if total > self._page_size(channel) else ""
title = (
f"【{request.title}】共找到{total}条相关资源,"
f"请回复对应数字下载(0: 自动选择{page_hint})"
)
buttons = None
text = "\n".join(
f"{index}.【{context.torrent_info.site_name}】"
f"{context.torrent_info.title} "
f"{size_tools.format_compact_size(context.torrent_info.size)} "
f"{context.torrent_info.seeders}↑"
for index, context in enumerate(page_items, start=1)
)
self.post_message(
Message(
channel=channel,
source=source,
title=title,
text=text,
userid=userid,
link=self.runtime_config.resource_url,
buttons=buttons,
original_message_id=original_message_id,
original_chat_id=original_chat_id,
parse_mode="",
save_history=False,
)
)
return
if self._supports_interactive_buttons(channel):
title = f"【{request.title}】共找到{total}条相关资源,请选择下载"
buttons = self._create_torrent_buttons(

View File

@@ -211,6 +211,7 @@ def post_music_candidates(
buttons=buttons,
original_message_id=original_message_id,
original_chat_id=original_chat_id,
parse_mode="",
save_history=False,
)
)

View File

@@ -150,10 +150,72 @@ def test_music_candidates_are_presented_as_text_for_plain_message_channel():
notification = post_message.call_args.args[0]
assert "请回复对应数字选择" in notification.title
assert notification.buttons is None
assert notification.parse_mode == ""
assert "1. [单曲] 晴天 — 周杰伦" in notification.text
assert "2. [专辑] 叶惠美 — 周杰伦" in notification.text
@pytest.mark.parametrize("channel", [NotificationChannel.Wechat, NotificationChannel.Telegram])
def test_music_torrents_show_original_titles_and_keep_selection(channel):
"""音乐资源选择显示原始音乐标题,并保留当前渠道的序号或按钮操作。"""
chain = MediaInteractionChain()
album = MusicInfo(
media_source=MediaSource.MusicBrainz,
media_id="album-1",
music_type=MUSIC_ENTITY_ALBUM,
title="叶惠美",
artists=["周杰伦"],
)
request = media_interaction_manager.create_or_replace(
user_id="music-user",
channel=channel,
source="music-test",
username="tester",
action="MusicReSearch",
keyword="周杰伦 叶惠美",
title="叶惠美",
meta=MetaMusic.parse_query("周杰伦 叶惠美"),
items=[],
)
request.current_media = album
request.phase = "torrent"
request.items = [
Context(
media_info=album,
meta_info=MetaMusic.parse_resource("周杰伦 - 叶惠美 FLAC 24bit 96kHz"),
torrent_info=TorrentInfo(
title="周杰伦 - 叶惠美 FLAC 24bit 96kHz",
site_name="TestSite",
size=1024,
seeders=10,
),
)
]
with (
patch.object(chain, "post_message") as post_message,
patch.object(chain, "post_torrents_message") as post_torrents_message,
):
chain._post_torrents_message(
request=request,
channel=channel,
source="music-test",
userid="music-user",
)
notification = post_message.call_args.args[0]
assert "1.【TestSite】周杰伦 - 叶惠美 FLAC 24bit 96kHz" in notification.text
assert notification.parse_mode == ""
assert notification.link == chain.runtime_config.resource_url
assert "0: 自动选择" in notification.title or notification.buttons
if notification.buttons:
assert any(
button["callback_data"].endswith(":download:1")
for row in notification.buttons for button in row
)
post_torrents_message.assert_not_called()
def test_music_subscription_selection_preserves_selected_music_type():
"""选择音乐专辑创建订阅时应将实体类型传给订阅链。"""
chain = MediaInteractionChain()