ForcePilot/backend/package/yuxi/channels/adapters/bluebubbles/templates.py

69 lines
1.9 KiB
Python
Raw Normal View History

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"<b>{_escape_html(title)}</b>")
if subtitle:
parts.append(f"<i>{_escape_html(subtitle)}</i>")
if image_url:
parts.append(f'<img src="{_escape_html(image_url)}" alt="image" style="max-width:100%">')
if body:
parts.append(body)
if footer:
parts.append(f'<small style="color:#888888">{_escape_html(footer)}</small>')
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} <b>{_escape_html(title)}</b>"]
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'<a href="{_escape_html(url)}">{_escape_html(label)}</a>')
else:
links.append(f"[{_escape_html(label)}]")
return " | ".join(links)
def _escape_html(text: str) -> str:
return text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;")