# 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")