From 0626454253c6849c9313d1e5c9246b0f2cc6f658 Mon Sep 17 00:00:00 2001 From: Verum Date: Thu, 2 Apr 2026 21:16:05 +0700 Subject: [PATCH] 423 --- session_bot/bot.py | 6 ++++-- session_bot/render.py | 41 ++++++++++++++++------------------------- tests/test_render.py | 6 ++++-- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/session_bot/bot.py b/session_bot/bot.py index 238806f..ce3e4d2 100644 --- a/session_bot/bot.py +++ b/session_bot/bot.py @@ -110,8 +110,10 @@ def extract_template_text(message: Message) -> str | None: return message.text.split(maxsplit=1)[1] source = message.reply_to_message or message + if source.html_text: + return source.html_text if source.text: - return source.md_text + return source.text return None @@ -179,7 +181,7 @@ async def update_channel_post(bot: Bot, app_config: dict, state_storage: JsonSta chat_id=settings.channel_id, message_id=settings.channel_message_id, text=text, - parse_mode=ParseMode.MARKDOWN_V2, + parse_mode=ParseMode.HTML, disable_web_page_preview=False, ) diff --git a/session_bot/render.py b/session_bot/render.py index f6eeb4b..33e6790 100644 --- a/session_bot/render.py +++ b/session_bot/render.py @@ -1,5 +1,7 @@ from __future__ import annotations +from html import escape + DEFAULT_STATUS_LABELS = { "open": "исполняет роль", @@ -8,23 +10,13 @@ DEFAULT_STATUS_LABELS = { "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)})" + invisible = config.get("hidden_link_char", "​") + return f'{invisible}' def build_actor_lines(config: dict, state: dict) -> str: @@ -37,21 +29,20 @@ def build_actor_lines(config: dict, state: dict) -> str: 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", "")) + display_name = actor.get("display_html", escape(actor["display_name"])) + meta = actor.get("meta_html", escape(actor["pronouns"])) + emoji = actor.get("emoji_html", escape(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)}\\." + f'{emoji} ' + f'{display_name}' + f"{meta}{escape(label)}." ) if phrase: - line = f"{line}\n {escape_markdown_v2(phrase)}" + line = f"{line}\n {escape(phrase)}" actor_lines.append(line) - actor_lines.extend(config.get("static_actor_lines_md", [])) + actor_lines.extend(config.get("static_actor_lines_html", [])) return "\n".join(actor_lines) @@ -61,17 +52,17 @@ def build_default_template(config: dict) -> str: if hidden: blocks.append(hidden) - for key in ("header", "intro_links", "projects_block", "actors_title"): + for key in ("header_html", "intro_links_html", "projects_block_html", "actors_title_html"): value = config.get(key, "").strip() if value: - blocks.append(escape_markdown_v2(value)) + blocks.append(value) blocks.append("{{actors}}") - for key in ("legend", "footer"): + for key in ("legend_html", "footer_html"): value = config.get(key, "").strip() if value: - blocks.append(escape_markdown_v2(value)) + blocks.append(value) return "\n\n".join(blocks) diff --git a/tests/test_render.py b/tests/test_render.py index 3b2e5bb..920cd12 100644 --- a/tests/test_render.py +++ b/tests/test_render.py @@ -9,8 +9,10 @@ def test_build_channel_text_includes_phrase_and_status() -> None: { "key": "astat", "display_name": "ASTAT", + "display_html": "ASTAT", "link": "https://t.me/example", "pronouns": "he/him", + "meta_html": " he/him ", "emoji": "🌟", "default_status": "backstage", "phrases": {"open": "принимает тейки"}, @@ -22,7 +24,7 @@ def test_build_channel_text_includes_phrase_and_status() -> None: text = build_channel_text(config, state) - assert "[⁣](https://example.com/image.png)" in text - assert "[ASTAT](https://t.me/example)" in text + assert '' in text + assert 'ASTAT' in text assert "исполняет роль" in text assert "готов к игре" in text