feat: validate .tsd on upload, auto-extract manifest metadata
This commit is contained in:
+34
-4
@@ -543,17 +543,47 @@ async def api_market_register(data: dict):
|
||||
|
||||
@router.post("/market/upload")
|
||||
async def api_market_upload(file: UploadFile = File(...), name: str = "", category: str = "", author: str = "", token: str = ""):
|
||||
import httpx
|
||||
import httpx, io, zipfile, json as _json
|
||||
|
||||
# Validate .tsd
|
||||
if not file.filename or not file.filename.endswith('.tsd'):
|
||||
return {"error": "仅支持 .tsd 文件"}
|
||||
|
||||
try:
|
||||
zip_data = await file.read()
|
||||
with zipfile.ZipFile(io.BytesIO(zip_data), 'r') as zf:
|
||||
names = zf.namelist()
|
||||
if 'manifest.json' not in names:
|
||||
return {"error": "无效的仪表盘文件:缺少 manifest.json"}
|
||||
if 'index.html' not in names:
|
||||
return {"error": "无效的仪表盘文件:缺少 index.html"}
|
||||
|
||||
manifest = _json.loads(zf.read('manifest.json').decode('utf-8'))
|
||||
actual_name = name or manifest.get('name', file.filename.replace('.tsd', ''))
|
||||
actual_category = category or manifest.get('category', 'community')
|
||||
actual_author = author or manifest.get('author', 'Unknown')
|
||||
actual_version = manifest.get('version', '1.0.0')
|
||||
supported = manifest.get('supported_games', 'all')
|
||||
icon = manifest.get('config', {}).get('icon', '📦')
|
||||
desc = manifest.get('description', '')
|
||||
except zipfile.BadZipFile:
|
||||
return {"error": "无效的 zip 文件"}
|
||||
except Exception as e:
|
||||
return {"error": f"文件解析失败: {str(e)}"}
|
||||
|
||||
cfg = get_config()
|
||||
url = cfg.get("market_url", "http://127.0.0.1:5301")
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
files_httpx = {"file": (file.filename, await file.read(), file.content_type)}
|
||||
resp = await client.post(
|
||||
f"{url}/api/collections/dashboards/records",
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
data={"name": name, "category": category, "author": author, "version": "1.0.0", "dashb_pending": true},
|
||||
files=files_httpx,
|
||||
data={
|
||||
"name": actual_name, "category": actual_category, "author": actual_author,
|
||||
"version": actual_version, "supported_games": supported,
|
||||
"icon": icon, "description": desc, "dashb_pending": True,
|
||||
},
|
||||
files={"file": (file.filename, zip_data, file.content_type)},
|
||||
)
|
||||
return resp.json()
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user