feat: publish-from-local with builtin/market filter, file picker modal
This commit is contained in:
@@ -763,3 +763,75 @@ async def api_market_delete(data: dict):
|
||||
return {"ok": resp.status_code < 400}
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": str(e)}
|
||||
|
||||
|
||||
@router.post("/market/publish-local")
|
||||
async def api_market_publish_local(data: dict):
|
||||
import io, zipfile, json as _json
|
||||
token = data.get("token", "")
|
||||
dash_id = data.get("id", "")
|
||||
pub_type = data.get("type", "dashboard")
|
||||
|
||||
if not token:
|
||||
return {"error": "需要登录"}
|
||||
|
||||
try:
|
||||
from models.dashboard import dashboard_manager
|
||||
from models.scene import scene_manager
|
||||
|
||||
if pub_type == "scene":
|
||||
scene = scene_manager.get(dash_id)
|
||||
if not scene:
|
||||
return {"error": "场景不存在"}
|
||||
if scene.get("is_builtin"):
|
||||
return {"error": "不能发布内置场景"}
|
||||
|
||||
buf = io.BytesIO()
|
||||
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
|
||||
zf.writestr("scene.json", _json.dumps(scene, indent=2, ensure_ascii=False))
|
||||
zip_data = buf.getvalue()
|
||||
|
||||
cfg = get_config()
|
||||
url = cfg.get("market_url", "https://turbosu.yeij.top")
|
||||
import httpx
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.post(
|
||||
f"{url}/api/collections/scenes/records",
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
data={"name": scene.get("name",""), "description": scene.get("description",""),
|
||||
"game_id": scene.get("game_id",""), "author": scene.get("author",""),
|
||||
"dashb_pending": "true", "manifest_id": scene.get("id","")},
|
||||
files={"file": (f"{dash_id}.tss", zip_data, "application/zip")},
|
||||
)
|
||||
return resp.json()
|
||||
else:
|
||||
theme_dir = dashboard_manager.get_dir(dash_id)
|
||||
if not theme_dir:
|
||||
return {"error": "仪表盘不存在"}
|
||||
theme = dashboard_manager.get(dash_id)
|
||||
if not theme or theme.get("is_builtin"):
|
||||
return {"error": "不能发布内置或市场仪表盘"}
|
||||
|
||||
buf = io.BytesIO()
|
||||
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
|
||||
for f in sorted(theme_dir.rglob('*')):
|
||||
if f.is_file():
|
||||
zf.write(f, f.relative_to(theme_dir))
|
||||
zip_data = buf.getvalue()
|
||||
|
||||
cfg = get_config()
|
||||
url = cfg.get("market_url", "https://turbosu.yeij.top")
|
||||
import httpx
|
||||
async with httpx.AsyncClient(timeout=30) as client:
|
||||
resp = await client.post(
|
||||
f"{url}/api/collections/dashboards/records",
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
data={"name": theme.get("name",""), "category": theme.get("category",""),
|
||||
"author": theme.get("author",""), "version": theme.get("version","1.0"),
|
||||
"dashb_pending": "true", "manifest_id": theme.get("id",""),
|
||||
"icon": theme.get("icon",""), "supported_games": theme.get("supported_games","all")},
|
||||
files={"file": (f"{dash_id}.tsd", zip_data, "application/zip")},
|
||||
)
|
||||
return resp.json()
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
Reference in New Issue
Block a user