diff --git a/plugins/message_summary/main.py b/plugins/message_summary/main.py index d9800e5..5d7d8c4 100644 --- a/plugins/message_summary/main.py +++ b/plugins/message_summary/main.py @@ -1020,6 +1020,119 @@ class MessageSummaryPlugin(MessagePluginInterface): break return aux_sections + @classmethod + def _collect_section_texts(cls, section: Dict[str, Any], limit: int = 6) -> List[str]: + """从分节中提取可展示文本,统一做长度控制。""" + texts: List[str] = [] + for item in section.get("items", []): + text = str(item.get("text") or "").strip() + if not text: + continue + # 说明:模板展示强调“短信息块”,避免单条过长撑爆布局。 + texts.append(text[:120]) + if len(texts) >= limit: + break + return texts + + @classmethod + def _extract_contributor_names_from_texts(cls, texts: List[str], limit: int = 3) -> List[str]: + """从文本中抽取贡献者昵称(优先提取 @昵称)。""" + names: List[str] = [] + for text in texts: + # 说明:昵称不做翻译和重写,尽量保留原始 @ 片段,兼容中文/英文/符号昵称。 + for match in re.findall(r"@([^\s::,,。]{1,24})", text): + name = str(match).strip() + if not name or name in names: + continue + names.append(name) + if len(names) >= limit: + return names + # 若没有 @昵称,则退化为文本前缀,保证至少有可展示头像缩写数据。 + for text in texts: + candidate = cls._strip_markdown_inline(text).strip() + if not candidate: + continue + candidate = candidate[:12] + if candidate in names: + continue + names.append(candidate) + if len(names) >= limit: + break + return names + + @classmethod + def _build_template_named_modules(cls, sections: List[Dict[str, Any]]) -> Dict[str, Any]: + """按 gemini-code 模板模块语义抽取结构化数据。""" + modules: Dict[str, Any] = { + "shared_resources": [], + "marketplace": [], + "unresolved_pool": [], + "core_points": [], + "top_contributors": [], + } + if not sections: + return modules + + for section in sections: + title_raw = str(section.get("title") or "").strip() + title = title_raw.lower() + if not title: + continue + texts = cls._collect_section_texts(section, limit=8) + if not texts: + continue + + # 资源区:仓库、文档、工具链接等。 + if any(key in title for key in ["shared resources", "资源", "工具", "链接"]): + for text in texts: + if text not in modules["shared_resources"]: + modules["shared_resources"].append(text) + continue + + # 交易区:出/求/报价/服务等。 + if any(key in title for key in ["marketplace", "交易", "卖货", "快报"]): + for text in texts: + if text not in modules["marketplace"]: + modules["marketplace"].append(text) + continue + + # 待解问题池。 + if any(key in title for key in ["unresolved", "待解", "未解决", "问题池"]): + for text in texts: + if text not in modules["unresolved_pool"]: + modules["unresolved_pool"].append(text) + continue + + # 核心知识点。 + if any(key in title for key in ["core knowledge", "知识", "经验", "配置"]): + for text in texts: + if text not in modules["core_points"]: + modules["core_points"].append(text) + continue + + # 贡献者/荣誉榜。 + if any(key in title for key in ["top contributors", "荣誉榜", "mvp", "贡献者"]): + names = cls._extract_contributor_names_from_texts(texts, limit=3) + for name in names: + if name not in modules["top_contributors"]: + modules["top_contributors"].append(name) + continue + + # 兜底:若未抽到贡献者,则尝试从全部分节文本粗提取。 + if not modules["top_contributors"]: + all_texts: List[str] = [] + for section in sections: + all_texts.extend(cls._collect_section_texts(section, limit=2)) + modules["top_contributors"] = cls._extract_contributor_names_from_texts(all_texts, limit=3) + + # 统一上限,控制页面高度与信息密度。 + modules["shared_resources"] = modules["shared_resources"][:6] + modules["marketplace"] = modules["marketplace"][:6] + modules["unresolved_pool"] = modules["unresolved_pool"][:4] + modules["core_points"] = modules["core_points"][:4] + modules["top_contributors"] = modules["top_contributors"][:3] + return modules + def _render_summary_template_html( self, group_name: str, @@ -1042,6 +1155,7 @@ class MessageSummaryPlugin(MessagePluginInterface): topic_cards = self._build_topic_cards_from_sections(sections, limit=5) topic_titles = [card.get("title", "") for card in topic_cards] auxiliary_sections = self._build_auxiliary_sections(sections, topic_titles) + named_modules = self._build_template_named_modules(sections) # 说明: # 1. 这里注入“本地字体 CSS”到模板,避免依赖 Google Fonts 等外网资源; # 2. 字体文件统一从仓库根目录 fonts/ 下读取,便于部署时统一管理; @@ -1059,6 +1173,11 @@ class MessageSummaryPlugin(MessagePluginInterface): "summary_sections": layout_data.get("sections", []), "summary_topics": topic_cards, "summary_aux_sections": auxiliary_sections, + "summary_shared_resources": named_modules.get("shared_resources", []), + "summary_marketplace": named_modules.get("marketplace", []), + "summary_unresolved_pool": named_modules.get("unresolved_pool", []), + "summary_core_points": named_modules.get("core_points", []), + "summary_top_contributors": named_modules.get("top_contributors", []), "summary_fallback_text": layout_data.get("fallback_text", ""), "summary_metrics": metrics_data, "local_font_css": Markup(local_font_css), diff --git a/plugins/message_summary/templates/gemini_summary_card.html b/plugins/message_summary/templates/gemini_summary_card.html index 24efe0f..864dcfc 100644 --- a/plugins/message_summary/templates/gemini_summary_card.html +++ b/plugins/message_summary/templates/gemini_summary_card.html @@ -5,478 +5,501 @@ {{ title }} -
-
-
-
-
CHAT INSIGHTS SUMMARY
-
{{ generated_at }}
-
-
{{ summary_metrics.activity_badge or "Daily Archive" }}
+
+
+
+
+

