91 lines
2.9 KiB
Python
91 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
|
|
DEFAULT_STATUS_LABELS = {
|
|
"open": "исполняет роль",
|
|
"backstage": "в закулисье",
|
|
"delay": "задержки",
|
|
"rest": "антракт",
|
|
}
|
|
|
|
MARKDOWN_V2_SPECIALS = r"_*[]()~`>#+-=|{}.!"
|
|
|
|
|
|
def escape_markdown_v2(value: str) -> str:
|
|
return "".join(f"\\{char}" if char in MARKDOWN_V2_SPECIALS else char for char in value)
|
|
|
|
|
|
def escape_markdown_v2_url(value: str) -> str:
|
|
return value.replace("\\", "\\\\").replace(")", "\\)")
|
|
|
|
|
|
def build_hidden_link(config: dict) -> str:
|
|
url = config.get("hidden_link_url", "").strip()
|
|
if not url:
|
|
return ""
|
|
invisible = config.get("hidden_link_char", "\u2063")
|
|
return f"[{invisible}]({escape_markdown_v2_url(url)})"
|
|
|
|
|
|
def build_actor_lines(config: dict, state: dict) -> str:
|
|
actor_lines: list[str] = []
|
|
actor_state = state.get("actors", {})
|
|
status_labels = {**DEFAULT_STATUS_LABELS, **config.get("status_labels", {})}
|
|
|
|
for actor in config["actors"]:
|
|
current = actor_state.get(actor["key"], {})
|
|
status = current.get("status", actor.get("default_status", "backstage"))
|
|
phrase = current.get("phrase", actor.get("phrases", {}).get(status, ""))
|
|
label = status_labels.get(status, status)
|
|
display_name = actor.get("display_md", actor["display_name"])
|
|
meta = actor.get("meta_md", actor["pronouns"])
|
|
emoji = actor.get("emoji_md", actor.get("emoji", ""))
|
|
|
|
line = (
|
|
f"{emoji} "
|
|
f"[{escape_markdown_v2(display_name)}]({escape_markdown_v2_url(actor['link'])}) "
|
|
f"{escape_markdown_v2(meta)} "
|
|
f"{escape_markdown_v2(label)}\\."
|
|
)
|
|
if phrase:
|
|
line = f"{line}\n {escape_markdown_v2(phrase)}"
|
|
actor_lines.append(line)
|
|
|
|
actor_lines.extend(config.get("static_actor_lines_md", []))
|
|
return "\n".join(actor_lines)
|
|
|
|
|
|
def build_default_template(config: dict) -> str:
|
|
blocks = []
|
|
hidden = build_hidden_link(config)
|
|
if hidden:
|
|
blocks.append(hidden)
|
|
|
|
for key in ("header", "intro_links", "projects_block", "actors_title"):
|
|
value = config.get(key, "").strip()
|
|
if value:
|
|
blocks.append(escape_markdown_v2(value))
|
|
|
|
blocks.append("{{actors}}")
|
|
|
|
for key in ("legend", "footer"):
|
|
value = config.get(key, "").strip()
|
|
if value:
|
|
blocks.append(escape_markdown_v2(value))
|
|
|
|
return "\n\n".join(blocks)
|
|
|
|
|
|
def build_channel_text(config: dict, state: dict) -> str:
|
|
template = state.get("template", {}).get("text") or config.get("template_text") or build_default_template(config)
|
|
actors_block = build_actor_lines(config, state)
|
|
hidden_link = build_hidden_link(config)
|
|
|
|
text = template.replace("{{actors}}", actors_block)
|
|
text = text.replace("{{hidden_link}}", hidden_link)
|
|
|
|
if "{{hidden_link}}" not in template and hidden_link:
|
|
text = f"{hidden_link}\n{text}"
|
|
|
|
return text
|