Фото: pending-состояние — модуль остаётся открыт; тест-режим: фото можно отправить на тест; прочий ввод → ошибка неверного выбора
This commit is contained in:
Binary file not shown.
+48
-3
@@ -31,6 +31,8 @@ from utils.texts import (
|
|||||||
photo_preview_ready,
|
photo_preview_ready,
|
||||||
photo_moderation_pending,
|
photo_moderation_pending,
|
||||||
photo_welcome_with_status,
|
photo_welcome_with_status,
|
||||||
|
photo_invalid_cmd,
|
||||||
|
photo_test_welcome,
|
||||||
PHOTO_TEST_WELCOME_TEXT,
|
PHOTO_TEST_WELCOME_TEXT,
|
||||||
PHOTO_TEST_PREVIEW_TEXT,
|
PHOTO_TEST_PREVIEW_TEXT,
|
||||||
PHOTO_TEST_AI_CHECKING_TEXT,
|
PHOTO_TEST_AI_CHECKING_TEXT,
|
||||||
@@ -51,6 +53,10 @@ pending_photos = {}
|
|||||||
# Пользователи, находящиеся в под-режиме «тест проверка фото»
|
# Пользователи, находящиеся в под-режиме «тест проверка фото»
|
||||||
test_submode_users = set()
|
test_submode_users = set()
|
||||||
|
|
||||||
|
# Пользователи, у которых фото на модерации (вход заблокирован,
|
||||||
|
# модуль остаётся открыт: в тест-режиме можно отправить фото на тест)
|
||||||
|
moderation_pending_users = set()
|
||||||
|
|
||||||
def in_test_submode(user_id: str) -> bool:
|
def in_test_submode(user_id: str) -> bool:
|
||||||
"""Проверяет, находится ли пользователь в под-режиме тест-проверки фото"""
|
"""Проверяет, находится ли пользователь в под-режиме тест-проверки фото"""
|
||||||
if user_id not in test_submode_users:
|
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):
|
async def send_dynamic_photo_main_menu(msg: Message, user_id: str):
|
||||||
"""Вход в раздел фото (паттерн ЛК): модуль сам запрашивает данные и показывает их.
|
"""Вход в раздел фото (паттерн ЛК): модуль сам запрашивает данные и показывает их.
|
||||||
|
|
||||||
- pending — отдельное сообщение «фото на модерации», модуль НЕ открывается
|
- pending — сообщение «фото на модерации»; модуль остаётся открыт
|
||||||
(кнопок загрузки фото нет);
|
(цифры → ошибка неверного выбора, 0 — выход). Тест-режим:
|
||||||
|
фото можно отправить на проверку в ИИ;
|
||||||
- rejected — ОДНО сообщение: меню + причина отказа (кнопки на месте);
|
- rejected — ОДНО сообщение: меню + причина отказа (кнопки на месте);
|
||||||
- иначе/ошибка API — штатное меню входа.
|
- иначе/ошибка API — штатное меню входа.
|
||||||
Статус проверяется и показывается всегда, включая тестовый режим.
|
Статус проверяется и показывается всегда, включая тестовый режим.
|
||||||
@@ -166,9 +173,17 @@ async def send_dynamic_photo_main_menu(msg: Message, user_id: str):
|
|||||||
# Статус модерации запрашиваем всегда (и в тестовом режиме тоже)
|
# Статус модерации запрашиваем всегда (и в тестовом режиме тоже)
|
||||||
status = await check_moderation_status(user_id)
|
status = await check_moderation_status(user_id)
|
||||||
if status.get("status") == "ok" and status.get("moderation_status") == "pending":
|
if status.get("status") == "ok" and status.get("moderation_status") == "pending":
|
||||||
# Фото на модерации — не вводим в модуль (кнопок загрузки нет)
|
# Фото на модерации — штатная загрузка заблокирована,
|
||||||
|
# но модуль остаётся открыт (PHOTO_MODE), чтобы цифры не ушли в главное меню
|
||||||
photo_id = status.get("photo_id", "???")
|
photo_id = status.get("photo_id", "???")
|
||||||
log_menu_stats(user_id, "Photo Bot", "Вход заблокирован — фото на модерации")
|
log_menu_stats(user_id, "Photo Bot", "Вход заблокирован — фото на модерации")
|
||||||
|
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(
|
await msg.answer(
|
||||||
photo_moderation_pending(photo_id),
|
photo_moderation_pending(photo_id),
|
||||||
parse_mode="html"
|
parse_mode="html"
|
||||||
@@ -219,6 +234,7 @@ async def photo_module_handler(msg: Message):
|
|||||||
log_menu_stats(user_id, "Photo Bot", "Выход в главное меню")
|
log_menu_stats(user_id, "Photo Bot", "Выход в главное меню")
|
||||||
states.clear_state(user_id)
|
states.clear_state(user_id)
|
||||||
test_submode_users.discard(user_id)
|
test_submode_users.discard(user_id)
|
||||||
|
moderation_pending_users.discard(user_id)
|
||||||
if user_id in pending_photos:
|
if user_id in pending_photos:
|
||||||
photo_data = pending_photos[user_id]
|
photo_data = pending_photos[user_id]
|
||||||
if os.path.exists(photo_data['path']):
|
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")
|
await msg.answer(MENU_TEXT, parse_mode="html")
|
||||||
return
|
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, проверяем статус модерации ---
|
# --- ПРОВЕРКА СТАТУСА: если нет фото в pending_photos, проверяем статус модерации ---
|
||||||
# (в тестовом режиме статусы тоже показываем — поведение как в обычном режиме)
|
# (в тестовом режиме статусы тоже показываем — поведение как в обычном режиме)
|
||||||
if user_id not in pending_photos and not is_attachment:
|
if user_id not in pending_photos and not is_attachment:
|
||||||
|
|||||||
Binary file not shown.
+25
-4
@@ -225,6 +225,13 @@ def _photo_unknown(emojis: dict) -> str:
|
|||||||
f"{emojis['0']} — В главное меню"
|
f"{emojis['0']} — В главное меню"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _photo_invalid_cmd(emojis: dict) -> str:
|
||||||
|
return (
|
||||||
|
f"⚠️ <b>Неверный выбор пункта меню.</b>\n"
|
||||||
|
f"Пожалуйста, используйте кнопки из сообщения выше.\n\n"
|
||||||
|
f"{emojis['0']} — В главное меню"
|
||||||
|
)
|
||||||
|
|
||||||
def _photo_processing_face(emojis: dict) -> str:
|
def _photo_processing_face(emojis: dict) -> str:
|
||||||
return "⏳ <i>Ищу лицо на фото, пожалуйста, подождите...</i>"
|
return "⏳ <i>Ищу лицо на фото, пожалуйста, подождите...</i>"
|
||||||
|
|
||||||
@@ -269,13 +276,20 @@ def _photo_status_info(status: dict = None, emojis: dict = None) -> str | None:
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _photo_test_welcome(emojis: dict) -> str:
|
def _photo_test_welcome(emojis: dict, photo_id: str = None) -> str:
|
||||||
return (
|
"""Тест-приветствие. photo_id — если у пользователя ещё есть фото
|
||||||
|
на модерации (тестовая проверка его не затрагивает)."""
|
||||||
|
text = (
|
||||||
f"🧪 <b>Тестовый режим фото-проверки</b>\n\n"
|
f"🧪 <b>Тестовый режим фото-проверки</b>\n\n"
|
||||||
f"📸 Пришлите фотографию — она уйдёт <b>напрямую в ИИ</b>.\n"
|
f"📸 Пришлите фотографию — она уйдёт <b>напрямую в ИИ</b>.\n"
|
||||||
f"Бот покажет вердикт ИИ. <b>Фото никуда не публикуется</b>.\n\n"
|
f"Бот покажет вердикт ИИ. <b>Фото никуда не публикуется</b>.\n"
|
||||||
f"{emojis['0']} — В главное меню"
|
|
||||||
)
|
)
|
||||||
|
if photo_id:
|
||||||
|
text += (
|
||||||
|
f"\n⏳ <b>У вас уже есть фото на модерации (№ {photo_id}).</b>\n"
|
||||||
|
f"Ожидайте решения модератора. Тестовая проверка его не затрагивает.\n"
|
||||||
|
)
|
||||||
|
return text + f"\n\n{emojis['0']} — В главное меню"
|
||||||
|
|
||||||
def _photo_test_preview(emojis: dict) -> str:
|
def _photo_test_preview(emojis: dict) -> str:
|
||||||
return (
|
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_TEST_ENTRY_TEXT = _photo_welcome(EMOJI_DIGITS, show_test=True)
|
||||||
PHOTO_UNKNOWN_CMD_TEXT = _photo_unknown(EMOJI_DIGITS)
|
PHOTO_UNKNOWN_CMD_TEXT = _photo_unknown(EMOJI_DIGITS)
|
||||||
|
|
||||||
|
def photo_invalid_cmd() -> str:
|
||||||
|
return _photo_invalid_cmd(EMOJI_DIGITS)
|
||||||
|
|
||||||
def photo_error_handling() -> str:
|
def photo_error_handling() -> str:
|
||||||
return system_error_text(EMOJI_DIGITS, show_back=False)
|
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)
|
return _photo_welcome(EMOJI_DIGITS, show_test=show_test, info=info)
|
||||||
|
|
||||||
PHOTO_TEST_WELCOME_TEXT = _photo_test_welcome(EMOJI_DIGITS)
|
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_PREVIEW_TEXT = _photo_test_preview(EMOJI_DIGITS)
|
||||||
PHOTO_TEST_AI_CHECKING_TEXT = _photo_test_ai_checking(EMOJI_DIGITS)
|
PHOTO_TEST_AI_CHECKING_TEXT = _photo_test_ai_checking(EMOJI_DIGITS)
|
||||||
PHOTO_TEST_RECEIVING_TEXT = _photo_test_receiving(EMOJI_DIGITS)
|
PHOTO_TEST_RECEIVING_TEXT = _photo_test_receiving(EMOJI_DIGITS)
|
||||||
|
|||||||
Reference in New Issue
Block a user