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}
|
return {"ok": resp.status_code < 400}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"ok": False, "error": str(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)}
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ const PageMarket = {
|
|||||||
<p style="color:var(--text-secondary);font-size:14px;margin-top:4px">浏览并安装社区分享的仪表盘和场景 <span id="m-status" style="color:var(--text-tertiary)"> 未登录</span></p>
|
<p style="color:var(--text-secondary);font-size:14px;margin-top:4px">浏览并安装社区分享的仪表盘和场景 <span id="m-status" style="color:var(--text-tertiary)"> 未登录</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:8px">
|
<div style="display:flex;gap:8px">
|
||||||
<button id="btn-m-upload" class="btn btn-sm btn-secondary" style="display:none">发布仪表盘</button>
|
<button id="btn-m-upload" class="btn btn-sm btn-secondary" style="display:none">发布你的作品</button>
|
||||||
<button id="btn-m-login" class="btn btn-sm btn-primary">登录</button>
|
<button id="btn-m-login" class="btn btn-sm btn-primary">登录</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user