feat: 2,3,7,8,9 - search/sort, Docker, log viewer, .tsb backup
- Dashboard browser: search box + sort dropdown (name/category/author) - Dockerfile + docker-compose.yml - Debug page: log viewer button (/api/logs) - Settings: .tsb full backup export (dashboards+scenes+config) - F1 composite dashboard previously included
This commit is contained in:
@@ -313,6 +313,50 @@ async def api_reload_game_plugins():
|
||||
return {"ok": True, "count": len(game_plugin_manager.list_all())}
|
||||
|
||||
|
||||
# ---- Logs ----
|
||||
@router.get("/logs")
|
||||
async def api_get_logs(lines: int = 50):
|
||||
from pathlib import Path
|
||||
log_file = Path(__file__).resolve().parent.parent / "logs" / "turbosu.log"
|
||||
if not log_file.exists():
|
||||
return {"lines": []}
|
||||
try:
|
||||
with open(log_file, "r", encoding="utf-8", errors="replace") as f:
|
||||
all_lines = f.readlines()
|
||||
return {"lines": [l.rstrip() for l in all_lines[-lines:]]}
|
||||
except Exception:
|
||||
return {"lines": []}
|
||||
|
||||
|
||||
# ---- Full Backup (.tsb) ----
|
||||
@router.get("/backup/export")
|
||||
async def api_export_backup():
|
||||
import io, zipfile
|
||||
from fastapi.responses import Response
|
||||
|
||||
buf = io.BytesIO()
|
||||
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
|
||||
base = Path(__file__).resolve().parent.parent
|
||||
data_dir = base / "data"
|
||||
if data_dir.exists():
|
||||
for f in data_dir.rglob("*"):
|
||||
if f.is_file() and "__pycache__" not in str(f):
|
||||
zf.write(f, f.relative_to(base))
|
||||
dash_dir = base / "dashboards"
|
||||
if dash_dir.exists():
|
||||
for f in dash_dir.rglob("*"):
|
||||
if f.is_file():
|
||||
zf.write(f, f.relative_to(base))
|
||||
games_dir = base / "games" / "user"
|
||||
if games_dir.exists():
|
||||
for f in games_dir.rglob("*"):
|
||||
if f.is_file():
|
||||
zf.write(f, f.relative_to(base))
|
||||
|
||||
return Response(content=buf.getvalue(), media_type="application/zip",
|
||||
headers={"Content-Disposition": "attachment; filename=turbosu_backup.tsb"})
|
||||
|
||||
|
||||
# ---- Data Forwarding ----
|
||||
@router.get("/forward")
|
||||
async def api_list_forward_targets():
|
||||
|
||||
Reference in New Issue
Block a user