-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclean_issues.py
More file actions
155 lines (120 loc) · 4.95 KB
/
clean_issues.py
File metadata and controls
155 lines (120 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python3
"""
GitHub Issue 评论清理脚本
功能:
- 清理指定用户的重复/模板评论
- 支持 dry-run 预览模式
- 安全的删除确认机制
"""
import argparse
import os
import sys
from pathlib import Path
try:
from github import Github
except ImportError:
print("❌ 请安装 PyGithub: pip install PyGithub")
sys.exit(1)
# 默认模板内容
DEFAULT_TEMPLATE = "感谢您的回复!如果您遇到了安装或部署方面的问题"
def get_github_client():
"""创建 GitHub 客户端"""
token = os.environ.get("GITHUB_TOKEN")
if not token:
raise ValueError("请设置 GITHUB_TOKEN 环境变量")
return Github(token)
def find_comments_to_delete(issue, target_user, template):
"""查找需要删除的评论"""
comments_to_delete = []
for comment in issue.get_comments():
# 检查是否是目标用户
if comment.user.login != target_user:
continue
# 检查是否包含模板内容
if template in comment.body:
comments_to_delete.append({
"id": comment.id,
"body": comment.body[:100] + "..." if len(comment.body) > 100 else comment.body,
"created_at": comment.created_at
})
return comments_to_delete
def clean_issue_comments(repo_name, target_user, template, dry_run=True):
"""清理 Issue 评论"""
github = get_github_client()
repo = github.get_repo(repo_name)
total_deleted = 0
total_comments = 0
print(f"\n📋 扫描仓库: {repo_name}")
print(f"👤 目标用户: {target_user}")
print(f"📝 模板内容: {template}")
print(f"🔍 模式: {'预览 (dry-run)' if dry_run else '实际删除'}")
print("-" * 60)
# 只处理 Open 状态的 Issue
for issue in repo.get_issues(state="open"):
comments = find_comments_to_delete(issue, target_user, template)
if not comments:
continue
print(f"\n📌 Issue #{issue.number}: {issue.title}")
total_comments += len(comments)
for i, comment in enumerate(comments, 1):
print(f" [{i}] Comment ID: {comment['id']}")
print(f" 创建时间: {comment['created_at']}")
print(f" 内容: {comment['body']}")
if not dry_run:
# 实际删除评论
for comment_info in comments:
try:
comment = issue.get_comment(comment_info["id"])
comment.delete()
print(f" ✅ 已删除评论 {comment_info['id']}")
total_deleted += 1
except Exception as e:
print(f" ❌ 删除失败: {e}")
# 也检查已关闭的 Issue
print("\n" + "=" * 60)
print("🔍 扫描已关闭的 Issue...")
for issue in repo.get_issues(state="closed"):
comments = find_comments_to_delete(issue, target_user, template)
if not comments:
continue
print(f"\n📌 Issue #{issue.number} (已关闭): {issue.title}")
total_comments += len(comments)
for i, comment in enumerate(comments, 1):
print(f" [{i}] Comment ID: {comment['id']}")
print(f" 创建时间: {comment['created_at']}")
print(f" 内容: {comment['body']}")
if not dry_run:
for comment_info in comments:
try:
comment = issue.get_comment(comment_info["id"])
comment.delete()
print(f" ✅ 已删除评论 {comment_info['id']}")
total_deleted += 1
except Exception as e:
print(f" ❌ 删除失败: {e}")
# 总结
print("\n" + "=" * 60)
print("📊 总结")
print(f" 发现评论数: {total_comments}")
print(f" 删除评论数: {total_deleted if not dry_run else '(dry-run 模式,未实际删除)'}")
return total_comments, total_deleted
def main():
parser = argparse.ArgumentParser(description="清理 GitHub Issue 中的模板评论")
parser.add_argument("--repo", required=True, help="仓库路径 (owner/repo)")
parser.add_argument("--user", required=True, help="目标用户名")
parser.add_argument("--template", default=DEFAULT_TEMPLATE, help="要删除的模板内容")
parser.add_argument("--dry-run", action="store_true", help="预览模式,不实际删除")
args = parser.parse_args()
# 确认删除
if not args.dry_run:
confirm = input("\n⚠️ 确认要删除评论吗? (yes/no): ")
if confirm.lower() != "yes":
print("❌ 已取消操作")
return
try:
clean_issue_comments(args.repo, args.user, args.template, args.dry_run)
except Exception as e:
print(f"❌ 错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()