Files
new_lottery_bot/main.py
Andrew K. Choi 0fdf01d1c7 feat: update admin panel keyboard structure and registration button logic
- Updated admin panel keyboard to match admin_panel.py handlers
- Changed registration button logic: show only for unregistered non-admins
- Added missing methods to IBotController interface
- Updated get_main_keyboard to accept is_registered parameter
- Simplified admin panel structure with proper callback routing
- Removed test callback button from production UI
- Created ADMIN_PANEL_STRUCTURE.md and ADMIN_PANEL_TESTING.md documentation
2025-11-17 07:50:08 +09:00

178 lines
7.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Новая модульная версия 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
# Настройка логирования
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"""
async with get_controller() as controller:
if not controller.is_admin(message.from_user.id):
await message.answer("❌ Недостаточно прав для доступа к админ панели")
return
# Создаем callback query объект для совместимости
from aiogram.types import CallbackQuery
fake_callback = CallbackQuery(
id="admin_cmd",
from_user=message.from_user,
chat_instance="admin",
data="admin_panel",
message=message
)
await controller.handle_admin_panel(fake_callback)
# === CALLBACK HANDLERS ===
@router.callback_query(F.data == "test_callback")
async def test_callback_handler(callback: CallbackQuery):
"""Тестовый callback handler"""
await callback.answer("✅ Тест прошел успешно! Колбэки работают.", show_alert=True)
@router.callback_query(F.data == "admin_panel")
async def admin_panel_handler(callback: CallbackQuery):
"""Обработчик админ панели"""
async with get_controller() as controller:
await controller.handle_admin_panel(callback)
@router.callback_query(F.data == "lottery_management")
async def lottery_management_handler(callback: CallbackQuery):
"""Обработчик управления розыгрышами (старый callback)"""
async with get_controller() as controller:
await controller.handle_lottery_management(callback)
@router.callback_query(F.data == "conduct_lottery_admin")
async def conduct_lottery_admin_handler(callback: CallbackQuery):
"""Обработчик выбора розыгрыша для проведения"""
async with get_controller() as controller:
await controller.handle_conduct_lottery_admin(callback)
@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.startswith("conduct_") & ~F.data.in_(["conduct_lottery_admin"]))
async def conduct_specific_lottery_handler(callback: CallbackQuery):
"""Обработчик проведения конкретного розыгрыша"""
async with get_controller() as controller:
await controller.handle_conduct_lottery(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)
# === ЗАГЛУШКИ ДЛЯ ОСТАЛЬНЫХ CALLBACKS ===
# === ЗАГЛУШКИ НЕ НУЖНЫ - ВСЕ ФУНКЦИИ РЕАЛИЗОВАНЫ В РОУТЕРАХ ===
# Функции обрабатываются в:
# - 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(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(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}")