|
# retoor <retoor@molodetz.nl>
|
|
|
|
import logging
|
|
from typing import Annotated
|
|
from fastapi import APIRouter, Form, Request
|
|
from fastapi.responses import HTMLResponse
|
|
from devplacepy.models import GameEraStartForm
|
|
from devplacepy.responses import respond, action_result, json_error, wants_json
|
|
from devplacepy.schemas import AdminGameOut
|
|
from devplacepy.seo import base_seo_context, site_url, website_schema
|
|
from devplacepy.services.audit import record as audit
|
|
from devplacepy.services.game import GameError, store
|
|
from devplacepy.utils import require_admin
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
|
|
def _era_context() -> dict:
|
|
era = store.active_era()
|
|
return {
|
|
"era_active": bool(era),
|
|
"era_name": era["name"] if era else "",
|
|
"era_number": int(era["era_number"]) if era else 0,
|
|
"era_started_at": era["started_at"] if era else "",
|
|
"era_ends_at": era["ends_at"] if era else "",
|
|
}
|
|
|
|
|
|
@router.get("/game", response_class=HTMLResponse)
|
|
async def admin_game(request: Request):
|
|
admin = require_admin(request)
|
|
base = site_url(request)
|
|
seo_ctx = base_seo_context(
|
|
request,
|
|
title="Code Farm - Admin",
|
|
description="Manage Code Farm Eras.",
|
|
robots="noindex,nofollow",
|
|
breadcrumbs=[
|
|
{"name": "Home", "url": "/feed"},
|
|
{"name": "Admin", "url": "/admin"},
|
|
{"name": "Code Farm", "url": "/admin/game"},
|
|
],
|
|
schemas=[website_schema(base)],
|
|
)
|
|
return respond(
|
|
request,
|
|
"admin_game.html",
|
|
{
|
|
**seo_ctx,
|
|
"request": request,
|
|
"user": admin,
|
|
"admin_section": "game",
|
|
**_era_context(),
|
|
},
|
|
model=AdminGameOut,
|
|
)
|
|
|
|
|
|
@router.post("/game/era/start")
|
|
async def admin_game_era_start(request: Request, data: Annotated[GameEraStartForm, Form()]):
|
|
admin = require_admin(request)
|
|
try:
|
|
era = store.start_era(data.name, data.duration_days)
|
|
except GameError as exc:
|
|
logger.warning(f"Admin {admin['username']} failed to start Era: {exc}")
|
|
if wants_json(request):
|
|
return json_error(400, str(exc))
|
|
return action_result(request, "/admin/game")
|
|
audit.record(
|
|
request,
|
|
"admin.game.era_start",
|
|
user=admin,
|
|
metadata={"era_number": era["era_number"], "name": era["name"]},
|
|
summary=f"admin {admin['username']} started Era {era['name']}",
|
|
)
|
|
return action_result(request, "/admin/game")
|
|
|
|
|
|
@router.post("/game/era/end")
|
|
async def admin_game_era_end(request: Request):
|
|
admin = require_admin(request)
|
|
try:
|
|
result = store.end_era()
|
|
except GameError as exc:
|
|
logger.warning(f"Admin {admin['username']} failed to end Era: {exc}")
|
|
if wants_json(request):
|
|
return json_error(400, str(exc))
|
|
return action_result(request, "/admin/game")
|
|
audit.record(
|
|
request,
|
|
"admin.game.era_end",
|
|
user=admin,
|
|
metadata=result,
|
|
summary=f"admin {admin['username']} ended Era {result['era_number']}",
|
|
)
|
|
return action_result(request, "/admin/game")
|