- 新增完整的 Python 实现,替代 Go 版本 - 添加 Web 登录界面和仪表板 - 实现 JWT 认证和 API 密钥管理 - 添加数据库存储功能 - 保持与 Go 版本一致的目录结构和启动脚本 - 包含完整的文档和测试脚本
130 lines
3.2 KiB
Python
130 lines
3.2 KiB
Python
"""
|
|
Gitea Webhook 数据模型
|
|
"""
|
|
|
|
from typing import List, Optional
|
|
from pydantic import BaseModel, Field
|
|
from datetime import datetime
|
|
|
|
|
|
class User(BaseModel):
|
|
"""Gitea 用户模型"""
|
|
id: int
|
|
login: str
|
|
full_name: Optional[str] = None
|
|
email: Optional[str] = None
|
|
username: Optional[str] = None
|
|
|
|
|
|
class Commit(BaseModel):
|
|
"""Git 提交模型"""
|
|
id: str
|
|
message: str
|
|
url: str
|
|
author: User
|
|
timestamp: Optional[datetime] = None
|
|
|
|
|
|
class Repository(BaseModel):
|
|
"""Git 仓库模型"""
|
|
id: int
|
|
name: str
|
|
owner: User
|
|
full_name: str
|
|
private: bool = False
|
|
clone_url: str
|
|
ssh_url: Optional[str] = None
|
|
html_url: str
|
|
default_branch: str = "main"
|
|
|
|
|
|
class GiteaWebhook(BaseModel):
|
|
"""Gitea Webhook 模型"""
|
|
secret: Optional[str] = None
|
|
ref: str
|
|
before: str
|
|
after: str
|
|
compare_url: Optional[str] = None
|
|
commits: List[Commit] = Field(default_factory=list)
|
|
repository: Repository
|
|
pusher: User
|
|
|
|
def get_branch_name(self) -> str:
|
|
"""从 ref 中提取分支名"""
|
|
prefix = "refs/heads/"
|
|
if self.ref.startswith(prefix):
|
|
return self.ref[len(prefix):]
|
|
return self.ref
|
|
|
|
def get_event_id(self) -> str:
|
|
"""生成唯一的事件 ID"""
|
|
return f"{self.repository.full_name}-{self.after}"
|
|
|
|
def get_commit_hash(self) -> str:
|
|
"""获取提交哈希"""
|
|
return self.after
|
|
|
|
def get_deduplication_key(self) -> str:
|
|
"""生成防抖键值"""
|
|
branch = self.get_branch_name()
|
|
return f"{self.after}:{branch}"
|
|
|
|
def is_push_event(self) -> bool:
|
|
"""判断是否为推送事件"""
|
|
return self.ref.startswith("refs/heads/")
|
|
|
|
def is_tag_event(self) -> bool:
|
|
"""判断是否为标签事件"""
|
|
return self.ref.startswith("refs/tags/")
|
|
|
|
def get_commit_message(self) -> str:
|
|
"""获取提交信息"""
|
|
if self.commits:
|
|
return self.commits[0].message
|
|
return ""
|
|
|
|
def get_author_info(self) -> dict:
|
|
"""获取作者信息"""
|
|
if self.commits:
|
|
author = self.commits[0].author
|
|
return {
|
|
"name": author.full_name or author.login,
|
|
"email": author.email,
|
|
"username": author.login
|
|
}
|
|
return {
|
|
"name": self.pusher.full_name or self.pusher.login,
|
|
"email": self.pusher.email,
|
|
"username": self.pusher.login
|
|
}
|
|
|
|
|
|
class WebhookEvent(BaseModel):
|
|
"""Webhook 事件模型"""
|
|
id: str
|
|
repository: str
|
|
branch: str
|
|
commit_hash: str
|
|
event_type: str
|
|
timestamp: datetime
|
|
payload: dict
|
|
|
|
class Config:
|
|
json_encoders = {
|
|
datetime: lambda v: v.isoformat()
|
|
}
|
|
|
|
|
|
class WebhookResponse(BaseModel):
|
|
"""Webhook 响应模型"""
|
|
success: bool
|
|
message: str
|
|
event_id: Optional[str] = None
|
|
job_name: Optional[str] = None
|
|
environment: Optional[str] = None
|
|
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
|
|
class Config:
|
|
json_encoders = {
|
|
datetime: lambda v: v.isoformat()
|
|
} |