Slim sxc/pages/__init__.py for federation, test, cart, blog
Move render functions, layouts, helpers, and utils from __init__.py to sub-modules (renders.py, layouts.py, helpers.py, utils.py). Update all bp route imports to point at sub-modules directly. Each __init__.py is now ≤20 lines of setup + registration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ async def _render_social_auth_page(component: str, title: str, **kwargs) -> str:
|
||||
"""Render an auth page with social layout — replaces sx_components helpers."""
|
||||
from shared.sx.helpers import render_to_sx
|
||||
from shared.sx.page import get_template_context
|
||||
from sxc.pages import _social_page
|
||||
from sxc.pages.utils import _social_page
|
||||
ctx = await get_template_context()
|
||||
content = await render_to_sx(component, **{k: v for k, v in kwargs.items() if v})
|
||||
return await _social_page(ctx, None, content=content, title=title)
|
||||
|
||||
@@ -33,7 +33,7 @@ async def _render_choose_username(*, actor=None, error="", username=""):
|
||||
from shared.sx.helpers import render_to_sx
|
||||
from shared.sx.parser import SxExpr
|
||||
from shared.sx.page import get_template_context
|
||||
from sxc.pages import _social_page
|
||||
from sxc.pages.utils import _social_page
|
||||
from markupsafe import escape
|
||||
|
||||
ctx = await get_template_context()
|
||||
|
||||
@@ -95,7 +95,7 @@ def register(url_prefix="/social"):
|
||||
|
||||
@bp.get("/search/page")
|
||||
async def search_page():
|
||||
from sxc.pages import _serialize_remote_actor, _serialize_actor
|
||||
from sxc.pages.utils import _serialize_remote_actor, _serialize_actor
|
||||
|
||||
actor = getattr(g, "_social_actor", None)
|
||||
query = request.args.get("q", "").strip()
|
||||
@@ -154,7 +154,7 @@ def register(url_prefix="/social"):
|
||||
|
||||
async def _actor_card_response(actor, remote_actor_url, is_followed):
|
||||
"""Re-render a single actor card after follow/unfollow via HTMX."""
|
||||
from sxc.pages import _serialize_remote_actor, _serialize_actor
|
||||
from sxc.pages.utils import _serialize_remote_actor, _serialize_actor
|
||||
|
||||
remote_dto = await services.federation.get_or_fetch_remote_actor(
|
||||
g.s, remote_actor_url,
|
||||
@@ -298,7 +298,7 @@ def register(url_prefix="/social"):
|
||||
|
||||
@bp.get("/following/page")
|
||||
async def following_list_page():
|
||||
from sxc.pages import _serialize_remote_actor, _serialize_actor
|
||||
from sxc.pages.utils import _serialize_remote_actor, _serialize_actor
|
||||
|
||||
actor = _require_actor()
|
||||
page = request.args.get("page", 1, type=int)
|
||||
@@ -320,7 +320,7 @@ def register(url_prefix="/social"):
|
||||
|
||||
@bp.get("/followers/page")
|
||||
async def followers_list_page():
|
||||
from sxc.pages import _serialize_remote_actor, _serialize_actor
|
||||
from sxc.pages.utils import _serialize_remote_actor, _serialize_actor
|
||||
|
||||
actor = _require_actor()
|
||||
page = request.args.get("page", 1, type=int)
|
||||
@@ -387,7 +387,7 @@ def register(url_prefix="/social"):
|
||||
|
||||
async def _render_timeline_items(items, timeline_type, actor, actor_id=None):
|
||||
"""Render timeline pagination items as SX fragment."""
|
||||
from sxc.pages import _serialize_timeline_item, _serialize_actor
|
||||
from sxc.pages.utils import _serialize_timeline_item, _serialize_actor
|
||||
|
||||
item_dicts = [_serialize_timeline_item(i) for i in items]
|
||||
actor_data = _serialize_actor(actor)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
"""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."""
|
||||
@@ -16,82 +14,7 @@ def _load_federation_page_files() -> None:
|
||||
load_page_dir(os.path.dirname(__file__), "federation")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Layouts — .sx defcomps read free variables from env
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _register_federation_layouts() -> None:
|
||||
from shared.sx.layouts import register_custom_layout
|
||||
from .utils import _social_full, _social_oob
|
||||
register_custom_layout("social", _social_full, _social_oob)
|
||||
|
||||
|
||||
def _actor_data(ctx: dict) -> dict | None:
|
||||
actor = ctx.get("actor")
|
||||
if not actor:
|
||||
return None
|
||||
from services.federation_page import _serialize_actor
|
||||
return _serialize_actor(actor)
|
||||
|
||||
|
||||
async def _social_full(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env
|
||||
env = _ctx_to_env(ctx)
|
||||
env["actor"] = kw.get("actor") or _actor_data(ctx)
|
||||
return await render_to_sx_with_env("social-layout-full", env)
|
||||
|
||||
|
||||
async def _social_oob(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env
|
||||
env = _ctx_to_env(ctx, oob=True)
|
||||
env["actor"] = kw.get("actor") or _actor_data(ctx)
|
||||
return await render_to_sx_with_env("social-layout-oob", env)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers still used by 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_with_env, _ctx_to_env, full_page_sx
|
||||
from markupsafe import escape
|
||||
|
||||
env = _ctx_to_env(ctx)
|
||||
env["actor"] = _serialize_actor(actor) if actor else None
|
||||
header_rows = await render_to_sx_with_env("social-layout-full", env)
|
||||
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
|
||||
|
||||
71
federation/sxc/pages/utils.py
Normal file
71
federation/sxc/pages/utils.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""Federation page utilities — serializers, actor helpers, social page builder."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
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_with_env, _ctx_to_env, full_page_sx
|
||||
from markupsafe import escape
|
||||
|
||||
env = _ctx_to_env(ctx)
|
||||
env["actor"] = _serialize_actor(actor) if actor else None
|
||||
header_rows = await render_to_sx_with_env("social-layout-full", env)
|
||||
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
|
||||
|
||||
|
||||
def _actor_data(ctx: dict) -> dict | None:
|
||||
actor = ctx.get("actor")
|
||||
if not actor:
|
||||
return None
|
||||
return _serialize_actor(actor)
|
||||
|
||||
|
||||
async def _social_full(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env
|
||||
env = _ctx_to_env(ctx)
|
||||
env["actor"] = kw.get("actor") or _actor_data(ctx)
|
||||
return await render_to_sx_with_env("social-layout-full", env)
|
||||
|
||||
|
||||
async def _social_oob(ctx: dict, **kw: Any) -> str:
|
||||
from shared.sx.helpers import render_to_sx_with_env, _ctx_to_env
|
||||
env = _ctx_to_env(ctx, oob=True)
|
||||
env["actor"] = kw.get("actor") or _actor_data(ctx)
|
||||
return await render_to_sx_with_env("social-layout-oob", env)
|
||||
Reference in New Issue
Block a user