CHAT INSIGHTS REPORT

+

ID: {{ generated_at }}

-
- {% for card in summary_metrics.kpi_cards %} -
- {{ card.label }} -
{{ card.value }}
-
- {% endfor %} -
-
- # Personal Interest Radar -
- {% for tag in summary_metrics.topic_tags %} - {{ tag }} - {% endfor %} - {% if not summary_metrics.topic_tags %} - 暂无热点标签 - {% endif %} -
-
-
+
{{ summary_metrics.activity_badge or "Daily Archive" }}
+
-
- # {{ summary_doc_title or title }} -
- {{ summary_lead or "暂无总结内容。" }} +
+ {% for card in summary_metrics.kpi_cards|default([]) %} +
+ {{ card.label }} + {{ card.value }}
-
- {% for topic in summary_topics %} -
-

{{ loop.index }}. {{ topic["title"] }}

-
- {% if topic["time_range"] %}
🕒 {{ topic["time_range"] }}
{% endif %} - {% if topic["participants"] %}
👥 {{ topic["participants"] }}
{% endif %} -
- {% if topic["overview_points"] %} -
-

核心观点

+ {% endfor %} +
+
+ +
+ # Personal Interest Radar +
+ {% for tag in summary_metrics.topic_tags|default([]) %} + {{ tag }} + {% endfor %} + {% if not (summary_metrics.topic_tags|default([])) %} + 暂无热点标签 + {% endif %} +
+
+ +
+ # {{ summary_doc_title or title }} +

{{ summary_lead or "暂无总结内容。" }}

+ + # Key Discussions +
+ {% for topic in summary_topics|default([]) %} +
+
+

{{ "%02d"|format(loop.index) }}. {{ topic["title"] }}

+
+
+ + {% if topic["time_range"] or topic["participants"] %} +
+ {% if topic["time_range"] %}
时段:{{ topic["time_range"] }}
{% endif %} + {% if topic["participants"] %}
参与人数:{{ topic["participants"] }}
{% endif %} +
+ {% endif %} + + {% if topic["analysis_points"]|default([]) %} +
+ Background +

{{ topic["analysis_points"][0] }}

+
+ {% endif %} + + {% if topic["overview_points"]|default([]) %} +
+ Key Points +
    {% for line in topic["overview_points"] %} -

    {{ line }}

    +
  • {{ line }}
  • {% endfor %} -
- {% endif %} - {% if topic["analysis_points"] %} -
-

客观分析

- {% for line in topic["analysis_points"] %} -

{{ line }}

- {% endfor %} -
- {% endif %} - {% if topic["quote_text"] %} -
-

亮点瞬间

-
{{ topic["quote_text"] }}
-
- {% endif %} -
- {% endfor %} -
- {% if not summary_topics %} -
{{ summary_fallback_text }}
- {% endif %} - {% if summary_aux_sections %} -
- {% for block in summary_aux_sections %} -
-

{{ block["title"] }}

- {% for line in block["items"] %} -

• {{ line }}

- {% endfor %} -
- {% endfor %} -
- {% endif %} -
-
-

# Deep Stats

-
- {% for item in summary_metrics.mini_stats %} -
- {{ item.label }} - {{ item.value }} -
- {% endfor %} -
+
-
-

# Core Highlights

-
- {% for text in summary_metrics.highlights %} -

{{ text }}

- {% endfor %} - {% if not summary_metrics.highlights %} -

暂无可提取的核心看点

- {% endif %} -
+ {% endif %} + + {% if topic["quote_text"] %} +
+ Conclusion +

{{ topic["quote_text"] }}

-
-
内容已按结构化规则重排渲染,不再直接内嵌原始 HTML。
- + + {% if not (summary_topics|default([])) %} +

{{ summary_fallback_text }}

+ {% endif %} + + {% if summary_shared_resources|default([]) %} +
+ # Shared Resources +
+ {% for line in summary_shared_resources %} +

{{ line }}

+ {% endfor %}
-
+ {% endif %} + +
+
+ # Marketplace + {% for line in summary_marketplace|default([]) %} +

{{ line }}

+ {% endfor %} + {% if not (summary_marketplace|default([])) %} +

暂无交易信息

+ {% endif %} +
+ +
+ # Unresolved Pool + {% for line in summary_unresolved_pool|default([]) %} +

{{ line }}

+ {% endfor %} + {% if not (summary_unresolved_pool|default([])) %} +

暂无待解问题

+ {% endif %} +
+
+ +
+
+ # Core Knowledge Points + {% for line in summary_core_points|default([]) %} +

{{ line }}

+ {% endfor %} + {% if not (summary_core_points|default([])) %} +

暂无核心知识点

+ {% endif %} +
+
+ +
+ Top Contributors +
+ {% for name in summary_top_contributors|default([]) %} + {{ name[:1] }} + {% endfor %} + {% if not (summary_top_contributors|default([])) %} + ABC + {% endif %} +
+
+ + +
+