mirror of
https://github.com/1c7/chinese-independent-developer.git
synced 2026-04-05 01:54:25 +08:00
Compare commits
345 Commits
add-projec
...
batch-add-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ec40ead7c | ||
|
|
583ca06a95 | ||
|
|
32c94d91fc | ||
|
|
3162434372 | ||
|
|
cff1058553 | ||
|
|
ed4c1a1f73 | ||
|
|
6f628d4a91 | ||
|
|
11dacb34f4 | ||
|
|
44dc18735e | ||
|
|
9f9984870d | ||
|
|
916331803e | ||
|
|
d7907b97f1 | ||
|
|
df87ece706 | ||
|
|
b51dd23010 | ||
|
|
dd8cedcac2 | ||
|
|
02f8400d9d | ||
|
|
f08df6bf38 | ||
|
|
716d754e5c | ||
|
|
699208d341 | ||
|
|
5af8e8de78 | ||
|
|
98070d9058 | ||
|
|
3f9cdacece | ||
|
|
85b130c284 | ||
|
|
edc41f5ae5 | ||
|
|
09453854c7 | ||
|
|
0eb795dcd2 | ||
|
|
b6cc5fa810 | ||
|
|
952f4e58c4 | ||
|
|
27a6726d15 | ||
|
|
f510e47feb | ||
|
|
3c84aea229 | ||
|
|
d6305984d5 | ||
|
|
23e90d602c | ||
|
|
8474f2eb69 | ||
|
|
9b3f431951 | ||
|
|
095b8c2798 | ||
|
|
e67ce1eb0b | ||
|
|
64eb5626c3 | ||
|
|
64f2d5c511 | ||
|
|
d604ce0711 | ||
|
|
de2d83a412 | ||
|
|
a06426d446 | ||
|
|
f5cec1ea05 | ||
|
|
71d4574dc7 | ||
|
|
a3a7699ab4 | ||
|
|
d4c2c4f9d5 | ||
|
|
2c7fa289e3 | ||
|
|
3ca3cd43c2 | ||
|
|
57b3d25c0f | ||
|
|
ff2918ce56 | ||
|
|
0929d713ec | ||
|
|
7deb764171 | ||
|
|
fe6773e86a | ||
|
|
5d95790028 | ||
|
|
fbe5c9ecd7 | ||
|
|
f2944627f5 | ||
|
|
c2a0edacd9 | ||
|
|
5e3caa67c2 | ||
|
|
c30aa3dd46 | ||
|
|
6a200863d0 | ||
|
|
eca65a70f8 | ||
|
|
d7d4f9ef32 | ||
|
|
0312dc6f8d | ||
|
|
374e8673bc | ||
|
|
19eb3d9e3e | ||
|
|
58ca525341 | ||
|
|
4e940e6778 | ||
|
|
13ae35820a | ||
|
|
2a47ef63c8 | ||
|
|
d5d02f1550 | ||
|
|
c0b1bf6009 | ||
|
|
07fd3b1814 | ||
|
|
53f6237240 | ||
|
|
50d718f86e | ||
|
|
66dd329c65 | ||
|
|
f4a128bafa | ||
|
|
d2bbf4519c | ||
|
|
f8fb52f586 | ||
|
|
1dcee5904b | ||
|
|
bdc3fcee3f | ||
|
|
a0e839f67f | ||
|
|
e719744bb5 | ||
|
|
2efa801111 | ||
|
|
c60f7635c3 | ||
|
|
cee1e8b72e | ||
|
|
748b7fe54d | ||
|
|
273a19c578 | ||
|
|
6b4d6f3451 | ||
|
|
65c9a5c6f1 | ||
|
|
2b9ac64846 | ||
|
|
c3f821136f | ||
|
|
c470c3431a | ||
|
|
dcb04d0e20 | ||
|
|
ccbc5b378f | ||
|
|
ee7609e1dd | ||
|
|
fe77fa82bc | ||
|
|
c0c1705c67 | ||
|
|
990c8825ce | ||
|
|
5f08db82db | ||
|
|
be7f6d96b0 | ||
|
|
f54d7673dd | ||
|
|
d3fe8fddf3 | ||
|
|
9e6e10668a | ||
|
|
93ecb728df | ||
|
|
081d03b564 | ||
|
|
5a70c7ce90 | ||
|
|
905263cbb9 | ||
|
|
fede6041f0 | ||
|
|
6ce5ec176a | ||
|
|
88e05df79f | ||
|
|
aabdc6f41b | ||
|
|
3627eb4886 | ||
|
|
7740a2a640 | ||
|
|
af7d86e7b4 | ||
|
|
30c159d0eb | ||
|
|
5f14449893 | ||
|
|
83a057a85f | ||
|
|
72fe759275 | ||
|
|
00351aa5da | ||
|
|
b634e9ca52 | ||
|
|
1ccc4b4829 | ||
|
|
ae13e9bc77 | ||
|
|
32b5a85f09 | ||
|
|
1dd96e87b4 | ||
|
|
ed68f74783 | ||
|
|
71845f2823 | ||
|
|
9f91c0bcc4 | ||
|
|
c6a43136fd | ||
|
|
40bc8dbb7c | ||
|
|
1bdc615e47 | ||
|
|
86519f7ff1 | ||
|
|
58d860782a | ||
|
|
727927bf3f | ||
|
|
5eeb3ae632 | ||
|
|
0c8c14bff8 | ||
|
|
154022589d | ||
|
|
1e9d197cd5 | ||
|
|
3235622453 | ||
|
|
5138686eb9 | ||
|
|
811afb2073 | ||
|
|
d90e4a0f5c | ||
|
|
7d88d7c58e | ||
|
|
947c02ef22 | ||
|
|
473fafb380 | ||
|
|
23012ce742 | ||
|
|
6cb46041c5 | ||
|
|
6ed8ec8ddb | ||
|
|
2a398a462c | ||
|
|
c6823641bf | ||
|
|
bad4c0dadd | ||
|
|
fcfafc097e | ||
|
|
80aaa9ef88 | ||
|
|
113d4b0a4a | ||
|
|
92991df535 | ||
|
|
267b2fe9e8 | ||
|
|
76af999078 | ||
|
|
c1b1c2f8bd | ||
|
|
b148a0f1c5 | ||
|
|
7a5c5ac123 | ||
|
|
6f1e2226f0 | ||
|
|
e20d16a226 | ||
|
|
a716db7823 | ||
|
|
6318a10106 | ||
|
|
ad2cfa1e83 | ||
|
|
885db52430 | ||
|
|
ad4c3318e9 | ||
|
|
9816f57d2e | ||
|
|
213075923d | ||
|
|
515b0b6dd2 | ||
|
|
530546c050 | ||
|
|
b0e60d56fb | ||
|
|
31285345c9 | ||
|
|
3305ddbc1c | ||
|
|
7d04449ad9 | ||
|
|
fb37ef227d | ||
|
|
c8acfb86f1 | ||
|
|
546e896e71 | ||
|
|
5fb4f0b4bf | ||
|
|
0cb521a8e4 | ||
|
|
565ac0b921 | ||
|
|
bcfba6d2d4 | ||
|
|
c0fe5b0bcf | ||
|
|
4f3fb68618 | ||
|
|
33ade60496 | ||
|
|
8b5e2f2be1 | ||
|
|
2ee99d44df | ||
|
|
932a39ab53 | ||
|
|
fc37ca156e | ||
|
|
e0aa3bd8bc | ||
|
|
416ab100f2 | ||
|
|
cfe7ed688f | ||
|
|
3dd51e6396 | ||
|
|
24d57bfedc | ||
|
|
d95fc4e5de | ||
|
|
043715b247 | ||
|
|
117ec5916e | ||
|
|
e6fff44296 | ||
|
|
28e7c9b685 | ||
|
|
9652fc86da | ||
|
|
9df82b9412 | ||
|
|
58e1291d40 | ||
|
|
ac0d20ca94 | ||
|
|
39ea10737b | ||
|
|
d020fcf45a | ||
|
|
b1ffec4e56 | ||
|
|
9c134bf4fe | ||
|
|
fdcafe22a5 | ||
|
|
7866d2acf6 | ||
|
|
274f8cf32b | ||
|
|
6ebb5fd5c0 | ||
|
|
4f49f5cffa | ||
|
|
413d91189b | ||
|
|
e08ed38943 | ||
|
|
0c86ac6d84 | ||
|
|
8361f7e2da | ||
|
|
eb30530787 | ||
|
|
a7d8b78cbc | ||
|
|
aa34750cf5 | ||
|
|
5d8279717e | ||
|
|
7e503e2076 | ||
|
|
65d6085bce | ||
|
|
4162adb056 | ||
|
|
a2c7d050f6 | ||
|
|
75fbcbafaa | ||
|
|
c5d9cdecd6 | ||
|
|
fc5adbf8dd | ||
|
|
4036a5e928 | ||
|
|
43d7a6069a | ||
|
|
4129d684e9 | ||
|
|
4af5d072a4 | ||
|
|
3d3292daeb | ||
|
|
07847f8449 | ||
|
|
c457844d3b | ||
|
|
bf9383f7c6 | ||
|
|
947ce29e9f | ||
|
|
c69ca7d1db | ||
|
|
b4925f6de1 | ||
|
|
922f039c47 | ||
|
|
146ed315df | ||
|
|
f89f72fcc3 | ||
|
|
8b4ca05b23 | ||
|
|
44bd8f60a7 | ||
|
|
7b775baee6 | ||
|
|
4d446356ac | ||
|
|
7dddaea440 | ||
|
|
441d7fbd91 | ||
|
|
2e24bd0ff6 | ||
|
|
d672241e70 | ||
|
|
21a22eea54 | ||
|
|
189df6b63a | ||
|
|
48721a48b0 | ||
|
|
a362687f00 | ||
|
|
a31142cce2 | ||
|
|
1f0c2af612 | ||
|
|
300c7e98cb | ||
|
|
a166ddf5e2 | ||
|
|
d05e4d0db8 | ||
|
|
5fef1ea516 | ||
|
|
34bb5e0809 | ||
|
|
23d67890d5 | ||
|
|
edbf4a1763 | ||
|
|
5708e95303 | ||
|
|
d606019cf5 | ||
|
|
0b8758dbf1 | ||
|
|
e81237295c | ||
|
|
2aa5011597 | ||
|
|
4ddce43e95 | ||
|
|
9730357680 | ||
|
|
6cc7969aef | ||
|
|
75edb6d3ed | ||
|
|
627f6eaad8 | ||
|
|
185659c0d8 | ||
|
|
ca9ff11043 | ||
|
|
a065b58b24 | ||
|
|
48ec90b494 | ||
|
|
fe9b1caa15 | ||
|
|
242cea6da5 | ||
|
|
556a190ecb | ||
|
|
91d8d786bb | ||
|
|
be40dd94ee | ||
|
|
7b6443a216 | ||
|
|
a6951b69bb | ||
|
|
87b5433042 | ||
|
|
d8a88884d2 | ||
|
|
bdf4cbf7cc | ||
|
|
8ca7442508 | ||
|
|
92bf35d570 | ||
|
|
7b8a33a30c | ||
|
|
73bc284c2b | ||
|
|
83706b5180 | ||
|
|
2d4c6f2196 | ||
|
|
c70cb97494 | ||
|
|
4e6798d728 | ||
|
|
cf034e8f58 | ||
|
|
41d8919ecf | ||
|
|
e73523b47c | ||
|
|
5ecacb8144 | ||
|
|
7efedebd4d | ||
|
|
59367aa18f | ||
|
|
56403b3d46 | ||
|
|
065b6219c9 | ||
|
|
4a3564f76d | ||
|
|
fd49649568 | ||
|
|
c21bdd7ba4 | ||
|
|
cb695f68e9 | ||
|
|
44b1fc02f9 | ||
|
|
14046cba12 | ||
|
|
c598b20ecf | ||
|
|
38ee2059ee | ||
|
|
c770cd781b | ||
|
|
62da88c1f6 | ||
|
|
6709929f33 | ||
|
|
9cec7b86bc | ||
|
|
d4bf5c7534 | ||
|
|
cbe2571d36 | ||
|
|
574ca1902f | ||
|
|
d0e83ceed3 | ||
|
|
385dbf3fdd | ||
|
|
356bf66be0 | ||
|
|
6392bdcb94 | ||
|
|
f70e563de8 | ||
|
|
2d273b49f3 | ||
|
|
0832737b39 | ||
|
|
30b4a27c90 | ||
|
|
4a32602922 | ||
|
|
2431927eae | ||
|
|
2b166791df | ||
|
|
7bd87d7b80 | ||
|
|
7bfc5a4d23 | ||
|
|
f1f63a4b51 | ||
|
|
c698c87087 | ||
|
|
ea155bd8d8 | ||
|
|
508bf6c3c8 | ||
|
|
3480b04a32 | ||
|
|
09b476b0bc | ||
|
|
2e133401c8 | ||
|
|
f83699c075 | ||
|
|
875fa8c111 | ||
|
|
28ae2734d0 | ||
|
|
cd2b9e2243 | ||
|
|
f12b822a55 | ||
|
|
a7604c6648 | ||
|
|
70d6df0ba7 | ||
|
|
53ef61c07e | ||
|
|
fb5331e6e2 |
28
.github/MAINTAINER.md
vendored
Normal file
28
.github/MAINTAINER.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
## 介绍 `.github/` 文件夹的用途
|
||||
|
||||
## 概括
|
||||
用户在 https://github.com/1c7/chinese-independent-developer/issues/160 提交评论。
|
||||
大部分情况下,格式是不符合规范的(可以理解)
|
||||
需要用程序自动化处理,减少我的时间投入。
|
||||
|
||||
## 流程
|
||||
1. 我(1c7)在用户提交的评论点击 🚀 图标(表情)
|
||||
1. 触发 Github Action 执行(手动触发 或 定时执行(每 6 小时)
|
||||
1. Github Action 会触发 .github/scripts/process_item.py
|
||||
2. 查找 "当前日期-3天" 开始(这个时间点往后) 所有标记 🚀 图标 的评论
|
||||
3. 处理格式,创建 Pull Request。
|
||||
4. 给评论新增一个 🎉 图标(意思是"处理完成")
|
||||
7. 回复这条评论:感谢提交,已添加。
|
||||
|
||||
我只需要修改 PR 然后 merge 就行。
|
||||
|
||||
一句话概括:我点击 🚀 标签,然后 PR 会自动创建,我只需要 merge PR。我大概点击 3 次左右就可以了(如果介绍语有改进空间,我还得改一下文字,然后才 merge)
|
||||
|
||||
## 本地运行(为了开发调试)
|
||||
```bash
|
||||
cp .env.example .env
|
||||
|
||||
uv sync
|
||||
|
||||
uv run .github/scripts/process_item.py
|
||||
```
|
||||
296
.github/scripts/process_item.py
vendored
296
.github/scripts/process_item.py
vendored
@@ -1,3 +1,4 @@
|
||||
# 自动扫描 GitHub Issues 中被标记为 🚀 的项目提交,通过 AI 格式化后批量添加到 README 并创建 Pull Request。
|
||||
import os
|
||||
import re
|
||||
import datetime
|
||||
@@ -6,16 +7,28 @@ from openai import OpenAI
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
# ================= 配置区 =================
|
||||
PAT_TOKEN = os.getenv("PAT_TOKEN")
|
||||
API_KEY = os.getenv("LLM_API_KEY")
|
||||
BASE_URL = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1")
|
||||
REPO_NAME = "1c7/chinese-independent-developer"
|
||||
ISSUE_NUMBER = 160
|
||||
ADMIN_HANDLE = "1c7"
|
||||
TRIGGER_EMOJI = "rocket" # 🚀
|
||||
SUCCESS_EMOJI = "hooray" # 🎉
|
||||
PAT_TOKEN = os.getenv("PAT_TOKEN") # GitHub Personal Access Token
|
||||
API_KEY = os.getenv("LLM_API_KEY") # LLM API 密钥(如 DeepSeek、OpenAI)
|
||||
BASE_URL = os.getenv("LLM_BASE_URL", "https://api.openai.com/v1") # LLM API 基础 URL
|
||||
REPO_NAME = "1c7/chinese-independent-developer" # GitHub 仓库名称
|
||||
ISSUE_NUMBER = 160 # 用于收集项目提交的 Issue 编号
|
||||
ADMIN_HANDLE = "1c7" # 管理员 GitHub 用户名
|
||||
TRIGGER_EMOJI = "rocket" # 触发处理的表情符号 🚀
|
||||
SUCCESS_EMOJI = "hooray" # 处理成功的表情符号 🎉
|
||||
# ==========================================
|
||||
|
||||
def check_environment():
|
||||
"""检查必需的环境变量是否存在"""
|
||||
if not PAT_TOKEN:
|
||||
raise ValueError("❌ 缺少环境变量 PAT_TOKEN!请设置 GitHub Personal Access Token。")
|
||||
if not API_KEY:
|
||||
raise ValueError("❌ 缺少环境变量 LLM_API_KEY!请设置 LLM API Key。")
|
||||
|
||||
print(f"✅ 环境变量检查通过")
|
||||
print(f" - PAT_TOKEN: {'*' * 10}{PAT_TOKEN[-4:]}")
|
||||
print(f" - API_KEY: {'*' * 10}{API_KEY[-4:]}")
|
||||
print(f" - BASE_URL: {BASE_URL}\n")
|
||||
|
||||
def remove_quote_blocks(text: str) -> str:
|
||||
"""移除 GitHub 引用回复块"""
|
||||
lines = text.split('\n')
|
||||
@@ -28,16 +41,34 @@ def remove_quote_blocks(text: str) -> str:
|
||||
return result.strip()
|
||||
|
||||
def get_ai_project_line(raw_text):
|
||||
"""只让 AI 提取项目名称、链接和描述行"""
|
||||
"""让 AI 提取项目名称、链接和描述(支持多个产品)"""
|
||||
client = OpenAI(api_key=API_KEY, base_url=BASE_URL)
|
||||
prompt = f"""
|
||||
任务:将用户的项目介绍转换为单行 Markdown 格式。
|
||||
任务:将用户的项目介绍转换为 Markdown 格式。
|
||||
|
||||
要求:
|
||||
1. 在文字的开头,去掉“一款、一个、完全免费、高效、简洁、强大、快速、好用、安全”等营销废话。
|
||||
2. 严禁使用加粗格式(不要使用 **)。
|
||||
3. 将产品名称从文字的后面提升到最前面。比如"一个安全高效的 AI 生图网站,基于 nano banana pro",改成 "AI 生图网站,,基于 nano banana pro"
|
||||
3. 仅输出以下格式的一行文字:
|
||||
* :white_check_mark: [项目名](网址):用途描述
|
||||
1. 识别文本中的所有产品/项目(可能有多个)
|
||||
2. 每个项目占一行
|
||||
3. 在文字的开头,去掉"一款、一个、完全免费、高效、简洁、强大、快速、好用、安全"等营销废话
|
||||
4. 严禁使用加粗格式(不要使用 **)
|
||||
5. 将产品名称从文字的后面提升到最前面
|
||||
6. 每行格式:* :white_check_mark: [项目名](网址):用途描述
|
||||
|
||||
示例 1:
|
||||
输入:https://example.com:一款基于 AI 的高效视频生成网站
|
||||
输出:* :white_check_mark: [example.com](https://example.com):AI 视频生成网站
|
||||
|
||||
示例 2:
|
||||
输入:[MyApp](https://myapp.com) 完全免费的强大工具,帮助用户管理任务
|
||||
输出:* :white_check_mark: [MyApp](https://myapp.com):任务管理工具
|
||||
|
||||
示例 3(多个项目):
|
||||
输入:
|
||||
[ProductA](https://a.com):AI 绘画工具
|
||||
[ProductB](https://b.com):AI 写作助手
|
||||
输出:
|
||||
* :white_check_mark: [ProductA](https://a.com):AI 绘画工具
|
||||
* :white_check_mark: [ProductB](https://b.com):AI 写作助手
|
||||
|
||||
待处理文本:
|
||||
{raw_text}
|
||||
@@ -49,107 +80,178 @@ 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)
|
||||
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)
|
||||
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))
|
||||
|
||||
processed_count = 0
|
||||
|
||||
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)
|
||||
# 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
|
||||
|
||||
if header_match:
|
||||
# 1. 提取用户自己写的 Header
|
||||
header_line = header_match.group(0).strip()
|
||||
# 2. 从正文中移除这一行,避免干扰 AI
|
||||
body_for_ai = cleaned_body.replace(header_line, "").strip()
|
||||
print(f"检测到用户自带 Header: {header_line}")
|
||||
else:
|
||||
# 1. 自动生成 Header
|
||||
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}")
|
||||
|
||||
# 3. AI 仅处理项目详情行
|
||||
project_line = get_ai_project_line(body_for_ai)
|
||||
# 1. 检查 Issue Body
|
||||
has_t, has_s = check_reactions(issue)
|
||||
if has_t and not has_s:
|
||||
pending_items.append((issue, issue))
|
||||
|
||||
# 组合成最终条目
|
||||
formatted_entry = f"{header_line}\n{project_line}"
|
||||
|
||||
# 4. 更新 README.md 逻辑
|
||||
content = repo.get_contents("README.md", ref="master")
|
||||
readme_text = content.decoded_content.decode("utf-8")
|
||||
# 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))
|
||||
|
||||
today_str = datetime.now().strftime("%Y 年 %m 月 %d 号添加")
|
||||
date_header = f"### {today_str}"
|
||||
|
||||
if date_header not in readme_text:
|
||||
new_readme = readme_text.replace("3. 项目列表\n", f"3. 项目列表\n\n{date_header}\n")
|
||||
else:
|
||||
new_readme = readme_text
|
||||
if not pending_items:
|
||||
print("无待处理项")
|
||||
return
|
||||
|
||||
insertion_point = new_readme.find(date_header) + len(date_header)
|
||||
final_readme = new_readme[:insertion_point] + "\n\n" + formatted_entry + new_readme[insertion_point:]
|
||||
print(f"\n共收集 {len(pending_items)} 个待处理项")
|
||||
|
||||
# 5. 提交 PR 逻辑
|
||||
branch_name = f"add-project-{comment.id}"
|
||||
base = repo.get_branch("master")
|
||||
# ===== 阶段 2:格式化和 AI 处理 =====
|
||||
formatted_entries = []
|
||||
processed_items = [] # 用于最后标记和回复
|
||||
|
||||
try:
|
||||
repo.get_git_ref(f"heads/{branch_name}").delete()
|
||||
except:
|
||||
pass
|
||||
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")
|
||||
|
||||
repo.create_git_ref(ref=f"refs/heads/{branch_name}", sha=base.commit.sha)
|
||||
repo.update_file(
|
||||
"README.md",
|
||||
f"docs: add project from {comment.user.login}",
|
||||
final_readme,
|
||||
content.sha,
|
||||
branch=branch_name
|
||||
)
|
||||
cleaned_body = remove_quote_blocks(obj.body)
|
||||
|
||||
# 为了彻底消除 Issue 里的 "mentioned this" 红框,
|
||||
# 在 https:// 后面插入一个不可见字符 \u200b
|
||||
safe_url = comment.html_url.replace("https://", "https://\u200b")
|
||||
# 判断用户是否自带了 Header
|
||||
header_match = re.search(r'^####\s+.*', cleaned_body, re.MULTILINE)
|
||||
|
||||
pr = repo.create_pull(
|
||||
title=f"新增项目:来自 {comment.user.login} 的评论",
|
||||
body=f"原评论内容:```{comment.body}``` \n\n 原评论链接:{safe_url} \n\n --- \n\n 此 PR 自动生成,触发机制:Github 用户 1c7 在评论下方点击了'火箭'图标。",
|
||||
head=branch_name,
|
||||
base="master"
|
||||
)
|
||||
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}")
|
||||
|
||||
comment.create_reaction(SUCCESS_EMOJI)
|
||||
# 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))
|
||||
|
||||
# 构建包含引用的回复评论
|
||||
# reply_body = f"@{comment.user.login} 感谢提交,已添加至待审核列表!\n\nPR 链接:{pr.html_url}\n\n---\n*回复 [此评论]({comment.html_url})*"
|
||||
# issue.create_comment(reply_body)
|
||||
# ===== 阶段 3:批量提交 =====
|
||||
# 更新 README
|
||||
content = repo.get_contents("README.md", ref="master")
|
||||
readme_text = content.decoded_content.decode("utf-8")
|
||||
|
||||
processed_count += 1
|
||||
today_str = datetime.now().strftime("%Y 年 %-m 月 %-d 号添加")
|
||||
date_header = f"### {today_str}"
|
||||
|
||||
if processed_count == 0:
|
||||
print("未发现新标记的任务。")
|
||||
if date_header not in readme_text:
|
||||
new_readme = readme_text.replace("3. 项目列表\n", f"3. 项目列表\n\n{date_header}\n")
|
||||
else:
|
||||
new_readme = readme_text
|
||||
|
||||
# 插入所有条目(用两个换行分隔)
|
||||
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:]
|
||||
|
||||
# 创建分支
|
||||
branch_name = f"batch-add-projects-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
||||
base = repo.get_branch("master")
|
||||
|
||||
try:
|
||||
repo.get_git_ref(f"heads/{branch_name}").delete()
|
||||
except:
|
||||
pass
|
||||
|
||||
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",
|
||||
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
|
||||
])
|
||||
|
||||
formatted_list = "\n\n".join([
|
||||
f"### {i+1}. {entry}"
|
||||
for i, (obj, parent, entry) in enumerate(processed_items)
|
||||
])
|
||||
|
||||
pr_body = f"""批量添加 {len(processed_items)} 个项目
|
||||
|
||||
## 原始链接
|
||||
{item_links}
|
||||
|
||||
## 格式化结果
|
||||
{formatted_list}
|
||||
|
||||
---
|
||||
自动生成,触发机制:用户 {ADMIN_HANDLE} 点击 🚀
|
||||
"""
|
||||
|
||||
pr = repo.create_pull(
|
||||
title=f"新增项目:批量添加 {len(processed_items)} 个项目",
|
||||
body=pr_body,
|
||||
head=branch_name,
|
||||
base="master"
|
||||
)
|
||||
|
||||
print(f"\n✅ PR 创建成功:{pr.html_url}")
|
||||
|
||||
# ===== 阶段 4:标记成功并回复 =====
|
||||
replies = {} # parent_issue -> set of users
|
||||
|
||||
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)
|
||||
|
||||
# 分别在各 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__":
|
||||
main()
|
||||
8
.github/workflows/process_list.yml
vendored
8
.github/workflows/process_list.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: 提交项目
|
||||
name: 提交项目(每 24 小时运行一次,晚上 00:00)
|
||||
on:
|
||||
# schedule:
|
||||
# - cron: '0 */6 * * *' # 每 6 小时运行一次
|
||||
schedule:
|
||||
- cron: '0 16 * * *' # 每天 UTC 16:00 运行(北京时间 00:00)
|
||||
workflow_dispatch: # 支持手动触发
|
||||
|
||||
jobs:
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
|
||||
- name: Run script
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
|
||||
# 如果你用的不是 OpenAI 原生接口,可以设置这个环境变量,否则默认使用 OpenAI
|
||||
LLM_BASE_URL: "https://api.deepseek.com"
|
||||
|
||||
@@ -2,6 +2,40 @@
|
||||
|
||||
本版面放的都是游戏,起始于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游戏工具
|
||||
|
||||
### 2026 年 1 月 2 号添加
|
||||
* :white_check_mark: [PokePath-TD](https://play-pokepath-td.online/):PokePath-TD一款海外爆火的宝可梦塔防游戏,在9 条不同的路线上抵御一波又一波的敌人,失败了也可以累积资源和升级宝可梦成员。
|
||||
|
||||
### 2025 年 12 月 27 号添加
|
||||
* :white_check_mark: [Riddle School](https://riddle-school.online/):Riddle School 是一款以校园为背景的解谜冒险游戏,采用简单直观的点击操作方式,适合各类玩家上手。游戏通过一系列环环相扣的谜题,引导玩家不断思考不同道具和场景之间的关系。解谜过程清晰,让人能够专注于推理本身。
|
||||
|
||||
### 2025 年 12 月 21 号添加
|
||||
#### shuiwuhen - [GitHub](https://github.com/290713469)
|
||||
* :white_check_mark: [Universal Tower Defense Calculator](https://universaltowerdefensecalculator.com):Roblox 游戏 Universal Tower Defense 工具站
|
||||
|
||||
### 2025 年 12 月 14 号添加
|
||||
#### seven(沈阳)
|
||||
* :white_check_mark: [Pips game](https://pipsgame.dev/): 每日逻辑谜题,你通过纯推理放置多米诺骨牌——无需猜测(Pips Game is a daily logic puzzle where you place dominoes using pure deduction — no guessing)
|
||||
|
||||
@@ -16,6 +16,34 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
|
||||
程序员版开始于 2019 年 4 月 11 号, 主版面开始于 2018 年 3 月
|
||||
-->
|
||||
|
||||
### 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
|
||||
@@ -109,7 +137,7 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
|
||||
|
||||
### 2025 年 5 月 13 号添加
|
||||
#### masz
|
||||
* :white_check_mark: [ui2vue](https://www.ui2vue.cn):生成 vue3 代码的工具网站,支持拖拽&编辑方式添加组件,可直接导出vue3代码
|
||||
* :x: [ui2vue](https://www.ui2vue.cn):生成 vue3 代码的工具网站,支持拖拽&编辑方式添加组件,可直接导出vue3代码
|
||||
|
||||
### 2025 年 5 月 11 号添加
|
||||
#### 草梅友仁 - [Github](https://github.com/CaoMeiYouRen), [博客](https://blog.cmyr.ltd/)
|
||||
@@ -148,7 +176,7 @@ Issue 和 PR 里偶尔有人提交一些不错的东西,但打开一看,不
|
||||
|
||||
### 2025 年 3 月 17 号添加
|
||||
#### 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 号添加
|
||||
#### yvling(合肥) - [Github](https://github.com/yv1ing), [博客](https://blog.yvling.cn)
|
||||
@@ -728,5 +756,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/)
|
||||
* :white_check_mark: [LemonTea](http://lemontea.slothindie.org/):极简且特别的静态网站生成器 - [更多介绍](http://lemontea.slothindie.org/book/index.html)
|
||||
#### 袁慠棱 - [Github](https://github.com/alengYuan), [博客](http://slothindie.org/)
|
||||
* :x: [LemonTea](http://lemontea.slothindie.org/):极简且特别的静态网站生成器 - [更多介绍](http://lemontea.slothindie.org/book/index.html)
|
||||
|
||||
Reference in New Issue
Block a user