From 9a9b90b3a10cb782f07ff1762af93feb6f6f1958 Mon Sep 17 00:00:00 2001 From: dddennnisss Date: Fri, 14 Aug 2026 00:54:27 +0700 Subject: [PATCH] photo_bot: remove AI validator, restore prepare_ad_photo workflow --- photo_bot/handlers.py | 68 ++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/photo_bot/handlers.py b/photo_bot/handlers.py index f69dd4b..d792d2f 100644 --- a/photo_bot/handlers.py +++ b/photo_bot/handlers.py @@ -15,11 +15,19 @@ from trueconf.types import FSInputFile import config.config as config from utils import states from utils.menu import MENU_TEXT -from utils.texts import * # 👈 Импортируем все тексты и константы проекта - -# 🔌 Бизнес-логика обработки и ИИ-валидации from photo_bot.photo_processor import prepare_ad_photo -from photo_bot.ai_validator import validate_photo_ai +from utils.texts import ( + EMOJI_DIGITS, + PHOTO_MAIN_MENU_TEXT, + system_error_text, + photo_error_handling, + PHOTO_UPLOADING_TEXT, + photo_success_sent, + photo_cancel_text, + PHOTO_PROCESSING_TEXT, + photo_preview_ready, + photo_error_processing, +) # 🔌 Импортируем централизованную функцию сбора статистики из main from utils.stats_logger import log_menu_stats @@ -94,6 +102,7 @@ def log_and_notify_photo_error(user_id: str, action: str, error_details: str): async def handle_photo_error(msg: Message, user_id: str, action: str, error_details: str): """Вызывает системное логирование и выдает заглушку пользователю""" await asyncio.to_thread(log_and_notify_photo_error, user_id, action, error_details) + await msg.answer(photo_error_handling(), parse_mode="html") @@ -149,6 +158,7 @@ async def photo_module_handler(msg: Message): response = await client.post(config.TRASH_API_URL, files=files) if response.status_code == 200: + # ФИКСАЦИЯ СТАТИСТИКИ: Успешная выгрузка фото на утверждение log_menu_stats(user_id, "Photo Bot", "Отправка фото на утверждение") await msg.answer(photo_success_sent(), parse_mode="html") @@ -176,6 +186,7 @@ async def photo_module_handler(msg: Message): await msg.answer(photo_cancel_text(), parse_mode="html") return + # --- ИСПРАВЛЕНО: Защита от мусорного ввода при висящем превью --- else: await msg.answer(system_error_text(EMOJI_DIGITS), parse_mode="html") return @@ -184,37 +195,20 @@ async def photo_module_handler(msg: Message): if is_attachment: file_id = getattr(msg.content, "file_id", None) ready_path = f"/tmp/{user_login}.bmp" - raw_path = f"/tmp/raw_{user_login}.webp" + raw_path = None await msg.answer(PHOTO_PROCESSING_TEXT, parse_mode="html") try: - # 1. Скачиваем байты файла из TrueConf - file_bytes = await states.tc_bot.download_file_by_id(file_id) + downloaded_file = await states.tc_bot.download_file_by_id(file_id) + raw_path = downloaded_file + result = await asyncio.to_thread(prepare_ad_photo, raw_path, ready_path, 96) - # 2. Сохраняем байты во временный файл на диск - def save_raw_bytes(b_data, target_path): - with open(target_path, "wb") as f: - f.write(b_data) - - await asyncio.to_thread(save_raw_bytes, file_bytes, raw_path) - - # 3. Техническая конвертация в BMP без геометрических проверок - def convert_to_bmp_only(src_path, dst_path): - with Image.open(src_path) as img: - img.convert("RGB").save(dst_path, format="BMP") - - await asyncio.to_thread(convert_to_bmp_only, raw_path, ready_path) - - # 4. ИИ-ПРОВЕРКА ЧЕРЕЗ GEMMA 4 VISION (srvkem-ii-03) - ai_res = await validate_photo_ai(raw_path) - - if ai_res["success"] and ai_res["approved"]: - # --- УСПЕШНАЯ ПРОВЕРКА ИИ --- - log_menu_stats(user_id, "Photo Bot", "Загрузка фото: Одобрено ИИ") + if result["success"]: + # ФИКСАЦИЯ СТАТИСТИКИ: Факт успешной загрузки и обработки нового фото + log_menu_stats(user_id, "Photo Bot", "Загрузка и конвертация нового фото") pending_photos[user_id] = ready_path preview_path = f"/tmp/prev_{user_login}.jpg" - try: Image.open(ready_path).save(preview_path, format="JPEG") p_main = FSInputFile(preview_path, filename="preview.jpg") @@ -227,19 +221,16 @@ async def photo_module_handler(msg: Message): os.remove(preview_path) await asyncio.sleep(0.5) - await msg.answer(photo_preview_ready(), parse_mode="html") - - else: - # --- ИИ ОТКЛОНИЛ ФОТО ИЛИ ПРОИЗОШЛА ОШИБКА --- - log_menu_stats(user_id, "Photo Bot", "Загрузка фото: Отклонено ИИ") - - reason_text = ai_res["text"] if ai_res["success"] else ai_res.get("error", "Не удалось проверить фото через ИИ.") - await msg.answer( - f"❌ Фотография не прошла проверку\n\n{reason_text}", + photo_preview_ready(), + parse_mode="html" + ) + else: + error_text = result.get('error', 'Не удалось обработать фото.') + await msg.answer( + photo_error_processing(error_text), parse_mode="html" ) - except Exception as e: await handle_photo_error(msg, user_id, "Скачивание и обработка файла", str(e)) finally: @@ -249,4 +240,3 @@ async def photo_module_handler(msg: Message): except Exception as cleanup_err: await asyncio.to_thread(log_and_notify_photo_error, user_id, "Очистка временных файлов", str(cleanup_err)) return -