Skip to content

Commit 0caa443

Browse files
authored
Merge pull request #8 from AptS-1547/feat-template
Feat template
2 parents 45482f2 + ed0898d commit 0caa443

26 files changed

Lines changed: 2017 additions & 194 deletions

.dockerignore

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,15 @@ tmp/
3838
.DS_Store
3939

4040
# 测试
41-
test/
4241
tests/
4342
.pytest_cache/
4443
.coverage
4544
htmlcov/
4645

4746
# 文档
4847
docs/
49-
*.md
5048
LICENSE
5149

5250
# 容器相关
53-
Dockerfile
51+
docker/
5452
.dockerignore
55-
docker-compose.yml

.github/workflows/pylint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ jobs:
2424
pip install -r ./requirements.txt
2525
- name: Analysing the code with pylint
2626
run: |
27-
pylint $(git ls-files '*.py')
27+
pylint $(git ls-files '*.py' | grep -v "tests/")

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.venv/
2+
.pytest_cache/
23
__pycache__/
34

45
*.pyc

.pylintrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[MASTER]
2+
ignore=tests
3+
ignore-patterns=test_.*?.py
4+
5+
[FORMAT]
6+
max-line-length=120

Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ RUN mkdir -p /app/templates \
1414

1515
COPY --chown=appuser:appuser . .
1616

17+
VOLUME [ "/app/config" ]
18+
1719
USER appuser
1820

1921
EXPOSE 8000
2022

21-
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
23+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

README.md

Lines changed: 53 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ source .venv/bin/activate # Linux/Mac
8282

8383
```bash
8484
pip install -r requirements.txt
85+
# 或者使用 Poetry
86+
# poetry install
8587
```
8688

8789
4. 配置文件设置:
@@ -90,7 +92,7 @@ pip install -r requirements.txt
9092
或者复制示例配置文件:
9193

9294
```bash
93-
cp config.yaml.example config.yaml
95+
cp config/config.example.yaml config.yaml
9496
```
9597

9698
## 配置说明
@@ -129,13 +131,13 @@ GITHUB_WEBHOOK:
129131
## 运行
130132
131133
```bash
132-
uvicorn app:app --host 0.0.0.0 --port 8000
134+
uvicorn main:app --host 0.0.0.0 --port 8000
133135
```
134136

135137
或者直接执行:
136138

137139
```bash
138-
python app.py
140+
python main.py
139141
```
140142

141143
## GitHub Webhook 设置
@@ -149,144 +151,51 @@ python app.py
149151

150152
## 开发路线图
151153

