From e08c8611496086bed53a1725faf0e12835a8258d Mon Sep 17 00:00:00 2001 From: dddennnisss Date: Sat, 22 Aug 2026 00:08:34 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A4=D0=BE=D1=82=D0=BE:=20pending-=D1=81?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D0=B5=20=E2=80=94=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20=D0=BE=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D1=91=D1=82=D1=81=D1=8F=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82?= =?UTF-8?q?;=20=D1=82=D0=B5=D1=81=D1=82-=D1=80=D0=B5=D0=B6=D0=B8=D0=BC:=20?= =?UTF-8?q?=D1=84=D0=BE=D1=82=D0=BE=20=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=82=D0=B5=D1=81=D1=82;=20=D0=BF=D1=80=D0=BE=D1=87?= =?UTF-8?q?=D0=B8=D0=B9=20=D0=B2=D0=B2=D0=BE=D0=B4=20=E2=86=92=20=D0=BE?= =?UTF-8?q?=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20=D0=BD=D0=B5=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__pycache__/handlers.cpython-313.pyc | Bin 24828 -> 26672 bytes photo_bot/handlers.py | 59 +++++++++++++++--- utils/__pycache__/texts.cpython-313.pyc | Bin 46987 -> 48377 bytes utils/texts.py | 29 +++++++-- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/photo_bot/__pycache__/handlers.cpython-313.pyc b/photo_bot/__pycache__/handlers.cpython-313.pyc index 1dec9c5d0f39ff2600a0f3d5afea56168b1192ec..688ef267f90b0187def7a3aa08c2119095342c5c 100644 GIT binary patch delta 7878 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 L6cRg4K#+8X diff --git a/photo_bot/handlers.py b/photo_bot/handlers.py index dd53d4b..e02371a 100644 --- a/photo_bot/handlers.py +++ b/photo_bot/handlers.py @@ -31,6 +31,8 @@ from utils.texts import ( photo_preview_ready, photo_moderation_pending, photo_welcome_with_status, + photo_invalid_cmd, + photo_test_welcome, PHOTO_TEST_WELCOME_TEXT, PHOTO_TEST_PREVIEW_TEXT, PHOTO_TEST_AI_CHECKING_TEXT, @@ -51,6 +53,10 @@ pending_photos = {} # Пользователи, находящиеся в под-режиме «тест проверка фото» test_submode_users = set() +# Пользователи, у которых фото на модерации (вход заблокирован, +# модуль остаётся открыт: в тест-режиме можно отправить фото на тест) +moderation_pending_users = set() + def in_test_submode(user_id: str) -> bool: """Проверяет, находится ли пользователь в под-режиме тест-проверки фото""" if user_id not in test_submode_users: @@ -157,8 +163,9 @@ async def check_moderation_status(user_id: str) -> dict: async def send_dynamic_photo_main_menu(msg: Message, user_id: str): """Вход в раздел фото (паттерн ЛК): модуль сам запрашивает данные и показывает их. - - pending — отдельное сообщение «фото на модерации», модуль НЕ открывается - (кнопок загрузки фото нет); + - pending — сообщение «фото на модерации»; модуль остаётся открыт + (цифры → ошибка неверного выбора, 0 — выход). Тест-режим: + фото можно отправить на проверку в ИИ; - rejected — ОДНО сообщение: меню + причина отказа (кнопки на месте); - иначе/ошибка API — штатное меню входа. Статус проверяется и показывается всегда, включая тестовый режим. @@ -166,13 +173,21 @@ async def send_dynamic_photo_main_menu(msg: Message, user_id: str): # Статус модерации запрашиваем всегда (и в тестовом режиме тоже) status = await check_moderation_status(user_id) if status.get("status") == "ok" and status.get("moderation_status") == "pending": - # Фото на модерации — не вводим в модуль (кнопок загрузки нет) + # Фото на модерации — штатная загрузка заблокирована, + # но модуль остаётся открыт (PHOTO_MODE), чтобы цифры не ушли в главное меню photo_id = status.get("photo_id", "???") log_menu_stats(user_id, "Photo Bot", "Вход заблокирован — фото на модерации") - await msg.answer( - photo_moderation_pending(photo_id), - parse_mode="html" - ) + states.set_state(user_id, "PHOTO_MODE") + moderation_pending_users.add(user_id) + if config.PHOTO_TEST_MODE: + # Тест-режим: можно отправить фото на проверку в ИИ + test_submode_users.add(user_id) + await msg.answer(photo_test_welcome(photo_id), parse_mode="html") + else: + await msg.answer( + photo_moderation_pending(photo_id), + parse_mode="html" + ) return if status.get("status") == "ok" and status.get("moderation_status") == "rejected": log_menu_stats(user_id, "Photo Bot", "Вход — фото отклонено, показана причина") @@ -219,6 +234,7 @@ async def photo_module_handler(msg: Message): log_menu_stats(user_id, "Photo Bot", "Выход в главное меню") states.clear_state(user_id) test_submode_users.discard(user_id) + moderation_pending_users.discard(user_id) if user_id in pending_photos: photo_data = pending_photos[user_id] if os.path.exists(photo_data['path']): @@ -230,6 +246,35 @@ async def photo_module_handler(msg: Message): await msg.answer(MENU_TEXT, parse_mode="html") return + # --- СОСТОЯНИЕ «ФОТО НА МОДЕРАЦИИ»: активного фото нет --- + if user_id in moderation_pending_users and user_id not in pending_photos: + if not is_attachment: + status = await check_moderation_status(user_id) + still_pending = ( + status.get("status") == "ok" + and status.get("moderation_status") == "pending" + ) + if still_pending: + photo_id = status.get("photo_id", "???") + if config.PHOTO_TEST_MODE and in_test_submode(user_id): + # тест-режим: повторяем инфо (можно отправить фото на тест) + await msg.answer(photo_test_welcome(photo_id), parse_mode="html") + else: + # стандартная ошибка: кнопок, кроме 0, нет + await msg.answer(photo_invalid_cmd(), parse_mode="html") + return + # Статус изменился (одобрено/отклонено) — разблокируем + moderation_pending_users.discard(user_id) + if config.PHOTO_TEST_MODE: + await msg.answer(PHOTO_TEST_WELCOME_TEXT, parse_mode="html") + else: + await msg.answer( + photo_welcome_with_status(status), parse_mode="html" + ) + return + # is_attachment — пропускаем: фото обрабатывается штатно ниже + # (тест-под-режим: превью + отправка в ИИ) + # --- ПРОВЕРКА СТАТУСА: если нет фото в pending_photos, проверяем статус модерации --- # (в тестовом режиме статусы тоже показываем — поведение как в обычном режиме) if user_id not in pending_photos and not is_attachment: diff --git a/utils/__pycache__/texts.cpython-313.pyc b/utils/__pycache__/texts.cpython-313.pyc index 5e5c8938c4b4939fdaee702d603df5858eddcbb9..82b9084b3ec89d6ec0bc9ae3a848b576c99aeccd 100644 GIT binary patch delta 5555 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 delta 4672 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 IXFTEcAEMgCxc~qF diff --git a/utils/texts.py b/utils/texts.py index cdf5757..91c9a3e 100644 --- a/utils/texts.py +++ b/utils/texts.py @@ -225,6 +225,13 @@ def _photo_unknown(emojis: dict) -> str: f"{emojis['0']} — В главное меню" ) +def _photo_invalid_cmd(emojis: dict) -> str: + return ( + f"⚠️ Неверный выбор пункта меню.\n" + f"Пожалуйста, используйте кнопки из сообщения выше.\n\n" + f"{emojis['0']} — В главное меню" + ) + def _photo_processing_face(emojis: dict) -> str: return "⏳ Ищу лицо на фото, пожалуйста, подождите..." @@ -269,13 +276,20 @@ def _photo_status_info(status: dict = None, emojis: dict = None) -> str | None: ) return None -def _photo_test_welcome(emojis: dict) -> str: - return ( +def _photo_test_welcome(emojis: dict, photo_id: str = None) -> str: + """Тест-приветствие. photo_id — если у пользователя ещё есть фото + на модерации (тестовая проверка его не затрагивает).""" + text = ( f"🧪 Тестовый режим фото-проверки\n\n" f"📸 Пришлите фотографию — она уйдёт напрямую в ИИ.\n" - f"Бот покажет вердикт ИИ. Фото никуда не публикуется.\n\n" - f"{emojis['0']} — В главное меню" + f"Бот покажет вердикт ИИ. Фото никуда не публикуется.\n" ) + if photo_id: + text += ( + f"\n⏳ У вас уже есть фото на модерации (№ {photo_id}).\n" + f"Ожидайте решения модератора. Тестовая проверка его не затрагивает.\n" + ) + return text + f"\n\n{emojis['0']} — В главное меню" def _photo_test_preview(emojis: dict) -> str: return ( @@ -367,6 +381,9 @@ 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_invalid_cmd() -> str: + return _photo_invalid_cmd(EMOJI_DIGITS) + def photo_error_handling() -> str: return system_error_text(EMOJI_DIGITS, show_back=False) @@ -403,6 +420,10 @@ def photo_welcome_with_status(status: dict = None, show_test: bool = False) -> s return _photo_welcome(EMOJI_DIGITS, show_test=show_test, info=info) PHOTO_TEST_WELCOME_TEXT = _photo_test_welcome(EMOJI_DIGITS) + +def photo_test_welcome(photo_id: str = None) -> str: + """Тест-приветствие; photo_id — если у пользователя ещё фото на модерации.""" + return _photo_test_welcome(EMOJI_DIGITS, photo_id) PHOTO_TEST_PREVIEW_TEXT = _photo_test_preview(EMOJI_DIGITS) PHOTO_TEST_AI_CHECKING_TEXT = _photo_test_ai_checking(EMOJI_DIGITS) PHOTO_TEST_RECEIVING_TEXT = _photo_test_receiving(EMOJI_DIGITS)