from sqlalchemy import select, and_ from sqlalchemy.ext.asyncio import AsyncSession from typing import List, Optional from datetime import datetime from ..models.group_members import GroupMember, GroupKeyword, GroupStatistics class GroupMemberRepository: """Репозиторий для работы с участниками групп""" def __init__(self, session: AsyncSession): self.session = session async def add_member(self, group_id: int, user_id: str, username: str = None, first_name: str = None, last_name: str = None, is_bot: bool = False, is_admin: bool = False, is_owner: bool = False) -> GroupMember: """Добавить участника в группу""" member = GroupMember( group_id=group_id, user_id=user_id, username=username, first_name=first_name, last_name=last_name, is_bot=is_bot, is_admin=is_admin, is_owner=is_owner, joined_at=datetime.utcnow() ) self.session.add(member) await self.session.flush() return member async def get_member_by_user_id(self, group_id: int, user_id: str) -> Optional[GroupMember]: """Получить участника по user_id""" result = await self.session.execute( select(GroupMember).where( and_( GroupMember.group_id == group_id, GroupMember.user_id == user_id ) ) ) return result.scalar_one_or_none() async def get_members_by_group(self, group_id: int, is_admin: bool = None) -> List[GroupMember]: """Получить всех участников группы""" query = select(GroupMember).where(GroupMember.group_id == group_id) if is_admin is not None: query = query.where(GroupMember.is_admin == is_admin) result = await self.session.execute(query) return result.scalars().all() async def update_member(self, group_id: int, user_id: str, **kwargs) -> Optional[GroupMember]: """Обновить данные участника""" member = await self.get_member_by_user_id(group_id, user_id) if not member: return None for key, value in kwargs.items(): if hasattr(member, key): setattr(member, key, value) member.updated_at = datetime.utcnow() await self.session.flush() return member async def delete_member(self, group_id: int, user_id: str) -> bool: """Удалить участника из группы""" member = await self.get_member_by_user_id(group_id, user_id) if not member: return False await self.session.delete(member) return True async def bulk_add_members(self, group_id: int, members_data: List[dict]) -> List[GroupMember]: """Массовое добавление участников""" members = [] for data in members_data: member = GroupMember( group_id=group_id, user_id=data.get('user_id'), username=data.get('username'), first_name=data.get('first_name'), last_name=data.get('last_name'), is_bot=data.get('is_bot', False), is_admin=data.get('is_admin', False), is_owner=data.get('is_owner', False), joined_at=datetime.utcnow() ) members.append(member) self.session.add_all(members) await self.session.flush() return members async def search_members_by_username(self, group_id: int, keyword: str) -> List[GroupMember]: """Поиск участников по username""" result = await self.session.execute( select(GroupMember).where( and_( GroupMember.group_id == group_id, GroupMember.username.ilike(f'%{keyword}%') ) ) ) return result.scalars().all() async def search_members_by_name(self, group_id: int, keyword: str) -> List[GroupMember]: """Поиск участников по имени""" result = await self.session.execute( select(GroupMember).where( and_( GroupMember.group_id == group_id, (GroupMember.first_name.ilike(f'%{keyword}%')) | (GroupMember.last_name.ilike(f'%{keyword}%')) ) ) ) return result.scalars().all() async def get_admin_count(self, group_id: int) -> int: """Получить количество администраторов""" result = await self.session.execute( select(GroupMember).where( and_( GroupMember.group_id == group_id, GroupMember.is_admin == True ) ) ) return len(result.scalars().all()) async def get_bot_count(self, group_id: int) -> int: """Получить количество ботов""" result = await self.session.execute( select(GroupMember).where( and_( GroupMember.group_id == group_id, GroupMember.is_bot == True ) ) ) return len(result.scalars().all()) async def clear_members(self, group_id: int) -> int: """Очистить всех участников группы""" result = await self.session.execute( select(GroupMember).where(GroupMember.group_id == group_id) ) members = result.scalars().all() count = len(members) for member in members: await self.session.delete(member) return count class GroupKeywordRepository: """Репозиторий для работы с ключевыми словами""" def __init__(self, session: AsyncSession): self.session = session async def add_keywords(self, group_id: int, keywords: str, description: str = None) -> GroupKeyword: """Добавить ключевые слова для группы""" keyword = GroupKeyword( group_id=group_id, keywords=keywords, description=description ) self.session.add(keyword) await self.session.flush() return keyword async def get_keywords(self, group_id: int) -> Optional[GroupKeyword]: """Получить ключевые слова для группы""" result = await self.session.execute( select(GroupKeyword).where(GroupKeyword.group_id == group_id) ) return result.scalar_one_or_none() async def update_keywords(self, group_id: int, keywords: str, description: str = None) -> Optional[GroupKeyword]: """Обновить ключевые слова""" kw = await self.get_keywords(group_id) if not kw: return None kw.keywords = keywords if description: kw.description = description kw.updated_at = datetime.utcnow() await self.session.flush() return kw async def delete_keywords(self, group_id: int) -> bool: """Удалить ключевые слова""" kw = await self.get_keywords(group_id) if not kw: return False await self.session.delete(kw) return True class GroupStatisticsRepository: """Репозиторий для работы со статистикой групп""" def __init__(self, session: AsyncSession): self.session = session async def get_or_create_statistics(self, group_id: int) -> GroupStatistics: """Получить или создать статистику""" result = await self.session.execute( select(GroupStatistics).where(GroupStatistics.group_id == group_id) ) stats = result.scalar_one_or_none() if not stats: stats = GroupStatistics(group_id=group_id) self.session.add(stats) await self.session.flush() return stats async def update_members_count(self, group_id: int, total: int, admins: int = 0, bots: int = 0): """Обновить количество участников""" stats = await self.get_or_create_statistics(group_id) stats.total_members = total stats.total_admins = admins stats.total_bots = bots stats.last_updated = datetime.utcnow() await self.session.flush() async def increment_sent_messages(self, group_id: int, via_client: bool = False): """Увеличить счетчик отправленных сообщений""" stats = await self.get_or_create_statistics(group_id) stats.messages_sent += 1 if via_client: stats.messages_via_client += 1 stats.last_updated = datetime.utcnow() await self.session.flush() async def increment_failed_messages(self, group_id: int): """Увеличить счетчик ошибок""" stats = await self.get_or_create_statistics(group_id) stats.messages_failed += 1 stats.last_updated = datetime.utcnow() await self.session.flush() async def update_send_capabilities(self, group_id: int, can_bot: bool, can_client: bool): """Обновить возможности отправки""" stats = await self.get_or_create_statistics(group_id) stats.can_send_as_bot = can_bot stats.can_send_as_client = can_client stats.last_updated = datetime.utcnow() await self.session.flush() async def get_statistics(self, group_id: int) -> Optional[GroupStatistics]: """Получить статистику""" result = await self.session.execute( select(GroupStatistics).where(GroupStatistics.group_id == group_id) ) return result.scalar_one_or_none()