152-
### 1. GitHub API 轮询(计划中)
153-
154-
对于无法使用 webhook 的场景(如私有仓库或受限环境),我们计划实现基于 GitHub API 的轮询机制。
155-
156-
#### 设计概要
157-
158-
- **配置方式**
159-
160-
```yaml
161-
GITHUB_API_POLLING:
162-
- NAME: "polling-example"
163-
REPO:
164-
- "username/repo"
165-
BRANCH:
166-
- "main"
167-
INTERVAL: 300 # 轮询间隔(秒)
168-
EVENTS:
169-
- "push"
170-
- "pull_request"
171-
TOKEN: "github_personal_access_token" # GitHub 个人访问令牌
172-
ONEBOT:
173-
- type: "group"
174-
id: 123456789
175-
```
176-
177-
- **功能**:
178-
- 定时检查仓库变更
179-
- 对比上次轮询结果,只通知新变更
180-
- 支持提交、PR、Issue 等多种数据类型轮询
181-
- 优化请求频率,避免触发 GitHub API 限流
182-
183-
- **实现计划**:
184-
- 使用 `APScheduler` 实现定时任务
185-
- 使用 `aiohttp` 实现异步 HTTP 请求
186-
- 使用本地文件存储上次轮询状态 ~~(轻量化的玩意不可能给你上数据库 or Redis)~~
187-
- 封装 GitHub API 客户端,处理认证和错误
188-
189-
### 2. 自定义模板系统(计划中)
190-
191-
允许用户自定义各类事件的通知消息格式,提供更灵活的展示方式。
192-
193-
#### 设计概要
194-
195-
- **模板存储**:
196-
- 模板文件存储在 `templates/` 目录下
197-
- 按照事件类型命名,如 `templates/push.txt`、`templates/issues.txt` 等
198-
- 也可以创建自定义命名的模板文件用于不同场景
199-
200-
- **配置方式**:
201-
202-
```yaml
203-
GITHUB_WEBHOOK:
204-
- NAME: "github"
205-
REPO:
206-
- "username/repo"
207-
BRANCH:
208-
- "main"
209-
SECRET: "your_secret"
210-
EVENTS:
211-
- "push"
212-
- "issues"
213-
TEMPLATES: # 为不同事件类型指定自定义模板
214-
push: "custom_push.txt" # 使用自定义推送模板
215-
issues: "default" # 使用默认 issues 模板
216-
ONEBOT:
217-
- type: "group"
218-
id: 123456789
219-
```
220-
221-
- **模板示例** (`templates/push.txt`):
222-
223-
```
224-
📢 GitHub 推送通知
225-
仓库:{{ repo_name }}
226-
分支:{{ branch }}
227-
推送者:{{ pusher }}
228-
提交数量:{{ commit_count }}
229-
{% for commit in commits %}
230-
[{{ loop.index }}] {{ commit.id[:7] }} by {{ commit.author.name }}
231-
{{ commit.message.split('\n')[0] }}
232-
{% endfor %}
233-
```
234-
235-
- **模板示例** (`templates/issues.txt`):
236-
237-
```
238-
📋 Issue {{ action }}
239-
仓库:{{ repo_name }}
240-
标题:{{ issue.title }}
241-
作者:{{ issue.user.login }}
242-
链接:{{ issue.html_url }}
243-
```
244-
245-
- **功能**:
246-
- 基于 Jinja2 模板引擎
247-
- 支持条件语句和循环
248-
- 每个 Webhook 可以指定不同的模板集合
249-
- 提供默认模板,无需配置即可使用
250-
- 模板变量自动文档化(将提供变量参考)
251-
252-
- **实现计划**:
253-
- 引入 Jinja2 依赖
254-
- 实现模板目录扫描和加载机制
255-
- 开发模板缓存以提高性能
256-
- 提供模板变量参考文档
257-
- 添加模板验证功能,避免语法错误
258-
259-
## API 参考
260-
261-
### Webhook 接口
262-
263-
- **路径**: `/github-webhook`
264-
- **方法**: POST
265-
- **请求头**:
266-
- `Content-Type`: application/json
267-
- `X-GitHub-Event`: 事件类型
268-
- `X-Hub-Signature-256`: SHA-256 HMAC 签名
269-
270-
- **响应**:
271-
272-
```json
273-
{
274-
"status": "success|ignored",
275-
"message": "处理信息"
276-
}
277-
```
154+
详细的开发路线图请参考 开发路线图文档。
278155

279156
## 项目结构
280157

281-
- app.py: 主应用入口和 Web 服务器
282-
- hooks/github_webhook.py: GitHub Webhook 处理逻辑
283-
- send_message.py: OneBot 消息发送客户端
284-
- settings.py: 配置加载和验证
285-
- requirements.txt: 项目依赖
158+
```
159+
onebot-github-webhook/
160+
161+
├── app/ # 应用程序核心模块
162+
│ ├── api/ # API 接口
163+
│ ├── core/ # 核心功能
164+
│ │ ├── github.py # GitHub Webhook 处理逻辑
165+
│ │ └── onebot.py # OneBot 消息发送客户端
166+
│ ├── models/ # 数据模型
167+
│ │ └── config.py # 配置模型
168+
│ └── utils/ # 工具函数
169+
│ └── matching.py # 匹配规则工具
170+
171+
├── config/ # 配置文件目录
172+
│ ├── config.example.yaml # 示例配置文件
173+
│ └── templates/ # 消息模板目录
174+
│ ├── push/ # 推送事件模板
175+
│ ├── issues/ # Issue 事件模板
176+
│ └── pull_request/ # Pull Request 事件模板
177+
178+
├── docs/ # 文档目录
179+
│ └── src/ # mdBook 文档源
180+
181+
├── tests/ # 测试目录
182+
│ ├── test_matching.py # 匹配规则测试
183+
│ ├── test_onebot_sender.py # OneBot 发送器测试
184+
│ └── test_webhook_signature.py # Webhook 签名验证测试
185+
186+
├── docker/ # Docker 相关文件
187+
│ └── docker-compose.yml # Docker Compose 配置文件
188+
189+
├── main.py # 应用程序入口点
190+
├── Dockerfile # Docker 构建文件
191+
├── pyproject.toml # Python 项目配置
192+
├── poetry.lock # Poetry 依赖锁定文件
193+
└── README.md # 项目说明文档
194+
```
286195

