Files
DanDingNoneBot/danding_bot/plugins/danding_qqpush/test_command.py

109 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""通知图片测试命令 - 供超级用户在群聊/私聊中预览统一通知卡片。
用法(仅超级用户,群内直接发送或私聊发送,均无需 @机器人):
测试通知图片
通知图片测试
测试通知卡片
"""
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("通知图片生成失败,请查看机器人日志后重试。")