154 lines
3.3 KiB
Python
154 lines
3.3 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import logging
|
|
|
|
from yuxi.channel.security.html_guard import sanitize_text_content_preserve_entities
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def build_markdown_card(text: str) -> dict:
|
|
return {
|
|
"schema": "2.0",
|
|
"config": {
|
|
"width_mode": "fill",
|
|
"enable_forward": True,
|
|
},
|
|
"body": {
|
|
"elements": [
|
|
{
|
|
"tag": "markdown",
|
|
"content": sanitize_text_content_preserve_entities(text),
|
|
}
|
|
]
|
|
},
|
|
}
|
|
|
|
|
|
def build_structured_card(
|
|
text: str,
|
|
*,
|
|
title: str | None = None,
|
|
template: str = "blue",
|
|
note: str | None = None,
|
|
) -> dict:
|
|
card: dict = {
|
|
"schema": "2.0",
|
|
"config": {"width_mode": "fill"},
|
|
}
|
|
|
|
if title:
|
|
card["header"] = {
|
|
"title": {"tag": "plain_text", "content": title},
|
|
"template": template,
|
|
}
|
|
|
|
card["body"] = {
|
|
"elements": [
|
|
{
|
|
"tag": "markdown",
|
|
"content": sanitize_text_content_preserve_entities(text),
|
|
}
|
|
]
|
|
}
|
|
|
|
if note:
|
|
card["note"] = {
|
|
"elements": [
|
|
{"tag": "plain_text", "content": note}
|
|
]
|
|
}
|
|
|
|
return card
|
|
|
|
|
|
def build_presentation_card(
|
|
text: str,
|
|
*,
|
|
title: str,
|
|
template: str = "blue",
|
|
actions: list[dict] | None = None,
|
|
) -> dict:
|
|
card: dict = {
|
|
"schema": "2.0",
|
|
"config": {"width_mode": "fill"},
|
|
"header": {
|
|
"title": {"tag": "plain_text", "content": title},
|
|
"template": template,
|
|
},
|
|
"body": {
|
|
"elements": [
|
|
{"tag": "markdown", "content": sanitize_text_content_preserve_entities(text)},
|
|
{"tag": "hr"},
|
|
]
|
|
},
|
|
}
|
|
|
|
if actions:
|
|
card["elements"] = card.get("elements", []) + actions
|
|
|
|
return card
|
|
|
|
|
|
def build_button(
|
|
text: str,
|
|
*,
|
|
action: str = "",
|
|
value: str = "",
|
|
button_type: str = "default",
|
|
confirm: dict | None = None,
|
|
) -> dict:
|
|
btn = {
|
|
"tag": "button",
|
|
"text": {"tag": "plain_text", "content": text},
|
|
"type": button_type,
|
|
}
|
|
if action:
|
|
btn["value"] = json.dumps({"action": action, "value": value}, ensure_ascii=False)
|
|
if confirm:
|
|
btn["confirm"] = confirm
|
|
return btn
|
|
|
|
|
|
def build_select_menu(
|
|
placeholder: str,
|
|
*,
|
|
options: list[dict] | None = None,
|
|
action: str = "",
|
|
) -> dict:
|
|
select = {
|
|
"tag": "select_static",
|
|
"placeholder": {"tag": "plain_text", "content": placeholder},
|
|
}
|
|
if options:
|
|
select["options"] = [
|
|
{"text": {"tag": "plain_text", "content": opt.get("text", "")}, "value": opt.get("value", "")}
|
|
for opt in options
|
|
]
|
|
return select
|
|
|
|
|
|
HEADER_TEMPLATE_COLORS = {
|
|
"blue": "blue",
|
|
"green": "green",
|
|
"red": "red",
|
|
"orange": "orange",
|
|
"purple": "purple",
|
|
"indigo": "indigo",
|
|
"wathet": "wathet",
|
|
"turquoise": "turquoise",
|
|
"yellow": "yellow",
|
|
"grey": "grey",
|
|
"carmine": "carmine",
|
|
"violet": "violet",
|
|
"lime": "lime",
|
|
}
|
|
|
|
TEMPLATE_TO_PRESENTATION_TONE = {
|
|
"blue": "default",
|
|
"green": "success",
|
|
"red": "danger",
|
|
"orange": "warning",
|
|
}
|