freeleaps-ops/apps/gitea-webhook-ambassador-python/app/models/gitea.py
Nicolas f6c515157c feat: 添加 Python 版本的 Gitea Webhook Ambassador
- 新增完整的 Python 实现,替代 Go 版本
- 添加 Web 登录界面和仪表板
- 实现 JWT 认证和 API 密钥管理
- 添加数据库存储功能
- 保持与 Go 版本一致的目录结构和启动脚本
- 包含完整的文档和测试脚本
2025-07-20 21:17:10 +08:00

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()
}