diff --git a/README-EN.md b/README-EN.md
new file mode 100644
index 00000000..2e8b3ce6
--- /dev/null
+++ b/README-EN.md
@@ -0,0 +1,83 @@
+# GitHub Sentinel
+
+
+
English | 中文
+
+
+GitHub Sentinel is an open-source tool AI Agent designed for developers and project managers. It automatically retrieves and aggregates updates from subscribed GitHub repositories on a regular basis (daily/weekly). Key features include subscription management, update retrieval, notification system, and report generation.
+
+## Features
+- Subscription management
+- Update retrieval
+- Notification system
+- Report generation
+
+## Getting Started
+
+### 1. Install Dependencies
+
+First, install the required dependencies:
+
+```sh
+pip install -r requirements.txt
+```
+
+### 2. Configure the Application
+
+Edit the `config.json` file to set up your GitHub token, notification settings, subscription file, and update interval:
+
+```json
+{
+ "github_token": "your_github_token",
+ "notification_settings": {
+ "email": "your_email@example.com",
+ "slack_webhook_url": "your_slack_webhook_url"
+ },
+ "subscriptions_file": "subscriptions.json",
+ "update_interval": 86400
+}
+```
+
+### 3. How to Run
+
+GitHub Sentinel supports three different ways to run the application:
+
+#### A. Run as a Command-Line Tool
+
+You can run the application interactively from the command line:
+
+```sh
+python src/command_tool.py
+```
+
+In this mode, you can manually input commands to manage subscriptions, retrieve updates, and generate reports.
+
+#### B. Run as a Daemon Process with Scheduler
+
+To run the application as a background service (daemon) that regularly checks for updates:
+
+1. Ensure you have the `python-daemon` package installed:
+
+ ```sh
+ pip install python-daemon
+ ```
+
+2. Launch the daemon process:
+
+ ```sh
+ nohup python3 src/daemon_process.py > logs/daemon_process.log 2>&1 &
+ ```
+
+ - This will start the scheduler in the background, checking for updates at the interval specified in your `config.json`.
+ - Logs will be saved to the `logs/daemon_process.log` file.
+
+#### C. Run as a Gradio Server
+
+To run the application with a Gradio interface, allowing users to interact with the tool via a web interface:
+
+```sh
+python src/gradio_server.py
+```
+
+- This will start a web server on your machine, allowing you to manage subscriptions and generate reports through a user-friendly interface.
+- By default, the Gradio server will be accessible at `http://localhost:7860`, but you can share it publicly if needed.
diff --git a/README.md b/README.md
index 62a5cc04..351f95c5 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,31 @@
# GitHub Sentinel
-GitHub Sentinel is an open-source tool AI Agent designed for developers and project managers. It automatically retrieves and aggregates updates from subscribed GitHub repositories on a regular basis (daily/weekly). Key features include subscription management, update retrieval, notification system, and report generation.
+
+
English | 中文
+
-## Features
-- Subscription management
-- Update retrieval
-- Notification system
-- Report generation
+GitHub Sentinel 是一个开源的工具 AI 代理,专为开发人员和项目经理设计。它会定期(每日/每周)自动从订阅的 GitHub 仓库中检索和汇总更新。主要功能包括订阅管理、更新检索、通知系统和报告生成。
-## Getting Started
-1. Install dependencies:
- ```sh
- pip install -r requirements.txt
- ```
+## 功能
+- 订阅管理
+- 更新检索
+- 通知系统
+- 报告生成
-2. Configure the application by editing `config.json`.
+## 快速开始
-3. Run the application:
- ```sh
- python src/main.py
- ```
+### 1. 安装依赖
+
+首先,安装所需的依赖项:
+
+```sh
+pip install -r requirements.txt
+```
+
+### 2. 配置应用
+
+编辑 `config.json` 文件,以设置您的 GitHub 令牌、通知设置、订阅文件和更新间隔:
-## Configuration
-The configuration file `config.json` should contain the following settings:
```json
{
"github_token": "your_github_token",
@@ -34,3 +37,47 @@ The configuration file `config.json` should contain the following settings:
"update_interval": 86400
}
```
+
+### 3. 如何运行
+
+GitHub Sentinel 支持以下三种运行方式:
+
+#### A. 作为命令行工具运行
+
+您可以从命令行交互式地运行该应用:
+
+```sh
+python src/command_tool.py
+```
+
+在此模式下,您可以手动输入命令来管理订阅、检索更新和生成报告。
+
+#### B. 作为后台进程运行(带调度器)
+
+要将该应用作为后台服务(守护进程)运行,它将定期检查更新:
+
+1. 确保您已安装 `python-daemon` 包:
+
+ ```sh
+ pip install python-daemon
+ ```
+
+2. 启动后台进程:
+
+ ```sh
+ nohup python3 src/daemon_process.py > logs/daemon_process.log 2>&1 &
+ ```
+
+ - 这将启动后台调度器,按照 `config.json` 中指定的间隔定期检查更新。
+ - 日志将保存到 `logs/daemon_process.log` 文件中。
+
+#### C. 作为 Gradio 服务器运行
+
+要使用 Gradio 界面运行应用,允许用户通过 Web 界面与该工具交互:
+
+```sh
+python src/gradio_server.py
+```
+
+- 这将在您的机器上启动一个 Web 服务器,允许您通过用户友好的界面管理订阅和生成报告。
+- 默认情况下,Gradio 服务器将可在 `http://localhost:7860` 访问,但如果需要,您可以公开共享它。
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index c428aa53..ddee22e2 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,5 @@
requests
openai
gradio
-logoru
\ No newline at end of file
+loguru
+python-daemon
\ No newline at end of file
diff --git a/src/command_tool.py b/src/command_tool.py
new file mode 100644
index 00000000..3a41a0f0
--- /dev/null
+++ b/src/command_tool.py
@@ -0,0 +1,40 @@
+import shlex
+
+from config import Config
+from github_client import GitHubClient
+from notifier import Notifier
+from report_generator import ReportGenerator
+from llm import LLM
+from subscription_manager import SubscriptionManager
+from command_handler import CommandHandler
+from logger import LOG
+
+def main():
+ config = Config()
+ github_client = GitHubClient(config.github_token)
+ notifier = Notifier(config.notification_settings)
+ llm = LLM()
+ report_generator = ReportGenerator(llm)
+ subscription_manager = SubscriptionManager(config.subscriptions_file)
+ command_handler = CommandHandler(github_client, subscription_manager, report_generator)
+
+ parser = command_handler.parser
+ command_handler.print_help()
+
+ while True:
+ try:
+ user_input = input("GitHub Sentinel> ")
+ if user_input in ['exit', 'quit']:
+ break
+ try:
+ args = parser.parse_args(shlex.split(user_input))
+ if args.command is None:
+ continue
+ args.func(args)
+ except SystemExit as e:
+ LOG.error("Invalid command. Type 'help' to see the list of available commands.")
+ except Exception as e:
+ LOG.error(f"Unexpected error: {e}")
+
+if __name__ == '__main__':
+ main()
diff --git a/src/daemon_process.py b/src/daemon_process.py
new file mode 100644
index 00000000..d084a925
--- /dev/null
+++ b/src/daemon_process.py
@@ -0,0 +1,51 @@
+import daemon
+import threading
+import time
+
+
+from config import Config
+from github_client import GitHubClient
+from notifier import Notifier
+from report_generator import ReportGenerator
+from llm import LLM
+from subscription_manager import SubscriptionManager
+from scheduler import Scheduler
+from logger import LOG
+
+def run_scheduler(scheduler):
+ scheduler.start()
+
+def main():
+ config = Config()
+ github_client = GitHubClient(config.github_token)
+ notifier = Notifier(config.notification_settings)
+ llm = LLM()
+ report_generator = ReportGenerator(llm)
+ subscription_manager = SubscriptionManager(config.subscriptions_file)
+
+ scheduler = Scheduler(
+ github_client=github_client,
+ notifier=notifier,
+ report_generator=report_generator,
+ subscription_manager=subscription_manager,
+ interval=config.update_interval
+ )
+
+ scheduler_thread = threading.Thread(target=run_scheduler, args=(scheduler,))
+ scheduler_thread.daemon = True
+ scheduler_thread.start()
+
+ LOG.info("Scheduler thread started.")
+
+ # Use python-daemon to properly daemonize the process
+ with daemon.DaemonContext():
+ try:
+ while True:
+ time.sleep(config.update_interval)
+ except KeyboardInterrupt:
+ LOG.info("Daemon process stopped.")
+
+if __name__ == '__main__':
+ main()
+
+# nohup python3 src/daemon_process.py > logs/daemon_process.log 2>&1 &
diff --git a/src/gradio_server.py b/src/gradio_server.py
new file mode 100644
index 00000000..ca8f5812
--- /dev/null
+++ b/src/gradio_server.py
@@ -0,0 +1,38 @@
+import gradio as gr
+
+from config import Config
+from github_client import GitHubClient
+from report_generator import ReportGenerator
+from llm import LLM
+from subscription_manager import SubscriptionManager
+from logger import LOG
+
+config = Config()
+github_client = GitHubClient(config.github_token)
+llm = LLM()
+report_generator = ReportGenerator(llm)
+subscription_manager = SubscriptionManager(config.subscriptions_file)
+
+
+def export_progress_by_date_range(repo, days):
+ raw_file_path = github_client.export_progress_by_date_range(repo, days)
+ report, report_file_path = report_generator.generate_report_by_date_range(raw_file_path, days)
+
+ return report, report_file_path
+
+demo = gr.Interface(
+ fn=export_progress_by_date_range,
+ title="GitHubSentinel",
+ inputs=[
+ gr.Dropdown(
+ subscription_manager.list_subscriptions(), label="订阅列表", info="已订阅GitHub项目"
+ ),
+ gr.Slider(value=2, minimum=1, maximum=7, step=1, label="报告周期", info="生成项目过去一段时间进展,单位:天"),
+
+ ],
+ outputs=[gr.Markdown(), gr.File(label="下载报告")],
+)
+
+if __name__ == "__main__":
+ demo.launch(share=True, server_name="0.0.0.0")
+ # demo.launch(share=True, server_name="0.0.0.0", auth=("django", "1234"))
\ No newline at end of file
diff --git a/src/report_generator.py b/src/report_generator.py
index a7734c8a..37aa7bdc 100644
--- a/src/report_generator.py
+++ b/src/report_generator.py
@@ -59,7 +59,11 @@ def generate_daily_report(self, markdown_file_path):
with open(report_file_path, 'w+') as report_file:
report_file.write(report) # 写入生成的报告
+
LOG.info(f"Generated report saved to {report_file_path}") # 记录生成报告日志
+
+ return report, report_file_path
+
def generate_report_by_date_range(self, markdown_file_path, days):
# 生成特定日期范围的报告,流程与日报生成类似
@@ -72,4 +76,8 @@ def generate_report_by_date_range(self, markdown_file_path, days):
with open(report_file_path, 'w+') as report_file:
report_file.write(report)
+
LOG.info(f"Generated report saved to {report_file_path}") # 记录生成报告日志
+
+ return report, report_file_path
+