pyrogram-client 0.0.5__tar.gz → 0.0.7.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyrogram_client-0.0.5/pyrogram_client.egg-info → pyrogram_client-0.0.7.dev2}/PKG-INFO +1 -1
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyro_client/client/base.py +38 -12
- pyrogram_client-0.0.7.dev2/pyro_client/client/bot.py +39 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyro_client/client/user.py +33 -38
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyro_client/loader.py +8 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyro_client/storage.py +50 -42
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2/pyrogram_client.egg-info}/PKG-INFO +1 -1
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyrogram_client.egg-info/SOURCES.txt +0 -1
- pyrogram_client-0.0.5/pyro_client/client/bot.py +0 -11
- pyrogram_client-0.0.5/pyro_client/client/single.py +0 -40
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/.env.sample +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/.gitignore +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/.pre-commit-config.yaml +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/makefile +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyproject.toml +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyro_client/client/dc.json +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyro_client/client/file.py +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyrogram_client.egg-info/dependency_links.txt +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyrogram_client.egg-info/requires.txt +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyrogram_client.egg-info/top_level.txt +0 -0
- {pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/setup.cfg +0 -0
|
@@ -4,30 +4,55 @@ from io import BytesIO
|
|
|
4
4
|
from typing import Literal
|
|
5
5
|
|
|
6
6
|
from pyrogram import Client
|
|
7
|
+
from pyrogram.errors import AuthKeyUnregistered, Unauthorized
|
|
7
8
|
from pyrogram.filters import chat, contact, AndFilter
|
|
8
9
|
from pyrogram.handlers import MessageHandler
|
|
9
10
|
from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton
|
|
11
|
+
from x_auth.models import Session, App, Username
|
|
10
12
|
|
|
11
|
-
from pyro_client.client.single import SingleMeta
|
|
12
13
|
from pyro_client.storage import PgStorage
|
|
13
14
|
|
|
14
15
|
AuthTopic = Literal["phone", "code", "pass"]
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
future = asyncio.run_coroutine_threadsafe(async_func(*args), loop)
|
|
21
|
-
return future.result(5) # Блокируемся, пока корутина не выполнится
|
|
18
|
+
class BaseClient(Client):
|
|
19
|
+
storage: PgStorage
|
|
20
|
+
uid: int = None
|
|
22
21
|
|
|
22
|
+
_insts: dict[int, "BaseClient"] = {}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
def __new__(cls, uid: int, *args, **kwargs):
|
|
25
|
+
"""Single client for each uid"""
|
|
26
|
+
cls.uid = uid
|
|
27
|
+
if uid not in cls._insts:
|
|
28
|
+
cls._insts[uid] = Client.__new__(cls)
|
|
29
|
+
return cls._insts[uid]
|
|
26
30
|
|
|
27
|
-
def __init__(self,
|
|
28
|
-
|
|
29
|
-
name
|
|
30
|
-
|
|
31
|
+
def __init__(self, *args, **kwargs):
|
|
32
|
+
if not hasattr(self, "name"):
|
|
33
|
+
name = str(self.uid)
|
|
34
|
+
super().__init__(name, storage_engine=PgStorage(name), **kwargs) # , workers=2
|
|
35
|
+
|
|
36
|
+
async def preload(self):
|
|
37
|
+
if not (session := await Session.get_or_none(id=self.uid).prefetch_related("api")):
|
|
38
|
+
app = await App[20373304]
|
|
39
|
+
username, _ = await Username.get_or_create(id=self.uid)
|
|
40
|
+
bt = self.bot_token and self.bot_token.split(":")[1]
|
|
41
|
+
session = await Session.create(id=self.uid, api=app, user=username, is_bot=bt)
|
|
42
|
+
self.api_id = app.id
|
|
43
|
+
self.api_hash = app.hsh
|
|
44
|
+
await session.fetch_related("api")
|
|
45
|
+
self.storage.session = session
|
|
46
|
+
|
|
47
|
+
async def start(self, use_qr: bool = False, except_ids: list[int] = None):
|
|
48
|
+
if not self.is_connected:
|
|
49
|
+
await self.preload()
|
|
50
|
+
try:
|
|
51
|
+
return await super().start(use_qr=use_qr, except_ids=except_ids or [])
|
|
52
|
+
except (AuthKeyUnregistered, Unauthorized) as e:
|
|
53
|
+
await self.storage.session.delete()
|
|
54
|
+
raise e
|
|
55
|
+
return self
|
|
31
56
|
|
|
32
57
|
async def send(
|
|
33
58
|
self,
|
|
@@ -64,6 +89,7 @@ class BaseClient(Client, metaclass=SingleMeta):
|
|
|
64
89
|
self.dispatcher.groups[g] = []
|
|
65
90
|
self.dispatcher.groups = OrderedDict(sorted(self.dispatcher.groups.items()))
|
|
66
91
|
self.dispatcher.groups[g].append(handler)
|
|
92
|
+
self.storage.session.state |= {uid: {"waiting_for": topic}}
|
|
67
93
|
#
|
|
68
94
|
while past < timeout:
|
|
69
95
|
if txt := self.storage.session.state.get(uid, {}).pop(topic, None):
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from pyro_client.client.base import BaseClient, AuthTopic
|
|
2
|
+
from pyro_client.loader import TOKEN
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class BotClient(BaseClient):
|
|
6
|
+
def __new__(cls, bid: int | str) -> "BotClient":
|
|
7
|
+
"""
|
|
8
|
+
:param bid: int | str - Если для такого bot_id в бд есть Session с его токеном в is_bot - можно просто id: int
|
|
9
|
+
если нет - нужно передавать весь токен, что б Сессия в бд создалась.
|
|
10
|
+
"""
|
|
11
|
+
if isinstance(bid, str):
|
|
12
|
+
bid = int(bid.split(":")[0])
|
|
13
|
+
return super().__new__(cls, bid)
|
|
14
|
+
|
|
15
|
+
def __init__(self, bid: int | str):
|
|
16
|
+
bt = isinstance(bid, str) and ":" in bid and bid
|
|
17
|
+
super().__init__(bid, bot_token=bt or None)
|
|
18
|
+
|
|
19
|
+
async def wait_auth_from(self, uid: int, topic: AuthTopic, past: int = 0, timeout: int = 60) -> str:
|
|
20
|
+
return await super().wait_from(uid, topic, past, timeout)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def main():
|
|
24
|
+
from x_model import init_db
|
|
25
|
+
from pyro_client.loader import TORM
|
|
26
|
+
|
|
27
|
+
_ = await init_db(TORM, True)
|
|
28
|
+
|
|
29
|
+
bc: BotClient = BotClient(6806432376)
|
|
30
|
+
bc1: BotClient = BotClient(TOKEN)
|
|
31
|
+
await bc.start()
|
|
32
|
+
await bc1.start()
|
|
33
|
+
await bc.stop()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
from asyncio import run
|
|
38
|
+
|
|
39
|
+
run(main())
|
|
@@ -5,20 +5,25 @@ from os.path import dirname
|
|
|
5
5
|
from pydantic import BaseModel, Field
|
|
6
6
|
from pyrogram import enums
|
|
7
7
|
from pyrogram.enums import ClientPlatform
|
|
8
|
-
from pyrogram.errors import BadRequest, SessionPasswordNeeded
|
|
8
|
+
from pyrogram.errors import BadRequest, SessionPasswordNeeded
|
|
9
9
|
from pyrogram.session import Auth, Session as PyroSession
|
|
10
10
|
from pyrogram.types import Message, User, SentCode, InlineKeyboardButton, KeyboardButton
|
|
11
|
-
from x_auth.models import
|
|
11
|
+
from x_auth.models import Username, Proxy
|
|
12
12
|
|
|
13
13
|
from pyro_client.client.base import BaseClient, AuthTopic
|
|
14
14
|
from pyro_client.client.bot import BotClient
|
|
15
|
-
from pyro_client.loader import WSToken
|
|
15
|
+
from pyro_client.loader import WSToken
|
|
16
16
|
|
|
17
17
|
vers: dict[ClientPlatform, str] = {
|
|
18
18
|
ClientPlatform.IOS: "18.5",
|
|
19
19
|
ClientPlatform.ANDROID: "16",
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
devs: dict[ClientPlatform, str] = {
|
|
23
|
+
ClientPlatform.IOS: "iPhone 17 Air",
|
|
24
|
+
ClientPlatform.ANDROID: "Tesla Phone",
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
|
|
23
28
|
class Prx(BaseModel):
|
|
24
29
|
scheme: str = "socks5"
|
|
@@ -31,31 +36,24 @@ class Prx(BaseModel):
|
|
|
31
36
|
class UserClient(BaseClient):
|
|
32
37
|
bot: BotClient
|
|
33
38
|
|
|
34
|
-
def __init__(self,
|
|
39
|
+
def __init__(self, uid: int, bot: BotClient = None):
|
|
35
40
|
self.bot = bot
|
|
36
|
-
super().__init__(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
)
|
|
41
|
+
super().__init__(uid)
|
|
42
|
+
|
|
43
|
+
async def preload(self):
|
|
44
|
+
await super().preload()
|
|
45
|
+
self.device_model = devs[self.storage.session.api.platform]
|
|
46
|
+
self.app_version = self.storage.session.api.ver
|
|
47
|
+
self.system_version = vers[self.storage.session.api.platform]
|
|
48
|
+
self.client_platform = self.storage.session.api.platform
|
|
49
|
+
# await self.storage.session.fetch_related("proxy")
|
|
50
|
+
# self.proxy: Proxy = self.storage.session.proxy and self.storage.session.proxy.dict()
|
|
46
51
|
|
|
47
52
|
async def start(self, use_qr: bool = False, except_ids: list[int] = None):
|
|
48
53
|
if not self.bot.is_connected:
|
|
49
54
|
await self.bot.start()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
await super().start(use_qr=use_qr, except_ids=except_ids or [])
|
|
53
|
-
await self.send("im ok")
|
|
54
|
-
except AuthKeyUnregistered as e:
|
|
55
|
-
await self.storage.session.delete()
|
|
56
|
-
raise e
|
|
57
|
-
except (AuthKeyUnregistered, Unauthorized) as e:
|
|
58
|
-
raise e
|
|
55
|
+
await super().start(use_qr, except_ids)
|
|
56
|
+
# await self.send("/start", self.bot.uid)
|
|
59
57
|
|
|
60
58
|
async def ask_for(
|
|
61
59
|
self, topic: AuthTopic, question: str, btns: list[InlineKeyboardButton, KeyboardButton] = None
|
|
@@ -86,7 +84,7 @@ class UserClient(BaseClient):
|
|
|
86
84
|
return v
|
|
87
85
|
return 2
|
|
88
86
|
|
|
89
|
-
async def authorize(self, sent_code: SentCode = None) -> User:
|
|
87
|
+
async def authorize(self, sent_code: SentCode = None) -> User | None:
|
|
90
88
|
sent_code_desc = {
|
|
91
89
|
enums.SentCodeType.APP: "Telegram app",
|
|
92
90
|
enums.SentCodeType.SMS: "SMS",
|
|
@@ -136,19 +134,16 @@ class UserClient(BaseClient):
|
|
|
136
134
|
except BadRequest as e:
|
|
137
135
|
await self.send(e.MESSAGE)
|
|
138
136
|
self.password = None
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
else:
|
|
138
|
+
raise Exception("User does not sent code")
|
|
141
139
|
if isinstance(signed_in, User):
|
|
142
|
-
await self.send("✅"
|
|
140
|
+
await self.send("✅")
|
|
143
141
|
await self.storage.save()
|
|
144
142
|
return signed_in
|
|
145
143
|
|
|
146
144
|
if not signed_in:
|
|
147
145
|
await self.receive("No registered such phone number")
|
|
148
|
-
|
|
149
|
-
async def stop(self, block: bool = True):
|
|
150
|
-
await super().stop(block)
|
|
151
|
-
await self.bot.stop(block)
|
|
146
|
+
return None
|
|
152
147
|
|
|
153
148
|
async def session_update(self, dc: int):
|
|
154
149
|
await self.session.stop()
|
|
@@ -170,21 +165,21 @@ class UserClient(BaseClient):
|
|
|
170
165
|
|
|
171
166
|
|
|
172
167
|
async def main():
|
|
173
|
-
from x_auth import models
|
|
174
168
|
from x_model import init_db
|
|
169
|
+
from pyro_client.loader import TORM
|
|
175
170
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
_ = await init_db(PG_DSN, models, True)
|
|
171
|
+
_ = await init_db(TORM, True)
|
|
179
172
|
|
|
180
173
|
logging.basicConfig(level=logging.INFO)
|
|
181
174
|
|
|
182
|
-
await models.Proxy.load_list(WSToken)
|
|
175
|
+
# await models.Proxy.load_list(WSToken)
|
|
183
176
|
# session = await models.Session.filter(is_bot__isnull=True).order_by("-date").prefetch_related("proxy").first()
|
|
184
|
-
bc: BotClient =
|
|
185
|
-
uc: UserClient =
|
|
177
|
+
bc: BotClient = BotClient(6806432376)
|
|
178
|
+
uc: UserClient = UserClient(7314099964, bc)
|
|
186
179
|
# try:
|
|
187
180
|
await uc.start()
|
|
181
|
+
# b = await uc.resolve_peer('xyncnetbot')
|
|
182
|
+
await uc.send("/start", bc.me.username)
|
|
188
183
|
# except Exception as e:
|
|
189
184
|
# print(e.MESSAGE)
|
|
190
185
|
# await uc.send(e.MESSAGE)
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
from dotenv import load_dotenv
|
|
2
2
|
from os import getenv as env
|
|
3
3
|
|
|
4
|
+
from x_auth import models
|
|
5
|
+
|
|
4
6
|
load_dotenv()
|
|
5
7
|
|
|
6
8
|
API_ID = env("API_ID")
|
|
7
9
|
API_HASH = env("API_HASH")
|
|
8
10
|
PG_DSN = f"postgres://{env('POSTGRES_USER')}:{env('POSTGRES_PASSWORD')}@{env('POSTGRES_HOST', 'xyncdbs')}:" \
|
|
9
11
|
f"{env('POSTGRES_PORT', 5432)}/{env('POSTGRES_DB', env('POSTGRES_USER'))}"
|
|
12
|
+
TORM = {
|
|
13
|
+
"connections": {"default": PG_DSN},
|
|
14
|
+
"apps": {"models": {"models": [models]}},
|
|
15
|
+
"use_tz": False,
|
|
16
|
+
"timezone": "UTC",
|
|
17
|
+
}
|
|
10
18
|
TOKEN = env("TOKEN")
|
|
11
19
|
WSToken = env("WST")
|
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
import time
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
3
|
|
|
4
4
|
from pyrogram import raw, utils
|
|
5
5
|
from pyrogram.storage import Storage
|
|
6
|
+
from x_auth.enums import PeerType
|
|
6
7
|
from x_auth.models import Username, Version, Session, Peer, UpdateState
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
def get_input_peer(peer_id: int, access_hash: int, peer_type:
|
|
10
|
-
if peer_type in [
|
|
10
|
+
def get_input_peer(peer_id: int, access_hash: int, peer_type: PeerType):
|
|
11
|
+
if peer_type in [PeerType.user, PeerType.bot]:
|
|
11
12
|
return raw.types.InputPeerUser(user_id=peer_id, access_hash=access_hash)
|
|
12
|
-
|
|
13
|
-
if peer_type == "group":
|
|
13
|
+
if peer_type == PeerType.group:
|
|
14
14
|
return raw.types.InputPeerChat(chat_id=-peer_id)
|
|
15
|
-
|
|
16
|
-
if peer_type in ["channel", "supergroup"]:
|
|
15
|
+
if peer_type in [PeerType.channel, PeerType.supergroup]:
|
|
17
16
|
return raw.types.InputPeerChannel(channel_id=utils.get_channel_id(peer_id), access_hash=access_hash)
|
|
18
|
-
|
|
19
|
-
raise ValueError(f"Invalid peer type: {peer_type}")
|
|
17
|
+
raise ValueError(f"Invalid peer type: {peer_type.name}")
|
|
20
18
|
|
|
21
19
|
|
|
22
20
|
class PgStorage(Storage):
|
|
23
21
|
VERSION = 1
|
|
24
|
-
USERNAME_TTL =
|
|
22
|
+
USERNAME_TTL = 30 * 24 * 3600
|
|
25
23
|
session: Session
|
|
26
|
-
|
|
27
|
-
# me_id: int
|
|
24
|
+
sid: int
|
|
28
25
|
|
|
29
26
|
async def open(self):
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
self.sid = int(self.name)
|
|
28
|
+
if not self.session:
|
|
29
|
+
self.session = await Session[self.sid]
|
|
32
30
|
|
|
33
31
|
async def save(self):
|
|
34
32
|
await self.date(int(time.time()))
|
|
@@ -36,14 +34,14 @@ class PgStorage(Storage):
|
|
|
36
34
|
async def close(self): ...
|
|
37
35
|
|
|
38
36
|
async def delete(self):
|
|
39
|
-
await Session.filter(id=self.
|
|
37
|
+
await Session.filter(id=self.sid).delete()
|
|
40
38
|
|
|
41
39
|
async def update_peers(self, peers: list[tuple[int, int, str, str]]):
|
|
42
40
|
for peer in peers:
|
|
43
41
|
uid, ac_hsh, typ, phone = peer
|
|
44
42
|
un, _ = await Username.update_or_create(phone and {"phone": phone}, id=uid)
|
|
45
43
|
await Peer.update_or_create(
|
|
46
|
-
{"username": un, "type": typ, "phone_number": phone}, session_id=self.
|
|
44
|
+
{"username": un, "type": PeerType[typ], "phone_number": phone}, session_id=self.sid, id=ac_hsh
|
|
47
45
|
)
|
|
48
46
|
|
|
49
47
|
async def update_usernames(self, usernames: list[tuple[int, list[str]]]):
|
|
@@ -51,37 +49,45 @@ class PgStorage(Storage):
|
|
|
51
49
|
for username in user_list:
|
|
52
50
|
await Username.update_or_create({"username": username}, id=telegram_id)
|
|
53
51
|
|
|
54
|
-
async def get_peer_by_id(self,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
async def get_peer_by_id(self, uid: int | str):
|
|
53
|
+
if isinstance(uid, str):
|
|
54
|
+
if uid.isnumeric():
|
|
55
|
+
uid = int(uid)
|
|
56
|
+
else:
|
|
57
|
+
return await self.get_peer_by_username(uid)
|
|
58
|
+
if not (peer := await Peer.get_or_none(session_id=self.sid, username_id=uid)):
|
|
59
|
+
raise KeyError(f"Peer#{uid} not found")
|
|
58
60
|
if peer.last_update_on:
|
|
59
61
|
if abs(time.time() - peer.last_update_on.timestamp()) > self.USERNAME_TTL:
|
|
60
|
-
raise KeyError(f"Username expired: {
|
|
62
|
+
raise KeyError(f"Username expired: {uid}")
|
|
61
63
|
return get_input_peer(peer.username_id, peer.id, peer.type)
|
|
62
64
|
|
|
63
65
|
async def get_peer_by_username(self, username: str):
|
|
64
|
-
|
|
66
|
+
if not (peer := await Peer.get_or_none(session_id=self.sid, username__username=username)):
|
|
67
|
+
if not (user := await Username.get_or_none(username=username)):
|
|
68
|
+
raise KeyError(f"Username: {username} not found")
|
|
69
|
+
return await self.get_peer_by_id(user.id)
|
|
70
|
+
return get_input_peer(peer.username_id, peer.id, peer.type)
|
|
65
71
|
|
|
66
|
-
async def update_state(self, value: tuple[int, int, int, int, int] =
|
|
72
|
+
async def update_state(self, value: tuple[int, int, int, int, int] = ...):
|
|
67
73
|
if value is None:
|
|
68
|
-
return await UpdateState.filter(session_id=self.
|
|
74
|
+
return await UpdateState.filter(session_id=self.sid)
|
|
69
75
|
elif isinstance(value, int):
|
|
70
|
-
await UpdateState.filter(session_id=self.
|
|
76
|
+
await UpdateState.filter(session_id=self.sid, id=value).delete()
|
|
71
77
|
else:
|
|
72
78
|
sid, pts, qts, date, seq = value
|
|
73
79
|
await UpdateState.get_or_create(
|
|
74
|
-
{"pts": pts, "qts": qts, "date": date, "seq": seq}, session_id=self.
|
|
80
|
+
{"pts": pts, "qts": qts, "date": date, "seq": seq}, session_id=self.sid, id=sid
|
|
75
81
|
)
|
|
76
82
|
|
|
77
83
|
async def get_peer_by_phone_number(self, phone_number: str):
|
|
78
84
|
attrs = "id", "access_hash", "type"
|
|
79
|
-
if not (peer := await Peer.get_or_none(session_id=self.
|
|
80
|
-
peer = await Peer.get(session_id=self.
|
|
85
|
+
if not (peer := await Peer.get_or_none(session_id=self.sid, phone_number=phone_number).values_list(*attrs)):
|
|
86
|
+
peer = await Peer.get(session_id=self.sid, username__phone=phone_number).values_list(*attrs)
|
|
81
87
|
return get_input_peer(*peer)
|
|
82
88
|
|
|
83
89
|
async def _get(self, attr: str):
|
|
84
|
-
return await Session.get(id=self.
|
|
90
|
+
return await Session.get(id=self.sid).values_list(attr, flat=True)
|
|
85
91
|
|
|
86
92
|
async def _set(self, attr: str, value):
|
|
87
93
|
# if "__" in attr:
|
|
@@ -90,40 +96,42 @@ class PgStorage(Storage):
|
|
|
90
96
|
# rel.__setattr__(attr, value)
|
|
91
97
|
# await rel.save()
|
|
92
98
|
# else:
|
|
93
|
-
await Session.update_or_create({attr: value}, id=self.
|
|
99
|
+
await Session.update_or_create({attr: value}, id=self.sid)
|
|
94
100
|
|
|
95
|
-
async def _accessor(self, attr: str, value: Any =
|
|
96
|
-
if value is
|
|
101
|
+
async def _accessor(self, attr: str, value: Any = ...):
|
|
102
|
+
if value is ...:
|
|
97
103
|
return await self._get(attr)
|
|
104
|
+
# elif attr == ...:
|
|
105
|
+
# return await self._set(attr, ...)
|
|
98
106
|
else:
|
|
99
107
|
await self._set(attr, value)
|
|
100
108
|
|
|
101
|
-
async def dc_id(self, value: int =
|
|
109
|
+
async def dc_id(self, value: int = ...):
|
|
102
110
|
return await self._accessor("dc_id", value)
|
|
103
111
|
|
|
104
|
-
async def api_id(self, value: int =
|
|
112
|
+
async def api_id(self, value: int = ...):
|
|
105
113
|
return await self._accessor("api_id", value)
|
|
106
114
|
|
|
107
|
-
async def test_mode(self, value: bool =
|
|
115
|
+
async def test_mode(self, value: bool = ...):
|
|
108
116
|
return await self._accessor("test_mode", value)
|
|
109
117
|
|
|
110
|
-
async def auth_key(self, value: bytes =
|
|
118
|
+
async def auth_key(self, value: bytes = ...):
|
|
111
119
|
return await self._accessor("auth_key", value)
|
|
112
120
|
|
|
113
|
-
async def date(self, value: int =
|
|
121
|
+
async def date(self, value: int = ...):
|
|
114
122
|
return await self._accessor("date", value)
|
|
115
123
|
|
|
116
|
-
async def user_id(self, value: int =
|
|
124
|
+
async def user_id(self, value: int = ...):
|
|
117
125
|
return await self._accessor("user_id", value)
|
|
118
126
|
|
|
119
|
-
async def is_bot(self, value: bool =
|
|
120
|
-
if value is not
|
|
127
|
+
async def is_bot(self, value: bool = ...):
|
|
128
|
+
if value is not ...:
|
|
121
129
|
value = self.session.is_bot if value else None # dirty
|
|
122
130
|
return bool(await self._accessor("is_bot", value))
|
|
123
131
|
|
|
124
132
|
@staticmethod
|
|
125
|
-
async def version(value: int =
|
|
126
|
-
if value is
|
|
133
|
+
async def version(value: int = ...):
|
|
134
|
+
if value is ...:
|
|
127
135
|
ver = await Version.first()
|
|
128
136
|
return ver.number
|
|
129
137
|
else:
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from x_auth.models import Session
|
|
2
|
-
|
|
3
|
-
from pyro_client.client.base import BaseClient, AuthTopic
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class BotClient(BaseClient):
|
|
7
|
-
def __init__(self, sess: Session, _=None):
|
|
8
|
-
super().__init__(sess.id, sess.api.id, sess.api.hsh, bot_token=f"{sess.id}:{sess.is_bot}")
|
|
9
|
-
|
|
10
|
-
async def wait_auth_from(self, uid: int, topic: AuthTopic, past: int = 0, timeout: int = 60) -> str:
|
|
11
|
-
return await super().wait_from(uid, topic, past, timeout)
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
from tortoise.functions import Count
|
|
2
|
-
from x_auth.models import Proxy, Session, Username, App
|
|
3
|
-
|
|
4
|
-
from pyro_client.loader import WSToken
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class SingleMeta(type):
|
|
8
|
-
_instances = {}
|
|
9
|
-
|
|
10
|
-
async def __call__(cls, uid: int | str, bot=None):
|
|
11
|
-
if cls not in cls._instances:
|
|
12
|
-
prx = ...
|
|
13
|
-
bt = None
|
|
14
|
-
if isinstance(uid, str):
|
|
15
|
-
if len(ub := uid.split(":")) == 2:
|
|
16
|
-
uid, bt = ub
|
|
17
|
-
prx = None
|
|
18
|
-
if uid.isnumeric():
|
|
19
|
-
uid = int(uid)
|
|
20
|
-
sess = await cls._sess(uid, bt, prx)
|
|
21
|
-
cls._instances[cls] = super().__call__(sess, bot)
|
|
22
|
-
return cls._instances[cls]
|
|
23
|
-
|
|
24
|
-
async def _sess(self, uid: int | str, bt: str = None, px: Proxy | None = ..., dc: int = 2) -> Session:
|
|
25
|
-
username, _ = await Username.get_or_create(**{"id" if isinstance(uid, int) else "username": uid})
|
|
26
|
-
if not (
|
|
27
|
-
session := await Session.get_or_none(user=username, api__dc=dc) or await Session.get_or_none(id=username.id)
|
|
28
|
-
):
|
|
29
|
-
if px is Ellipsis:
|
|
30
|
-
await Proxy.load_list(WSToken)
|
|
31
|
-
# await Proxy.get_replaced(WSToken)
|
|
32
|
-
px = await Proxy.annotate(sc=Count("sessions")).filter(valid=True).order_by("sc", "-updated_at").first()
|
|
33
|
-
if username.phone:
|
|
34
|
-
# noinspection PyUnresolvedReferences
|
|
35
|
-
dc = dc or self.get_dc()
|
|
36
|
-
session = await Session.create(
|
|
37
|
-
id=username.id, api=await App[20373304], user=username, dc_id=dc, proxy=px, is_bot=bt
|
|
38
|
-
)
|
|
39
|
-
await session.fetch_related("proxy", "api")
|
|
40
|
-
return session
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyrogram_client-0.0.5 → pyrogram_client-0.0.7.dev2}/pyrogram_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|