127 lines
4.2 KiB
Python
127 lines
4.2 KiB
Python
"""Главный файл для запуска обоих ботов."""
|
||
import asyncio
|
||
import logging
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
from app.config import Config
|
||
from app.queue_manager import QueueManager
|
||
from app.admin_manager import AdminManager
|
||
from app.statistics import Statistics
|
||
from app.user_bot import create_user_bot_application, worker_function
|
||
from app.admin_bot import create_admin_bot_application
|
||
|
||
|
||
def setup_logging(log_level: str):
|
||
"""Настройка логирования."""
|
||
level = getattr(logging, log_level.upper(), logging.INFO)
|
||
logging.basicConfig(
|
||
level=level,
|
||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||
handlers=[
|
||
logging.StreamHandler(sys.stdout)
|
||
]
|
||
)
|
||
|
||
|
||
async def main():
|
||
"""Главная функция запуска сервиса."""
|
||
# Загружаем конфигурацию
|
||
try:
|
||
config = Config()
|
||
except Exception as e:
|
||
print(f"Ошибка загрузки конфигурации: {e}")
|
||
sys.exit(1)
|
||
|
||
# Настраиваем логирование
|
||
setup_logging(config.log_level)
|
||
logger = logging.getLogger(__name__)
|
||
|
||
logger.info(f"Starting service in {'PROD' if config.is_prod else 'TEST'} mode")
|
||
|
||
# Создаём менеджер администраторов
|
||
admins_file = config.workdir / "admins.json"
|
||
admin_manager = AdminManager(admins_file)
|
||
|
||
# Создаём статистику
|
||
stats_file = config.workdir / "statistics.json"
|
||
statistics = Statistics(stats_file)
|
||
|
||
# Создаём admin-bot приложение
|
||
admin_bot_app = create_admin_bot_application(config, admin_manager, statistics)
|
||
|
||
user_bot_app = None
|
||
|
||
# Создаём функцию-воркер с замыканием на config, admin_manager и statistics
|
||
async def worker(task):
|
||
return await worker_function(task, config, admin_manager, admin_bot_app, statistics, user_bot_app)
|
||
|
||
# Создаём менеджер очереди
|
||
queue_manager = QueueManager(worker)
|
||
|
||
# Создаём user-bot приложение
|
||
user_bot_app = create_user_bot_application(
|
||
config,
|
||
queue_manager,
|
||
admin_manager,
|
||
admin_bot_app,
|
||
statistics
|
||
)
|
||
|
||
# Сохраняем ссылку на user_bot_app в admin_bot_app для доступа из worker
|
||
admin_bot_app.bot_data['user_bot_app'] = user_bot_app
|
||
|
||
# Запускаем очередь
|
||
await queue_manager.start()
|
||
|
||
# Инициализируем ботов
|
||
await admin_bot_app.initialize()
|
||
await user_bot_app.initialize()
|
||
|
||
# Запускаем ботов
|
||
await admin_bot_app.start()
|
||
await user_bot_app.start()
|
||
|
||
logger.info("Both bots started successfully")
|
||
|
||
try:
|
||
# Запускаем polling (start_polling возвращает очередь и не блокирует)
|
||
await admin_bot_app.updater.start_polling(drop_pending_updates=True)
|
||
await user_bot_app.updater.start_polling(drop_pending_updates=True)
|
||
|
||
logger.info("Polling started for both bots")
|
||
|
||
# Держим процесс живым, пока не прилетит остановка/сигнал
|
||
await asyncio.Event().wait()
|
||
except KeyboardInterrupt:
|
||
logger.info("Received shutdown signal")
|
||
finally:
|
||
# Останавливаем ботов
|
||
try:
|
||
await user_bot_app.updater.stop()
|
||
await admin_bot_app.updater.stop()
|
||
except Exception as e:
|
||
logger.error(f"Error stopping updaters: {e}")
|
||
|
||
try:
|
||
await user_bot_app.stop()
|
||
await admin_bot_app.stop()
|
||
except Exception as e:
|
||
logger.error(f"Error stopping apps: {e}")
|
||
|
||
# Останавливаем очередь
|
||
await queue_manager.stop()
|
||
|
||
logger.info("Service stopped")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
asyncio.run(main())
|
||
except KeyboardInterrupt:
|
||
print("\nShutting down...")
|
||
except Exception as e:
|
||
print(f"Fatal error: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
sys.exit(1)
|