-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor command handling and subscription logic, export commits in d…
…aily progress, and enhance report generation with GPT-3.5
- Loading branch information
1 parent
8da7236
commit ba06231
Showing
11 changed files
with
228 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
requests | ||
openai |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# src/command_handler.py | ||
|
||
import argparse | ||
|
||
class CommandHandler: | ||
def __init__(self, github_client, subscription_manager, report_generator): | ||
self.github_client = github_client | ||
self.subscription_manager = subscription_manager | ||
self.report_generator = report_generator | ||
self.parser = self.create_parser() | ||
|
||
def create_parser(self): | ||
parser = argparse.ArgumentParser( | ||
description='GitHub Sentinel Command Line Interface', | ||
formatter_class=argparse.RawTextHelpFormatter | ||
) | ||
subparsers = parser.add_subparsers(title='Commands', dest='command') | ||
|
||
parser_add = subparsers.add_parser('add', help='Add a subscription') | ||
parser_add.add_argument('repo', type=str, help='The repository to subscribe to (e.g., owner/repo)') | ||
parser_add.set_defaults(func=self.add_subscription) | ||
|
||
parser_remove = subparsers.add_parser('remove', help='Remove a subscription') | ||
parser_remove.add_argument('repo', type=str, help='The repository to unsubscribe from (e.g., owner/repo)') | ||
parser_remove.set_defaults(func=self.remove_subscription) | ||
|
||
parser_list = subparsers.add_parser('list', help='List all subscriptions') | ||
parser_list.set_defaults(func=self.list_subscriptions) | ||
|
||
parser_fetch = subparsers.add_parser('fetch', help='Fetch updates immediately') | ||
parser_fetch.set_defaults(func=self.fetch_updates) | ||
|
||
parser_export = subparsers.add_parser('export', help='Export daily progress') | ||
parser_export.add_argument('repo', type=str, help='The repository to export progress from (e.g., owner/repo)') | ||
parser_export.set_defaults(func=self.export_daily_progress) | ||
|
||
parser_generate = subparsers.add_parser('generate', help='Generate daily report from markdown file') | ||
parser_generate.add_argument('file', type=str, help='The markdown file to generate report from') | ||
parser_generate.set_defaults(func=self.generate_daily_report) | ||
|
||
parser_help = subparsers.add_parser('help', help='Show help message') | ||
parser_help.set_defaults(func=self.print_help) | ||
|
||
return parser | ||
|
||
def add_subscription(self, args): | ||
self.subscription_manager.add_subscription(args.repo) | ||
print(f"Added subscription for repository: {args.repo}") | ||
|
||
def remove_subscription(self, args): | ||
self.subscription_manager.remove_subscription(args.repo) | ||
print(f"Removed subscription for repository: {args.repo}") | ||
|
||
def list_subscriptions(self, args): | ||
subscriptions = self.subscription_manager.list_subscriptions() | ||
print("Current subscriptions:") | ||
for sub in subscriptions: | ||
print(f" - {sub}") | ||
|
||
def fetch_updates(self, args): | ||
updates = self.github_client.fetch_updates() | ||
for update in updates: | ||
print(update) | ||
|
||
def export_daily_progress(self, args): | ||
self.github_client.export_daily_progress(args.repo) | ||
print(f"Exported daily progress for repository: {args.repo}") | ||
|
||
def generate_daily_report(self, args): | ||
self.report_generator.generate_daily_report(args.file) | ||
print(f"Generated daily report from file: {args.file}") | ||
|
||
def print_help(self, args=None): | ||
self.parser.print_help() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,55 @@ | ||
# src/github_client.py | ||
|
||
import requests | ||
import datetime | ||
|
||
class GitHubClient: | ||
def __init__(self, token): | ||
self.token = token | ||
|
||
def fetch_updates(self, subscriptions): | ||
headers = { | ||
'Authorization': f'token {self.token}' | ||
self.headers = {'Authorization': f'token {self.token}'} | ||
|
||
def fetch_updates(self, repo): | ||
# 获取特定 repo 的更新(commits, issues, pull requests) | ||
updates = { | ||
'commits': self.fetch_commits(repo), | ||
'issues': self.fetch_issues(repo), | ||
'pull_requests': self.fetch_pull_requests(repo) | ||
} | ||
updates = {} | ||
for repo in subscriptions: | ||
response = requests.get(f'https://api.github.com/repos/{repo}/releases/latest', headers=headers) | ||
if response.status_code == 200: | ||
updates[repo] = response.json() | ||
return updates | ||
|
||
def fetch_commits(self, repo): | ||
url = f'https://api.github.com/repos/{repo}/commits' | ||
response = requests.get(url, headers=self.headers) | ||
response.raise_for_status() | ||
return response.json() | ||
|
||
def fetch_issues(self, repo): | ||
url = f'https://api.github.com/repos/{repo}/issues' | ||
response = requests.get(url, headers=self.headers) | ||
response.raise_for_status() | ||
return response.json() | ||
|
||
def fetch_pull_requests(self, repo): | ||
url = f'https://api.github.com/repos/{repo}/pulls' | ||
response = requests.get(url, headers=self.headers) | ||
response.raise_for_status() | ||
return response.json() | ||
|
||
|
||
def export_daily_progress(self, repo): | ||
date_str = datetime.datetime.now().strftime('%Y-%m-%d') | ||
issues = self.fetch_issues(repo) | ||
pull_requests = self.fetch_pull_requests(repo) | ||
filename = f'daily_progress/{repo.replace("/", "_")}_{date_str}.md' | ||
with open(filename, 'w') as f: | ||
f.write(f"# {repo} Daily Progress - {date_str}\n\n") | ||
f.write("## Issues\n") | ||
for issue in issues: | ||
f.write(f"- {issue['title']} #{issue['number']}\n") | ||
f.write("\n## Pull Requests\n") | ||
for pr in pull_requests: | ||
f.write(f"- {pr['title']} #{pr['number']}\n") | ||
|
||
print(f"Exported daily progress to {filename}") | ||
|
||
return filename |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# src/llm.py | ||
|
||
import os | ||
from openai import OpenAI | ||
|
||
class LLM: | ||
def __init__(self): | ||
self.client = OpenAI() | ||
|
||
def generate_daily_report(self, markdown_content, dry_run=False): | ||
prompt = f"以下是项目的最新进展,根据功能合并同类项,形成一份简报,至少包含:1)新增功能;2)主要改进;3)修复问题;:\n\n{markdown_content}" | ||
if dry_run: | ||
with open("daily_progress/prompt.txt", "w+") as f: | ||
f.write(prompt) | ||
return "DRY RUN" | ||
|
||
print("Before call GPT") | ||
response = self.client.chat.completions.create( | ||
model="gpt-3.5-turbo", | ||
messages=[ | ||
{"role": "user", "content": prompt} | ||
] | ||
) | ||
print("After call GPT") | ||
print(response) | ||
return response.choices[0].message.content |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,35 @@ | ||
# src/report_generator.py | ||
|
||
import os | ||
from datetime import date | ||
|
||
class ReportGenerator: | ||
def generate(self, updates): | ||
report = "Latest Release Information:\n\n" | ||
for repo, release in updates.items(): | ||
report += f"Repository: {repo}\n" | ||
report += f"Latest Version: {release['tag_name']}\n" | ||
report += f"Release Name: {release['name']}\n" | ||
report += f"Published at: {release['published_at']}\n" | ||
report += f"Release Notes:\n{release['body']}\n" | ||
report += "-" * 40 + "\n" | ||
return report | ||
def __init__(self, llm): | ||
self.llm = llm | ||
|
||
def export_daily_progress(self, repo, updates): | ||
file_path = f'daily_progress/{repo.replace("/", "_")}_{date.today()}.md' | ||
with open(file_path, 'w') as file: | ||
file.write(f"# Daily Progress for {repo} ({date.today()})\n\n") | ||
file.write("## Commits\n") | ||
for commit in updates['commits']: | ||
file.write(f"- {commit}\n") | ||
file.write("\n## Issues\n") | ||
for issue in updates['issues']: | ||
file.write(f"- {issue}\n") | ||
file.write("\n## Pull Requests\n") | ||
for pr in updates['pull_requests']: | ||
file.write(f"- {pr}\n") | ||
return file_path | ||
|
||
def generate_daily_report(self, markdown_file_path): | ||
with open(markdown_file_path, 'r') as file: | ||
markdown_content = file.read() | ||
|
||
report = self.llm.generate_daily_report(markdown_content) | ||
|
||
report_file_path = os.path.splitext(markdown_file_path)[0] + "_report.md" | ||
with open(report_file_path, 'w+') as report_file: | ||
report_file.write(report) | ||
|
||
print(f"Generated report saved to {report_file_path}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,23 @@ | ||
# src/scheduler.py | ||
|
||
import time | ||
import threading | ||
|
||
class Scheduler: | ||
def __init__(self, github_client, notifier, report_generator, subscription_manager, interval): | ||
def __init__(self, github_client, notifier, report_generator, subscription_manager, interval=86400): | ||
self.github_client = github_client | ||
self.notifier = notifier | ||
self.report_generator = report_generator | ||
self.subscription_manager = subscription_manager | ||
self.interval = interval | ||
|
||
def start(self): | ||
self.run() | ||
|
||
def run(self): | ||
while True: | ||
self.run() | ||
subscriptions = self.subscription_manager.get_subscriptions() | ||
for repo in subscriptions: | ||
updates = self.github_client.fetch_updates(repo) | ||
markdown_file_path = self.report_generator.export_daily_progress(repo, updates) | ||
self.report_generator.generate_daily_report(markdown_file_path) | ||
time.sleep(self.interval) | ||
|
||
def run(self): | ||
subscriptions = self.subscription_manager.get_subscriptions() | ||
updates = self.github_client.fetch_updates(subscriptions) | ||
report = self.report_generator.generate(updates) | ||
self.notifier.notify(report) |
Oops, something went wrong.