from __future__ import annotations import base64 import html import json from collections import defaultdict from datetime import datetime from pathlib import Path from typing import Any from backend.spaces_index import filter_public_spaces, get_category_distribution from backend.storage import get_recent_feedback CARD_DECORATIONS = ["compass", "camera", "lantern", "boot", "pine", "flower", "peak", "map"] CARD_DECORATION_MARKS = { "compass": "🧭", "camera": "📷", "lantern": "🏮", "boot": "🥾", "pine": "🌲", "flower": "🌸", "peak": "🏔", "map": "🗺", } def safe(text: Any) -> str: return html.escape("" if text is None else str(text)) PROJECT_ROOT = Path(__file__).resolve().parent.parent BANNER_PATH = PROJECT_ROOT / "banner.png" BADGE_PATH = PROJECT_ROOT / "hackathon-badge.png" def _image_data_uri(path: Path) -> str: data = path.read_bytes() encoded = base64.b64encode(data).decode("ascii") return f"data:image/png;base64,{encoded}" BANNER_SRC = _image_data_uri(BANNER_PATH) BADGE_SRC = _image_data_uri(BADGE_PATH) def _js_literal(value: Any) -> str: return html.escape(json.dumps(value, ensure_ascii=False), quote=True) def _tags_text(tags: list[str] | None) -> str: tags = [str(tag).strip() for tag in (tags or []) if str(tag).strip()] return ", ".join(tags[:7]) def _group_feedback() -> dict[str, list[dict]]: grouped: dict[str, list[dict]] = defaultdict(list) for row in get_recent_feedback(limit=2000): repo_id = str(row.get("repo_id", "")).strip() if repo_id: grouped[repo_id].append(row) return grouped def _human_datetime(value: str | None) -> str: if not value: return "Just now" try: parsed = datetime.fromisoformat(value.replace("Z", "+00:00")) except Exception: return str(value) local = parsed.astimezone() return local.strftime("%b %d, %Y at %I:%M %p").replace(" 0", " ") COMMENTS_MODAL_HTML = """ """ COMMENTS_MODAL_SCRIPT = """ """ FIELD_GUIDE_SHELL_SCRIPT = """ """ def render_page_shell(stats: dict, *, active_category: str = "All", active_query: str = "") -> str: return f"""
Hackathon Space Recommender banner illustration
""" def render_footer_shell() -> str: return """ """.format(badge_src=BADGE_SRC) def _meta_button(text: str, *, css_class: str = "", attrs: str = "", tag: str = "button") -> str: class_attr = f"card-action {css_class}".strip() if tag == "a": return f'{text}' return f'' def render_space_card( space: dict, comments_by_repo: dict[str, list[dict]] | None = None, *, show_reason: bool = True, enable_inline_comment: bool = False, source_query: str = "", tone_index: int = 0, ) -> str: comments_by_repo = comments_by_repo or {} repo_id = str(space.get("id", "")).strip() comments = comments_by_repo.get(repo_id, []) comment_count = len(comments) reason = str(space.get("reason", "") or "").strip() category = str(space.get("category", "Other") or "Other").strip() track = str(space.get("track", "") or "").strip() title = str(space.get("name", "") or "").strip() likes = int(space.get("likes", 0) or 0) tag_text = _tags_text(space.get("tags")) deco_key = CARD_DECORATIONS[tone_index % len(CARD_DECORATIONS)] deco_mark = CARD_DECORATION_MARKS[deco_key] title_js = _js_literal(title) repo_id_js = _js_literal(repo_id) source_query_js = _js_literal(source_query) open_url = safe(space.get("url", "")) reason_html = "" if show_reason and reason: reason_html = f'
Why it fits

{safe(reason)}

' inline_comment_html = "" if enable_inline_comment and repo_id: inline_comment_html = f"""
Not sure what to write? Open the Space and give it a quick try.
""" category_chip = f'{safe(category)}' if category else "" track_chip = f'{safe(track)}' if track else "" comment_button = _meta_button( f'💬 {comment_count}', css_class="card-action--count", attrs=f'onclick="window.bsqfOpenComments({title_js}, {repo_id_js})"', ) like_chip = f'♥ {likes}' open_button = _meta_button("Open Space ↗", css_class="card-action--open", attrs=f'href="{open_url}" target="_blank" rel="noreferrer"', tag="a") return f"""
{category_chip} {track_chip}
{like_chip} {comment_button} {open_button}

{safe(title)}

{reason_html} {inline_comment_html}
{safe(tag_text)}
""" def render_recommendation_cards(results: list[dict], *, show_reason: bool = False, source_query: str = "") -> str: results = filter_public_spaces(results) comments_by_repo = _group_feedback() if not results: return """

No matching spaces found.

Try to modify your search query

""" cards = "\n".join( render_space_card( result, comments_by_repo, show_reason=show_reason, enable_inline_comment=True, source_query=source_query, tone_index=index, ) for index, result in enumerate(results) ) return f"""
{cards}
""" def render_category_section(spaces: list[dict], category: str) -> str: spaces = filter_public_spaces(spaces) comments_by_repo = _group_feedback() if not spaces: return """

No Spaces in this category

Nothing in the current index matches this category yet.

""" cards = "\n".join( render_space_card( space, comments_by_repo, show_reason=False, enable_inline_comment=False, tone_index=index, ) for index, space in enumerate(spaces) ) return f"""
{cards}
"""