Files
TDATA-Checker/modules/checker.py
T

154 lines
5.1 KiB
Python

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()