From 35f1fbc97856d1017f3458744398e29a57dd8f8f Mon Sep 17 00:00:00 2001 From: liuwei Date: Thu, 23 Apr 2026 09:37:31 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BE=A4=E6=80=BB=E7=BB=93=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=EF=BC=9A=E6=96=B0=E5=A2=9EGemini=E9=A3=8E?= =?UTF-8?q?=E6=A0=BC=E5=8D=A1=E7=89=87=E5=B9=B6=E4=BC=98=E5=8C=96Markdown?= =?UTF-8?q?=E5=AF=8C=E6=A0=87=E7=AD=BE=E6=B8=B2=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 变更项: 1. 新增 templates/gemini_summary_card.html,按 Gemini 风格实现移动卡片化总结模板。 2. message_summary 渲染链路升级:支持更完整的 Markdown 富标签转 HTML(标题/列表/表格/代码块/引用等)。 3. 增加渲染后 HTML 安全过滤,清理 script/iframe/on* 事件与 javascript: 链接。 4. 增加 markdown 依赖缺失时的轻量回退解析,保证插件在最小环境下可用。 5. 默认输出配置切换为 template,并指向新 Gemini 风格模板。 --- plugins/message_summary/config.toml | 4 +- plugins/message_summary/main.py | 83 ++++- .../templates/gemini-code-1776907723749.html | 199 ++++++++++++ .../templates/gemini_summary_card.html | 298 ++++++++++++++++++ 4 files changed, 576 insertions(+), 8 deletions(-) create mode 100644 plugins/message_summary/templates/gemini-code-1776907723749.html create mode 100644 plugins/message_summary/templates/gemini_summary_card.html 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 @@ + + + + + Group_Digest_Mobile_V4 + + + + + + +
+ +
+
+
+

CHAT INSIGHTS REPORT

+

ID: 20260423-L-OPEN

+
+
+ Daily Archive +
+
+ +
+
+ Msgs + 1,402 +
+
+ Links + 12 +
+
+ Files + 5 +
+
+ Alerts + 3 +
+
+
+ +
+ # Personal Interest Radar +
+ Gemma 4 + RTX 5090 + Playwright + Nasdaq 100 + frp Tunnel +
+
+ +
+ # Key Discussions + +
+
+ 01. LLM 本地部署显存压测 +
+
+
+
+ Background +

群友在 Mac mini M1 (16G) 环境下运行 Gemma 4 26B,出现内存频繁交换导致系统卡顿。

+
+
+ Key Points +
    +
  • 4-bit 量化(GGUF/Q4_K_M)显存占用约 17.5GB。
  • +
  • 需通过脚本强制清理物理内存 Swap 以缓解抖动。
  • +
  • Ollama 推理时建议关闭 Electron 全家桶。
  • +
+
+
+ Conclusion +

“16G 内存是底线,追求速度建议 32G 或 24G 显存 GPU 运行。”

+
+
+
+ +
+
+ 02. Dota 2 击杀识别 OCR 算法 +
+
+
+ Analysis +

弃用 Tesseract 改用 PaddleOCR。在处理 Douyu 直播间 1080P 高码率画面时,识别准确率从 72% 提升至 91%。

+
+
+
+ +
+ # Shared Resources +
+
+
+ + ollama-python/v2.1-stable +
+ +
+
+
+ + RTX_5090_Whitepaper_Draft.pdf +
+ +
+
+
+ +
+
+ # Marketplace +
+
+ [出] 3060Ti + ¥1650 +
+
+ [求] TI 饰品 + 面议 +
+
+
+
+ # Unresolved Pool +
+

"Ubuntu 24.04 驱动掉线如何修复?"

+

"Nasdaq 100 ETF 最优定投点?"

+
+
+
+ +
+
+ # Core Knowledge Points +

+ FRP 配置项优化: 针对内网穿透超时,需将 tcp_mux 设置为 true,并检查服务端防火墙 MTU 限制。 +

+
+
+ +
+ Top Contributors +
+
L
+
G
+
T
+
+
+ +
+ +
+ Engine: Playwright 1.42 / Renderer: Webkit / User: Liuwei +
+ + + \ No newline at end of file diff --git a/plugins/message_summary/templates/gemini_summary_card.html b/plugins/message_summary/templates/gemini_summary_card.html new file mode 100644 index 0000000..9fe575c --- /dev/null +++ b/plugins/message_summary/templates/gemini_summary_card.html @@ -0,0 +1,298 @@ + + + + + + {{ title }} + + + +
+
+
+
+
CHAT INSIGHTS SUMMARY
+
{{ generated_at }}
+
+
Daily Archive
+
+
+
+ Type +
群总结
+
+
+ Mode +
Template
+
+
+ Render +
HTML
+
+
+ Engine +
LLM
+
+
+
+ +
+ # {{ title }} +
+ {{ summary_html }} +
+
+ 内容已按 Markdown 富标签样式渲染(标题、列表、表格、代码块、引用)。 +
+ +
+
+ + +