""" Новая модульная версия main.py с применением SOLID принципов """ import asyncio import logging from contextlib import asynccontextmanager from aiogram import Bot, Dispatcher, Router, F from aiogram.types import Message, CallbackQuery from aiogram.filters import Command from aiogram.fsm.storage.memory import MemoryStorage from src.core.config import BOT_TOKEN from src.core.database import async_session_maker from src.container import container from src.interfaces.base import IBotController from src.handlers.admin_panel import admin_router from src.handlers.registration_handlers import router as registration_router from src.handlers.admin_account_handlers import router as admin_account_router from src.handlers.redraw_handlers import router as redraw_router from src.handlers.chat_handlers import router as chat_router from src.handlers.admin_chat_handlers import router as admin_chat_router from src.handlers.account_handlers import account_router from src.handlers.message_management import message_admin_router from src.handlers.p2p_chat import router as p2p_chat_router # Настройка логирования logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # Создание бота и диспетчера bot = Bot(token=BOT_TOKEN) storage = MemoryStorage() dp = Dispatcher(storage=storage) router = Router() @asynccontextmanager async def get_controller(): """Контекстный менеджер для получения контроллера с БД сессией""" async with async_session_maker() as session: scoped_container = container.create_scoped_container(session) controller = scoped_container.get(IBotController) yield controller # === COMMAND HANDLERS === @router.message(Command("start")) async def cmd_start(message: Message): """Обработчик команды /start""" async with get_controller() as controller: await controller.handle_start(message) @router.message(Command("admin")) async def cmd_admin(message: Message): """Обработчик команды /admin - перенаправляет в admin_panel""" from src.core.config import ADMIN_IDS if message.from_user.id not in ADMIN_IDS: await message.answer("❌ Недостаточно прав для доступа к админ панели") return # Отправляем сообщение с кнопкой админ панели from src.components.ui import KeyboardBuilderImpl kb = KeyboardBuilderImpl() keyboard = kb.get_admin_keyboard() text = "⚙️ **Панель администратора**\n\n" text += "Выберите раздел для управления:" await message.answer(text, reply_markup=keyboard, parse_mode="Markdown") # === CALLBACK HANDLERS === @router.callback_query(F.data == "active_lotteries") async def active_lotteries_handler(callback: CallbackQuery): """Обработчик показа активных розыгрышей""" async with get_controller() as controller: await controller.handle_active_lotteries(callback) @router.callback_query(F.data == "back_to_main") async def back_to_main_handler(callback: CallbackQuery): """Обработчик возврата в главное меню""" async with get_controller() as controller: await controller.handle_start(callback.message) # Функции обрабатываются в: # - admin_panel.py: создание розыгрышей, управление пользователями, счетами, чатом, статистика # - registration_handlers.py: регистрация пользователей # - admin_account_handlers.py: управление счетами # - admin_chat_handlers.py: управление чатом # - chat_handlers.py: пользовательский чат # === FALLBACK HANDLERS === # Обработка неизвестных callback и сообщений происходит в соответствующих роутерах async def main(): """Главная функция запуска бота""" logger.info("Запуск бота...") # Подключаем роутеры в правильном порядке # 1. Основной роутер main.py с базовыми командами (/start, /help, /admin) dp.include_router(router) # 2. Специфичные роутеры dp.include_router(message_admin_router) # Управление сообщениями администратором dp.include_router(admin_router) # Админ панель - самая высокая специфичность dp.include_router(registration_router) # Регистрация dp.include_router(admin_account_router) # Админские команды счетов dp.include_router(admin_chat_router) # Админские команды чата dp.include_router(redraw_router) # Повторные розыгрыши dp.include_router(p2p_chat_router) # P2P чат между пользователями dp.include_router(account_router) # Пользовательские счета # 3. Chat router ПОСЛЕДНИМ (ловит все необработанные сообщения) dp.include_router(chat_router) # Пользовательский чат (последним - ловит все сообщения) # Запускаем polling try: logger.info("Бот запущен") await dp.start_polling(bot) except Exception as e: logger.error(f"Ошибка при запуске бота: {e}") finally: await bot.session.close() if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: logger.info("Бот остановлен пользователем") except Exception as e: logger.error(f"Критическая ошибка: {e}")