收敛summary模板渲染并对齐gemini-code版式

- main.py 新增模板命名模块提取:Shared Resources/Marketplace/Unresolved/Core Points/Top Contributors\n- 新增贡献者昵称抽取与文本长度控制,提升模板数据稳定性\n- gemini_summary_card.html 重构为接近 gemini-code 的模块顺序与样式语言\n- 恢复 Key Discussions -> Resources -> Marketplace/Unresolved -> Core Points -> Contributors 的版式节奏\n- 保持模板为纯展示层,使用 main.py 结构化数据喂给模板,减少样式与内容错位
This commit is contained in:
liuwei
2026-04-23 10:49:17 +08:00
parent 56aa532aa1
commit 9072e7d60b
2 changed files with 510 additions and 368 deletions

View File

@@ -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),