""" Celery задачи для UserBot микросервиса Запускает парсинг групп в фоновом режиме """ import asyncio import logging from celery import shared_task from app.userbot.parser import userbot_parser from app.database import AsyncSessionLocal from app.database.repository import GroupRepository logger = logging.getLogger(__name__) def run_async(coro): """Вспомогательная функция для запуска async функций в Celery""" loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: return loop.run_until_complete(coro) finally: loop.close() @shared_task(name='app.userbot.tasks.initialize_userbot') def initialize_userbot_task(): """Инициализировать UserBot при запуске""" logger.info("🚀 Инициализация UserBot...") result = run_async(userbot_parser.initialize()) if result: logger.info("✅ UserBot успешно инициализирован") return {'status': 'success', 'message': 'UserBot initialized'} else: logger.error("❌ Ошибка инициализации UserBot") return {'status': 'error', 'message': 'UserBot initialization failed'} @shared_task(name='app.userbot.tasks.parse_group') def parse_group_task(chat_id: int): """ Парсить группу и сохранить в БД Args: chat_id: ID группы для парсинга """ logger.info(f"📊 Парсинг группы {chat_id}...") result = run_async(userbot_parser.sync_group_to_db(chat_id)) if result: logger.info(f"✅ Группа {chat_id} успешно спарсена") return {'status': 'success', 'chat_id': chat_id, 'message': 'Group parsed successfully'} else: logger.error(f"❌ Ошибка парсинга группы {chat_id}") return {'status': 'error', 'chat_id': chat_id, 'message': 'Group parsing failed'} @shared_task(name='app.userbot.tasks.sync_all_groups') def sync_all_groups_task(): """Синхронизировать все активные группы из БД""" logger.info("🔄 Начало синхронизации всех групп...") async def _sync_all(): try: async with AsyncSessionLocal() as session: repo = GroupRepository(session) groups = await repo.get_all_active_groups() if not groups: logger.info("ℹ️ Нет активных групп для синхронизации") return {'status': 'success', 'groups_synced': 0} synced = 0 failed = 0 for group in groups: success = await userbot_parser.sync_group_to_db(group.chat_id) if success: synced += 1 else: failed += 1 logger.info(f"✅ Синхронизировано {synced} групп (ошибок: {failed})") return {'status': 'success', 'groups_synced': synced, 'groups_failed': failed} except Exception as e: logger.error(f"❌ Ошибка при синхронизации групп: {e}") return {'status': 'error', 'message': str(e)} return run_async(_sync_all()) @shared_task(name='app.userbot.tasks.parse_group_members') def parse_group_members_task(chat_id: int, limit: int = 10000): """ Парсить участников группы Args: chat_id: ID группы limit: максимум участников """ logger.info(f"👥 Парсинг участников группы {chat_id} (лимит: {limit})...") async def _parse_members(): try: members = await userbot_parser.parse_group_members(chat_id, limit) if not members: return {'status': 'error', 'chat_id': chat_id, 'members_count': 0} # Сохранить в БД async with AsyncSessionLocal() as session: from app.database.repository import GroupMemberRepository member_repo = GroupMemberRepository(session) for member in members: member_data = { 'group_id': chat_id, 'user_id': int(member['user_id']), 'username': member['username'], 'first_name': member['first_name'], 'last_name': member['last_name'], 'is_bot': member['is_bot'], } await member_repo.add_or_update_member(member_data) await session.commit() logger.info(f"✅ {len(members)} участников группы {chat_id} сохранено в БД") return {'status': 'success', 'chat_id': chat_id, 'members_count': len(members)} except Exception as e: logger.error(f"❌ Ошибка при парсинге участников {chat_id}: {e}") return {'status': 'error', 'chat_id': chat_id, 'message': str(e)} return run_async(_parse_members())