Merge pull request #6 from 1c7/master

同步Repo
This commit is contained in:
超能刚哥
2026-03-25 11:12:45 +08:00
committed by GitHub
4 changed files with 806 additions and 356 deletions

View File

@@ -1,3 +1,4 @@
# 自动扫描 GitHub Issues 中被标记为 🚀 的项目提交,通过 AI 格式化后批量添加到 README 并创建 Pull Request。
import os import os
import re import re
import datetime import datetime
@@ -79,62 +80,92 @@ def get_ai_project_line(raw_text):
) )
return response.choices[0].message.content.strip() 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(): def main():
# 检查环境变量 # 检查环境变量
check_environment() check_environment()
g = Github(PAT_TOKEN) g = Github(PAT_TOKEN)
repo = g.get_repo(REPO_NAME) repo = g.get_repo(REPO_NAME)
issue = repo.get_issue(ISSUE_NUMBER)
# ===== 阶段 1收集待处理项 (Issue 160 评论 + 其他 Open Issue) =====
pending_items = [] # 存储 (item_object, parent_issue_object)
# 1.1 处理 Issue 160 的评论 (Legacy)
issue160 = repo.get_issue(ISSUE_NUMBER)
time_threshold = datetime.now(timezone.utc) - timedelta(days=3) time_threshold = datetime.now(timezone.utc) - timedelta(days=3)
comments = issue.get_comments(since=time_threshold) 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))
# ===== 阶段 1收集待处理评论 ===== # 1.2 扫描所有其他 Open Issue
pending_comments = [] open_issues = repo.get_issues(state='open')
formatted_entries = [] comment_time_threshold = datetime.now(timezone.utc) - timedelta(days=7)
for comment in comments: for issue in open_issues:
reactions = comment.get_reactions() if issue.number == ISSUE_NUMBER:
has_trigger = any(r.content == TRIGGER_EMOJI and r.user.login == ADMIN_HANDLE for r in reactions) continue
has_success = any(r.content == SUCCESS_EMOJI for r in reactions)
if has_trigger and not has_success: # 1. 检查 Issue Body
print(f"\n{'='*60}") has_t, has_s = check_reactions(issue)
print(f"处理评论:\n{comment.body}") if has_t and not has_s:
print(f"\n评论链接:{comment.html_url}") pending_items.append((issue, issue))
print(f"{'='*60}\n")
cleaned_body = remove_quote_blocks(comment.body) # 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))
# 判断用户是否自带了 Header if not pending_items:
header_match = re.search(r'^####\s+.*', cleaned_body, re.MULTILINE) print("无待处理项")
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 return
print(f"\n共收集 {len(pending_comments)} 个待处理评论") print(f"\n共收集 {len(pending_items)} 个待处理")
# ===== 阶段 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 # 更新 README
content = repo.get_contents("README.md", ref="master") content = repo.get_contents("README.md", ref="master")
readme_text = content.decoded_content.decode("utf-8") readme_text = content.decoded_content.decode("utf-8")
@@ -149,8 +180,8 @@ def main():
# 插入所有条目(用两个换行分隔) # 插入所有条目(用两个换行分隔)
insertion_point = new_readme.find(date_header) + len(date_header) insertion_point = new_readme.find(date_header) + len(date_header)
all_entries = "\n\n".join(formatted_entries) all_entries_str = "\n\n".join(formatted_entries)
final_readme = new_readme[:insertion_point] + "\n\n" + all_entries + new_readme[insertion_point:] final_readme = new_readme[:insertion_point] + "\n\n" + all_entries_str + new_readme[insertion_point:]
# 创建分支 # 创建分支
branch_name = f"batch-add-projects-{datetime.now().strftime('%Y%m%d-%H%M%S')}" branch_name = f"batch-add-projects-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
@@ -164,27 +195,27 @@ def main():
repo.create_git_ref(ref=f"refs/heads/{branch_name}", sha=base.commit.sha) repo.create_git_ref(ref=f"refs/heads/{branch_name}", sha=base.commit.sha)
repo.update_file( repo.update_file(
"README.md", "README.md",
f"docs: batch add {len(pending_comments)} projects", f"docs: batch add {len(processed_items)} projects",
final_readme, final_readme,
content.sha, content.sha,
branch=branch_name branch=branch_name
) )
# 构建 PR body # 构建 PR body
comment_links = "\n".join([ item_links = "\n".join([
f"- [{c.user.login}]({c.html_url})" f"- [{obj.user.login}]({obj.html_url})"
for c in pending_comments for obj, parent, entry in processed_items
]) ])
formatted_list = "\n\n".join([ formatted_list = "\n\n".join([
f"### {i+1}. {formatted_entries[i]}" f"### {i+1}. {entry}"
for i in range(len(formatted_entries)) for i, (obj, parent, entry) in enumerate(processed_items)
]) ])
pr_body = f"""批量添加 {len(pending_comments)} 个项目 pr_body = f"""批量添加 {len(processed_items)} 个项目
## 原始评论链接 ## 原始链接
{comment_links} {item_links}
## 格式化结果 ## 格式化结果
{formatted_list} {formatted_list}
@@ -194,7 +225,7 @@ def main():
""" """
pr = repo.create_pull( pr = repo.create_pull(
title=f"新增项目:批量添加 {len(pending_comments)} 个项目", title=f"新增项目:批量添加 {len(processed_items)} 个项目",
body=pr_body, body=pr_body,
head=branch_name, head=branch_name,
base="master" base="master"
@@ -202,16 +233,25 @@ def main():
print(f"\n✅ PR 创建成功:{pr.html_url}") print(f"\n✅ PR 创建成功:{pr.html_url}")
# 标记所有评论(添加 🎉 表情) # ===== 阶段 4标记成功并回复 =====
for comment in pending_comments: replies = {} # parent_issue -> set of users
comment.create_reaction(SUCCESS_EMOJI)
# 创建一条评论提及所有用户 for obj, parent, entry in processed_items:
user_mentions = " ".join([f"@{c.user.login}" for c in pending_comments]) # 标记所有条目(添加 🎉 表情)
reply_body = f"{user_mentions} 感谢提交,已添加!\n\n PR 链接:{pr.html_url}" obj.create_reaction(SUCCESS_EMOJI)
issue.create_comment(reply_body)
print(f"\n✅ 已标记所有 {len(pending_comments)} 个评论") # 收集需要回复的 Issue 和用户
if parent not in replies:
replies[parent] = set()
replies[parent].add(obj.user.login)
# 分别在各 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 中标记并回复")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -2,6 +2,11 @@
本版面放的都是游戏起始于2025年1月4号 本版面放的都是游戏起始于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 号添加 ### 2026 年 1 月 10 号添加
#### 290713469 - [Github](https://github.com/290713469) #### 290713469 - [Github](https://github.com/290713469)

View File

@@ -16,6 +16,20 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
程序员版开始于 2019 年 4 月 11 号, 主版面开始于 2018 年 3 月 程序员版开始于 2019 年 4 月 11 号, 主版面开始于 2018 年 3 月
--> -->
### 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 号添加 ### 2026 年 1 月 14 号添加
#### 草梅友仁 - [Github](https://github.com/CaoMeiYouRen), [博客](https://momei.app/) #### 草梅友仁 - [Github](https://github.com/CaoMeiYouRen), [博客](https://momei.app/)
* :white_check_mark: [墨梅博客](https://github.com/CaoMeiYouRen/momei):博客平台,专为技术开发者和跨境内容创作者量身定制。专业、高性能、国际化 - [更多介绍](https://docs.momei.app/) * :white_check_mark: [墨梅博客](https://github.com/CaoMeiYouRen/momei):博客平台,专为技术开发者和跨境内容创作者量身定制。专业、高性能、国际化 - [更多介绍](https://docs.momei.app/)
@@ -113,7 +127,7 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
### 2025 年 5 月 13 号添加 ### 2025 年 5 月 13 号添加
#### masz #### masz
* :white_check_mark: [ui2vue](https://www.ui2vue.cn):生成 vue3 代码的工具网站,支持拖拽&编辑方式添加组件可直接导出vue3代码 * :x: [ui2vue](https://www.ui2vue.cn):生成 vue3 代码的工具网站,支持拖拽&编辑方式添加组件可直接导出vue3代码
### 2025 年 5 月 11 号添加 ### 2025 年 5 月 11 号添加
#### 草梅友仁 - [Github](https://github.com/CaoMeiYouRen), [博客](https://blog.cmyr.ltd/) #### 草梅友仁 - [Github](https://github.com/CaoMeiYouRen), [博客](https://blog.cmyr.ltd/)
@@ -152,7 +166,7 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
### 2025 年 3 月 17 号添加 ### 2025 年 3 月 17 号添加
#### dodid - [Github](https://github.com/dodid) #### dodid - [Github](https://github.com/dodid)
* :white_check_mark: [PAC代理自动配置管理器](https://github.com/dodid/pac-proxy-manager)管理代理自动配置文件PAC支持灵活的代理规则设置 * :x: [PAC代理自动配置管理器](https://github.com/dodid/pac-proxy-manager)管理代理自动配置文件PAC支持灵活的代理规则设置
### 2025 年 2 月 10 号添加 ### 2025 年 2 月 10 号添加
#### yvling(合肥) - [Github](https://github.com/yv1ing), [博客](https://blog.yvling.cn) #### yvling(合肥) - [Github](https://github.com/yv1ing), [博客](https://blog.yvling.cn)
@@ -732,5 +746,5 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
* :white_check_mark: [Image2ASCII](https://github.com/qeesung/image2ascii.git) : 图片转化为 ASCII 码的命令行工具 * :white_check_mark: [Image2ASCII](https://github.com/qeesung/image2ascii.git) : 图片转化为 ASCII 码的命令行工具
* :white_check_mark: [ASCIIPlayer](https://github.com/qeesung/asciiplayer) : 图片GIF视屏 ASCII 转化播放命令行工具 * :white_check_mark: [ASCIIPlayer](https://github.com/qeesung/asciiplayer) : 图片GIF视屏 ASCII 转化播放命令行工具
#### 袁慠棱(南京) - [Github](https://github.com/alengYuan), [博客](http://slothindie.org/) #### 袁慠棱 - [Github](https://github.com/alengYuan), [博客](http://slothindie.org/)
* :white_check_mark: [LemonTea](http://lemontea.slothindie.org/):极简且特别的静态网站生成器 - [更多介绍](http://lemontea.slothindie.org/book/index.html) * :x: [LemonTea](http://lemontea.slothindie.org/):极简且特别的静态网站生成器 - [更多介绍](http://lemontea.slothindie.org/book/index.html)

969
README.md

File diff suppressed because it is too large Load Diff