From d0f91d7daac84486ba4f83cc24e48c1f24d40348 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Fri, 27 Feb 2026 19:49:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D1=83=D0=B5=D0=BC=20asyncio.Event=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=B1=D0=BB=D0=BE=D0=BA=D0=B8=D1=80=D1=83=D1=8E?= =?UTF-8?q?=D1=89=D0=B5=D0=B3=D0=BE=20=D0=BE=D0=B6=D0=B8=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Qwen-Coder --- bot/handlers/callbacks.py | 12 ++++++++++-- bot/models/user_state.py | 1 + bot/utils/formatters.py | 26 +++++++++++++++----------- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/bot/handlers/callbacks.py b/bot/handlers/callbacks.py index a1e1301..d38155d 100644 --- a/bot/handlers/callbacks.py +++ b/bot/handlers/callbacks.py @@ -56,11 +56,15 @@ async def menu_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): state = state_manager.get(user_id) state.waiting_for_output_control = False state.continue_output = True - # Сразу удаляем сообщение с кнопками + # Удаляем сообщение с кнопками try: await query.delete_message() except: pass + # Устанавливаем event чтобы разблокировать send_long_message + if state.output_continue_event: + state.output_continue_event.set() + await query.answer() return elif callback == "cancel_output": @@ -68,11 +72,15 @@ async def menu_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): state = state_manager.get(user_id) state.waiting_for_output_control = False state.continue_output = False - # Сразу удаляем сообщение с кнопками + # Удаляем сообщение с кнопками try: await query.delete_message() except: pass + # Устанавливаем event чтобы разблокировать send_long_message + if state.output_continue_event: + state.output_continue_event.set() + await query.answer() return elif callback == "preset_menu": diff --git a/bot/models/user_state.py b/bot/models/user_state.py index b020fbb..507a219 100644 --- a/bot/models/user_state.py +++ b/bot/models/user_state.py @@ -34,6 +34,7 @@ class UserState: waiting_for_output_control: bool = False # Ожидание решения пользователя output_remaining: int = 0 # Сколько сообщений осталось output_wait_message = None # Сообщение с кнопками + output_continue_event = None # asyncio.Event для разблокировки continue_output: bool = True # Решение пользователя diff --git a/bot/utils/formatters.py b/bot/utils/formatters.py index ff7b95a..4ce9842 100644 --- a/bot/utils/formatters.py +++ b/bot/utils/formatters.py @@ -231,21 +231,22 @@ async def send_long_message(update: Update, text: str, parse_mode: str = None, p reply_markup=keyboard ) - # Ждём ответа пользователя БЕСКОНЕЧНО + # Ждём ответа пользователя через asyncio.Event (не блокируем event loop) from bot.config import state_manager + import asyncio user_id = update.effective_user.id - # Сохраняем состояние ожидания + # Создаём Event для этого пользователя + continue_event = asyncio.Event() state = state_manager.get(user_id) state.waiting_for_output_control = True state.output_remaining = remaining state.output_wait_message = wait_msg + state.output_continue_event = continue_event - # Ждём пока пользователь не нажмёт кнопку - while state.waiting_for_output_control: - await asyncio.sleep(1) - state = state_manager.get(user_id) + # Ждём пока callback handler не установит event + await continue_event.wait() # Пользователь ответил if state.continue_output: @@ -254,17 +255,20 @@ async def send_long_message(update: Update, text: str, parse_mode: str = None, p await wait_msg.delete() except: pass - # Очищаем состояние - state.output_remaining = None - state.output_wait_message = None else: - # Отменил - редактируем сообщение и убираем кнопки + # Отменил - удаляем сообщение с кнопками try: - await wait_msg.edit_text("❌ **Вывод отменен пользователем**", parse_mode="Markdown") + await wait_msg.delete() except: pass return # Прерываем вывод + # Очищаем состояние + state.waiting_for_output_control = False + state.output_remaining = None + state.output_wait_message = None + state.output_continue_event = None + def format_long_output(text: str, max_lines: int = 100, head_lines: int = 50, tail_lines: int = 50) -> str: """