Initial commit: rdgen with GitHub/Gitea dual build backend
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
import secrets
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
|
||||
|
||||
# GitHub Actions 运行状态 -> 中文展示文案
|
||||
STATUS_LABELS = {
|
||||
"Starting generator...please wait": "正在启动构建任务",
|
||||
"queued": "排队中",
|
||||
"in_progress": "构建中",
|
||||
"success": "构建成功",
|
||||
"failure": "构建失败",
|
||||
"cancelled": "已取消",
|
||||
"timed_out": "已超时",
|
||||
"skipped": "已跳过",
|
||||
"action_required": "等待人工处理",
|
||||
}
|
||||
|
||||
# 状态对应的徽标样式(模板中使用)
|
||||
STATUS_BADGE = {
|
||||
"Starting generator...please wait": "badge-info",
|
||||
"queued": "badge-info",
|
||||
"in_progress": "badge-info",
|
||||
"success": "badge-success",
|
||||
"failure": "badge-danger",
|
||||
"cancelled": "badge-warning",
|
||||
"timed_out": "badge-warning",
|
||||
"skipped": "badge-secondary",
|
||||
"action_required": "badge-warning",
|
||||
}
|
||||
|
||||
PLATFORM_LABELS = {
|
||||
"windows": "Windows 64 位",
|
||||
"windows-x86": "Windows 32 位",
|
||||
"linux": "Linux",
|
||||
"android": "Android",
|
||||
"macos": "macOS",
|
||||
}
|
||||
|
||||
|
||||
def generate_token_key():
|
||||
return secrets.token_hex(20)
|
||||
|
||||
|
||||
class GithubRun(models.Model):
|
||||
uuid = models.CharField("任务 UUID", max_length=100, db_index=True)
|
||||
status = models.CharField("构建状态", max_length=100, default="queued")
|
||||
github_run_id = models.BigIntegerField("GitHub 运行编号", null=True, blank=True)
|
||||
# 构建平台:github / gitea;历史任务默认 github。切换平台后旧任务仍按此值查询状态
|
||||
backend = models.CharField("构建平台", max_length=20, default="github")
|
||||
platform = models.CharField("目标平台", max_length=20, blank=True, default="")
|
||||
filename = models.CharField("文件名", max_length=200, blank=True, default="")
|
||||
# 提交时的表单快照(纯字符串/数值,图片为 data URL),供失败后「一键重试」重新派发
|
||||
config_data = models.JSONField("构建配置快照", blank=True, default=dict)
|
||||
created_by = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
verbose_name="提交用户",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="builds",
|
||||
)
|
||||
created_at = models.DateTimeField("提交时间", auto_now_add=True)
|
||||
updated_at = models.DateTimeField("更新时间", auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "构建任务"
|
||||
verbose_name_plural = "构建任务"
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.filename or self.uuid}({self.status_label()})"
|
||||
|
||||
def status_label(self):
|
||||
return STATUS_LABELS.get(self.status, self.status)
|
||||
|
||||
def status_badge(self):
|
||||
return STATUS_BADGE.get(self.status, "badge-secondary")
|
||||
|
||||
def platform_label(self):
|
||||
return PLATFORM_LABELS.get(self.platform, self.platform or "未知平台")
|
||||
|
||||
def is_finished(self):
|
||||
return self.status in ("success", "failure", "cancelled", "timed_out", "skipped")
|
||||
|
||||
@property
|
||||
def github_log_url(self):
|
||||
if self.github_run_id:
|
||||
# 局部导入避免循环依赖;按任务记录的平台生成对应站点的日志链接
|
||||
from .build_backends import get_backend
|
||||
return get_backend(self.backend or 'github').log_url(self.github_run_id)
|
||||
return ""
|
||||
|
||||
def short_uuid(self):
|
||||
return self.uuid[:8] if len(self.uuid) >= 8 else self.uuid
|
||||
|
||||
|
||||
class SiteSetting(models.Model):
|
||||
"""后台可改的站点配置(键值存储)。
|
||||
|
||||
取值优先级由 app_settings 统一处理:后台配置(本表)→ 环境变量 → 默认值,
|
||||
因此历史的环境变量部署方式继续有效。
|
||||
"""
|
||||
|
||||
key = models.CharField("配置项", max_length=50, primary_key=True)
|
||||
value = models.TextField("配置值", blank=True, default='')
|
||||
updated_at = models.DateTimeField("更新时间", auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "站点配置"
|
||||
verbose_name_plural = "站点配置"
|
||||
|
||||
def __str__(self):
|
||||
return self.key
|
||||
|
||||
|
||||
class SavedConfig(models.Model):
|
||||
"""用户保存的客户端构建配置方案(与账号绑定,可在定制页直接载入、可导出/导入)。"""
|
||||
|
||||
owner = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
verbose_name="所属用户",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="saved_configs",
|
||||
)
|
||||
name = models.CharField("方案名称", max_length=100)
|
||||
data = models.JSONField("配置内容", default=dict)
|
||||
created_at = models.DateTimeField("创建时间", auto_now_add=True)
|
||||
updated_at = models.DateTimeField("更新时间", auto_now=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "构建配置方案"
|
||||
verbose_name_plural = "构建配置方案"
|
||||
unique_together = [('owner', 'name')]
|
||||
ordering = ["-updated_at"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name}({self.owner})"
|
||||
|
||||
def platform_label(self):
|
||||
return PLATFORM_LABELS.get(self.data.get('platform', ''), '未指定平台')
|
||||
|
||||
@property
|
||||
def version_label(self):
|
||||
return self.data.get('version', '') or '未指定版本'
|
||||
|
||||
|
||||
class ApiToken(models.Model):
|
||||
"""供 JSON API(如 rdgen-cli)使用的个人访问令牌"""
|
||||
|
||||
key = models.CharField("令牌", max_length=64, primary_key=True, default=generate_token_key, editable=False)
|
||||
name = models.CharField("令牌名称", max_length=100, help_text="便于识别用途,例如:CI 构建机")
|
||||
user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
verbose_name="所属用户",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="api_tokens",
|
||||
)
|
||||
is_active = models.BooleanField("启用", default=True)
|
||||
created_at = models.DateTimeField("创建时间", auto_now_add=True)
|
||||
last_used_at = models.DateTimeField("最后使用时间", null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "API 令牌"
|
||||
verbose_name_plural = "API 令牌"
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name}({self.user})"
|
||||
Reference in New Issue
Block a user