# VIN-обработчики: декодирование, проверка, поиск фотографий import logging from typing import Optional, List from aiogram import Router from aiogram.types import Message, CallbackQuery, FSInputFile, InputMediaPhoto from aiogram.utils.keyboard import InlineKeyboardBuilder from aiogram.fsm.state import State, StatesGroup from aiogram.fsm.context import FSMContext from database import DatabaseManager from utils.formatting import escape_markdown router = Router() class VinStates(StatesGroup): waiting_for_vin = State() waiting_for_check_vin = State() waiting_for_photo_vin = State() @router.callback_query(lambda c: c.data == "decode_vin") async def decode_vin_callback(callback: CallbackQuery, state: FSMContext, db: DatabaseManager = None): """Начало процесса декодирования VIN""" try: await state.set_state(VinStates.waiting_for_vin) builder = InlineKeyboardBuilder() builder.button(text="🏠 Main Menu", callback_data="main_menu") await callback.message.edit_text( "🔍 **VIN Decode Service**\n\nPlease enter the VIN number (17 characters):\n\nExample: `1HGBH41JXMN109186`", reply_markup=builder.as_markup(), parse_mode="Markdown" ) await callback.answer() except Exception as e: logging.error(f"Error in decode_vin_callback: {e}") await callback.answer("Произошла ошибка", show_alert=True) @router.message(VinStates.waiting_for_vin) async def process_vin(message: Message, state: FSMContext, db: DatabaseManager = None): """Обработка VIN для декодирования""" try: vin = message.text.strip().upper() if len(vin) != 17: builder = InlineKeyboardBuilder() builder.button(text="🏠 Main Menu", callback_data="main_menu") await message.answer( "❌ **Invalid VIN**\n\nVIN number must be exactly 17 characters.\nPlease try again:", reply_markup=builder.as_markup(), parse_mode="Markdown" ) return await state.clear() # Заглушка для декодирования VIN builder = InlineKeyboardBuilder() builder.button(text="🔍 Check History", callback_data=f"check_vin:{vin}") builder.button(text="📸 Search Photos", callback_data=f"search_photos:{vin}") builder.button(text="🏠 Main Menu", callback_data="main_menu") builder.adjust(1) await message.answer( f"✅ **VIN Decoded Successfully**\n\n" f"**VIN:** `{vin}`\n" f"**Make:** Toyota\n" f"**Model:** Camry\n" f"**Year:** 2015\n" f"**Engine:** 2.5L\n\n" f"Choose an action:", reply_markup=builder.as_markup(), parse_mode="Markdown" ) except Exception as e: logging.error(f"Error in process_vin: {e}") await message.answer("Произошла ошибка при обработке VIN") async def send_vehicle_photos(message: Message, vin: str, photo_paths: List[str], make: str, model: str, year: str): """Отправка фотографий автомобиля пользователю""" try: from utils.photo_utils import prepare_photo_paths logging.info(f"Sending {len(photo_paths)} photos for VIN {vin}") prepared_paths = prepare_photo_paths(photo_paths) if not prepared_paths: await message.answer( "📸 **No Photos Available**\n\nUnfortunately, the photos for this vehicle are currently unavailable.", parse_mode="Markdown" ) return # Отправляем фотографии группами по 10 photo_batch_size = 10 total_batches = (len(prepared_paths) + photo_batch_size - 1) // photo_batch_size for batch_num in range(total_batches): start_idx = batch_num * photo_batch_size end_idx = min(start_idx + photo_batch_size, len(prepared_paths)) batch_paths = prepared_paths[start_idx:end_idx] media_group = [] for i, photo_path in enumerate(batch_paths): try: if batch_num == 0 and i == 0: caption = f"📸 **Vehicle Photos**\n**VIN:** {vin}\n**Vehicle:** {year} {make} {model}\n**Photos:** {len(prepared_paths)} total" media_group.append(InputMediaPhoto(media=FSInputFile(photo_path), caption=caption, parse_mode="Markdown")) else: media_group.append(InputMediaPhoto(media=FSInputFile(photo_path))) except Exception as e: logging.error(f"Error preparing photo {photo_path}: {e}") continue if media_group: try: await message.answer_media_group(media_group) logging.info(f"Sent batch {batch_num + 1}/{total_batches} with {len(media_group)} photos") except Exception as e: logging.error(f"Error sending photo batch {batch_num + 1}: {e}") builder = InlineKeyboardBuilder() builder.button(text="📸 Search More Photos", callback_data="search_car_photo") builder.button(text="🚗 Get Detailed Report", callback_data=f"pay_check_detailed:{vin}") builder.button(text="🏠 Main Menu", callback_data="main_menu") builder.adjust(1) await message.answer( f"✅ **Photos sent successfully!**\n\n**VIN:** `{escape_markdown(vin)}`\n**Photos sent:** {len(prepared_paths)}", reply_markup=builder.as_markup(), parse_mode="Markdown" ) except Exception as e: logging.error(f"Error in send_vehicle_photos: {e}") await message.answer( f"❌ **Error sending photos**\n\nThere was an error sending the photos for VIN `{escape_markdown(vin)}`.", parse_mode="Markdown" )