Merge pull request #1 from Nezumi-2711/i18n/vietnamese-qq-official-markdown

feat(i18n): Việt hoá báo cáo QQ Official Markdown
This commit is contained in:
2026-07-22 15:36:12 +07:00
committed by GitHub
2 changed files with 46 additions and 43 deletions
@@ -62,19 +62,22 @@ class QQOfficialMarkdownReportGenerator:
for hour, count in enumerate(hourly_counts) for hour, count in enumerate(hourly_counts)
] ]
metrics = [ metrics = [
{"value": self.format_metric(stats.message_count), "label": "消息"}, {"value": self.format_metric(stats.message_count), "label": "Tin nhắn"},
{"value": self.format_metric(stats.participant_count), "label": "参与"}, {
{"value": self.format_metric(stats.total_characters), "label": "字符"}, "value": self.format_metric(stats.participant_count),
{"value": self.format_metric(stats.emoji_count), "label": "表情"}, "label": "Tham gia",
},
{"value": self.format_metric(stats.total_characters), "label": "Ký tự"},
{"value": self.format_metric(stats.emoji_count), "label": "Biểu cảm"},
{ {
"value": self.format_peak_period(stats.most_active_period), "value": self.format_peak_period(stats.most_active_period),
"label": "高峰", "label": "Cao điểm",
}, },
] ]
html_content = self.html_templates.render_platform_template( html_content = self.html_templates.render_platform_template(
"qq_official", "qq_official",
"summary_dashboard.html", "summary_dashboard.html",
report_title="群聊日常分析", report_title="Phân tích nhóm",
report_date=datetime.now().strftime("%Y.%m.%d"), report_date=datetime.now().strftime("%Y.%m.%d"),
metrics=metrics, metrics=metrics,
chart_data=chart_data, chart_data=chart_data,
@@ -99,7 +102,7 @@ class QQOfficialMarkdownReportGenerator:
url = str(result or "").strip() url = str(result or "").strip()
if url.startswith(("http://", "https://")): if url.startswith(("http://", "https://")):
return url return url
logger.warning("[QQOfficial] T2I 概览图未返回可公开访问的 URL") logger.warning("[QQOfficial] Ảnh tổng quan T2I không trả về URL công khai")
return None return None
try: try:
@@ -108,7 +111,7 @@ class QQOfficialMarkdownReportGenerator:
async with self.render_semaphore: async with self.render_semaphore:
return await render() return await render()
except Exception as exc: except Exception as exc:
logger.warning("[QQOfficial] T2I 群聊概览图生成失败: %s", exc) logger.warning("[QQOfficial] Không thể tạo ảnh tổng quan T2I: %s", exc)
return None return None
def _generate_markdown_report( def _generate_markdown_report(
@@ -120,20 +123,20 @@ class QQOfficialMarkdownReportGenerator:
if summary_dashboard_url: if summary_dashboard_url:
lines = [ lines = [
f"![群聊分析概览 #800px #360px]({summary_dashboard_url})", f"![Tổng quan phân tích nhóm #800px #360px]({summary_dashboard_url})",
"", "",
] ]
else: else:
lines = [ lines = [
"# 🎯 群聊日常分析报告", "# 🎯 Báo cáo phân tích nhóm hôm nay",
f"📅 {datetime.now().strftime('%Y年%m月%d')}", f"📅 {datetime.now().strftime('%d/%m/%Y')}",
"", "",
"## 📊 基础统计", "## 📊 Thống kê cơ bản",
f"- **消息总数**{stats.message_count}", f"- **Tổng tin nhắn**: {stats.message_count}",
f"- **参与人数**{stats.participant_count}", f"- **Người tham gia**: {stats.participant_count}",
f"- **总字符数**{stats.total_characters}", f"- **Tổng ký tự**: {stats.total_characters}",
f"- **表情数量**{stats.emoji_count}", f"- **Biểu cảm**: {stats.emoji_count}",
f"- **最活跃时段**{stats.most_active_period}", f"- **Khung giờ sôi nổi nhất**: {stats.most_active_period}",
"", "",
] ]
activity_chart = self.build_activity_chart(stats) activity_chart = self.build_activity_chart(stats)
@@ -141,7 +144,7 @@ class QQOfficialMarkdownReportGenerator:
lines.extend(activity_chart) lines.extend(activity_chart)
lines.append("") lines.append("")
lines.append("## 💬 热门话题") lines.append("## 💬 Chủ đề nổi bật")
max_topics = self.config_manager.get_max_topics() max_topics = self.config_manager.get_max_topics()
for index, topic in enumerate(topics[:max_topics], 1): for index, topic in enumerate(topics[:max_topics], 1):
topic_name = self.render_identity_text(topic.topic, analysis_result) topic_name = self.render_identity_text(topic.topic, analysis_result)
@@ -149,13 +152,13 @@ class QQOfficialMarkdownReportGenerator:
contributor_ids = list(getattr(topic, "contributor_ids", []) or []) contributor_ids = list(getattr(topic, "contributor_ids", []) or [])
mentions = self.mentions(contributor_ids) mentions = self.mentions(contributor_ids)
if mentions: if mentions:
lines.append(f"**参与者**{mentions}") lines.append(f"**Người tham gia**: {mentions}")
detail = self.render_identity_text(topic.detail, analysis_result) detail = self.render_identity_text(topic.detail, analysis_result)
if detail: if detail:
lines.append(detail) lines.append(detail)
lines.append("") lines.append("")
lines.append("## 🏆 群友称号") lines.append("## 🏆 Danh hiệu thành viên")
max_user_titles = self.config_manager.get_max_user_titles() max_user_titles = self.config_manager.get_max_user_titles()
for title in user_titles[:max_user_titles]: for title in user_titles[:max_user_titles]:
mention = self.mention(getattr(title, "user_id", "")) mention = self.mention(getattr(title, "user_id", ""))
@@ -168,7 +171,7 @@ class QQOfficialMarkdownReportGenerator:
lines.append(f" > {reason}") lines.append(f" > {reason}")
lines.append("") lines.append("")
lines.append("## 💬 群圣经") lines.append("## 💬 Câu nói ấn tượng")
max_golden_quotes = self.config_manager.get_max_golden_quotes() max_golden_quotes = self.config_manager.get_max_golden_quotes()
for index, golden_quote in enumerate( for index, golden_quote in enumerate(
stats.golden_quotes[:max_golden_quotes], 1 stats.golden_quotes[:max_golden_quotes], 1
@@ -216,7 +219,7 @@ class QQOfficialMarkdownReportGenerator:
return [] return []
effective_width = max(1, int(bar_width)) effective_width = max(1, int(bar_width))
lines = ["## ⏰ 活跃时间分布"] lines = ["## ⏰ Phân bố thời gian hoạt động"]
for hour, count in enumerate(hourly_counts): for hour, count in enumerate(hourly_counts):
if count > 0: if count > 0:
blocks = max( blocks = max(
+21 -21
View File
@@ -171,8 +171,8 @@ def test_qq_official_markdown_uses_mentions_for_all_identity_sections():
without_mentions = report.replace(f"<@{openid}>", "") without_mentions = report.replace(f"<@{openid}>", "")
assert openid not in without_mentions assert openid not in without_mentions
assert nickname not in without_mentions assert nickname not in without_mentions
assert "## 💬 热门话题" in report assert "## 💬 Chủ đề nổi bật" in report
assert "**参与者**" in report assert "**Người tham gia**" in report
assert "**龙王**" in report assert "**龙王**" in report
assert f"- **1. <@{openid}> 说了一句话** — <@{openid}>" in report assert f"- **1. <@{openid}> 说了一句话** — <@{openid}>" in report
assert f" > <@{openid}> 的发言很精彩" in report assert f" > <@{openid}> 的发言很精彩" in report
@@ -284,14 +284,14 @@ def test_qq_official_markdown_renders_simple_hourly_bar_chart():
report = generate_qq_markdown(generator, analysis_result) report = generate_qq_markdown(generator, analysis_result)
assert "## ⏰ 活跃时间分布" in report assert "## ⏰ Phân bố thời gian hoạt động" in report
assert "- 00:00 — 0" in report assert "- 00:00 — 0" in report
assert "- 01:00 ███ 2" in report assert "- 01:00 ███ 2" in report
assert "- 02:00 ██████ 5" in report assert "- 02:00 ██████ 5" in report
assert "- 03:00 ████████████ 10" in report assert "- 03:00 ████████████ 10" in report
chart_section = report.split("## ⏰ 活跃时间分布", 1)[1].split("## 💬 热门话题", 1)[ chart_section = report.split("## ⏰ Phân bố thời gian hoạt động", 1)[1].split(
0 "## 💬 Chủ đề nổi bật", 1
] )[0]
assert sum(1 for line in chart_section.splitlines() if line.startswith("- ")) == 24 assert sum(1 for line in chart_section.splitlines() if line.startswith("- ")) == 24
@@ -315,7 +315,7 @@ def test_qq_official_markdown_omits_empty_hourly_bar_chart():
report = generate_qq_markdown(generator, analysis_result) report = generate_qq_markdown(generator, analysis_result)
assert "## ⏰ 活跃时间分布" not in report assert "## ⏰ Phân bố thời gian hoạt động" not in report
def test_qq_official_t2i_summary_dashboard_replaces_text_summary(): def test_qq_official_t2i_summary_dashboard_replaces_text_summary():
@@ -351,12 +351,12 @@ def test_qq_official_t2i_summary_dashboard_replaces_text_summary():
assert len(render_calls) == 1 assert len(render_calls) == 1
template, data, return_url, options = render_calls[0] template, data, return_url, options = render_calls[0]
assert "群聊日常分析" in template assert "Phân tích nhóm" in template
assert "消息" in template assert "Tin nhắn" in template
assert "参与" in template assert "Tham gia" in template
assert "字符" in template assert "Ký tự" in template
assert "表情" in template assert "Biểu cảm" in template
assert "高峰" in template assert "Cao điểm" in template
assert ">10<" in template assert ">10<" in template
assert ">2<" in template assert ">2<" in template
assert ">50<" in template assert ">50<" in template
@@ -385,18 +385,18 @@ def test_qq_official_t2i_summary_dashboard_replaces_text_summary():
assert options["omit_background"] is True assert options["omit_background"] is True
assert options["clip"] == {"x": 0, "y": 0, "width": 800, "height": 360} assert options["clip"] == {"x": 0, "y": 0, "width": 800, "height": 360}
assert "https://t2i.example/chart.png" in markdown_report assert "https://t2i.example/chart.png" in markdown_report
assert "# 🎯 群聊日常分析报告" not in markdown_report assert "# 🎯 Báo cáo phân tích nhóm hôm nay" not in markdown_report
assert "📅" not in markdown_report assert "📅" not in markdown_report
assert "## 📊 基础统计" not in markdown_report assert "## 📊 Thống kê cơ bản" not in markdown_report
assert "消息总数" not in markdown_report assert "Tổng tin nhắn" not in markdown_report
assert "## ⏰ 活跃时间分布" not in markdown_report assert "## ⏰ Phân bố thời gian hoạt động" not in markdown_report
assert "████" not in markdown_report assert "████" not in markdown_report
assert "https://t2i.example/chart.png" not in fallback_report assert "https://t2i.example/chart.png" not in fallback_report
assert "# 🎯 群聊日常分析报告" in fallback_report assert "# 🎯 Báo cáo phân tích nhóm hôm nay" in fallback_report
assert "📅" in fallback_report assert "📅" in fallback_report
assert "## 📊 基础统计" in fallback_report assert "## 📊 Thống kê cơ bản" in fallback_report
assert "消息总数" in fallback_report assert "Tổng tin nhắn" in fallback_report
assert "## ⏰ 活跃时间分布" in fallback_report assert "## ⏰ Phân bố thời gian hoạt động" in fallback_report
assert "████" in fallback_report assert "████" in fallback_report