pyrogram-client 0.0.6__tar.gz → 0.0.8__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.
Files changed (20) hide show
  1. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/.pre-commit-config.yaml +1 -1
  2. {pyrogram_client-0.0.6/pyrogram_client.egg-info → pyrogram_client-0.0.8}/PKG-INFO +1 -1
  3. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyro_client/client/base.py +3 -2
  4. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyro_client/client/bot.py +7 -6
  5. pyrogram_client-0.0.8/pyro_client/client/filler.py +157 -0
  6. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyro_client/client/user.py +7 -8
  7. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyro_client/loader.py +9 -1
  8. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyro_client/storage.py +11 -1
  9. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8/pyrogram_client.egg-info}/PKG-INFO +1 -1
  10. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyrogram_client.egg-info/SOURCES.txt +1 -0
  11. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/.env.sample +0 -0
  12. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/.gitignore +0 -0
  13. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/makefile +0 -0
  14. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyproject.toml +0 -0
  15. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyro_client/client/dc.json +0 -0
  16. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyro_client/client/file.py +0 -0
  17. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyrogram_client.egg-info/dependency_links.txt +0 -0
  18. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyrogram_client.egg-info/requires.txt +0 -0
  19. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/pyrogram_client.egg-info/top_level.txt +0 -0
  20. {pyrogram_client-0.0.6 → pyrogram_client-0.0.8}/setup.cfg +0 -0
@@ -23,7 +23,7 @@ repos:
23
23
 
24
24
  - repo: https://github.com/astral-sh/ruff-pre-commit
25
25
  ### Ruff version.
26
- rev: v0.11.5
26
+ rev: v0.12.4
27
27
  hooks:
28
28
  ### Run the linter.
29
29
  - id: ruff
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyrogram-client
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/pyro-client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/pyro-client
@@ -41,17 +41,18 @@ class BaseClient(Client):
41
41
  session = await Session.create(id=self.uid, api=app, user=username, is_bot=bt)
42
42
  self.api_id = app.id
43
43
  self.api_hash = app.hsh
44
- await session.fetch_related("api")
44
+ # await session.fetch_related("api")
45
45
  self.storage.session = session
46
46
 
47
47
  async def start(self, use_qr: bool = False, except_ids: list[int] = None):
48
48
  if not self.is_connected:
49
49
  await self.preload()
50
50
  try:
51
- await super().start(use_qr=use_qr, except_ids=except_ids or [])
51
+ return await super().start(use_qr=use_qr, except_ids=except_ids or [])
52
52
  except (AuthKeyUnregistered, Unauthorized) as e:
53
53
  await self.storage.session.delete()
54
54
  raise e
55
+ return self
55
56
 
