From a17e21c9836d8aad4afccf83088c1046c158001c Mon Sep 17 00:00:00 2001 From: Roman Vrubel Date: Sun, 14 Jun 2026 21:01:10 +0000 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D1=87=D0=B8=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=BA=D1=80=D0=B0=D1=88=D0=B8=20MarkdownV2:=20=D1=8D?= =?UTF-8?q?=D0=BA=D1=80=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=82=D0=BE=D1=87=D0=B5=D0=BA=20=D0=B2=20=D0=BE?= =?UTF-8?q?=D1=87=D0=BA=D0=B0=D1=85,=20fallback=20=D0=BD=D0=B0=20plain=20t?= =?UTF-8?q?ext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Очки теперь через _md_escape (4.0 → 4\.0) - Каждая пара в две строки (белые сверху, чёрные снизу) - Защита: при ошибке MarkdownV2 парсинга — plain text - Экранрованы точки в статусных сообщениях --- bots/client_bot.py | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/bots/client_bot.py b/bots/client_bot.py index e8c61f1..c9e1f8d 100644 --- a/bots/client_bot.py +++ b/bots/client_bot.py @@ -72,8 +72,11 @@ def format_pairings(pairings_data: dict, tournament_name: str) -> str: lines.append( f'{board}\\. {_md_escape(white.name)} ' - f'\\({white.points:.1f}\\) — ' - f'{_md_escape(black.name)} \\({black.points:.1f}\\)' + f'\\({_md_escape(f"{white.points:.1f}")}\\)' + ) + lines.append( + f' {_md_escape(black.name)} ' + f'\\({_md_escape(f"{black.points:.1f}")}\\)' ) board += 1 @@ -121,7 +124,7 @@ async def handle_url(update: Update, context: ContextTypes.DEFAULT_TYPE): return if tournament['current_round'] >= tournament['num_rounds']: - await msg.edit_text('🏁 Турнир уже завершён. Жеребьёвки не будет.', + await msg.edit_text('🏁 Турнир уже завершён\\. Жеребьёвки не будет\\.', parse_mode=ParseMode.MARKDOWN_V2) record_request(user.id, url, tournament.get('name', ''), True) return @@ -178,16 +181,27 @@ async def handle_url(update: Update, context: ContextTypes.DEFAULT_TYPE): output = format_pairings(result, tournament['name']) # Telegram has 4096 char limit - if len(output) > 4000: - chunks = _chunk_output(output, 3800) - await calc_msg.edit_text(chunks[0], parse_mode=ParseMode.MARKDOWN_V2, - disable_web_page_preview=True) - for chunk in chunks[1:]: - await update.message.reply_text(chunk, parse_mode=ParseMode.MARKDOWN_V2, - disable_web_page_preview=True) - else: - await calc_msg.edit_text(output, parse_mode=ParseMode.MARKDOWN_V2, - disable_web_page_preview=True) + try: + if len(output) > 4000: + chunks = _chunk_output(output, 3800) + await calc_msg.edit_text(chunks[0], parse_mode=ParseMode.MARKDOWN_V2, + disable_web_page_preview=True) + for chunk in chunks[1:]: + await update.message.reply_text(chunk, parse_mode=ParseMode.MARKDOWN_V2, + disable_web_page_preview=True) + else: + await calc_msg.edit_text(output, parse_mode=ParseMode.MARKDOWN_V2, + disable_web_page_preview=True) + except Exception: + # MarkdownV2 parse failed — fall back to plain text + plain = output.replace('*', '').replace('_', '').replace('\\', '') + if len(plain) > 4000: + chunks = _chunk_output(plain, 3800) + await calc_msg.edit_text(chunks[0]) + for chunk in chunks[1:]: + await update.message.reply_text(chunk) + else: + await calc_msg.edit_text(plain) record_request(user.id, url, tournament.get('name', ''), True)