diff --git a/plugins/message_summary/config.toml b/plugins/message_summary/config.toml index fbaf3ad..f584b39 100644 --- a/plugins/message_summary/config.toml +++ b/plugins/message_summary/config.toml @@ -15,6 +15,6 @@ image_format = "png" # 图片渲染模式: # - template: 使用 HTML 模板渲染(模板样式稳定后再切换) # - markdown: 使用历史 md2image 样式 -summary_image_mode = "markdown" +summary_image_mode = "template" # 总结卡片模板路径(相对项目根目录) -summary_image_template_path = "plugins/message_summary/templates/summary_card.html" +summary_image_template_path = "plugins/message_summary/templates/gemini_summary_card.html" diff --git a/plugins/message_summary/main.py b/plugins/message_summary/main.py index ef7aef3..f1e07e7 100644 --- a/plugins/message_summary/main.py +++ b/plugins/message_summary/main.py @@ -9,6 +9,11 @@ from typing import Dict, Any, Tuple, Optional, List from loguru import logger from markupsafe import Markup +try: + # 优先使用 markdown 库做完整渲染(支持表格、代码块等)。 + import markdown as markdown_lib +except Exception: + markdown_lib = None from base.plugin_common.message_plugin_interface import MessagePluginInterface from base.plugin_common.plugin_interface import PluginStatus @@ -410,11 +415,76 @@ class MessageSummaryPlugin(MessagePluginInterface): return cleaned @staticmethod - def _summary_markdown_to_html(summary_text: str) -> str: - """把总结 Markdown 转为基础 HTML 片段(模板内部展示用)。""" - # 这里不依赖第三方 markdown 库,保证在最小运行环境也能稳定渲染。 - # 规则按“标题/列表/段落”三类做轻量转换,足够覆盖总结文本场景。 - lines = str(summary_text or "").splitlines() + def _sanitize_rendered_html(rendered_html: str) -> str: + """对渲染后的 HTML 做最小安全过滤。 + + 安全策略: + 1. 移除 script/style/iframe 等高风险标签,避免模板渲染执行脚本; + 2. 清除行内事件属性(onload/onerror/onclick...); + 3. 禁止 javascript: 协议链接。 + + 说明: + - 这里是“轻量过滤”,目标是平衡安全与展示完整度; + - 若后续需要更严格过滤,可接入专门的 HTML Sanitizer。 + """ + safe_html = str(rendered_html or "") + # 删除高风险标签及其内容。 + safe_html = re.sub( + r"<\s*(script|style|iframe|object|embed|form|link|meta)\b[^>]*>.*?<\s*/\s*\1\s*>", + "", + safe_html, + flags=re.IGNORECASE | re.DOTALL, + ) + # 删除自闭合高风险标签。 + safe_html = re.sub( + r"<\s*(script|style|iframe|object|embed|form|link|meta)\b[^>]*/\s*>", + "", + safe_html, + flags=re.IGNORECASE | re.DOTALL, + ) + # 删除行内事件处理器属性。 + safe_html = re.sub(r"\son[a-zA-Z]+\s*=\s*(['\"]).*?\1", "", safe_html, flags=re.IGNORECASE | re.DOTALL) + # 阻断 javascript: 链接。 + safe_html = re.sub( + r"""(href|src)\s*=\s*(['"])\s*javascript:[^'"]*\2""", + r'\1=\2#\2', + safe_html, + flags=re.IGNORECASE, + ) + return safe_html + + @classmethod + def _summary_markdown_to_html(cls, summary_text: str) -> str: + """把总结 Markdown 转为 HTML 片段(模板内部展示用)。 + + 升级点: + 1. 使用 markdown 库完整支持标题、列表、粗斜体、引用、代码块、表格等结构; + 2. 对 LLM 输出里常见的富标签 markdown(例如 ```、|表格|、> 引用)效果更好; + 3. 渲染后做一次轻量安全过滤,避免模板内注入脚本。 + """ + text = str(summary_text or "").strip() + if not text: + return "
暂无总结内容。
" + + # 兼容处理: + # 1. 环境安装了 markdown 库时,走完整渲染; + # 2. 未安装时自动降级到内置轻量转换,避免插件启动失败。 + if markdown_lib is not None: + rendered = markdown_lib.markdown( + text, + extensions=[ + "extra", # 综合扩展:支持表格、定义列表等 + "fenced_code", # 支持 ``` 代码块 + "tables", # 支持 Markdown 表格 + "sane_lists", # 更稳定的列表解析 + "nl2br", # 保留换行,提升聊天总结可读性 + ], + output_format="html5", + ) + return cls._sanitize_rendered_html(rendered) + + # 轻量回退实现(兼容无 markdown 三方包的运行环境)。 + lines = text.splitlines() html_parts: List[str] = [] list_items: List[str] = [] @@ -443,7 +513,8 @@ class MessageSummaryPlugin(MessagePluginInterface): flush_list() html_parts.append(f"{html.escape(line)}
") flush_list() - return "".join(html_parts) + rendered = "".join(html_parts) + return cls._sanitize_rendered_html(rendered) def _render_summary_template_html(self, group_name: str, summary_text: str) -> str: """根据模板路径渲染总结图片 HTML。""" diff --git a/plugins/message_summary/templates/gemini-code-1776907723749.html b/plugins/message_summary/templates/gemini-code-1776907723749.html new file mode 100644 index 0000000..5b1948f --- /dev/null +++ b/plugins/message_summary/templates/gemini-code-1776907723749.html @@ -0,0 +1,199 @@ + + + + +ID: 20260423-L-OPEN
+群友在 Mac mini M1 (16G) 环境下运行 Gemma 4 26B,出现内存频繁交换导致系统卡顿。
+“16G 内存是底线,追求速度建议 32G 或 24G 显存 GPU 运行。”
+弃用 Tesseract 改用 PaddleOCR。在处理 Douyu 直播间 1080P 高码率画面时,识别准确率从 72% 提升至 91%。
+"Ubuntu 24.04 驱动掉线如何修复?"
+"Nasdaq 100 ETF 最优定投点?"
+
+ FRP 配置项优化: 针对内网穿透超时,需将 tcp_mux 设置为 true,并检查服务端防火墙 MTU 限制。
+