From dc0366aab2bf4d8f23a5148aaafb81de9e8d7cce Mon Sep 17 00:00:00 2001 From: fujie Date: Wed, 11 Feb 2026 12:19:16 +0800 Subject: [PATCH] feat: enable live stats for community reports via Gist dynamic badges --- docs/community-stats.json | 8 +-- docs/community-stats.md | 24 ++++---- docs/community-stats.zh.md | 24 ++++---- docs/stats-history.json | 2 +- scripts/openwebui_stats.py | 110 +++++++++++++++++++++++-------------- 5 files changed, 98 insertions(+), 70 deletions(-) diff --git a/docs/community-stats.json b/docs/community-stats.json index fefc68f..9114ce1 100644 --- a/docs/community-stats.json +++ b/docs/community-stats.json @@ -1,7 +1,7 @@ { "total_posts": 22, "total_downloads": 4156, - "total_views": 45912, + "total_views": 45916, "total_upvotes": 231, "total_downvotes": 2, "total_saves": 274, @@ -23,7 +23,7 @@ "author": "Fu-Jie", "description": "Intelligently analyzes text content and generates interactive mind maps to help users structure and visualize knowledge.", "downloads": 954, - "views": 8385, + "views": 8386, "upvotes": 22, "saves": 50, "comments": 13, @@ -295,7 +295,7 @@ "author": "Fu-Jie", "description": "A specialized filter to bypass OpenWebUI's default RAG for GitHub Copilot SDK models. It moves uploaded files to a safe location ('copilot_files') so the Copilot Pipe can process them natively without interference.", "downloads": 16, - "views": 851, + "views": 854, "upvotes": 3, "saves": 0, "comments": 0, @@ -311,7 +311,7 @@ "author": "", "description": "", "downloads": 0, - "views": 277, + "views": 278, "upvotes": 5, "saves": 0, "comments": 0, diff --git a/docs/community-stats.md b/docs/community-stats.md index 7f0afff..db2648d 100644 --- a/docs/community-stats.md +++ b/docs/community-stats.md @@ -1,6 +1,6 @@ # 📊 OpenWebUI Community Stats Report -> 📅 Updated: 2026-02-11 12:15 +> 📅 Updated: 2026-02-11 12:19 ### 📈 增长与趋势 (Last 14 Days) ```mermaid @@ -9,7 +9,7 @@ xychart-beta x-axis ["01-29", "01-30", "01-31", "02-01", "02-02", "02-03", "02-04", "02-05", "02-06", "02-07", "02-08", "02-09", "02-10", "02-11"] y-axis "Total Counts" line [2780, 2877, 2979, 3030, 3168, 3236, 3374, 3522, 3663, 3779, 3872, 3996, 4131, 4156] - line [32888, 34134, 35248, 35805, 37424, 38133, 39440, 40964, 43171, 44354, 45255, 46645, 48876, 45912] + line [32888, 34134, 35248, 35805, 37424, 38133, 39440, 40964, 43171, 44354, 45255, 46645, 48876, 45916] ``` > *蓝色: 总下载量 | 紫色: 总浏览量* @@ -39,14 +39,14 @@ xychart-beta | Metric | Value | Growth (24h) | |------|------|:---:| -| 📝 Total Posts | 22 | - | -| ⬇️ Total Downloads | 4156 | **+25** 🚀 | -| 👁️ Total Views | 45912 | - | -| 👍 Total Upvotes | 231 | **+1** 🚀 | -| 💾 Total Saves | 274 | - | +| 📝 Total Posts | ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) | - | +| ⬇️ Total Downloads | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) | **+25** 🚀 | +| 👁️ Total Views | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) | - | +| 👍 Total Upvotes | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) | **+1** 🚀 | +| 💾 Total Saves | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) | - | | 💬 Total Comments | 55 | - | -| ⭐ Author Points | 271 | **+1** 🚀 | -| 👥 Followers | 220 | - | +| ⭐ Author Points | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&style=flat) | **+1** 🚀 | +| 👥 Followers | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&style=flat) | - | ## 📂 By Type @@ -61,7 +61,7 @@ xychart-beta | Rank | Title | Type | Version | Downloads | Views | Upvotes | Saves | Updated | |:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:| -| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.2 | 954 | 8385 | 22 | 50 | 2026-01-29 | +| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.2 | 954 | 8386 | 22 | 50 | 2026-01-29 | | 2 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.5.0 | 707 | 6701 | 24 | 34 | 2026-01-31 | | 3 | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.4 | 383 | 3026 | 14 | 26 | 2026-02-07 | | 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | 1.2.2 | 363 | 3755 | 14 | 34 | 2026-01-29 | @@ -78,8 +78,8 @@ xychart-beta | 15 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.2.2 | 33 | 669 | 7 | 5 | 2026-01-29 | | 16 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 27 | 690 | 8 | 1 | 2026-01-29 | | 17 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 24 | 444 | 5 | 1 | 2026-01-08 | -| 18 | [GitHub Copilot SDK Files Filter](https://openwebui.com/posts/github_copilot_sdk_files_filter_403a62ee) | filter | 0.1.2 | 16 | 851 | 3 | 0 | 2026-02-10 | -| 19 | [🚀 GitHub Copilot SDK Pipe: AI That Executes, Not Just Talks](https://openwebui.com/posts/github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293) | post | | 0 | 277 | 5 | 0 | 2026-02-10 | +| 18 | [GitHub Copilot SDK Files Filter](https://openwebui.com/posts/github_copilot_sdk_files_filter_403a62ee) | filter | 0.1.2 | 16 | 854 | 3 | 0 | 2026-02-10 | +| 19 | [🚀 GitHub Copilot SDK Pipe: AI That Executes, Not Just Talks](https://openwebui.com/posts/github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293) | post | | 0 | 278 | 5 | 0 | 2026-02-10 | | 20 | [🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager](https://openwebui.com/posts/open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e) | post | | 0 | 1525 | 12 | 19 | 2026-01-29 | | 21 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | review | | 0 | 161 | 2 | 0 | 2026-01-14 | | 22 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | post | | 0 | 1421 | 14 | 10 | 2026-01-10 | diff --git a/docs/community-stats.zh.md b/docs/community-stats.zh.md index 8786068..df6c63d 100644 --- a/docs/community-stats.zh.md +++ b/docs/community-stats.zh.md @@ -1,6 +1,6 @@ # 📊 OpenWebUI 社区统计报告 -> 📅 更新时间: 2026-02-11 12:15 +> 📅 更新时间: 2026-02-11 12:19 ### 📈 增长与趋势 (Last 14 Days) ```mermaid @@ -9,7 +9,7 @@ xychart-beta x-axis ["01-29", "01-30", "01-31", "02-01", "02-02", "02-03", "02-04", "02-05", "02-06", "02-07", "02-08", "02-09", "02-10", "02-11"] y-axis "Total Counts" line [2780, 2877, 2979, 3030, 3168, 3236, 3374, 3522, 3663, 3779, 3872, 3996, 4131, 4156] - line [32888, 34134, 35248, 35805, 37424, 38133, 39440, 40964, 43171, 44354, 45255, 46645, 48876, 45912] + line [32888, 34134, 35248, 35805, 37424, 38133, 39440, 40964, 43171, 44354, 45255, 46645, 48876, 45916] ``` > *蓝色: 总下载量 | 紫色: 总浏览量* @@ -39,14 +39,14 @@ xychart-beta | 指标 | 数值 | 增长 (24h) | |------|------|:---:| -| 📝 发布数量 | 22 | - | -| ⬇️ 总下载量 | 4156 | **+25** 🚀 | -| 👁️ 总浏览量 | 45912 | - | -| 👍 总点赞数 | 231 | **+1** 🚀 | -| 💾 总收藏数 | 274 | - | +| 📝 发布数量 | ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) | - | +| ⬇️ 总下载量 | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) | **+25** 🚀 | +| 👁️ 总浏览量 | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) | - | +| 👍 总点赞数 | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) | **+1** 🚀 | +| 💾 总收藏数 | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) | - | | 💬 总评论数 | 55 | - | -| ⭐ 作者总积分 | 271 | **+1** 🚀 | -| 👥 粉丝数量 | 220 | - | +| ⭐ 作者总积分 | ![points](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_points.json&style=flat) | **+1** 🚀 | +| 👥 粉丝数量 | ![followers](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_followers.json&style=flat) | - | ## 📂 按类型分类 @@ -61,7 +61,7 @@ xychart-beta | 排名 | 标题 | 类型 | 版本 | 下载 | 浏览 | 点赞 | 收藏 | 更新日期 | |:---:|------|:---:|:---:|:---:|:---:|:---:|:---:|:---:| -| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.2 | 954 | 8385 | 22 | 50 | 2026-01-29 | +| 1 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | action | 0.9.2 | 954 | 8386 | 22 | 50 | 2026-01-29 | | 2 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | action | 1.5.0 | 707 | 6701 | 24 | 34 | 2026-01-31 | | 3 | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | action | 0.4.4 | 383 | 3026 | 14 | 26 | 2026-02-07 | | 4 | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | filter | 1.2.2 | 363 | 3755 | 14 | 34 | 2026-01-29 | @@ -78,8 +78,8 @@ xychart-beta | 15 | [异步上下文压缩](https://openwebui.com/posts/异步上下文压缩_5c0617cb) | action | 1.2.2 | 33 | 669 | 7 | 5 | 2026-01-29 | | 16 | [闪记卡 (Flash Card)](https://openwebui.com/posts/闪记卡生成插件_4a31eac3) | action | 0.2.4 | 27 | 690 | 8 | 1 | 2026-01-29 | | 17 | [精读](https://openwebui.com/posts/精读_99830b0f) | action | 1.0.0 | 24 | 444 | 5 | 1 | 2026-01-08 | -| 18 | [GitHub Copilot SDK Files Filter](https://openwebui.com/posts/github_copilot_sdk_files_filter_403a62ee) | filter | 0.1.2 | 16 | 851 | 3 | 0 | 2026-02-10 | -| 19 | [🚀 GitHub Copilot SDK Pipe: AI That Executes, Not Just Talks](https://openwebui.com/posts/github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293) | post | | 0 | 277 | 5 | 0 | 2026-02-10 | +| 18 | [GitHub Copilot SDK Files Filter](https://openwebui.com/posts/github_copilot_sdk_files_filter_403a62ee) | filter | 0.1.2 | 16 | 854 | 3 | 0 | 2026-02-10 | +| 19 | [🚀 GitHub Copilot SDK Pipe: AI That Executes, Not Just Talks](https://openwebui.com/posts/github_copilot_sdk_for_openwebui_elevate_your_ai_t_a140f293) | post | | 0 | 278 | 5 | 0 | 2026-02-10 | | 20 | [🚀 Open WebUI Prompt Plus: AI-Powered Prompt Manager](https://openwebui.com/posts/open_webui_prompt_plus_ai_powered_prompt_manager_s_15fa060e) | post | | 0 | 1525 | 12 | 19 | 2026-01-29 | | 21 | [Review of Claude Haiku 4.5](https://openwebui.com/posts/review_of_claude_haiku_45_41b0db39) | review | | 0 | 161 | 2 | 0 | 2026-01-14 | | 22 | [ 🛠️ Debug Open WebUI Plugins in Your Browser](https://openwebui.com/posts/debug_open_webui_plugins_in_your_browser_81bf7960) | post | | 0 | 1421 | 14 | 10 | 2026-01-10 | diff --git a/docs/stats-history.json b/docs/stats-history.json index 68793e6..9483b4e 100644 --- a/docs/stats-history.json +++ b/docs/stats-history.json @@ -1084,7 +1084,7 @@ "date": "2026-02-11", "total_posts": 22, "total_downloads": 4156, - "total_views": 45912, + "total_views": 45916, "total_upvotes": 231, "total_saves": 274, "followers": 220, diff --git a/scripts/openwebui_stats.py b/scripts/openwebui_stats.py index 6e81c99..295aa7b 100644 --- a/scripts/openwebui_stats.py +++ b/scripts/openwebui_stats.py @@ -534,6 +534,8 @@ class OpenWebUIStats: } t = texts.get(lang, texts["en"]) + user = stats.get("user", {}) + delta = self.get_stat_delta(stats) md = [] md.append(t["title"]) @@ -558,25 +560,30 @@ class OpenWebUIStats: md.append("") md.append(t["overview_header"]) md.append("|------|------|:---:|") - md.append(f"| {t['posts']} | {stats['total_posts']} | - |") md.append( - f"| {t['downloads']} | {stats['total_downloads']} | {fmt_delta('downloads')} |" + f"| {t['posts']} | {self.get_badge('posts', stats, user, delta)} | - |" ) - md.append(f"| {t['views']} | {stats['total_views']} | {fmt_delta('views')} |") md.append( - f"| {t['upvotes']} | {stats['total_upvotes']} | {fmt_delta('upvotes')} |" + f"| {t['downloads']} | {self.get_badge('downloads', stats, user, delta)} | {fmt_delta('downloads')} |" + ) + md.append( + f"| {t['views']} | {self.get_badge('views', stats, user, delta)} | {fmt_delta('views')} |" + ) + md.append( + f"| {t['upvotes']} | {self.get_badge('upvotes', stats, user, delta)} | {fmt_delta('upvotes')} |" + ) + md.append( + f"| {t['saves']} | {self.get_badge('saves', stats, user, delta)} | - |" ) - md.append(f"| {t['saves']} | {stats['total_saves']} | - |") md.append(f"| {t['comments']} | {stats['total_comments']} | - |") # 作者信息 - user = stats.get("user", {}) if user: md.append( - f"| {t['author_points']} | {user.get('total_points', 0)} | {fmt_delta('points')} |" + f"| {t['author_points']} | {self.get_badge('points', stats, user, delta)} | {fmt_delta('points')} |" ) md.append( - f"| {t['author_followers']} | {user.get('followers', 0)} | {fmt_delta('followers')} |" + f"| {t['author_followers']} | {self.get_badge('followers', stats, user, delta)} | {fmt_delta('followers')} |" ) md.append("") @@ -596,6 +603,11 @@ class OpenWebUIStats: for i, post in enumerate(stats["posts"], 1): title_link = f"[{post['title']}]({post['url']})" + + # 使用 get_badge 处理单个帖子的下载和浏览量徽章 (仅前 10 个使用索引,其余使用通用处理或暂留静态) + # 为了报告的简洁,我们这里可以考虑对 Top 10 使用动态徽章,或者统一设计一种按 slug 获取的机制 + # 简化方案:报告中我们直接用对应 key 的 get_badge + md.append( f"| {i} | {title_link} | {post['type']} | {post['version']} | " f"{post['downloads']} | {post['views']} | {post['upvotes']} | " @@ -778,6 +790,48 @@ class OpenWebUIStats: else: print(f"⚠️ 徽章上传失败: {resp.status_code} {resp.text}") + def get_badge( + self, + key: str, + stats: dict, + user: dict, + delta: dict, + is_post: bool = False, + style: str = "flat", + ) -> str: + """获取 Shields.io 徽章 URL (包含增量显示)""" + import urllib.parse + + gist_user = "Fu-Jie" + + def _fmt_delta(k: str) -> str: + val = delta.get(k, 0) + if val > 0: + return f"
(+{val}🚀)" + return "" + + if not self.gist_id: + if is_post: + return "**-**" + val = stats.get(f"total_{key}", 0) + if key == "followers": + val = user.get("followers", 0) + if key == "points": + val = user.get("total_points", 0) + if key == "contributions": + val = user.get("contributions", 0) + if key == "posts": + val = stats.get("total_posts", 0) + if key == "saves": + val = stats.get("total_saves", 0) + return f"**{val}**{_fmt_delta(key)}" + + raw_url = f"https://gist.githubusercontent.com/{gist_user}/{self.gist_id}/raw/badge_{key}.json" + encoded_url = urllib.parse.quote(raw_url, safe="") + return ( + f"![{key}](https://img.shields.io/endpoint?url={encoded_url}&style={style})" + ) + def generate_readme_stats(self, stats: dict, lang: str = "zh") -> str: """ 生成 README 统计区域 (精简版) @@ -827,33 +881,7 @@ class OpenWebUIStats: lines.append(f"> {t['updated']}") lines.append("") - # 定义徽章 URL (使用 Gist ID) - import urllib.parse - - gist_user = "Fu-Jie" - - def get_badge(key: str, is_post: bool = False, style: str = "flat") -> str: - if not self.gist_id: - # 降级:如果没有 Gist,显示静态文本 - if is_post: - return "**-**" - val = stats.get(f"total_{key}", 0) - if key == "followers": - val = user.get("followers", 0) - if key == "points": - val = user.get("total_points", 0) - if key == "contributions": - val = user.get("contributions", 0) - if key == "posts": - val = stats.get("total_posts", 0) - if key == "saves": - val = stats.get("total_saves", 0) - return f"**{val}**{fmt_delta(key)}" - - # 对 Gist Raw URL 进行转义,确保 Shields.io 正确处理 - raw_url = f"https://gist.githubusercontent.com/{gist_user}/{self.gist_id}/raw/badge_{key}.json" - encoded_url = urllib.parse.quote(raw_url, safe="") - return f"![{key}](https://img.shields.io/endpoint?url={encoded_url}&style={style})" + delta = self.get_stat_delta(stats) # 作者信息表格 if user: @@ -862,8 +890,8 @@ class OpenWebUIStats: lines.append(t["author_header"]) lines.append("| :---: | :---: | :---: | :---: |") lines.append( - f"| [{username}]({profile_url}) | {get_badge('followers')} | " - f"{get_badge('points')} | {get_badge('contributions')} |" + f"| [{username}]({profile_url}) | {self.get_badge('followers', stats, user, delta)} | " + f"{self.get_badge('points', stats, user, delta)} | {self.get_badge('contributions', stats, user, delta)} |" ) lines.append("") @@ -871,8 +899,8 @@ class OpenWebUIStats: lines.append(t["header"]) lines.append("| :---: | :---: | :---: | :---: | :---: |") lines.append( - f"| {get_badge('posts')} | {get_badge('downloads')} | " - f"{get_badge('views')} | {get_badge('upvotes')} | {get_badge('saves')} |" + f"| {self.get_badge('posts', stats, user, delta)} | {self.get_badge('downloads', stats, user, delta)} | " + f"{self.get_badge('views', stats, user, delta)} | {self.get_badge('upvotes', stats, user, delta)} | {self.get_badge('saves', stats, user, delta)} |" ) lines.append("") @@ -886,8 +914,8 @@ class OpenWebUIStats: idx = i + 1 medal = medals[i] if i < len(medals) else str(idx) - dl_cell = get_badge(f"p{idx}_dl", is_post=True) - vw_cell = get_badge(f"p{idx}_vw", is_post=True) + dl_cell = self.get_badge(f"p{idx}_dl", stats, user, delta, is_post=True) + vw_cell = self.get_badge(f"p{idx}_vw", stats, user, delta, is_post=True) lines.append( f"| {medal} | [{post['title']}]({post['url']}) | {post['version']} | {dl_cell} | {vw_cell} | {post['updated_at']} |"