from __future__ import annotations
from typing import Any
def render_card(
title: str | None = None,
body: str = "",
subtitle: str | None = None,
image_url: str | None = None,
footer: str | None = None,
accent_color: str = "#007AFF",
) -> str:
parts = []
if title:
parts.append(f"{_escape_html(title)}")
if subtitle:
parts.append(f"{_escape_html(subtitle)}")
if image_url:
parts.append(f'
')
if body:
parts.append(body)
if footer:
parts.append(f'{_escape_html(footer)}')
return "\n".join(parts)
def render_notification(title: str, body: str = "", level: str = "info") -> str:
level_icons = {"info": "ℹ️", "warning": "⚠️", "error": "❌", "success": "✅"}
icon = level_icons.get(level, "ℹ️")
lines = [f"{icon} {_escape_html(title)}"]
if body:
lines.append(body)
return "\n".join(lines)
def render_items(items: list[dict[str, Any]], item_template: str = "{label}: {value}") -> str:
lines = []
for item in items:
line = item_template
for key, val in item.items():
line = line.replace(f"{{{key}}}", str(val))
lines.append(f"• {line}")
return "\n".join(lines)
def render_button_row(buttons: list[dict[str, str]]) -> str:
if not buttons:
return ""
links = []
for btn in buttons:
label = btn.get("label", "")
url = btn.get("url", "")
if url:
links.append(f'{_escape_html(label)}')
else:
links.append(f"[{_escape_html(label)}]")
return " | ".join(links)
def _escape_html(text: str) -> str:
return text.replace("&", "&").replace("<", "<").replace(">", ">").replace('"', """)