Task 1: Move BUILTIN_COMMANDERS + load_commander_meta() to shared.py
Fix import_routes.py to use _shared.COMMANDER_META (module ref)
Task 2: Rewrite precon.py to use _shared.PRECON_INDEX (module ref)
Task 3: Add @app.on_event('startup') safety net for uvicorn --reload
96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
"""
|
|
routes/precon.py
|
|
================
|
|
Precon deck management endpoints:
|
|
GET /api/lab/precons
|
|
POST /api/lab/precons/install
|
|
POST /api/lab/precons/install-batch
|
|
POST /api/lab/precons/refresh
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
|
|
import routes.shared as _shared # module reference, not value import
|
|
from routes.shared import CFG, PRECON_DIR, download_precon_database, log
|
|
|
|
router = APIRouter(tags=["precon"])
|
|
|
|
|
|
@router.get("/api/lab/precons")
|
|
async def list_precons():
|
|
"""List all available precon decks."""
|
|
return {"precons": _shared.PRECON_INDEX} # reads current value every call
|
|
|
|
|
|
@router.post("/api/lab/precons/install")
|
|
async def install_precon(req: dict):
|
|
"""Install a precon deck to the Forge decks directory.
|
|
Body: {"fileName": "Elven_Empire.dck"}
|
|
"""
|
|
file_name = req.get("fileName", "")
|
|
if not file_name:
|
|
raise HTTPException(400, "fileName is required")
|
|
|
|
src = PRECON_DIR / file_name
|
|
if not src.exists():
|
|
raise HTTPException(404, f"Precon not found: {file_name}")
|
|
|
|
decks_dir = CFG.forge_decks_dir
|
|
if not decks_dir or not os.path.isdir(decks_dir):
|
|
raise HTTPException(500, f"Forge decks directory not found: {decks_dir}")
|
|
|
|
dst = Path(decks_dir) / file_name
|
|
shutil.copy2(str(src), str(dst))
|
|
|
|
deck_name = file_name.replace(".dck", "")
|
|
return {
|
|
"installed": True,
|
|
"deckName": deck_name,
|
|
"destination": str(dst),
|
|
"message": f"Installed {deck_name} to Forge decks",
|
|
}
|
|
|
|
|
|
@router.post("/api/lab/precons/install-batch")
|
|
async def install_precons_batch(req: dict):
|
|
"""Install multiple precon decks at once.
|
|
Body: {"fileNames": ["Elven_Empire.dck", "Necron_Dynasties.dck"]}
|
|
"""
|
|
file_names = req.get("fileNames", [])
|
|
if not file_names:
|
|
raise HTTPException(400, "fileNames list is required")
|
|
|
|
decks_dir = CFG.forge_decks_dir
|
|
if not decks_dir or not os.path.isdir(decks_dir):
|
|
raise HTTPException(500, f"Forge decks directory not found: {decks_dir}")
|
|
|
|
results = []
|
|
for file_name in file_names:
|
|
src = PRECON_DIR / file_name
|
|
if not src.exists():
|
|
results.append({"fileName": file_name, "installed": False, "error": "not found"})
|
|
continue
|
|
dst = Path(decks_dir) / file_name
|
|
shutil.copy2(str(src), str(dst))
|
|
deck_name = file_name.replace(".dck", "")
|
|
results.append({"fileName": file_name, "installed": True, "deckName": deck_name})
|
|
|
|
return {"results": results}
|
|
|
|
|
|
@router.post("/api/lab/precons/refresh")
|
|
async def refresh_precons():
|
|
"""Force re-download of all Commander precon decks from GitHub."""
|
|
result = download_precon_database(force=True)
|
|
if result.get("error"):
|
|
raise HTTPException(502, result["error"])
|
|
return {
|
|
"message": f"Downloaded {result['downloaded']} Commander precon decks",
|
|
"total": result.get("total", 0),
|
|
}
|