Fix bot polling, downloads, and file delivery

This commit is contained in:
vrubel 2026-01-28 14:45:56 +03:00
commit 8a21cbe18a
16 changed files with 1712 additions and 0 deletions

127
app/main.py Normal file
View file

@ -0,0 +1,127 @@
"""Главный файл для запуска обоих ботов."""
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)