128 lines
4.2 KiB
Python
128 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)
|