56
57
  async def send(
57
58
  self,
@@ -1,5 +1,6 @@
1
+ import logging
2
+
1
3
  from pyro_client.client.base import BaseClient, AuthTopic
2
- from pyro_client.loader import TOKEN
3
4
 
4
5
 
5
6
  class BotClient(BaseClient):
@@ -21,17 +22,17 @@ class BotClient(BaseClient):
21
22
 
22
23
 
23
24
  async def main():
24
- from x_auth import models
25
25
  from x_model import init_db
26
+ from pyro_client.loader import TORM
26
27
 
27
- from pyro_client.loader import PG_DSN
28
+ _ = await init_db(TORM, True)
28
29
 
29
- _ = await init_db(PG_DSN, models, True)
30
+ logging.basicConfig(level=logging.INFO)
30
31
 
31
32
  bc: BotClient = BotClient(6806432376)
32
- bc1: BotClient = BotClient(TOKEN)
33
+ # bc1: BotClient = BotClient(TOKEN)
33
34
  await bc.start()
34
- await bc1.start()
35
+ # await bc1.start()
35
36
  await bc.stop()
36
37
 
37
38
 
@@ -0,0 +1,157 @@
1
+ import re
2
+ from enum import IntEnum
3
+ from inspect import isclass
4
+ from typing import Coroutine
5
+
6
+ from pyrogram.filters import chat, private
7
+ from pyrogram.handlers import CallbackQueryHandler, MessageHandler
8
+ from pyrogram.types import (
9
+ Message,
10
+ User,
11
+ ReplyKeyboardMarkup,
12
+ CallbackQuery,
13
+ KeyboardButton,
14
+ InlineKeyboardButton,
15
+ InlineKeyboardMarkup,
16
+ )
17
+ from xync_schema import models
18
+ from xync_schema.enums import SynonymType, Party, Slip, AbuserType, NameType
19
+
20
+ from pyro_client.client.file import FileClient
21
+
22
+
23
+ async def cbank(txt: str) -> list[tuple[int, str]]:
24
+ return await models.Pm.filter(norm__startswith=txt[0], bank=True).values_list("id", "norm")
25
+
26
+
27
+ async def cppo(txt: str) -> list[tuple[int, str]]:
28
+ opts = re.findall(r"\d+", txt) or [1, 2, 3, 5, 10]
29
+ return [(o, str(o)) for o in opts]
30
+
31
+
32
+ async def btns(typ: SynonymType.__class__, txt: str = None) -> InlineKeyboardMarkup | None:
33
+ if lst := synopts[typ]:
34
+ if isinstance(lst, list):
35
+ kb = [[InlineKeyboardButton(n, f"st:{typ.name}:{i}")] for i, n in enumerate(lst)]
36
+ elif isclass(lst) and issubclass(lst, IntEnum):
37
+ kb = [[InlineKeyboardButton(i.name, f"st:{typ.name}:{i.value}")] for i in lst]
38
+ else:
39
+ kb = [[InlineKeyboardButton(n, f"st:{typ.name}:{i}")] for i, n in await lst(txt)]
40
+ return InlineKeyboardMarkup(kb)
41
+ else:
42
+ return lst
43
+
44
+
45
+ def get_val(typ: SynonymType.__class__, val: str) -> tuple[SynonymType | int | bool, str]:
46
+ if isinstance(val, str) and val.isnumeric():
47
+ val = int(val)
48
+ if isclass(lst := synopts[typ]) and issubclass(lst, IntEnum):
49
+ return (v := lst(val)), v.name
50
+ elif isinstance(lst, list):
51
+ return val, lst[val]
52
+ return val, val
53
+
54
+
55
+ synopts: dict[SynonymType, list[str] | IntEnum | None | Coroutine] = {
56
+ SynonymType.name: ["not_slavic", "slavic"],
57
+ SynonymType.ppo: cppo,
58
+ SynonymType.from_party: Party,
59
+ SynonymType.to_party: Party,
60
+ SynonymType.slip_req: Slip,
61
+ SynonymType.slip_send: Slip,
62
+ SynonymType.abuser: AbuserType,
63
+ SynonymType.scale: ["1", "10", "100", "1000"],
64
+ SynonymType.slavic: NameType,
65
+ SynonymType.mtl_like: None,
66
+ SynonymType.bank: cbank,
67
+ SynonymType.bank_side: ["except", "only"],
68
+ }
69
+
70
+
71
+ class FillerClient(FileClient): ...
72
+
73
+
74
+ async def cond_start_handler(bot: FillerClient, msg: Message, *args, **kwargs):
75
+ me: User = msg.from_user
76
+ cond = await models.Cond.filter(parsed__isnull=True).order_by("-created_at").first().prefetch_related("parsed")
77
+ rm = ReplyKeyboardMarkup(
78
+ [
79
+ [KeyboardButton("ppo"), KeyboardButton("abuser")],
80
+ [KeyboardButton("from_party"), KeyboardButton("to_party")],
81
+ [KeyboardButton("slip_send"), KeyboardButton("slip_req")],
82
+ [KeyboardButton("name"), KeyboardButton("slavic")],
83
+ [KeyboardButton("scale"), KeyboardButton("mtl_like")],
84
+ [KeyboardButton("bank"), KeyboardButton("bank_side")],
85
+ ]
86
+ )
87
+ bot.add_handler(MessageHandler(got_synonym, chat(me.id) & private))
88
+ bot.storage.session.state |= {me.id: {"synonym": {"id": cond.id}}}
89
+
90
+ return await msg.reply_text(await wrap_cond(cond.raw_txt), reply_markup=rm)
91
+
92
+
93
+ async def wrap_cond(txt: str):
94
+ rs = {syn.txt: f'`{syn.txt}`||{syn.typ.name}="{syn.val}"||' for syn in await models.Synonym.all() if syn.txt in txt}
95
+ [txt := txt.replace(o, n) for o, n in rs.items()]
96
+ return txt
97
+
98
+
99
+ async def got_synonym(bot: FillerClient, msg: Message):
100
+ if not (msg.text in {st.name for st in SynonymType} and (typ := SynonymType[msg.text])):
101
+ return await msg.reply_text(
102
+ f'Нет раздела "{msg.text}", не пиши текст сам, выдели кусок из моего сообщения,'
103
+ f"ответь на него, выбери кнопку раздела"
104
+ )
105
+ if not msg.quote:
106
+ return await msg.reply_text(f"Вы забыли выделить кусок текста для {msg.text}")
107
+ me: User = msg.from_user
108
+ ((state, cidd),) = bot.storage.session.state.get(me.id, {None: {}}).items()
109
+ if state == "synonym":
110
+ if typ := SynonymType[msg.text]:
111
+ bot.storage.session.state[me.id][state] |= {typ: msg.quote.text}
112
+ # bot.rm_handler(me.id)
113
+ await models.Synonym.update_or_create({"typ": typ}, txt=msg.quote.text)
114
+ bot.add_handler(CallbackQueryHandler(got_synonym_val, chat(me.id) & private))
115
+ if rm := await btns(typ, msg.quote.text):
116
+ return await msg.reply_text("Уточните", reply_to_message_id=msg.id, reply_markup=rm)
117
+ return await syn_result(bot, msg, f"st:{typ.name}:1")
118
+ elif state:
119
+ ...
120
+ return await msg.reply_text("Не туда попал")
121
+
122
+
123
+ async def got_synonym_val(bot: FillerClient, cbq: CallbackQuery):
124
+ return await syn_result(bot, cbq.message, cbq.data)
125
+
126
+
127
+ async def syn_result(bot: FillerClient, msg: Message, data: str):
128
+ t, st, sv = data.split(":")
129
+ if t == "st":
130
+ typ = SynonymType[st]
131
+ cid = bot.storage.session.state[msg.chat.id]["synonym"]["id"]
132
+ txt = bot.storage.session.state[msg.chat.id]["synonym"][typ]
133
+ val, hval = get_val(typ, sv)
134
+ syn, _ = await models.Synonym.update_or_create({"val": val}, typ=typ, txt=txt)
135
+ await models.CondParsed.update_or_create({typ.name: val}, cond_id=cid)
136
+ await msg.reply_text(
137
+ f'Текст "{txt}" определен как синоним для `{typ.name}` со значением {hval}',
138
+ reply_markup=InlineKeyboardMarkup(
139
+ [
140
+ [
141
+ InlineKeyboardButton("Готово! Давай новый", f"cond:complete:{cid}"),
142
+ # , InlineKeyboardButton('Хватит! Я устал', f'cond:complete:{cid}')
143
+ ]
144
+ ]
145
+ ),
146
+ )
147
+ await wrap_cond(await models.Cond.get(id=cid).values_list("raw_txt", flat=True))
148
+ # await bot.edit_message_text(bot.me.id, msg.reply_to_message.reply_to_message_id, wrapped_txt)
149
+ await msg.reply_to_message.delete()
150
+ await msg.delete()
151
+ await msg.delete()
152
+
153
+ elif t == "cond":
154
+ await models.CondParsed.update_or_create({"parsed": True}, cond_id=int(sv))
155
+ await cond_start_handler(bot, msg)
156
+ else:
157
+ await msg.reply_text("Где я?")
@@ -50,7 +50,7 @@ class UserClient(BaseClient):
50
50
  # self.proxy: Proxy = self.storage.session.proxy and self.storage.session.proxy.dict()
51
51
 
52
52
  async def start(self, use_qr: bool = False, except_ids: list[int] = None):
53
- if not self.bot.is_connected:
53
+ if self.bot and not self.bot.is_connected:
54
54
  await self.bot.start()
55
55
  await super().start(use_qr, except_ids)
56
56
  # await self.send("/start", self.bot.uid)
@@ -84,7 +84,7 @@ class UserClient(BaseClient):
84
84
  return v
85
85
  return 2
86
86
 
87
- async def authorize(self, sent_code: SentCode = None) -> User:
87
+ async def authorize(self, sent_code: SentCode = None) -> User | None:
88
88
  sent_code_desc = {
89
89
  enums.SentCodeType.APP: "Telegram app",
90
90
  enums.SentCodeType.SMS: "SMS",
@@ -134,8 +134,8 @@ class UserClient(BaseClient):
134
134
  except BadRequest as e:
135
135
  await self.send(e.MESSAGE)
136
136
  self.password = None
137
- else:
138
- raise Exception("User does not sent code")
137
+ else:
138
+ raise Exception("User does not sent code")
139
139
  if isinstance(signed_in, User):
140
140
  await self.send("✅")
141
141
  await self.storage.save()
@@ -143,6 +143,7 @@ class UserClient(BaseClient):
143
143
 
144
144
  if not signed_in:
145
145
  await self.receive("No registered such phone number")
146
+ return None
146
147
 
147
148
  async def session_update(self, dc: int):
148
149
  await self.session.stop()
@@ -164,12 +165,10 @@ class UserClient(BaseClient):
164
165
 
165
166
 
166
167
  async def main():
167
- from x_auth import models
168
168
  from x_model import init_db
169
+ from pyro_client.loader import TORM
169
170
 
170
- from pyro_client.loader import PG_DSN
171
-
172
- _ = await init_db(PG_DSN, models, True)
171
+ _ = await init_db(TORM, True)
173
172
 
174
173
  logging.basicConfig(level=logging.INFO)
175
174
 
@@ -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
- PG_DSN = f"postgres://{env('POSTGRES_USER')}:{env('POSTGRES_PASSWORD')}@{env('POSTGRES_HOST', 'xyncdbs')}:" \
10
+ PG_DSN = f"postgres://{env('POSTGRES_USER')}:{env('POSTGRES_PASSWORD')}@{env('POSTGRES_HOST', 'dbs')}:" \
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")
@@ -4,7 +4,7 @@ from typing import Any
4
4
  from pyrogram import raw, utils
5
5
  from pyrogram.storage import Storage
6
6
  from x_auth.enums import PeerType
7
- from x_auth.models import Username, Version, Session, Peer, UpdateState
7
+ from x_auth.models import Username, Version, Session, Peer, UpdateState, Dc
8
8
 
9
9
 
10
10
  def get_input_peer(peer_id: int, access_hash: int, peer_type: PeerType):
@@ -136,3 +136,13 @@ class PgStorage(Storage):
136
136
  return ver.number
137
137
  else:
138
138
  await Version.update_or_create(id=value)
139
+
140
+ async def server_address(self, value: str = ...) -> str:
141
+ if value is ...:
142
+ dc = await Dc[await self.dc_id()]
143
+ return dc.ip
144
+ dc = await Dc.get(ip=value)
145
+ await self.dc_id(dc.id)
146
+
147
+ async def port(self, value: int = 443) -> int:
148
+ return value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyrogram-client
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/pyro-client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/pyro-client
@@ -9,6 +9,7 @@ pyro_client/client/base.py
9
9
  pyro_client/client/bot.py
10
10
  pyro_client/client/dc.json
11
11
  pyro_client/client/file.py
12
+ pyro_client/client/filler.py
12
13
  pyro_client/client/user.py
13
14
  pyrogram_client.egg-info/PKG-INFO
14
15
  pyrogram_client.egg-info/SOURCES.txt