feat: 新增通知图片测试命令

This commit is contained in:
2026-09-22 21:50:27 +08:00
parent 87c59a0335
commit f4d3abcd09
9 changed files with 2068 additions and 680 deletions

View File

@@ -0,0 +1,108 @@
"""通知图片测试命令 - 供超级用户在群聊/私聊中预览统一通知卡片。
用法(仅超级用户,群内直接发送或私聊发送,均无需 @机器人):
测试通知图片
通知图片测试
测试通知卡片
"""
import asyncio
from nonebot import on_command, logger
from nonebot.adapters.onebot.v11 import Bot, Message, MessageEvent, MessageSegment
from nonebot.matcher import Matcher
from nonebot.permission import SUPERUSER
from .preview_image_render import get_preview_renderer
from .text_parser import TextParser
# 主命令与别名,唯一的命令入口定义,测试直接据此断言
TEST_COMMAND = "测试通知图片"
"""主命令"""
TEST_COMMAND_ALIASES = ("通知图片测试", "测试通知卡片")
"""命令别名"""
# 固定预览内容:覆盖标题、中文、多行、Emoji 与中文标点,便于肉眼核对版式
PREVIEW_TITLE = "# 会被解析为换行:"
"""预览卡片标题行文案:同时演示 # 作为换行符的用法"""
PREVIEW_TEXT = "\n".join(
(
"【通知卡片测试】",
"本卡片由「测试通知图片」命令生成,用于核对统一通知卡片版式。",
"中文标点:逗号,句号。顿号、分号;冒号:问号?感叹号!",
"Emoji:🎉 🏇 😀 👍🏻 🇨🇳",
"混合排版:emoji 与正文之间不应错位 🎊,行距与折行都要正常。",
)
)
"""预览正文(按换行符直接给出,未经 # 替换)"""
PREVIEW_PREVIEW_TEXT = PREVIEW_TEXT.replace("\n", "#")
"""预览文本的 # 写法,经 TextParser 解析后与 PREVIEW_TEXT 一致"""
def resolve_scene(event: MessageEvent) -> str:
"""
按事件来源选择场景徽章
Args:
event: 消息事件
Returns:
群聊为 "group",否则为 "private"
"""
return "group" if getattr(event, "group_id", None) else "private"
def build_message(image_base64: str) -> Message:
"""
构建 OneBot V11 图片消息
Args:
image_base64: base64:// 前缀的图片数据
Returns:
可直接发送的 Message
"""
return Message(MessageSegment.image(image_base64))
def preview_text() -> str:
"""
构造固定预览文本(以 # 表示换行,交由 TextParser 解析)
Returns:
预览文本
"""
return PREVIEW_PREVIEW_TEXT
test_notification_image = on_command(
TEST_COMMAND,
aliases=set(TEST_COMMAND_ALIASES),
permission=SUPERUSER,
priority=1,
block=True,
)
@test_notification_image.handle()
async def handle_test_notification_image(matcher: Matcher, bot: Bot, event: MessageEvent):
"""把固定预览内容渲染成通知卡片并回发到当前会话。"""
from . import plugin_config
scene = resolve_scene(event)
parsed_text = TextParser(max_length=plugin_config.MaxTextLength).parse(preview_text())
renderer = get_preview_renderer(plugin_config)
try:
# Pillow 渲染是同步阻塞操作,放到线程池避免阻塞事件循环
image_base64 = await asyncio.to_thread(
renderer.render_to_base64, parsed_text, PREVIEW_TITLE, scene
)
# 用当前事件的 Bot 直接发送 OneBot V11 图片消息,群聊/私聊都回到触发会话
await bot.send(event, build_message(image_base64))
logger.info(f"[Danding_QqPush] 通知图片测试成功 - scene={scene}")
except BaseException as e:
# 保留 NoneBot 控制流异常(如 FinishedException),只处理真正的异常
if not isinstance(e, Exception):
raise
logger.error(f"[Danding_QqPush] 通知图片测试失败 - scene={scene}: {e}")
await matcher.finish("通知图片生成失败,请查看机器人日志后重试。")