import logging from dataclasses import dataclass from phonenumbers import parse, geocoder from typing import List, Optional from telethon.types import User, Chat, Channel from telethon.tl.functions.payments import GetStarsStatusRequest from telethon.tl.functions.contacts import GetContactsRequest from modules.tdata import TDATA logger = logging.getLogger(__name__) class SessionInvalid(Exception): pass # Unified Result class @dataclass class Result: me: Optional[User] = None stars: Optional[int] = None country: Optional[str] = None contacts: Optional[List[User]] = None chats: Optional[List[Chat]] = None channels: Optional[List[Channel]] = None admin_channels: Optional[List[Channel]] = None class Checker: def __init__(self, path: str): self.path = path self.client = None logger.info(f"Инициализация проверки для пути: {path}") try: self.desktop = TDATA(path=self.path) except Exception as e: logger.error(f"Ошибка инициализации TDATA: {e}") self.desktop = None async def __aenter__(self): self.__ensure_client() return self async def __aexit__(self, exc_type, exc_val, exc_tb): if self.client: logger.debug("Отключение клиента Telethon") try: await self.client.disconnect() except Exception as e: logger.error(f"Ошибка отключения клиента Telethon: {e}") async def __ensure_client(self): if self.client is None: if self.desktop is None: raise Exception("TDATA не инициализирована") logger.debug("Инициализация клиента Telethon из TDATA") self.client = await self.desktop.convert() async def check_stars(self, me: User) -> int: try: stars_status = await self.client(GetStarsStatusRequest(peer=me)) return stars_status.balance.amount except Exception as e: logger.warning(f"Не удалось получить баланс звезд: {e}") return 0 async def check_country(self, me: User) -> str: try: phone_parse = parse(str(f"+{me.phone}")) return geocoder.description_for_number(phone_parse, "en") except Exception as e: logger.warning(f"Не удалось определить страну: {e}") return "N/A" async def check_contacts(self) -> List[User]: try: logger.debug("Получение контактов") result = await self.client(GetContactsRequest(hash=0)) return result.users except Exception as e: logger.warning(f"Не удалось получить контакты: {e}") async def check_chats(self) -> List[Chat]: try: logger.debug("Получение всех диалогов") chats = [] async for dialog in self.client.iter_dialogs(): chats.append(dialog.entity) return chats except Exception as e: logger.warning(f"Не удалось получить чаты: {e}") async def check_channels(self, chats: List[Chat]) -> List[Channel]: try: channels = [chat for chat in chats if isinstance(chat, Channel)] return channels except Exception as e: logger.warning(f"Не удалось отфильтровать каналы: {e}") async def check_admin_channels(self, channels: List[Channel]) -> List[Channel]: try: logger.debug("Проверка прав администратора") admin_channels = [] for channel in channels: permissions = await self.client.get_permissions(channel, "me") if permissions.is_admin or permissions.is_creator: admin_channels.append(channel) except Exception as e: logger.warning(f"Не удалось проверить админские права: {e}") async def check_all(self) -> Result: try: me = await self.client.get_me() # Собираем данные с обработкой ошибок stars = self.check_stars(me=me) country = self.check_country(me=me) contacts = self.check_contacts() chats = self.check_chats() channels = [] if chats == [] else self.check_channels(chats=chats) admin_channels = ( [] if channels == [] else self.check_admin_channels(channels=channels) ) return Result( me=me, stars=stars, country=country, contacts=contacts, chats=chats, channels=channels, admin_channels=admin_channels, ) except Exception as e: logger.error(f"Критическая ошибка при проверке: {e}") raise SessionInvalid()