site+server: add manual Zern Prologue pack variant (download zip + instructions) — site card with path %USERPROFILE%\.zernmc\instances\ZernPrologue, prism/multimc import, endpoint /pack/ZernPrologue/zip (requires pass)

This commit is contained in:
SashegDev
2026-09-02 00:57:43 +00:00
parent 48f73ef0d4
commit 3006408447
3 changed files with 60 additions and 469 deletions
+26
View File
@@ -1364,6 +1364,32 @@ async def get_pack_file(pack_name: str, file_path: str, request: Request, curren
return await send_file_async(full_path, request, cache=True)
@app.get("/pack/{pack_name}/zip")
async def download_pack_zip(pack_name: str, request: Request, current_user: dict = Depends(get_current_user)):
"""Download whole pack as zip for manual installation (requires pass)"""
if not has_permission(current_user["role"], Permissions.DOWNLOAD_PACK):
raise HTTPException(403, "Requires active pass")
if is_pack_disabled(pack_name):
raise HTTPException(403, "Pack is disabled")
pack_path = PACKS_DIR / pack_name
if not pack_path.exists() or not pack_path.is_dir():
raise HTTPException(404, "Pack not found")
import tempfile, zipfile
tmp = Path(tempfile.gettempdir()) / f"{pack_name}.zip"
# re-use if fresh (<5 min)
if tmp.exists() and (datetime.utcnow().timestamp() - tmp.stat().st_mtime) < 300:
return await send_file_async(tmp, request, content_type="application/zip", cache=False)
# create zip
def _zip():
with zipfile.ZipFile(tmp, 'w', zipfile.ZIP_DEFLATED) as zf:
for f in pack_path.rglob("*"):
if f.is_file():
zf.write(f, f.relative_to(pack_path))
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, _zip)
return await send_file_async(tmp, request, content_type="application/zip", cache=False)
# ====================== ЭНДПОИНТЫ ДЛЯ ЛАУНЧЕРА ======================
def get_current_launcher_version() -> str: