diff --git a/app.py b/app.py index 41be91c..e1d52e4 100644 --- a/app.py +++ b/app.py @@ -54,38 +54,68 @@ def create_app() -> "Quart": app.jinja_loader, ]) - # Market blueprint scoped under // + # Market blueprint nested under post slug: /// app.register_blueprint( register_market_bp( url_prefix="/", title=config()["coop_title"], ), - url_prefix="/", + url_prefix="//", ) - # --- Auto-inject market_slug into url_for() calls --- + # --- Auto-inject slug and market_slug into url_for() calls --- @app.url_value_preprocessor - def pull_market_slug(endpoint, values): - if values and "market_slug" in values: - g.market_slug = values.pop("market_slug") + def pull_slugs(endpoint, values): + if values: + if "slug" in values: + g.post_slug = values.pop("slug") + if "market_slug" in values: + g.market_slug = values.pop("market_slug") @app.url_defaults - def inject_market_slug(endpoint, values): - slug = g.get("market_slug") - if slug and "market_slug" not in values: - if app.url_map.is_endpoint_expecting(endpoint, "market_slug"): - values["market_slug"] = slug + def inject_slugs(endpoint, values): + for attr, param in [("post_slug", "slug"), ("market_slug", "market_slug")]: + val = g.get(attr) + if val and param not in values: + if app.url_map.is_endpoint_expecting(endpoint, param): + values[param] = val - # --- Load market data for market_slug --- + # --- Load post and market data --- @app.before_request async def hydrate_market(): - slug = getattr(g, "market_slug", None) - if not slug: + post_slug = getattr(g, "post_slug", None) + market_slug = getattr(g, "market_slug", None) + if not post_slug or not market_slug: return + + # Load post by slug + post = ( + await g.s.execute( + select(Post).where(Post.slug == post_slug) + ) + ).scalar_one_or_none() + if not post: + abort(404) + + g.post_data = { + "post": { + "id": post.id, + "title": post.title, + "slug": post.slug, + "feature_image": post.feature_image, + "html": post.html, + "status": post.status, + "visibility": post.visibility, + "is_page": post.is_page, + }, + } + + # Load market scoped to post market = ( await g.s.execute( select(MarketPlace).where( - MarketPlace.slug == slug, + MarketPlace.slug == market_slug, + MarketPlace.post_id == post.id, MarketPlace.deleted_at.is_(None), ) ) @@ -94,33 +124,16 @@ def create_app() -> "Quart": abort(404) g.market = market - # Load associated Post for context - post = ( - await g.s.execute( - select(Post).where(Post.id == market.post_id) - ) - ).scalar_one_or_none() - if post: - g.post_data = { - "post": { - "id": post.id, - "title": post.title, - "slug": post.slug, - "feature_image": post.feature_image, - "html": post.html, - "status": post.status, - "visibility": post.visibility, - "is_page": post.is_page, - }, - } - # --- Root route: market listing --- @app.get("/") async def markets_listing(): + from sqlalchemy.orm import selectinload + markets = ( await g.s.execute( select(MarketPlace) .where(MarketPlace.deleted_at.is_(None)) + .options(selectinload(MarketPlace.post)) .order_by(MarketPlace.name) ) ).scalars().all() diff --git a/scrape/persist_api/capture_listing.py b/scrape/persist_api/capture_listing.py index 6774602..3943253 100644 --- a/scrape/persist_api/capture_listing.py +++ b/scrape/persist_api/capture_listing.py @@ -11,7 +11,7 @@ async def capture_listing( total_pages: int ): - sync_url = os.getenv("CAPTURE_LISTING_URL", "http://localhost:8001/suma-market/api/products/listing/") + sync_url = os.getenv("CAPTURE_LISTING_URL", "http://localhost:8001/market/suma-market/api/products/listing/") async with httpx.AsyncClient(timeout=httpx.Timeout(20.0, connect=10.0)) as client: _d = { diff --git a/scrape/persist_api/save_nav.py b/scrape/persist_api/save_nav.py index 8ffd915..3feeadb 100644 --- a/scrape/persist_api/save_nav.py +++ b/scrape/persist_api/save_nav.py @@ -8,7 +8,7 @@ from typing import Dict async def save_nav( nav: Dict, ): - sync_url = os.getenv("SAVE_NAV_URL", "http://localhost:8001/suma-market/api/products/nav/") + sync_url = os.getenv("SAVE_NAV_URL", "http://localhost:8001/market/suma-market/api/products/nav/") async with httpx.AsyncClient(timeout=httpx.Timeout(20.0, connect=10.0)) as client: resp = await client.post(sync_url, json=nav) diff --git a/scrape/persist_api/upsert_product.py b/scrape/persist_api/upsert_product.py index 3e66b6b..d65149a 100644 --- a/scrape/persist_api/upsert_product.py +++ b/scrape/persist_api/upsert_product.py @@ -21,7 +21,7 @@ async def upsert_product( d["slug"] = slug # Where to post; override via env if needed - sync_url = os.getenv("PRODUCT_SYNC_URL", "http://localhost:8001/suma-market/api/products/sync/") + sync_url = os.getenv("PRODUCT_SYNC_URL", "http://localhost:8001/market/suma-market/api/products/sync/") diff --git a/shared_lib b/shared_lib index 42f4a8b..a420bfa 160000 --- a/shared_lib +++ b/shared_lib @@ -1 +1 @@ -Subproject commit 42f4a8b68f057c45c874f7eb4a53403932925a9a +Subproject commit a420bfa7f03617a01d75c24a8a6874531c181bf5 diff --git a/templates/_types/market/markets_listing.html b/templates/_types/market/markets_listing.html index 690d17b..f444d51 100644 --- a/templates/_types/market/markets_listing.html +++ b/templates/_types/market/markets_listing.html @@ -7,7 +7,7 @@ {% if markets %}
{% for m in markets %} -

{{ m.name }}

{% if m.description %}