From 1ea42a9197ea08b0c2d21e0723b423cf01cd2de9 Mon Sep 17 00:00:00 2001 From: Hermes Bot Date: Thu, 20 Aug 2026 13:06:35 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82-=D0=BC=D0=BE=D0=B4:=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4-=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=20=C2=AB1=20?= =?UTF-8?q?=E2=80=94=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D0=BA=D0=B0=20=D1=84=D0=BE=D1=82=D0=BE=C2=BB=20?= =?UTF-8?q?=D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8=20=D1=88=D1=82=D0=B0=D1=82?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D1=84=D0=BE=D1=82=D0=BE-=D1=80?= =?UTF-8?q?=D0=B5=D0=B6=D0=B8=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/config.py | 11 +++++++---- main.py | 4 ++-- photo_bot/handlers.py | 32 ++++++++++++++++++++++++++++---- utils/texts.py | 9 ++++++--- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/config/config.py b/config/config.py index 0f65beb..6aa664c 100644 --- a/config/config.py +++ b/config/config.py @@ -89,13 +89,16 @@ ENABLE_INSTRUCT = True # Модуль инструкций (Trueconf, ENABLE_LK = True # Личный кабинет сотрудника (отпуска, расчетные листки, справки) # ========================================================= -# 1.1 ТЕСТОВЫЙ МОД ФОТО-БОТА -# Фото уходит НАПРЯМУЮ в ИИ (llama.cpp, тот же endpoint и промпт, +# 1.1 ТЕСТОВЫЙ ПОД-РЕЖИМ ФОТО-БОТА («1 — тест проверка фото») +# При включённом флаге в меню «Режим обновления фото профиля» +# появляется пункт «1 — тест проверка фото». Внутри под-режима +# фото уходит НАПРЯМУЮ в ИИ (llama.cpp, тот же endpoint и промпт, # что в SibCemProfile/PhotoApp/photo_validator.py), результат # показывается пользователю. Само фото никуда НЕ ДОСЫЛАЕТСЯ -# не применяется (ни в AD, ни в API, ни на модерацию). +# (ни в AD, ни в API, ни на модерацию). Штатный поток +# (фото → превью → публикация) работает параллельно. # ========================================================= -PHOTO_TEST_MODE = False # True — тест-мод: фото напрямую в ИИ, результат показывается, фото никуда не публикуется +PHOTO_TEST_MODE = False # True — в меню фото-режима доступен пункт «тест проверка фото» PHOTO_TEST_AI_URL = "http://srvkem-ii-03:8083/v1/chat/completions" PHOTO_TEST_AI_MODEL = "/opt/llama.cpp-cpu/build/bin/models/gemma-4-E4B-mtp/gemma-4-E4B-it-UD-Q4_K_XL.gguf" PHOTO_TEST_AI_TIMEOUT = 180.0 # Таймаут обращения к ИИ, сек diff --git a/main.py b/main.py index 8e090b7..124e779 100644 --- a/main.py +++ b/main.py @@ -137,9 +137,9 @@ async def main_menu(msg: Message): return set_state(user_id, "PHOTO_MODE") log_menu_stats(user_id, "Photo Bot (TEST)" if PHOTO_TEST_MODE else "Photo Bot", "Вход") - from utils.texts import PHOTO_TEST_WELCOME_TEXT + from utils.texts import PHOTO_TEST_ENTRY_TEXT await msg.answer( - PHOTO_TEST_WELCOME_TEXT if PHOTO_TEST_MODE else PHOTO_MAIN_MENU_TEXT, + PHOTO_TEST_ENTRY_TEXT if PHOTO_TEST_MODE else PHOTO_MAIN_MENU_TEXT, parse_mode="html" ) return diff --git a/photo_bot/handlers.py b/photo_bot/handlers.py index 77f9094..242e3a2 100644 --- a/photo_bot/handlers.py +++ b/photo_bot/handlers.py @@ -32,7 +32,6 @@ from utils.texts import ( photo_moderation_pending, PHOTO_TEST_WELCOME_TEXT, PHOTO_TEST_PREVIEW_TEXT, - PHOTO_TEST_RECEIVING_TEXT, PHOTO_TEST_AI_CHECKING_TEXT, photo_test_result, photo_test_ai_error, @@ -48,6 +47,16 @@ router = Router() # Формат: {user_id: {'path': '/tmp/orig_user.jpg', 'coords': (x1,y1,x2,y2)}} pending_photos = {} +# Пользователи, находящиеся в под-режиме «тест проверка фото» +test_submode_users = set() + +def in_test_submode(user_id: str) -> bool: + """Проверяет, находится ли пользователь в под-режиме тест-проверки фото""" + if user_id not in test_submode_users: + return False + # Если сессия истекла (состояние сброшено) — под-режим тоже недействителен + return states.get_state(user_id) == "PHOTO_MODE" + # ========================================================= # СИСТЕМА ОБРАБОТКИ ОШИБОК И ЛОГИРОВАНИЯ # ========================================================= @@ -170,6 +179,7 @@ async def photo_module_handler(msg: Message): if cmd in ["0", "9", "/start", "меню"]: log_menu_stats(user_id, "Photo Bot", "Выход в главное меню") states.clear_state(user_id) + test_submode_users.discard(user_id) if user_id in pending_photos: photo_data = pending_photos[user_id] if os.path.exists(photo_data['path']): @@ -196,8 +206,22 @@ async def photo_module_handler(msg: Message): # Ошибка проверки — не блокируем, просто логируем logger.warning(f"Не удалось проверить статус модерации для {user_id}: {status.get('reason')}") - # --- ТЕСТОВЫЙ МОД: кнопка 1 отправляет фото НАПРЯМУЮ в ИИ, фото никуда не публикуется --- - if not is_attachment and user_id in pending_photos and config.PHOTO_TEST_MODE: + # --- ТЕСТ-ПОД-РЕЖИМ: нет висящего фото — на любой текст повторяем тест-приветствие --- + if not is_attachment and user_id not in pending_photos and in_test_submode(user_id): + await msg.answer(PHOTO_TEST_WELCOME_TEXT, parse_mode="html") + return + + # --- ВХОД В ТЕСТ-ПОД-РЕЖИМ: кнопка 1 в меню фото-режима (тест включен) --- + if (not is_attachment and user_id not in pending_photos + and not in_test_submode(user_id) + and config.PHOTO_TEST_MODE and cmd == "1"): + test_submode_users.add(user_id) + log_menu_stats(user_id, "Photo Bot (TEST)", "Вход в тест-под-режим") + await msg.answer(PHOTO_TEST_WELCOME_TEXT, parse_mode="html") + return + + # --- ТЕСТ-ПОД-РЕЖИМ: кнопка 1 отправляет фото НАПРЯМУЮ в ИИ, фото никуда не публикуется --- + if not is_attachment and user_id in pending_photos and in_test_submode(user_id): if cmd == "1": photo_data = pending_photos[user_id] original_path = photo_data['path'] @@ -393,7 +417,7 @@ async def photo_module_handler(msg: Message): log_menu_stats(user_id, "Photo Bot", "Загрузка и обработка нового фото") await asyncio.sleep(0.5) - if config.PHOTO_TEST_MODE: + if in_test_submode(user_id): await msg.answer( PHOTO_TEST_PREVIEW_TEXT, parse_mode="html" diff --git a/utils/texts.py b/utils/texts.py index 1615f75..260ed8a 100644 --- a/utils/texts.py +++ b/utils/texts.py @@ -202,14 +202,16 @@ def sd_file_upload_error() -> str: # --- Private functions (Internal logic) --- -def _photo_welcome(emojis: dict) -> str: - return ( +def _photo_welcome(emojis: dict, show_test: bool = False) -> str: + text = ( f"🖼 Режим обновления фото профиля\n\n" f"📸 Пришлите мне вашу фотографию.\n\n" f"Бот автоматически найдёт лицо, покажет превью\n" f"и отправит фото на публикацию в ваши корпоративные сервисы.\n\n" - f"{emojis['0']} — В главное меню" ) + if show_test: + text += f"{emojis['1']} — тест проверка фото\n" + return text + f"{emojis['0']} — В главное меню" def _photo_unknown(emojis: dict) -> str: return ( @@ -338,6 +340,7 @@ def _photo_cancel(emojis: dict) -> str: # --- Public constants and functions --- PHOTO_MAIN_MENU_TEXT = _photo_welcome(EMOJI_DIGITS) +PHOTO_TEST_ENTRY_TEXT = _photo_welcome(EMOJI_DIGITS, show_test=True) PHOTO_UNKNOWN_CMD_TEXT = _photo_unknown(EMOJI_DIGITS) def photo_error_handling() -> str: