# retoor from fastapi import Request from devplacepy.database import get_table from devplacepy.services.game import store from devplacepy.services.pubsub import publish def farm_topic(username: str) -> str: return f"public.game.farm.{username}" async def notify_farm(username: str) -> None: if not username: return try: await publish(farm_topic(username), {"kind": "update", "username": username}) except Exception: pass def owner_by_username(username: str) -> dict | None: return get_table("users").find_one(username=username) def state_payload(user: dict, viewer: dict | None = None) -> dict: from devplacepy.services.game import economy from devplacepy.utils import award_rewards, track_action farm = store.ensure_farm(user["uid"]) payload = store.serialize_farm(farm, viewer=viewer or user, owner=user) harvested = int(payload.get("auto_harvested") or 0) if harvested: track_action(user["uid"], "harvest") award_rewards(user["uid"], economy.site_xp_for(payload.get("auto_harvest_xp") or 0)) return payload def action_error(request: Request, message: str, redirect_url: str): from urllib.parse import quote from devplacepy.responses import json_error, wants_json from fastapi.responses import RedirectResponse if wants_json(request): return json_error(400, message) separator = "&" if "?" in redirect_url else "?" return RedirectResponse( url=f"{redirect_url}{separator}error={quote(message)}", status_code=302 ) def game_seo(request: Request, title: str, description: str) -> dict: from devplacepy.seo import base_seo_context return base_seo_context( request, title=title, description=description, robots="noindex,follow", breadcrumbs=[ {"name": "Home", "url": "/feed"}, {"name": "Code Farm", "url": "/game"}, ], )