287196
## 部署建议
288197

289-
### Docker 部署(计划支持)
198+
### Docker 部署
290199

291200
```bash
292201
docker run -d \
@@ -296,6 +205,13 @@ docker run -d \
296205
e1saps/onebot-github-webhook:latest
297206
```
298207

208+
或使用 Docker Compose:
209+
210+
```bash
211+
cd docker
212+
docker-compose up -d
213+
```
214+
299215
### Systemd 服务
300216

301217
创建 `/etc/systemd/system/onebot-github-webhook.service`:
@@ -308,7 +224,7 @@ After=network.target
308224
[Service]
309225
User=www-data
310226
WorkingDirectory=/opt/onebot-github-webhook
311-
ExecStart=/opt/onebot-github-webhook/.venv/bin/python -m uvicorn app:app --host 0.0.0.0 --port 8000
227+
ExecStart=/opt/onebot-github-webhook/.venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8000
312228
Restart=on-failure
313229
RestartSec=5s
314230

@@ -350,4 +266,4 @@ A: 本程序暂时不支持推送到多个 QQ 机器人
350266

351267
## 许可证
352268

353-
本项目采用 [Apache License 2.0](LICENSE) 许可证。
269+
本项目采用 Apache License 2.0 许可证。
Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,40 +23,13 @@
2323
import hmac
2424
import hashlib
2525
import logging
26-
import fnmatch
2726
from typing import Optional, Dict, Any, List
2827

2928
from fastapi import Request, HTTPException, Header
3029

31-
logger = logging.getLogger(__name__)
32-
33-
def match_pattern(value: str, pattern: str) -> bool:
34-
"""
35-
检查字符串是否匹配配置中的模式
36-
支持大小写不敏感匹配和通配符模式
30+
from app.utils.matching import match_pattern
3731

38-
Args:
39-
value: 要匹配的字符串 (例如 'user/repo' 或 'main')
40-
pattern: 配置中的模式 (例如 'user/*', 'feature/*')
41-
treat_star_as_all: 是否将单独的 "*" 视为匹配所有内容(用于分支匹配)
42-
43-
Returns:
44-
bool: 是否匹配
45-
"""
46-
if not value or not pattern:
47-
return False
48-
49-
value = value.lower()
50-
pattern = pattern.lower()
51-
52-
# 分支匹配特殊情况:单独的 "*" 匹配所有内容
53-
if pattern == "*":
54-
return True
55-
56-
if '*' in pattern or '?' in pattern or '[' in pattern:
57-
return fnmatch.fnmatch(value, pattern)
58-
59-
return value == pattern
32+
logger = logging.getLogger(__name__)
6033

6134
async def verify_signature(
6235
request: Request,
File renamed without changes.

app/models/__init__.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Copyright 2025 AptS-1547
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
"""
15+
OneBot GitHub Webhook models 模块
16+
本模块用于定义 OneBot GitHub Webhook 的数据模型,包括 Webhook 配置和 OneBot 目标类型。
17+
版本:0.1.0-alpha
18+
日期:2025-04-17
19+
本程序遵循 Apache License 2.0 许可证
20+
"""
21+
22+
from .config import Config
23+
24+
__all__ = [
25+
"Config",
26+
]

0 commit comments

Comments
 (0)