Files
chinese-independent-developer/.github/scripts/process_item.py
Cheng Zheng 53ef61c07e x
2025-12-20 14:17:39 +08:00

181 lines
6.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import re
import datetime
from github import Github
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" # 🎉
# ==========================================
def remove_quote_blocks(text: str) -> str:
"""移除 GitHub 引用回复块"""
lines = text.split('\n')
cleaned_lines = []
for line in lines:
if not line.lstrip().startswith('>'):
cleaned_lines.append(line)
result = '\n'.join(cleaned_lines)
result = re.sub(r'\n{3,}', '\n\n', result)
return result.strip()
def get_ai_project_line(raw_text):
"""只让 AI 提取项目名称、链接和描述行"""
client = OpenAI(api_key=API_KEY, base_url=BASE_URL)
prompt = f"""
任务:将用户的项目介绍转换为单行 Markdown 格式。
要求:
1. 在文字的开头,去掉“一款、一个、完全免费、高效、简洁、强大、快速、好用、安全”等营销废话。
2. 严禁使用加粗格式(不要使用 **)。
3. 将产品名称从文字的后面提升到最前面。比如"一个安全高效的 AI 生图网站,基于 nano banana pro",改成 "AI 生图网站,,基于 nano banana pro"
3. 仅输出以下格式的一行文字:
* :white_check_mark: [项目名](网址):用途描述
待处理文本:
{raw_text}
"""
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
return response.choices[0].message.content.strip()
def main():
g = Github(PAT_TOKEN)
repo = g.get_repo(REPO_NAME)
issue = repo.get_issue(ISSUE_NUMBER)
time_threshold = datetime.now(timezone.utc) - timedelta(days=3)
comments = issue.get_comments(since=time_threshold)
# ===== 阶段 1收集待处理评论 =====
pending_comments = []
formatted_entries = []
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_comments)} 个待处理评论")
# 更新 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 号添加")
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
# 插入所有条目(用两个换行分隔)
insertion_point = new_readme.find(date_header) + len(date_header)
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')}"
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(pending_comments)} projects",
final_readme,
content.sha,
branch=branch_name
)
# 构建 PR body
comment_links = "\n".join([
f"- [{c.user.login}]({c.html_url})"
for c in pending_comments
])
formatted_list = "\n\n".join([
f"### {i+1}. {formatted_entries[i]}"
for i in range(len(formatted_entries))
])
pr_body = f"""批量添加 {len(pending_comments)} 个项目
## 原始评论链接
{comment_links}
## 格式化结果
{formatted_list}
---
自动生成,触发机制:用户 {ADMIN_HANDLE} 点击 🚀
"""
pr = repo.create_pull(
title=f"新增项目:批量添加 {len(pending_comments)} 个项目",
body=pr_body,
head=branch_name,
base="master"
)
print(f"\n✅ PR 创建成功:{pr.html_url}")
# 标记所有评论
for comment in pending_comments:
comment.create_reaction(SUCCESS_EMOJI)
reply_body = f"@{comment.user.login} 感谢提交,已添加至待审核列表!\n\nPR 链接:{pr.html_url}"
issue.create_comment(reply_body)
print(f"\n✅ 已标记所有 {len(pending_comments)} 个评论")
if __name__ == "__main__":
main()