feat: 皮肤包上传管理功能,持久化数据目录
- 新增皮肤包上传/列表/删除 API(基于 upload_key) - 构建时自动解压 ZIP 皮肤包应用到项目 - 配置和皮肤包迁移到 backend/data/ 目录,切分支不会丢失 - 旧式目录皮肤自动迁移为 ZIP 格式 - 前端皮肤包管理 UI(上传、删除、下拉选择) - .gitignore 排除运行时数据目录
This commit is contained in:
@@ -3,6 +3,7 @@ import asyncio
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
@@ -15,6 +16,7 @@ from ..config import (
|
||||
DEFAULT_BUILD_DIR_RETENTION_HOURS,
|
||||
GIT_REMOTE_URL,
|
||||
BUILD_TIMEOUT_HOURS,
|
||||
SKINS_DIR,
|
||||
get_source_dir,
|
||||
)
|
||||
from .log_streamer import log_streamer
|
||||
@@ -466,7 +468,38 @@ async def generate_config(task_id: str, task, build_dir: Path) -> dict:
|
||||
config_data["CERTIFICATE"] = cert.get("cer", "")
|
||||
config_data["PROVISIONING_PROFILE"] = cert.get("pro", "")
|
||||
config_data["BUNDLE_ID"] = cert.get("name", "")
|
||||
config_data["THEME"] = cert.get("theme", "")
|
||||
theme_value = cert.get("theme", "")
|
||||
config_data["THEME"] = theme_value
|
||||
|
||||
# 解析皮肤:优先识别旧式目录(AutoPacking/ymh),再尝试上传的 ZIP
|
||||
if theme_value:
|
||||
theme_resolved = False
|
||||
# 1) 相对路径:在 build_dir(源码副本)下查找
|
||||
candidate = build_dir / theme_value
|
||||
if candidate.is_dir():
|
||||
config_data["THEME"] = str(candidate)
|
||||
theme_resolved = True
|
||||
# 2) 绝对路径:直接使用
|
||||
if not theme_resolved and os.path.isabs(theme_value) and os.path.isdir(theme_value):
|
||||
theme_resolved = True
|
||||
# 3) 上传的 ZIP 皮肤包
|
||||
if not theme_resolved:
|
||||
# 皮肤名可能是 "ymh" 或 "AutoPacking/ymh",取最后一段作为 ZIP 名
|
||||
skin_name = Path(theme_value).name
|
||||
skin_zip = SKINS_DIR / app.get("upload_key", "") / f"{skin_name}.zip"
|
||||
if skin_zip.exists():
|
||||
skin_extract_dir = build_dir / "skin_temp"
|
||||
skin_extract_dir.mkdir(exist_ok=True)
|
||||
with zipfile.ZipFile(skin_zip, "r") as zf:
|
||||
zf.extractall(skin_extract_dir)
|
||||
entries = list(skin_extract_dir.iterdir())
|
||||
if len(entries) == 1 and entries[0].is_dir():
|
||||
config_data["THEME"] = str(entries[0])
|
||||
else:
|
||||
config_data["THEME"] = str(skin_extract_dir)
|
||||
await log_streamer.emit(task_id, f"皮肤包 {skin_name}.zip 已解压")
|
||||
else:
|
||||
await log_streamer.emit(task_id, f"皮肤 {theme_value} 不存在")
|
||||
|
||||
# 从 Provisioning Profile 提取 TEAM_ID 和 PROVISIONING_NAME
|
||||
provisioning_profile = config_data.get("PROVISIONING_PROFILE", "")
|
||||
|
||||
Reference in New Issue
Block a user