This commit is contained in:
2025-05-18 13:10:49 +03:00
parent 99c1457057
commit c976e3860c
6 changed files with 131 additions and 4 deletions

View File

@ -1,5 +1,14 @@
from .async_base_session import AsyncBaseSession
from .base_session import BaseSession from .base_session import BaseSession
from .base_thon import BaseData, BaseThon from .base_thon import BaseData, BaseThon
from .json_async_converter import JsonAsyncConverter
from .json_converter import JsonConverter from .json_converter import JsonConverter
__all__ = ["BaseThon", "BaseSession", "JsonConverter", "BaseData"] __all__ = [
"BaseThon",
"BaseSession",
"JsonConverter",
"BaseData",
"JsonAsyncConverter",
"AsyncBaseSession",
]

View File

@ -0,0 +1,30 @@
from pathlib import Path
from typing import AsyncGenerator
from jsoner.async_ import json_read
class AsyncBaseSession:
def __init__(self, base_dir: Path, errors_dir: Path, banned_dir: Path):
self.base_dir = base_dir
self.errors_dir = errors_dir
self.banned_dir = banned_dir
self.json_errors: set[Path] = set()
async def iter_sessions(self) -> AsyncGenerator[tuple[Path, Path, dict], None]:
"""
Поиск сессий в base_dir
Возвращает генератор с кортежами (item, json_path, json_data)
Если json_file не найден, то добавляет его (не существующий) в self.json_errors
Если json_data не найден, то добавляет его (не существующий) в self.json_errors
"""
for item in self.base_dir.glob("*.session"):
json_file = item.with_suffix(".json")
if not json_file.is_file():
self.json_errors.add(json_file)
continue
if not (json_data := await json_read(json_file)):
self.json_errors.add(json_file)
continue
yield item, json_file, json_data

View File

@ -1,7 +1,7 @@
from pathlib import Path from pathlib import Path
from typing import Generator from typing import Generator
from jsoner import json_read_sync from jsoner.sync import json_read
class BaseSession: class BaseSession:
@ -26,7 +26,7 @@ class BaseSession:
if not json_file.is_file(): if not json_file.is_file():
self.json_errors.add(json_file) self.json_errors.add(json_file)
continue continue
if not (json_data := json_read_sync(json_file)): if not (json_data := json_read(json_file)):
self.json_errors.add(json_file) self.json_errors.add(json_file)
continue continue
yield item, json_file, json_data yield item, json_file, json_data

View File

@ -14,7 +14,7 @@ from telethon.tl.functions.help import GetCountriesListRequest, GetNearestDcRequ
from telethon.tl.functions.langpack import GetLangPackRequest from telethon.tl.functions.langpack import GetLangPackRequest
from telethon.types import JsonNumber, JsonObject, JsonObjectValue, JsonString from telethon.types import JsonNumber, JsonObject, JsonObjectValue, JsonString
from .consts import API_PACKS from .constants import API_PACKS
from .exceptions import ThonBannedError from .exceptions import ThonBannedError

View File

@ -0,0 +1,88 @@
import asyncio
import contextlib
from pathlib import Path
from typing import AsyncGenerator
from jsoner import json_write_async
from telethon import TelegramClient
from telethon.sessions import StringSession
from basethon.async_base_session import AsyncBaseSession
from basethon.proxy_parser import ProxyParser
class JsonAsyncConverter(AsyncBaseSession):
def __init__(
self,
base_dir: Path,
errors_dir: Path,
banned_dir: Path,
proxy: str,
json_write: bool = True,
):
"""
Конвертер сессий в json
base_dir: директория с сессиями
errors_dir: директория куда перемещать сессии с ошибками
banned_dir: директория куда перемещать забаненные сессии
proxy: прокси для подключения формат: http:ip:port:user:pswd
json_write: записывать в json файл информацию о string_session + proxy?
"""
super().__init__(base_dir, errors_dir, banned_dir)
self.__api_id, self.__api_hash = 2040, "b18441a1ff607e10a989891a5462e627"
self.__json_write = json_write
self.__proxy = ProxyParser(proxy).asdict_thon
async def _main(
self,
item: Path,
json_file: Path,
json_data: dict,
) -> tuple[Path, Path, dict]:
"""
Конвертация сессии в json (string_session)
Возвращает кортеж (item, json_file, json_data)
"""
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
client = TelegramClient(str(item), self.__api_id, self.__api_hash)
ss = StringSession()
ss._server_address = client.session.server_address # type: ignore
ss._takeout_id = client.session.takeout_id # type: ignore
ss._auth_key = client.session.auth_key # type: ignore
ss._dc_id = client.session.dc_id # type: ignore
ss._port = client.session.port # type: ignore
string_session = ss.save()
with contextlib.suppress(Exception):
await client.disconnect() # type: ignore
del client, ss
loop.close()
json_data["proxy"] = self.__proxy
json_data["string_session"] = string_session
if self.__json_write:
await json_write_async(json_file, json_data)
return item, json_file, json_data
async def iter(self) -> AsyncGenerator[tuple[Path, Path, dict], None]:
"""
Поиск сессий в base_dir + конвертация сессии в json (string_session)
Возвращает генератор с кортежами (item, json_file, json_data)
json_data содержит:
string_session: str
proxy: dict
"""
async for item, json_file, json_data in self.iter_sessions():
_item, _json_file, _json_data = await self._main(item, json_file, json_data)
yield _item, _json_file, _json_data
async def main(self) -> int:
"""
Основная функция для записи сессий в json файлы
Возвращает количество записанных сессий
"""
count = 0
self.__json_write = True
async for item, json_file, json_data in self.iter_sessions():
await self._main(item, json_file, json_data)
count += 1
return count