All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m8s
All three services now fetch page data via (service ...) IO primitives in .sx defpages instead of Python middleman functions. - Account: newsletters-data → AccountPageService.newsletters_data - Federation: 8 page helpers → FederationPageService methods (timeline, compose, search, following, followers, notifications) - Cart: 4 page helpers → CartPageService methods (overview, page-cart, admin, payments) - Serializers moved to service modules, thin delegates kept for routes - ~520 lines of Python page helpers removed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
108 lines
4.0 KiB
Python
108 lines
4.0 KiB
Python
"""Federation defpage setup — registers layouts and loads .sx pages."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
|
|
def setup_federation_pages() -> None:
|
|
"""Register federation-specific layouts and load page definitions."""
|
|
_register_federation_layouts()
|
|
_load_federation_page_files()
|
|
|
|
|
|
def _load_federation_page_files() -> None:
|
|
import os
|
|
from shared.sx.pages import load_page_dir
|
|
load_page_dir(os.path.dirname(__file__), "federation")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Layouts
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def _register_federation_layouts() -> None:
|
|
from shared.sx.layouts import register_custom_layout
|
|
register_custom_layout("social", _social_full, _social_oob)
|
|
|
|
|
|
async def _social_full(ctx: dict, **kw: Any) -> str:
|
|
from shared.sx.helpers import root_header_sx, header_child_sx, render_to_sx
|
|
from shared.sx.parser import SxExpr
|
|
|
|
actor = ctx.get("actor")
|
|
actor_data = _serialize_actor(actor) if actor else None
|
|
nav = await render_to_sx("federation-social-nav", actor=actor_data)
|
|
social_hdr = await render_to_sx("federation-social-header", nav=SxExpr(nav))
|
|
root_hdr = await root_header_sx(ctx)
|
|
child = await header_child_sx(social_hdr)
|
|
return "(<> " + root_hdr + " " + child + ")"
|
|
|
|
|
|
async def _social_oob(ctx: dict, **kw: Any) -> str:
|
|
from shared.sx.helpers import root_header_sx, render_to_sx
|
|
from shared.sx.parser import SxExpr
|
|
|
|
actor = ctx.get("actor")
|
|
actor_data = _serialize_actor(actor) if actor else None
|
|
nav = await render_to_sx("federation-social-nav", actor=actor_data)
|
|
social_hdr = await render_to_sx("federation-social-header", nav=SxExpr(nav))
|
|
child_oob = await render_to_sx("oob-header-sx",
|
|
parent_id="root-header-child",
|
|
row=SxExpr(social_hdr))
|
|
root_hdr_oob = await root_header_sx(ctx, oob=True)
|
|
return "(<> " + child_oob + " " + root_hdr_oob + ")"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Serializers and helpers — still used by layouts and route handlers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def _serialize_actor(actor) -> dict | None:
|
|
"""Serialize an actor profile to a dict for sx defcomps."""
|
|
from services.federation_page import _serialize_actor as _impl
|
|
return _impl(actor)
|
|
|
|
|
|
def _serialize_timeline_item(item) -> dict:
|
|
"""Serialize a timeline item DTO to a dict for sx defcomps."""
|
|
from services.federation_page import _serialize_timeline_item as _impl
|
|
return _impl(item)
|
|
|
|
|
|
def _serialize_remote_actor(a) -> dict:
|
|
"""Serialize a remote actor DTO to a dict for sx defcomps."""
|
|
from services.federation_page import _serialize_remote_actor as _impl
|
|
return _impl(a)
|
|
|
|
|
|
async def _social_page(ctx: dict, actor, *, content: str,
|
|
title: str = "Rose Ash", meta_html: str = "") -> str:
|
|
"""Build a full social page with social header."""
|
|
from shared.sx.helpers import render_to_sx, root_header_sx, header_child_sx, full_page_sx
|
|
from shared.sx.parser import SxExpr
|
|
from markupsafe import escape
|
|
|
|
actor_data = _serialize_actor(actor)
|
|
nav = await render_to_sx("federation-social-nav", actor=actor_data)
|
|
social_hdr = await render_to_sx("federation-social-header", nav=SxExpr(nav))
|
|
hdr = await root_header_sx(ctx)
|
|
child = await header_child_sx(social_hdr)
|
|
header_rows = "(<> " + hdr + " " + child + ")"
|
|
return await full_page_sx(ctx, header_rows=header_rows, content=content,
|
|
meta_html=meta_html or f'<title>{escape(title)}</title>')
|
|
|
|
|
|
def _get_actor():
|
|
"""Return current user's actor or None."""
|
|
from quart import g
|
|
return getattr(g, "_social_actor", None)
|
|
|
|
|
|
def _require_actor():
|
|
"""Return current user's actor or abort 403."""
|
|
from quart import abort
|
|
actor = _get_actor()
|
|
if not actor:
|
|
abort(403, "You need to choose a federation username first")
|
|
return actor
|