diff --git a/basethon/__init__.py b/basethon/__init__.py index 7292f80..43e0104 100644 --- a/basethon/__init__.py +++ b/basethon/__init__.py @@ -3,6 +3,7 @@ from .base_session import BaseSession from .base_thon import BaseData, BaseThon from .json_async_converter import JsonAsyncConverter from .json_converter import JsonConverter +from .models import BaseThonOptions, BaseThonSearchCodeOptions __all__ = [ "BaseThon", @@ -11,4 +12,6 @@ __all__ = [ "BaseData", "JsonAsyncConverter", "AsyncBaseSession", + "BaseThonOptions", + "BaseThonSearchCodeOptions", ] diff --git a/basethon/async_base_session.py b/basethon/async_base_session.py index cc60ddc..53f5b0c 100644 --- a/basethon/async_base_session.py +++ b/basethon/async_base_session.py @@ -11,7 +11,7 @@ class AsyncBaseSession: self.banned_dir = banned_dir self.json_errors: set[Path] = set() - async def iter_sessions(self) -> AsyncGenerator[tuple[Path, Path, dict], None]: + async def __aiter__(self) -> AsyncGenerator[tuple[Path, Path, dict], None]: """ Поиск сессий в base_dir Возвращает генератор с кортежами (item, json_path, json_data) diff --git a/basethon/base_session.py b/basethon/base_session.py index 49e10ee..983573b 100644 --- a/basethon/base_session.py +++ b/basethon/base_session.py @@ -14,7 +14,7 @@ class BaseSession: self.banned_dir.mkdir(parents=True, exist_ok=True) self.json_errors: set[Path] = set() - def iter_sessions(self) -> Generator: + def __iter__(self) -> Generator: """ Поиск сессий в base_dir Возвращает генератор с кортежами (item, json_path, json_data) diff --git a/basethon/base_thon.py b/basethon/base_thon.py index 6a4f109..42bde50 100644 --- a/basethon/base_thon.py +++ b/basethon/base_thon.py @@ -3,7 +3,6 @@ import contextlib import logging import re from datetime import datetime, timedelta, timezone -from pathlib import Path from random import randint from typing import Self @@ -14,6 +13,8 @@ from telethon.tl.functions.help import GetCountriesListRequest, GetNearestDcRequ from telethon.tl.functions.langpack import GetLangPackRequest from telethon.types import JsonNumber, JsonObject, JsonObjectValue, JsonString +from basethon.models import BaseThonOptions, BaseThonSearchCodeOptions + from .constants import API_PACKS from .exceptions import ThonBannedError @@ -128,17 +129,12 @@ class BaseData: class BaseThon(BaseData): - def __init__( - self, - item: Path | None, - json_data: dict, - retries: int = 10, - timeout: int = 10, - raise_error: bool = True, - ): - self.__item, self.__retries, self.__timeout = item, retries, timeout + def __init__(self, options: BaseThonOptions): + self.__item = options.item + self.__retries = options.retries + self.__timeout = options.timeout self._logger = logging.getLogger("basethon") - super().__init__(json_data, raise_error) + super().__init__(options.json_data, options.raise_error) self.__client = self.__get_client() @property @@ -211,30 +207,26 @@ class BaseThon(BaseData): self._logger.exception(e) return f"ERROR_AUTH:{e}" - async def search_code( - self, - limit: int = 1, - date_delta: int = 60, - wait_time: int = 300, - chat_id: int = 777000, - regexp: str = r"\b\d{5,6}\b", - sleep_time: tuple[int, int] = (20, 30), - ) -> str: - future = datetime.now() + timedelta(seconds=wait_time) + async def search_code(self, options: BaseThonSearchCodeOptions) -> str: + future = datetime.now() + timedelta(seconds=options.wait_time) while future > datetime.now(): - async for message in self.client.iter_messages(chat_id, limit=limit): + async for message in self.client.iter_messages( + entity=options.entity, + limit=options.limit, + ): if not message.date: continue - date = datetime.now(tz=timezone.utc) - timedelta(minutes=date_delta) + now = datetime.now(tz=timezone.utc) + date = now - timedelta(minutes=options.date_delta) if message.date < date: continue - if not (match := re.search(regexp, message.text)): + if not (match := re.search(options.regexp, message.text)): continue _code = match.group() _code = _code.replace(" ", "").replace("-", "").replace("_", "") if _code.isdigit(): return _code - await asyncio.sleep(randint(*sleep_time)) + await asyncio.sleep(randint(*options.sleep_time)) return "" async def disconnect(self): diff --git a/basethon/json_async_converter.py b/basethon/json_async_converter.py index 1286046..88b1507 100644 --- a/basethon/json_async_converter.py +++ b/basethon/json_async_converter.py @@ -63,7 +63,7 @@ class JsonAsyncConverter(AsyncBaseSession): await json_write_async(json_file, json_data) return item, json_file, json_data - async def iter(self) -> AsyncGenerator[tuple[Path, Path, dict], None]: + async def __aiter__(self) -> AsyncGenerator[tuple[Path, Path, dict], None]: """ Поиск сессий в base_dir + конвертация сессии в json (string_session) Возвращает генератор с кортежами (item, json_file, json_data) @@ -71,7 +71,7 @@ class JsonAsyncConverter(AsyncBaseSession): string_session: str proxy: dict """ - async for item, json_file, json_data in self.iter_sessions(): + async for item, json_file, json_data in self: _item, _json_file, _json_data = await self._main(item, json_file, json_data) yield _item, _json_file, _json_data @@ -82,7 +82,7 @@ class JsonAsyncConverter(AsyncBaseSession): """ count = 0 self.__json_write = True - async for item, json_file, json_data in self.iter_sessions(): + async for item, json_file, json_data in self: await self._main(item, json_file, json_data) count += 1 return count diff --git a/basethon/json_converter.py b/basethon/json_converter.py index e3515f3..f71649d 100644 --- a/basethon/json_converter.py +++ b/basethon/json_converter.py @@ -34,7 +34,10 @@ class JsonConverter(BaseSession): self.__proxy = ProxyParser(proxy).asdict_thon def _main( - self, item: Path, json_file: Path, json_data: dict + self, + item: Path, + json_file: Path, + json_data: dict, ) -> tuple[Path, Path, dict]: """ Конвертация сессии в json (string_session) @@ -56,20 +59,11 @@ class JsonConverter(BaseSession): loop.close() json_data["proxy"] = self.__proxy json_data["string_session"] = string_session - # if phone := json_data.get("phone"): - # for char in ["+", " ", "-", "(", ")"]: - # phone = phone.replace(char, "") - # if phone.isdigit(): - # json_file.rename(self.base_dir / f"{phone}.json") - # item.rename(self.base_dir / f"{phone}.session") - # json_data["session_file"] = phone - # if not self.__json_write: - # json_write_sync(json_file, json_data) if self.__json_write: json_write_sync(json_file, json_data) return item, json_file, json_data - def iter(self) -> Generator: + def __iter__(self) -> Generator: """ Поиск сессий в base_dir + конвертация сессии в json (string_session) Возвращает генератор с кортежами (item, json_file, json_data) @@ -77,7 +71,7 @@ class JsonConverter(BaseSession): string_session: str proxy: dict """ - for item, json_file, json_data in self.iter_sessions(): + for item, json_file, json_data in self: _item, _json_file, _json_data = self._main(item, json_file, json_data) yield _item, _json_file, _json_data @@ -88,7 +82,7 @@ class JsonConverter(BaseSession): """ count = 0 self.__json_write = True - for item, json_file, json_data in self.iter_sessions(): + for item, json_file, json_data in self: self._main(item, json_file, json_data) count += 1 return count diff --git a/basethon/models/__init__.py b/basethon/models/__init__.py new file mode 100644 index 0000000..487f8bb --- /dev/null +++ b/basethon/models/__init__.py @@ -0,0 +1,21 @@ +from dataclasses import dataclass +from pathlib import Path + + +@dataclass +class BaseThonOptions: + item: Path | None + json_data: dict + retries: int = 10 + timeout: int = 10 + raise_error: bool = True + + +@dataclass +class BaseThonSearchCodeOptions: + limit: int = 1 + date_delta: int = 60 + wait_time: int = 300 + entity: int | str = 777000 + regexp: str = r"\b\d{5,6}\b" + sleep_time: tuple[int, int] = (20, 30)