mirror of
https://github.com/1c7/chinese-independent-developer.git
synced 2026-04-18 16:24:33 +08:00
Compare commits
2 Commits
master
...
batch-add-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6dfd6b27e | ||
|
|
66b4102335 |
168
.github/scripts/process_item.py
vendored
168
.github/scripts/process_item.py
vendored
@@ -1,4 +1,3 @@
|
||||
# 自动扫描 GitHub Issues 中被标记为 🚀 的项目提交,通过 AI 格式化后批量添加到 README 并创建 Pull Request。
|
||||
import os
|
||||
import re
|
||||
import datetime
|
||||
@@ -80,97 +79,67 @@ def get_ai_project_line(raw_text):
|
||||
)
|
||||
return response.choices[0].message.content.strip()
|
||||
|
||||
def check_reactions(item):
|
||||
"""检查对象(Issue 或 IssueComment)是否有触发表情且没有成功标记"""
|
||||
reactions = item.get_reactions()
|
||||
has_trigger = any(r.content == TRIGGER_EMOJI and r.user.login == ADMIN_HANDLE for r in reactions)
|
||||
has_success = any(r.content == SUCCESS_EMOJI for r in reactions)
|
||||
return has_trigger, has_success
|
||||
|
||||
def main():
|
||||
# 检查环境变量
|
||||
check_environment()
|
||||
|
||||
g = Github(PAT_TOKEN)
|
||||
repo = g.get_repo(REPO_NAME)
|
||||
|
||||
# ===== 阶段 1:收集待处理项 (Issue 160 评论 + 其他 Open Issue) =====
|
||||
pending_items = [] # 存储 (item_object, parent_issue_object)
|
||||
issue = repo.get_issue(ISSUE_NUMBER)
|
||||
|
||||
# 1.1 处理 Issue 160 的评论 (Legacy)
|
||||
issue160 = repo.get_issue(ISSUE_NUMBER)
|
||||
time_threshold = datetime.now(timezone.utc) - timedelta(days=3)
|
||||
comments160 = issue160.get_comments(since=time_threshold)
|
||||
for comment in comments160:
|
||||
has_t, has_s = check_reactions(comment)
|
||||
if has_t and not has_s:
|
||||
pending_items.append((comment, issue160))
|
||||
comments = issue.get_comments(since=time_threshold)
|
||||
|
||||
# 1.2 扫描所有其他 Open Issue
|
||||
open_issues = repo.get_issues(state='open')
|
||||
comment_time_threshold = datetime.now(timezone.utc) - timedelta(days=7)
|
||||
|
||||
for issue in open_issues:
|
||||
if issue.number == ISSUE_NUMBER:
|
||||
continue
|
||||
|
||||
# 1. 检查 Issue Body
|
||||
has_t, has_s = check_reactions(issue)
|
||||
if has_t and not has_s:
|
||||
pending_items.append((issue, issue))
|
||||
|
||||
# 2. 检查最近 7 天的所有评论
|
||||
comments = issue.get_comments(since=comment_time_threshold)
|
||||
for comment in comments:
|
||||
has_t, has_s = check_reactions(comment)
|
||||
if has_t and not has_s:
|
||||
pending_items.append((comment, issue))
|
||||
# ===== 阶段 1:收集待处理评论 =====
|
||||
pending_comments = []
|
||||
formatted_entries = []
|
||||
|
||||
if not pending_items:
|
||||
print("无待处理项")
|
||||
for comment in comments:
|
||||
reactions = comment.get_reactions()
|
||||
has_trigger = any(r.content == TRIGGER_EMOJI and r.user.login == ADMIN_HANDLE for r in reactions)
|
||||
has_success = any(r.content == SUCCESS_EMOJI for r in reactions)
|
||||
|
||||
if has_trigger and not has_success:
|
||||
print(f"\n{'='*60}")
|
||||
print(f"处理评论:\n{comment.body}")
|
||||
print(f"\n评论链接:{comment.html_url}")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
cleaned_body = remove_quote_blocks(comment.body)
|
||||
|
||||
# 判断用户是否自带了 Header
|
||||
header_match = re.search(r'^####\s+.*', cleaned_body, re.MULTILINE)
|
||||
|
||||
if header_match:
|
||||
header_line = header_match.group(0).strip()
|
||||
body_for_ai = cleaned_body.replace(header_line, "").strip()
|
||||
print(f"检测到用户自带 Header: {header_line}")
|
||||
else:
|
||||
author_name = comment.user.login
|
||||
author_url = comment.user.html_url
|
||||
header_line = f"#### {author_name} - [Github]({author_url})"
|
||||
body_for_ai = cleaned_body
|
||||
print(f"自动生成 Header: {header_line}")
|
||||
|
||||
# AI 处理项目详情行
|
||||
project_line = get_ai_project_line(body_for_ai)
|
||||
formatted_entry = f"{header_line}\n{project_line}"
|
||||
|
||||
pending_comments.append(comment)
|
||||
formatted_entries.append(formatted_entry)
|
||||
|
||||
# ===== 阶段 2:批量提交 =====
|
||||
if not pending_comments:
|
||||
print("无待处理评论")
|
||||
return
|
||||
|
||||
print(f"\n共收集 {len(pending_items)} 个待处理项")
|
||||
print(f"\n共收集 {len(pending_comments)} 个待处理评论")
|
||||
|
||||
# ===== 阶段 2:格式化和 AI 处理 =====
|
||||
formatted_entries = []
|
||||
processed_items = [] # 用于最后标记和回复
|
||||
|
||||
for obj, parent in pending_items:
|
||||
print(f"\n{'='*60}")
|
||||
print(f"处理项目:来自 {parent.html_url}")
|
||||
print(f"内容:\n{obj.body[:200]}...")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
cleaned_body = remove_quote_blocks(obj.body)
|
||||
|
||||
# 判断用户是否自带了 Header
|
||||
header_match = re.search(r'^####\s+.*', cleaned_body, re.MULTILINE)
|
||||
|
||||
if header_match:
|
||||
header_line = header_match.group(0).strip()
|
||||
body_for_ai = cleaned_body.replace(header_line, "").strip()
|
||||
print(f"检测到用户自带 Header: {header_line}")
|
||||
else:
|
||||
author_name = obj.user.login
|
||||
author_url = obj.user.html_url
|
||||
header_line = f"#### {author_name} - [Github]({author_url})"
|
||||
body_for_ai = cleaned_body
|
||||
print(f"自动生成 Header: {header_line}")
|
||||
|
||||
# AI 处理项目详情行
|
||||
project_line = get_ai_project_line(body_for_ai)
|
||||
formatted_entry = f"{header_line}\n{project_line}"
|
||||
|
||||
formatted_entries.append(formatted_entry)
|
||||
processed_items.append((obj, parent, formatted_entry))
|
||||
|
||||
# ===== 阶段 3:批量提交 =====
|
||||
# 更新 README
|
||||
content = repo.get_contents("README.md", ref="master")
|
||||
readme_text = content.decoded_content.decode("utf-8")
|
||||
|
||||
today_str = datetime.now().strftime("%Y 年 %-m 月 %-d 号添加")
|
||||
today_str = datetime.now().strftime("%Y 年 %m 月 %d 号添加")
|
||||
date_header = f"### {today_str}"
|
||||
|
||||
if date_header not in readme_text:
|
||||
@@ -180,8 +149,8 @@ def main():
|
||||
|
||||
# 插入所有条目(用两个换行分隔)
|
||||
insertion_point = new_readme.find(date_header) + len(date_header)
|
||||
all_entries_str = "\n\n".join(formatted_entries)
|
||||
final_readme = new_readme[:insertion_point] + "\n\n" + all_entries_str + new_readme[insertion_point:]
|
||||
all_entries = "\n\n".join(formatted_entries)
|
||||
final_readme = new_readme[:insertion_point] + "\n\n" + all_entries + new_readme[insertion_point:]
|
||||
|
||||
# 创建分支
|
||||
branch_name = f"batch-add-projects-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
||||
@@ -195,27 +164,27 @@ def main():
|
||||
repo.create_git_ref(ref=f"refs/heads/{branch_name}", sha=base.commit.sha)
|
||||
repo.update_file(
|
||||
"README.md",
|
||||
f"docs: batch add {len(processed_items)} projects",
|
||||
f"docs: batch add {len(pending_comments)} projects",
|
||||
final_readme,
|
||||
content.sha,
|
||||
branch=branch_name
|
||||
)
|
||||
|
||||
# 构建 PR body
|
||||
item_links = "\n".join([
|
||||
f"- [{obj.user.login}]({obj.html_url})"
|
||||
for obj, parent, entry in processed_items
|
||||
comment_links = "\n".join([
|
||||
f"- [{c.user.login}]({c.html_url})"
|
||||
for c in pending_comments
|
||||
])
|
||||
|
||||
formatted_list = "\n\n".join([
|
||||
f"### {i+1}. {entry}"
|
||||
for i, (obj, parent, entry) in enumerate(processed_items)
|
||||
f"### {i+1}. {formatted_entries[i]}"
|
||||
for i in range(len(formatted_entries))
|
||||
])
|
||||
|
||||
pr_body = f"""批量添加 {len(processed_items)} 个项目
|
||||
pr_body = f"""批量添加 {len(pending_comments)} 个项目
|
||||
|
||||
## 原始链接
|
||||
{item_links}
|
||||
## 原始评论链接
|
||||
{comment_links}
|
||||
|
||||
## 格式化结果
|
||||
{formatted_list}
|
||||
@@ -225,7 +194,7 @@ def main():
|
||||
"""
|
||||
|
||||
pr = repo.create_pull(
|
||||
title=f"新增项目:批量添加 {len(processed_items)} 个项目",
|
||||
title=f"新增项目:批量添加 {len(pending_comments)} 个项目",
|
||||
body=pr_body,
|
||||
head=branch_name,
|
||||
base="master"
|
||||
@@ -233,25 +202,16 @@ def main():
|
||||
|
||||
print(f"\n✅ PR 创建成功:{pr.html_url}")
|
||||
|
||||
# ===== 阶段 4:标记成功并回复 =====
|
||||
replies = {} # parent_issue -> set of users
|
||||
# 标记所有评论(添加 🎉 表情)
|
||||
for comment in pending_comments:
|
||||
comment.create_reaction(SUCCESS_EMOJI)
|
||||
|
||||
for obj, parent, entry in processed_items:
|
||||
# 标记所有条目(添加 🎉 表情)
|
||||
obj.create_reaction(SUCCESS_EMOJI)
|
||||
|
||||
# 收集需要回复的 Issue 和用户
|
||||
if parent not in replies:
|
||||
replies[parent] = set()
|
||||
replies[parent].add(obj.user.login)
|
||||
# 创建一条评论提及所有用户
|
||||
user_mentions = " ".join([f"@{c.user.login}" for c in pending_comments])
|
||||
reply_body = f"{user_mentions} 感谢提交,已添加!\n\n PR 链接:{pr.html_url}"
|
||||
issue.create_comment(reply_body)
|
||||
|
||||
# 分别在各 Issue 回复
|
||||
for parent, users in replies.items():
|
||||
user_mentions = " ".join([f"@{u}" for u in users])
|
||||
reply_body = f"{user_mentions} 感谢提交,已添加!\n\n PR 链接:{pr.html_url}"
|
||||
parent.create_comment(reply_body)
|
||||
|
||||
print(f"\n✅ 已在 {len(replies)} 个 Issue 中标记并回复")
|
||||
print(f"\n✅ 已标记所有 {len(pending_comments)} 个评论")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
22
.gitignore
vendored
22
.gitignore
vendored
@@ -1,21 +1 @@
|
||||
# 环境变量
|
||||
.env
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.pyo
|
||||
*.pyd
|
||||
.Python
|
||||
|
||||
# 虚拟环境
|
||||
.venv/
|
||||
venv/
|
||||
env/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
.env
|
||||
@@ -1,57 +0,0 @@
|
||||
# 如何提交项目
|
||||
|
||||
## 格式模板
|
||||
|
||||
```
|
||||
#### 制作者名字(城市名) - [Github](), [博客]()
|
||||
* :white_check_mark: [产品名称](网址):简短的介绍,尽量把事情说清楚 - [更多介绍]()
|
||||
```
|
||||
|
||||
城市名、Github、博客、更多介绍均为可选项。
|
||||
|
||||
## 格式模板 - 最精简的版本(只保留必填项)
|
||||
|
||||
```
|
||||
#### 制作者名字
|
||||
* :white_check_mark: [产品名称](网址):简短的介绍,尽量把事情说清楚
|
||||
```
|
||||
|
||||
## 填写示例
|
||||
|
||||
```
|
||||
#### 张三(上海) - [Github](https://github.com/zhangsan)
|
||||
* :white_check_mark: [VoiceClone](https://voiceclone.com):AI 语音克隆工具,3 秒克隆任何声音,支持中英日韩等 10 种语言
|
||||
```
|
||||
|
||||
```
|
||||
#### 李四 - [Github](https://github.com/lisi)
|
||||
* :white_check_mark: [MarkdownToWord](https://markdowntoword.com):Markdown 转 Word/PDF 工具,支持 LaTeX 公式和 Mermaid 图表,浏览器本地处理无需注册
|
||||
```
|
||||
|
||||
```
|
||||
#### 王五(深圳) - [Github](https://github.com/wangwu), [博客](https://wangwu.com)
|
||||
* :white_check_mark: [BookmarkPro](https://bookmarkpro.com):Chrome 书签管理插件,替代默认新标签页,支持文件夹卡片视图和拖拽排序 - [更多介绍](https://bookmarkpro.com/features)
|
||||
```
|
||||
|
||||
## 如何写好一句话介绍
|
||||
|
||||
**先定性,再加分**:开头先用最短的词说清楚产品是什么,然后说让你与众不同的地方。
|
||||
|
||||
```
|
||||
[产品类型],[核心价值或独特之处]
|
||||
```
|
||||
|
||||
以下是来自本列表的真实优秀例子,供参考:
|
||||
|
||||
- `AI 语音克隆工具,3 秒克隆任何声音,支持中英日韩等 10 种语言,提供 50+ 预设声音库`
|
||||
- `图片压缩工具,70%+ 压缩率同时保持画质,支持 PNG/JPEG/WebP 批量处理,纯本地运行不上传`
|
||||
- `Chrome 书签管理插件,替代默认新标签页,支持文件夹卡片视图、拖拽排序和批量操作`
|
||||
- `Markdown 转 Word/PDF 工具,支持 LaTeX 公式和 Mermaid 图表,浏览器本地处理无需注册`
|
||||
- `AI 数据工作台,支持 MySQL/Postgres/SQLite/Clickhouse,可替代 DBeaver 和 Navicat`
|
||||
- `Mac 菜单栏速记工具,全局悬浮不切屏,支持图文混排和一键调出剪贴板历史`
|
||||
- `AI Agent 安全沙箱,一条命令让 Claude Code、Codex 等 Agent 在完全隔离容器中运行,宿主机零风险`
|
||||
- `多人聚会地点推荐工具,输入多人地址自动计算公平中点,覆盖 350+ 城市,免费无需注册`
|
||||
- `多语言听力练习 App,支持导入 Podcast 和 YouTube 链接,提供双语字幕和跟读练习`
|
||||
- `极简表达平台,无账号、无互动、不留痕迹,适合"说出来就放下"的轻量表达需求`
|
||||
|
||||
没有独特之处时,加具体数字或使用限制(免费、无需注册、本地处理)也能让介绍语更有价值。
|
||||
@@ -2,26 +2,6 @@
|
||||
|
||||
本版面放的都是游戏,起始于2025年1月4号
|
||||
|
||||
|
||||
### 2026 年 2 月 4 号添加
|
||||
#### Shawn (北京) - [Github](https://github.com/ShawnHacks), [博客](https://indietion.com)
|
||||
* :white_check_mark: [Arcraiders.website](https://arcraiders.website):ARC raiders 游戏工具网站,功能比较丰富全面 - [更多介绍](https://arcraiders.website/quests)
|
||||
|
||||
### 2026 年 1 月 10 号添加
|
||||
|
||||
#### 290713469 - [Github](https://github.com/290713469)
|
||||
* :white_check_mark: [Star Rupture Calculator](https://starrupture-tools.com/):Stream 游戏 Star Rupture 工具网站
|
||||
|
||||
### 2026 年 1 月 7 号添加
|
||||
#### 290713469 - [Github](https://github.com/290713469)
|
||||
* :white_check_mark: [Obsessed Trace Calculator](https://obsessedtrace.com/):Stream 游戏 Obsessed Trace 工具网站
|
||||
|
||||
### 2026 年 1 月 4 号添加
|
||||
#### Ivanvolt(武汉) - [博客](https://ivanvolt.com),[Github](https://github.com/ivanvolt-labs)
|
||||
* :white_check_mark: [Square Face Generator](https://squarefacegenerator.co):生成方脸头像
|
||||
* :white_check_mark: [UB Games](https://ubgames.co):免费浏览器游戏
|
||||
* :white_check_mark: [Wenda Treatment](https://wendatreatment.com):暗黑音乐之旅
|
||||
|
||||
### 2026 年 1 月 3 号添加
|
||||
#### 290713469 - [Github](https://github.com/290713469)
|
||||
* :white_check_mark: [Anime Fighting Simulator Calculator](https://anime-fighting-simulator.com):Roblox Anime Fighting Simulator游戏工具
|
||||
|
||||
@@ -16,44 +16,6 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
|
||||
程序员版开始于 2019 年 4 月 11 号, 主版面开始于 2018 年 3 月
|
||||
-->
|
||||
|
||||
### 2026 年 4 月 10 号添加
|
||||
|
||||
#### nowork-studio - [Github](https://github.com/nowork-studio)
|
||||
* :white_check_mark: [toprank](https://github.com/nowork-studio/toprank):开源(MIT)的 Claude Code 插件,提供 9 个 SEO 和 Google Ads 技能。连接 Google Search Console、PageSpeed Insights、Google Ads API,自动重写 meta 标签、生成 JSON-LD 结构化数据,并将修改直接推送到 WordPress/Strapi/Contentful/Ghost。107 stars
|
||||
|
||||
### 2026 年 4 月 8 号添加
|
||||
|
||||
#### SunflowersLwtech - [Github](https://github.com/SunflowersLwtech)
|
||||
* :white_check_mark: [polanyi-design](https://github.com/SunflowersLwtech/polanyi-design):基于 Michael Polanyi 默会知识理论的前端设计认知引擎 Claude Code Skill,让 AI 生成有审美判断力的 UI 设计而非模板化输出 - [更多介绍](https://sunflowerslwtech.github.io/polanyi-design/showcase/)
|
||||
|
||||
### 2026 年 3 月 30 号添加
|
||||
|
||||
#### yanglian(珠海) - [Github](https://github.com/lian-yang)
|
||||
* :white_check_mark: [trans](https://github.com/lian-yang/trans):基于 OpenAI 兼容 API 的终端 AI 翻译工具,管道友好,即装即用
|
||||
|
||||
### 2026 年 3 月 25 号添加
|
||||
|
||||
#### Moresl - [Github](https://github.com/Moresl)
|
||||
* :white_check_mark: [CCHub](https://github.com/Moresl/cchub):Claude Code 生态管理平台,支持 MCP 服务器管理、Skill 技能管理、多配置切换、自定义 Slash Command 等功能,基于 Tauri v2 构建的桌面应用
|
||||
|
||||
### 2026 年 3 月 21 号添加
|
||||
|
||||
#### raullenchai - [Github](https://github.com/raullenchai)
|
||||
* :white_check_mark: [Rapid-MLX](https://github.com/raullenchai/Rapid-MLX):Apple Silicon 上最快的本地 AI 推理引擎,OpenAI API 兼容,比 Ollama 快 2-4 倍,支持 17 种工具调用解析器、推理分离、视觉模型和语音功能
|
||||
|
||||
### 2026 年 3 月 10 号添加
|
||||
|
||||
#### my19940202(上海) - [Github](https://github.com/my19940202)
|
||||
* :white_check_mark: [Cursor带我学英语](https://github.com/my19940202/cursor-thinking-stat):本地采集cursor对话英语语料信息,通过可视化方式分析,辅助程序员提升技术英语的学习,辅助写好英语prompt
|
||||
|
||||
### 2026 年 3 月 1 号添加
|
||||
#### @leodenglovescode(北京) - [Github](https://github.com/leodenglovescode), [博客](https://leodeng.dev)
|
||||
* :white_check_mark: [pm2-webmanager](https://github.com/leodenglovescode/pm2-webmanager):基于HTML和JS的新一代PM2进程管理器,简易上手。A modern, light-weight web manager for all your PM2 processes
|
||||
|
||||
### 2026 年 1 月 14 号添加
|
||||
#### 草梅友仁 - [Github](https://github.com/CaoMeiYouRen), [博客](https://momei.app/)
|
||||
* :white_check_mark: [墨梅博客](https://github.com/CaoMeiYouRen/momei):博客平台,专为技术开发者和跨境内容创作者量身定制。专业、高性能、国际化 - [更多介绍](https://docs.momei.app/)
|
||||
|
||||
### 2025 年 12 月 2 号添加
|
||||
#### phishdestroy - [GitHub](https://github.com/phishdestroy)
|
||||
* :white_check_mark: [Destroylist](https://github.com/phishdestroy/destroylist):Auto-updating phishing blacklist for threat intelligence
|
||||
@@ -147,7 +109,7 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
|
||||
|
||||
### 2025 年 5 月 13 号添加
|
||||
#### masz
|
||||
* :x: [ui2vue](https://www.ui2vue.cn):生成 vue3 代码的工具网站,支持拖拽&编辑方式添加组件,可直接导出vue3代码
|
||||
* :white_check_mark: [ui2vue](https://www.ui2vue.cn):生成 vue3 代码的工具网站,支持拖拽&编辑方式添加组件,可直接导出vue3代码
|
||||
|
||||
### 2025 年 5 月 11 号添加
|
||||
#### 草梅友仁 - [Github](https://github.com/CaoMeiYouRen), [博客](https://blog.cmyr.ltd/)
|
||||
@@ -186,7 +148,7 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
|
||||
|
||||
### 2025 年 3 月 17 号添加
|
||||
#### dodid - [Github](https://github.com/dodid)
|
||||
* :x: [PAC代理自动配置管理器](https://github.com/dodid/pac-proxy-manager):管理代理自动配置文件(PAC),支持灵活的代理规则设置
|
||||
* :white_check_mark: [PAC代理自动配置管理器](https://github.com/dodid/pac-proxy-manager):管理代理自动配置文件(PAC),支持灵活的代理规则设置
|
||||
|
||||
### 2025 年 2 月 10 号添加
|
||||
#### yvling(合肥) - [Github](https://github.com/yv1ing), [博客](https://blog.yvling.cn)
|
||||
@@ -766,5 +728,5 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
|
||||
* :white_check_mark: [Image2ASCII](https://github.com/qeesung/image2ascii.git) : 图片转化为 ASCII 码的命令行工具
|
||||
* :white_check_mark: [ASCIIPlayer](https://github.com/qeesung/asciiplayer) : 图片,GIF,视屏 ASCII 转化播放命令行工具
|
||||
|
||||
#### 袁慠棱 - [Github](https://github.com/alengYuan), [博客](http://slothindie.org/)
|
||||
* :x: [LemonTea](http://lemontea.slothindie.org/):极简且特别的静态网站生成器 - [更多介绍](http://lemontea.slothindie.org/book/index.html)
|
||||
#### 袁慠棱(南京) - [Github](https://github.com/alengYuan), [博客](http://slothindie.org/)
|
||||
* :white_check_mark: [LemonTea](http://lemontea.slothindie.org/):极简且特别的静态网站生成器 - [更多介绍](http://lemontea.slothindie.org/book/index.html)
|
||||
|
||||
Reference in New Issue
Block a user