Первый коммит

This commit is contained in:
2026-02-17 11:24:55 +07:00
commit a06448ca4b
109 changed files with 21165 additions and 0 deletions

172
main.py Normal file
View File

@@ -0,0 +1,172 @@
"""
Точка входа PrimoGuard Bot
"""
from asyncio import run
from configs import settings
from bot import bot, dp, BotInfo, WebhookManager, setup_middlewares, router
from database import get_manager
from middleware.loggers import logger
__all__ = ("main",)
async def setup_services(setup_webhook: bool = True) -> str:
"""
Инициализация всех сервисов: БД и бот.
Args:
setup_webhook: Устанавливать ли webhook в BotInfo.setup()
Returns:
str: Username бота
"""
# База данных
manager = get_manager()
await manager.init()
stats = await manager.get_stats()
logger.info(
f"📊 БД инициализирована: {stats.get('total_banwords', 0)} банвордов",
log_type="DATABASE"
)
# Бот: получение информации (БЕЗ webhook)
await BotInfo.setup(bots=bot, setup_webhook=setup_webhook)
# ВАЖНО: Регистрируем middleware и роутеры ДО установки webhook
setup_middlewares(
dp=dp,
bot=bot,
enable_spam_check=settings.ANTI_SPAM,
channel_ids=[],
)
# Подключение маршрутов
dp.include_router(router)
logger.info("Все handlers и middleware зарегистрированы", log_type="STARTUP")
return BotInfo.username
async def on_startup(app) -> None:
"""Выполняется при запуске webhook-сервера."""
# 1. Инициализируем всё БЕЗ webhook
username = await setup_services(setup_webhook=False)
# 2. ТЕПЕРЬ устанавливаем webhook (когда всё готово)
webhook = WebhookManager(bot, dp)
if settings.WEBHOOK_URL:
success = await webhook.setup(
webhook_url=settings.WEBHOOK_URL,
secret_token=settings.SECRET_TOKEN,
drop_pending_updates=True
)
if success:
logger.success(
f"✅ Бот @{username} запущен в режиме Webhook",
log_type="STARTUP"
)
else:
logger.error(
"Не удалось установить webhook, но сервер запущен",
log_type="STARTUP"
)
else:
logger.warning(
"⚠️ WEBHOOK_URL не указан",
log_type="STARTUP"
)
async def on_shutdown(app) -> None:
"""Очистка ресурсов при остановке сервера."""
logger.info("👋 Остановка бота...", log_type="SHUTDOWN")
try:
await get_manager().close()
await bot.session.close()
except Exception as e:
logger.error(f"Ошибка при закрытии: {e}", log_type="SHUTDOWN")
logger.success("✅ Бот остановлен", log_type="SHUTDOWN")
def start_webhook() -> None:
"""Запуск в режиме Webhook (синхронный)."""
logger.setup()
webhook = WebhookManager(bot, dp)
# ВАЖНО: Конфигурируем webhook ПЕРЕД on_startup
webhook.configure()
# Добавляем startup/shutdown handlers
webhook.app.on_startup.append(on_startup)
webhook.app.on_shutdown.append(on_shutdown)
# Запускаем webhook сервер
logger.info("🌐 Запуск Webhook сервера...", log_type="MAIN")
webhook.run()
async def start_polling() -> None:
"""Запуск в режиме Polling (асинхронный)."""
logger.setup()
try:
username = await setup_services(setup_webhook=False)
# Удаляем webhook для polling режима
webhook = WebhookManager(bot, dp)
await webhook.delete(drop_pending_updates=True)
logger.success(
f"✅ Бот @{username} запущен в режиме Polling",
log_type="STARTUP"
)
# Запускаем polling
await dp.start_polling(bot, drop_pending_updates=True)
except Exception as e:
logger.critical(
f"🔥 Критическая ошибка: {e}",
log_type="MAIN"
)
raise
finally:
try:
await bot.session.close()
await get_manager().close()
except:
pass
def main() -> None:
"""Входная точка проекта."""
try:
if settings.WEBHOOK:
# ========== WEBHOOK РЕЖИМ ==========
start_webhook()
else:
# ========== POLLING РЕЖИМ ==========
run(start_polling())
except KeyboardInterrupt:
logger.info("⚠️ Остановка по сигналу Ctrl+C", log_type="MAIN")
except Exception as e:
logger.critical(
f"🔥 Критическая ошибка при запуске: {e}",
log_type="MAIN"
)
raise
if __name__ == "__main__":
main()