"""Market app fragment endpoints. Exposes HTML fragments at ``/internal/fragments/`` for consumption by other coop apps via the fragment client. """ from __future__ import annotations from quart import Blueprint, Response, g, request from shared.infrastructure.fragments import FRAGMENT_HEADER from shared.services.registry import services def register(): bp = Blueprint("fragments", __name__, url_prefix="/internal/fragments") _handlers: dict[str, object] = {} @bp.before_request async def _require_fragment_header(): if not request.headers.get(FRAGMENT_HEADER): return Response("", status=403) @bp.get("/") async def get_fragment(fragment_type: str): handler = _handlers.get(fragment_type) if handler is None: return Response("", status=200, content_type="text/html") html = await handler() return Response(html, status=200, content_type="text/html") # --- container-nav fragment: market links -------------------------------- async def _container_nav_handler(): from quart import current_app from shared.infrastructure.urls import market_url from shared.sexp.jinja_bridge import render as render_comp container_type = request.args.get("container_type", "page") container_id = int(request.args.get("container_id", 0)) post_slug = request.args.get("post_slug", "") markets = await services.market.marketplaces_for_container( g.s, container_type, container_id, ) if not markets: return "" styles = current_app.jinja_env.globals.get("styles", {}) nav_class = styles.get("nav_button_less_pad", "") parts = [] for m in markets: href = market_url(f"/{post_slug}/{m.slug}/") parts.append(render_comp( "market-link-nav", href=href, name=m.name, nav_class=nav_class, )) return "\n".join(parts) _handlers["container-nav"] = _container_nav_handler # --- link-card fragment: product preview card -------------------------------- async def _link_card_handler(): from sqlalchemy import select from shared.models.market import Product from shared.infrastructure.urls import market_url from shared.sexp.jinja_bridge import render as render_comp slug = request.args.get("slug", "") keys_raw = request.args.get("keys", "") # Batch mode if keys_raw: slugs = [k.strip() for k in keys_raw.split(",") if k.strip()] parts = [] for s in slugs: parts.append(f"") product = ( await g.s.execute(select(Product).where(Product.slug == s)) ).scalar_one_or_none() if product: subtitle = product.brand or "" detail = "" if product.special_price: detail = f"{product.regular_price} {product.special_price}" elif product.regular_price: detail = str(product.regular_price) parts.append(render_comp( "link-card", title=product.title, image=product.image, subtitle=subtitle, detail=detail, link=market_url(f"/product/{product.slug}/"), )) return "\n".join(parts) # Single mode if not slug: return "" product = ( await g.s.execute(select(Product).where(Product.slug == slug)) ).scalar_one_or_none() if not product: return "" subtitle = product.brand or "" detail = "" if product.special_price: detail = f"{product.regular_price} {product.special_price}" elif product.regular_price: detail = str(product.regular_price) return render_comp( "link-card", title=product.title, image=product.image, subtitle=subtitle, detail=detail, link=market_url(f"/product/{product.slug}/"), ) _handlers["link-card"] = _link_card_handler bp._fragment_handlers = _handlers return bp