xync-bot 0.3.24.dev9__tar.gz → 0.3.24.dev11__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.
Potentially problematic release.
This version of xync-bot might be problematic. Click here for more details.
- {xync_bot-0.3.24.dev9/xync_bot.egg-info → xync_bot-0.3.24.dev11}/PKG-INFO +1 -1
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/__init__.py +1 -1
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/pay/cd.py +1 -0
- xync_bot-0.3.24.dev11/xync_bot/routers/pay/dep.py +244 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/pay/handler.py +20 -45
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/pay/window.py +74 -33
- xync_bot-0.3.24.dev11/xync_bot/typs.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11/xync_bot.egg-info}/PKG-INFO +1 -1
- xync_bot-0.3.24.dev9/xync_bot/routers/__init__.py +0 -98
- xync_bot-0.3.24.dev9/xync_bot/routers/pay/dep.py +0 -122
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/.env.dist +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/.gitignore +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/.pre-commit-config.yaml +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/makefile +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/pyproject.toml +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/setup.cfg +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/test_main.http +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/loader.py +0 -0
- /xync_bot-0.3.24.dev9/xync_bot/typs.py → /xync_bot-0.3.24.dev11/xync_bot/routers/__init__.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/cond/__init__.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/cond/func.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/main.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/order.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/photo.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/vpn.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/routers/xicon.png +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot/shared.py +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot.egg-info/SOURCES.txt +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot.egg-info/dependency_links.txt +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot.egg-info/requires.txt +0 -0
- {xync_bot-0.3.24.dev9 → xync_bot-0.3.24.dev11}/xync_bot.egg-info/top_level.txt +0 -0
|
@@ -5,8 +5,8 @@ from PGram import Bot
|
|
|
5
5
|
from aiogram.client.default import DefaultBotProperties
|
|
6
6
|
from x_model import init_db
|
|
7
7
|
|
|
8
|
-
from xync_bot.routers import Store
|
|
9
8
|
from xync_bot.routers.cond import cr as cr
|
|
9
|
+
from xync_bot.routers.pay.dep import Store
|
|
10
10
|
|
|
11
11
|
# from xync_bot.routers.main import mr
|
|
12
12
|
from xync_bot.routers.pay.handler import pay as pay
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
from asyncio import gather
|
|
2
|
+
from enum import IntEnum
|
|
3
|
+
|
|
4
|
+
from aiogram.exceptions import TelegramBadRequest
|
|
5
|
+
from aiogram.fsm.state import StatesGroup, State
|
|
6
|
+
from aiogram.types import Message, InlineKeyboardMarkup
|
|
7
|
+
from pyrogram.types import CallbackQuery
|
|
8
|
+
from tortoise.functions import Min
|
|
9
|
+
from x_auth.enums import Role
|
|
10
|
+
from x_model.func import ArrayAgg
|
|
11
|
+
from xync_schema import models
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Report(StatesGroup):
|
|
15
|
+
text = State()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CredState(StatesGroup):
|
|
19
|
+
detail = State()
|
|
20
|
+
name = State()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PaymentState(StatesGroup):
|
|
24
|
+
amount = State()
|
|
25
|
+
timer = State()
|
|
26
|
+
timer_active = State()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ActionType(IntEnum):
|
|
30
|
+
"""Цель (назначение) платежа (target)"""
|
|
31
|
+
|
|
32
|
+
sent = 1 # Отправил
|
|
33
|
+
received = 2 # Получил
|
|
34
|
+
not_received = 3 # Не получил
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class PayStep(IntEnum):
|
|
38
|
+
"""Цель (назначение) платежа (target)"""
|
|
39
|
+
|
|
40
|
+
t_type = 1 # Выбор типа
|
|
41
|
+
t_cur = 2 # Выбор валюты
|
|
42
|
+
t_coin = 3 # Выбор монеты
|
|
43
|
+
t_pm = 4 # Выбор платежки
|
|
44
|
+
t_ex = 5 # Выбор биржи
|
|
45
|
+
t_cred_dtl = 6 # Ввод номера карты
|
|
46
|
+
t_cred_name = 7 # Ввод имени
|
|
47
|
+
# t_addr = 8 # todo: позже добавим: Выбор/ввод крипто кошелька
|
|
48
|
+
t_amount = 9 # Ввод суммы
|
|
49
|
+
""" Источник платежа (source) """
|
|
50
|
+
s_type = 10 # Выбор типа
|
|
51
|
+
s_cur = 11 # Выбор типа
|
|
52
|
+
s_pm = 12 # Выбор типа
|
|
53
|
+
s_coin = 13 # Выбор типа
|
|
54
|
+
s_ex = 14 # Выбор типа
|
|
55
|
+
ppo = 15 # Выбор возможности разбивки платежа
|
|
56
|
+
urgency = 16 # Выбор срочности получения платежа
|
|
57
|
+
pending_send = 17 # Ожидание отправки (если мы платим фиатом)
|
|
58
|
+
pending_confirm = 18 # Ожидание пока на той стороне подтвердят получение нашего фиата (если мы платим фиатом)
|
|
59
|
+
pending_receive = 19 # Ожидание поступления (если мы получаем фиат)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
flags = {
|
|
63
|
+
"RUB": "🇷🇺",
|
|
64
|
+
"THB": "🇹🇭",
|
|
65
|
+
"IDR": "🇮🇩",
|
|
66
|
+
"TRY": "🇹🇷",
|
|
67
|
+
"GEL": "🇬🇪",
|
|
68
|
+
"VND": "🇻🇳",
|
|
69
|
+
"AED": "🇦🇪",
|
|
70
|
+
"AMD": "🇦🇲",
|
|
71
|
+
"AZN": "🇦🇿",
|
|
72
|
+
"CNY": "🇨🇳",
|
|
73
|
+
"EUR": "🇪🇺",
|
|
74
|
+
"HKD": "🇭🇰",
|
|
75
|
+
"INR": "🇮🇳",
|
|
76
|
+
"PHP": "🇵🇭",
|
|
77
|
+
"USD": "🇺🇸",
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class SingleStore(type):
|
|
82
|
+
_store = None
|
|
83
|
+
|
|
84
|
+
async def __call__(cls):
|
|
85
|
+
if not cls._store:
|
|
86
|
+
cls._store = super(SingleStore, cls).__call__()
|
|
87
|
+
cls._store.coins = {k: v for k, v in await models.Coin.all().order_by("ticker").values_list("id", "ticker")}
|
|
88
|
+
curs = {c.id: c for c in await models.Cur.filter(ticker__in=flags.keys()).order_by("ticker")}
|
|
89
|
+
cls._store.curs = curs
|
|
90
|
+
cls._store.exs = {k: v for k, v in await models.Ex.all().values_list("id", "name")}
|
|
91
|
+
cls._store.pmcurs = {
|
|
92
|
+
k: v
|
|
93
|
+
for k, v in await models.Pmex.filter(pm__pmcurs__cur_id__in=cls._store.curs.keys())
|
|
94
|
+
.annotate(sname=Min("name"))
|
|
95
|
+
.group_by("pm__pmcurs__id")
|
|
96
|
+
.values_list("pm__pmcurs__id", "sname")
|
|
97
|
+
}
|
|
98
|
+
cls._store.coinexs = {
|
|
99
|
+
c.id: [ex.ex_id for ex in c.coinexs] for c in await models.Coin.all().prefetch_related("coinexs")
|
|
100
|
+
}
|
|
101
|
+
cls._store.curpms = {
|
|
102
|
+
cur_id: ids
|
|
103
|
+
for cur_id, ids in await models.Pmcur.filter(cur_id__in=curs.keys())
|
|
104
|
+
.annotate(ids=ArrayAgg("id"))
|
|
105
|
+
.group_by("cur_id")
|
|
106
|
+
.values_list("cur_id", "ids")
|
|
107
|
+
}
|
|
108
|
+
cls._store.curpms = {
|
|
109
|
+
cur_id: ids
|
|
110
|
+
for cur_id, ids in await models.Pmcur.filter(cur_id__in=curs.keys())
|
|
111
|
+
.annotate(ids=ArrayAgg("id"))
|
|
112
|
+
.group_by("cur_id")
|
|
113
|
+
.values_list("cur_id", "ids")
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return cls._store
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class Store:
|
|
120
|
+
class Global(metaclass=SingleStore):
|
|
121
|
+
coins: dict[int, str] # id:ticker
|
|
122
|
+
curs: dict[int, models.Cur] # id:Cur
|
|
123
|
+
exs: dict[int, str] # id:name
|
|
124
|
+
coinexs: dict[int, list[int]] # id:[ex_ids]
|
|
125
|
+
pmcurs: dict[int, str] # pmcur_id:name
|
|
126
|
+
curpms: dict[int, list[int]] # id:[pmcur_ids]
|
|
127
|
+
|
|
128
|
+
class Permanent:
|
|
129
|
+
msg_id: int = None
|
|
130
|
+
user: models.User = None
|
|
131
|
+
actors: dict[int, int] = None # key=ex_id
|
|
132
|
+
creds: dict[int, models.Cred] = None # key=cred_id
|
|
133
|
+
cur_creds: dict[int, list[int]] = None # pmcur_id:[cred_ids]
|
|
134
|
+
|
|
135
|
+
class Current:
|
|
136
|
+
is_target: bool = True
|
|
137
|
+
is_fiat: bool = None
|
|
138
|
+
msg_to_del: Message = None
|
|
139
|
+
|
|
140
|
+
class Payment:
|
|
141
|
+
t_cur_id: int = None
|
|
142
|
+
s_cur_id: int = None
|
|
143
|
+
t_coin_id: int = None
|
|
144
|
+
s_coin_id: int = None
|
|
145
|
+
t_pmcur_id: int = None
|
|
146
|
+
s_pmcur_id: int = None
|
|
147
|
+
t_ex_id: int = None
|
|
148
|
+
s_ex_id: int = None
|
|
149
|
+
amount: int | float = None
|
|
150
|
+
ppo: int = 1
|
|
151
|
+
addr_id: int = None
|
|
152
|
+
cred_dtl: str = None
|
|
153
|
+
cred_id: int = None
|
|
154
|
+
urg: int = 5
|
|
155
|
+
pr_id: int = None
|
|
156
|
+
|
|
157
|
+
glob: Global
|
|
158
|
+
perm: Permanent = Permanent()
|
|
159
|
+
pay: Payment = Payment()
|
|
160
|
+
curr: Current = Current()
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
async def fill_creds(person_id: int) -> tuple[dict[int, models.Cred], dict[int, list[int]]]:
|
|
164
|
+
cq = models.Cred.filter(person_id=person_id)
|
|
165
|
+
creds = {c.id: c for c in await cq}
|
|
166
|
+
cur_creds = {
|
|
167
|
+
pci: ids
|
|
168
|
+
for pci, ids in await cq.annotate(ids=ArrayAgg("id")).group_by("pmcur_id").values_list("pmcur_id", "ids")
|
|
169
|
+
}
|
|
170
|
+
return creds, cur_creds
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
async def fill_actors(person_id: int) -> dict[int, int]:
|
|
174
|
+
ex_actors = {
|
|
175
|
+
# todo: check len(ids) == 1
|
|
176
|
+
exi: ids[0]
|
|
177
|
+
for exi, ids in await models.Actor.filter(person_id=person_id)
|
|
178
|
+
.annotate(ids=ArrayAgg("id"))
|
|
179
|
+
.group_by("ex_id")
|
|
180
|
+
.values_list("ex_id", "ids")
|
|
181
|
+
}
|
|
182
|
+
return ex_actors
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
async def edit(msg: Message, txt: str, rm: InlineKeyboardMarkup):
|
|
186
|
+
await gather(msg.edit_text(txt), msg.edit_reply_markup(reply_markup=rm))
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async def ans(cbq: CallbackQuery, txt: str = None):
|
|
190
|
+
await cbq.answer(txt, cache_time=0)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
async def dlt(msg: Message):
|
|
194
|
+
await msg.delete()
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
async def edt(msg: Message, txt: str, rm: InlineKeyboardMarkup):
|
|
198
|
+
if msg.message_id == msg.bot.store.perm.msg_id:
|
|
199
|
+
await msg.edit_text(txt, reply_markup=rm)
|
|
200
|
+
else: # окно вызвано в ответ на текст, а не кнопку
|
|
201
|
+
try:
|
|
202
|
+
await msg.bot.edit_message_text(
|
|
203
|
+
txt, chat_id=msg.chat.id, message_id=msg.bot.store.perm.msg_id, reply_markup=rm
|
|
204
|
+
)
|
|
205
|
+
except TelegramBadRequest as e:
|
|
206
|
+
print(msg.bot.store.perm.msg_id, e)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
async def have_coin_amount(store: Store) -> bool:
|
|
210
|
+
actor_id = store.perm.actors[store.pay.t_ex_id]
|
|
211
|
+
asset = await models.Asset.get_or_none(addr__coin_id=store.pay.t_coin_id, addr__actor_id=actor_id)
|
|
212
|
+
return store.pay.amount <= asset.free
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
async def need_ppo(store: Store):
|
|
216
|
+
cur_id = getattr(store.pay, ("t" if store.curr.is_target else "s") + "_cur_id")
|
|
217
|
+
usd_amount = store.pay.amount * store.glob.curs[cur_id].rate
|
|
218
|
+
if usd_amount < 50:
|
|
219
|
+
return 0
|
|
220
|
+
elif usd_amount > 100:
|
|
221
|
+
return 2
|
|
222
|
+
else:
|
|
223
|
+
return 1
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
async def get_in(store: Store) -> tuple[models.Addr | models.Cred, str]:
|
|
227
|
+
if store.pay.s_ex_id:
|
|
228
|
+
addr_in = await models.Addr.get(
|
|
229
|
+
actor__ex_id=store.pay.s_ex_id, coin_id=store.pay.s_coin_id, actor__user__role__gte=Role.ADMIN
|
|
230
|
+
).prefetch_related("actor")
|
|
231
|
+
return addr_in, (
|
|
232
|
+
f"{store.glob.coins[store.pay.s_coin_id]} на {store.glob.exs[store.pay.s_ex_id]}, "
|
|
233
|
+
f"по id: `{addr_in.actor.exid}`"
|
|
234
|
+
)
|
|
235
|
+
else:
|
|
236
|
+
s_pmcur = await models.Pmcur.get(id=store.pay.s_pmcur_id).prefetch_related("pm__grp")
|
|
237
|
+
cred_id = await models.Cred.get( # todo: extend cred search conditions
|
|
238
|
+
**({"pmcur__pm__grp": s_pmcur.pm.grp} if s_pmcur.pm.grp else {"pmcur_id": store.pay.s_pmcur_id}),
|
|
239
|
+
person__user__role__gte=Role.ADMIN,
|
|
240
|
+
)
|
|
241
|
+
return cred_id, (
|
|
242
|
+
f"{store.glob.curs[store.pay.s_cur_id]} на {store.glob.pmcurs[store.pay.s_pmcur_id]} "
|
|
243
|
+
f"по номеру: `{cred_id.detail}`, имя: {cred_id.name}{cred_id.extra and f' ({cred_id.extra})' or ''}"
|
|
244
|
+
)
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
from asyncio import
|
|
2
|
-
from datetime import
|
|
1
|
+
from asyncio import gather
|
|
2
|
+
from datetime import datetime
|
|
3
3
|
|
|
4
4
|
import PGram
|
|
5
5
|
from aiogram import Router, F
|
|
6
6
|
from aiogram.filters import Command
|
|
7
7
|
from aiogram.types import Message, CallbackQuery
|
|
8
8
|
from aiogram.fsm.context import FSMContext
|
|
9
|
-
from xync_bot.routers.pay.dep import fill_creds, fill_actors, dlt, ans
|
|
9
|
+
from xync_bot.routers.pay.dep import fill_creds, fill_actors, dlt, ans, Store
|
|
10
10
|
from xync_schema import models
|
|
11
11
|
|
|
12
|
-
from xync_bot import Store
|
|
13
12
|
from xync_bot.routers.pay import cd, dep, window
|
|
14
13
|
|
|
15
14
|
pay = Router()
|
|
@@ -36,7 +35,7 @@ async def h_got_fiat_type(query: CallbackQuery, bot: PGram):
|
|
|
36
35
|
async def h_got_crypto_type(query: CallbackQuery, bot: PGram):
|
|
37
36
|
"""Step 2c: Select coin"""
|
|
38
37
|
bot.store.curr.is_fiat = False
|
|
39
|
-
|
|
38
|
+
bot.store.perm.actors, *_ = await gather(
|
|
40
39
|
fill_actors(bot.store.perm.user.person_id), window.coin_select(query.message), ans(query, "Понял, крипта")
|
|
41
40
|
)
|
|
42
41
|
|
|
@@ -91,7 +90,8 @@ async def h_got_cred_name(msg: Message, state: FSMContext):
|
|
|
91
90
|
person_id=store.perm.user.person_id,
|
|
92
91
|
pmcur_id=store.pay.t_pmcur_id,
|
|
93
92
|
)
|
|
94
|
-
|
|
93
|
+
store.pay.cred_id = cred.id
|
|
94
|
+
store.perm.creds[cred.id] = cred
|
|
95
95
|
await gather(window.amount(msg), dlt(msg), state.set_state(dep.PaymentState.amount))
|
|
96
96
|
|
|
97
97
|
|
|
@@ -101,11 +101,15 @@ async def h_got_ex(query: CallbackQuery, callback_data: cd.Ex, state: FSMContext
|
|
|
101
101
|
store: Store = query.message.bot.store
|
|
102
102
|
ist = store.curr.is_target
|
|
103
103
|
setattr(store.pay, ("t" if ist else "s") + "_ex_id", callback_data.id)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
if ist:
|
|
105
|
+
await window.amount(query.message)
|
|
106
|
+
actor_id = store.perm.actors[store.pay.t_ex_id]
|
|
107
|
+
addr = await models.Addr.get(coin_id=store.pay.t_coin_id, actor_id=actor_id)
|
|
108
|
+
store.pay.addr_id = addr.id
|
|
109
|
+
else:
|
|
110
|
+
await window.set_ppo(query.message)
|
|
111
|
+
await ans(query, f"Биржа {store.glob.exs[callback_data.id]} выбрана")
|
|
112
|
+
await state.set_state(dep.PaymentState.amount)
|
|
109
113
|
|
|
110
114
|
|
|
111
115
|
@pay.message(dep.PaymentState.amount)
|
|
@@ -129,7 +133,7 @@ async def h_got_source_pm(query: CallbackQuery, callback_data: cd.Pm):
|
|
|
129
133
|
store.pay.s_pmcur_id = callback_data.pmcur_id
|
|
130
134
|
await gather(
|
|
131
135
|
window.set_ppo(query.message),
|
|
132
|
-
ans(query, store.glob.
|
|
136
|
+
ans(query, store.glob.pmcurs[callback_data.pmcur_id]),
|
|
133
137
|
)
|
|
134
138
|
|
|
135
139
|
|
|
@@ -140,39 +144,10 @@ async def h_got_ppo(query: CallbackQuery, callback_data: cd.Ppo):
|
|
|
140
144
|
|
|
141
145
|
|
|
142
146
|
@pay.callback_query(cd.Time.filter())
|
|
143
|
-
async def
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if ex_id := (store.pay.t_ex_id or store.pay.s_ex_id):
|
|
149
|
-
actor_id = store.perm.ex_actors[ex_id]
|
|
150
|
-
if not (addr_id := store.pay.addr_id):
|
|
151
|
-
coin_id = store.pay.t_coin_id or store.pay.s_coin_id
|
|
152
|
-
addr_id = await models.Addr.get(coin_id=coin_id, actor_id=actor_id).values_list("id", flat=True)
|
|
153
|
-
store.pay.addr_id = addr_id
|
|
154
|
-
else:
|
|
155
|
-
addr_id = None
|
|
156
|
-
pr_data = dict(
|
|
157
|
-
pay_until=pay_until,
|
|
158
|
-
amount=store.pay.amount,
|
|
159
|
-
parts=store.pay.ppo,
|
|
160
|
-
payed_at=None,
|
|
161
|
-
addr_id=addr_id,
|
|
162
|
-
cred_id=store.pay.cred_id,
|
|
163
|
-
user=store.perm.user,
|
|
164
|
-
)
|
|
165
|
-
(pay_req, _), *__ = await gather(
|
|
166
|
-
models.PayReq.update_or_create(**pr_data), ans(query, None), state.set_state(dep.PaymentState.timer)
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
await state.update_data(
|
|
170
|
-
timer=callback_data.minutes,
|
|
171
|
-
timer_active=True,
|
|
172
|
-
pay_until=pay_until,
|
|
173
|
-
pay_req_id=pay_req.id,
|
|
174
|
-
)
|
|
175
|
-
create_task(window.run_timer(query.message, state))
|
|
147
|
+
async def h_got_urgency(query: CallbackQuery, callback_data: cd.Time):
|
|
148
|
+
query.message.bot.store.pay.urg = callback_data.minutes
|
|
149
|
+
await window.create_payreq(query.message)
|
|
150
|
+
await ans(query, f"Ok {callback_data.minutes} min.")
|
|
176
151
|
|
|
177
152
|
|
|
178
153
|
# ACTIONS
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from asyncio import sleep
|
|
2
|
+
from datetime import datetime, timedelta
|
|
2
3
|
|
|
3
4
|
from aiogram.fsm.context import FSMContext
|
|
4
5
|
from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
|
|
5
6
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
|
6
|
-
from
|
|
7
|
+
from xync_schema import models
|
|
8
|
+
|
|
9
|
+
from xync_bot.routers.pay.dep import edt, need_ppo, have_coin_amount, get_in, Store
|
|
7
10
|
|
|
8
|
-
from xync_bot import Store
|
|
9
11
|
from xync_bot.routers.pay import cd, dep
|
|
10
12
|
|
|
11
13
|
|
|
@@ -25,7 +27,16 @@ async def type_select(msg: Message):
|
|
|
25
27
|
]
|
|
26
28
|
]
|
|
27
29
|
)
|
|
28
|
-
|
|
30
|
+
if store.curr.is_target:
|
|
31
|
+
txt = "Что нужно?"
|
|
32
|
+
else:
|
|
33
|
+
if store.pay.t_coin_id:
|
|
34
|
+
inf = f"{store.glob.coins[store.pay.t_coin_id]} на {store.glob.exs[store.pay.t_ex_id]}:{store.pay.addr_id}"
|
|
35
|
+
else:
|
|
36
|
+
cur = store.glob.curs[store.pay.t_cur_id].ticker
|
|
37
|
+
cred: models.Cred = store.perm.creds[store.pay.cred_id]
|
|
38
|
+
inf = f"{cur} на {store.glob.pmcurs[store.pay.t_pmcur_id]}: {cred.repr()}"
|
|
39
|
+
txt = f"Нужен платеж: {store.pay.amount} {inf}\nЧем будете платить?"
|
|
29
40
|
if store.perm.msg_id:
|
|
30
41
|
await edt(msg, txt, rm)
|
|
31
42
|
else:
|
|
@@ -37,8 +48,8 @@ async def cur_select(msg: Message):
|
|
|
37
48
|
"""Common using cur func"""
|
|
38
49
|
builder = InlineKeyboardBuilder()
|
|
39
50
|
ist: bool = msg.bot.store.curr.is_target
|
|
40
|
-
for cur_id,
|
|
41
|
-
builder.button(text=ticker + dep.flags[ticker], callback_data=cd.Cur(id=cur_id, is_target=ist))
|
|
51
|
+
for cur_id, cur in msg.bot.store.glob.curs.items():
|
|
52
|
+
builder.button(text=cur.ticker + dep.flags[cur.ticker], callback_data=cd.Cur(id=cur_id, is_target=ist))
|
|
42
53
|
builder.button(text="Назад к выбору типа", callback_data=cd.PayNav(to=cd.PayStep.t_type))
|
|
43
54
|
builder.adjust(3, 3, 3, 3, 3, 1)
|
|
44
55
|
sfx = "ую нужно" if ist else "ой платишь"
|
|
@@ -82,7 +93,7 @@ async def pm(msg: Message):
|
|
|
82
93
|
cur_id = getattr(store.pay, ("t" if ist else "s") + "_cur_id")
|
|
83
94
|
builder = InlineKeyboardBuilder()
|
|
84
95
|
for pmcur_id in store.glob.curpms[cur_id]:
|
|
85
|
-
builder.button(text=store.glob.
|
|
96
|
+
builder.button(text=store.glob.pmcurs[pmcur_id], callback_data=cd.Pm(pmcur_id=pmcur_id, is_target=ist))
|
|
86
97
|
builder.button(
|
|
87
98
|
text="Назад к выбору валюты", callback_data=cd.PayNav(to=cd.PayStep.t_cur if ist else cd.PayStep.s_cur)
|
|
88
99
|
)
|
|
@@ -99,10 +110,7 @@ async def fill_cred_dtl(msg: Message):
|
|
|
99
110
|
if cred_ids := store.perm.cur_creds.get(store.pay.t_pmcur_id):
|
|
100
111
|
for cred_id in cred_ids:
|
|
101
112
|
cred = store.perm.creds[cred_id]
|
|
102
|
-
|
|
103
|
-
if cred.extra:
|
|
104
|
-
txt += f" ({cred.extra})"
|
|
105
|
-
builder.button(text=txt, callback_data=cd.Cred(id=cred_id))
|
|
113
|
+
builder.button(text=cred.repr(), callback_data=cd.Cred(id=cred_id))
|
|
106
114
|
txt = "Выберите реквизиты куда нужно получить деньги, если в списке нет нужных, то\nв"
|
|
107
115
|
|
|
108
116
|
builder.button(text="Назад к выбору платежной системы", callback_data=cd.PayNav(to=cd.PayStep.t_pm))
|
|
@@ -110,7 +118,7 @@ async def fill_cred_dtl(msg: Message):
|
|
|
110
118
|
builder.adjust(2)
|
|
111
119
|
|
|
112
120
|
await msg.edit_text(
|
|
113
|
-
f"{txt}ведите номер для {store.glob.
|
|
121
|
+
f"{txt}ведите номер для {store.glob.pmcurs[store.pay.t_pmcur_id]}:", reply_markup=builder.as_markup()
|
|
114
122
|
)
|
|
115
123
|
|
|
116
124
|
|
|
@@ -121,9 +129,9 @@ async def fill_cred_name(msg: Message):
|
|
|
121
129
|
builder.adjust(2)
|
|
122
130
|
store: Store = msg.bot.store
|
|
123
131
|
cur = store.glob.curs[store.pay.t_cur_id]
|
|
124
|
-
payment = store.glob.
|
|
132
|
+
payment = store.glob.pmcurs[store.pay.t_pmcur_id]
|
|
125
133
|
detail = store.pay.cred_dtl
|
|
126
|
-
await edt(msg, f"{cur}:{payment}:{detail}: Введите имя получателя", builder.as_markup())
|
|
134
|
+
await edt(msg, f"{cur.ticker}:{payment}:{detail}: Введите имя получателя", builder.as_markup())
|
|
127
135
|
|
|
128
136
|
|
|
129
137
|
async def amount(msg: Message):
|
|
@@ -131,9 +139,9 @@ async def amount(msg: Message):
|
|
|
131
139
|
builder = InlineKeyboardBuilder()
|
|
132
140
|
store: Store = msg.bot.store
|
|
133
141
|
if store.curr.is_fiat:
|
|
134
|
-
cur_coin = store.glob.curs[store.pay.t_cur_id]
|
|
142
|
+
cur_coin = store.glob.curs[store.pay.t_cur_id].ticker
|
|
135
143
|
builder.button(text="Назад к вводу имени", callback_data=cd.PayNav(to=cd.PayStep.t_cred_name))
|
|
136
|
-
t_name = store.glob.
|
|
144
|
+
t_name = store.glob.pmcurs[store.pay.t_pmcur_id]
|
|
137
145
|
else:
|
|
138
146
|
cur_coin = store.glob.coins[store.pay.t_coin_id]
|
|
139
147
|
builder.button(text="Назад к выбору биржи", callback_data=cd.PayNav(to=cd.PayStep.t_ex))
|
|
@@ -146,29 +154,62 @@ async def amount(msg: Message):
|
|
|
146
154
|
|
|
147
155
|
|
|
148
156
|
async def set_ppo(msg: Message):
|
|
157
|
+
store: Store = msg.bot.store
|
|
158
|
+
ist = store.curr.is_target
|
|
159
|
+
if nppo := await need_ppo(store):
|
|
160
|
+
builder = InlineKeyboardBuilder()
|
|
161
|
+
builder.button(text="Нет", callback_data=cd.Ppo(num=1, is_target=ist)).button(
|
|
162
|
+
text="Да", callback_data=cd.Ppo(num=2, is_target=ist)
|
|
163
|
+
)
|
|
164
|
+
if nppo > 1:
|
|
165
|
+
builder.button(text="Да хоть 3мя", callback_data=cd.Ppo(num=3, is_target=ist))
|
|
166
|
+
builder.adjust(2)
|
|
167
|
+
await edt(msg, f"2мя платежами сможете {'принять' if ist else 'отравить'}?", builder.as_markup())
|
|
168
|
+
elif ist:
|
|
169
|
+
store.curr.is_target = False
|
|
170
|
+
await type_select(msg)
|
|
171
|
+
else:
|
|
172
|
+
await set_urgency(msg)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
async def set_urgency(msg: Message):
|
|
176
|
+
store: Store = msg.bot.store
|
|
177
|
+
if not store.curr.is_fiat or have_coin_amount(store):
|
|
178
|
+
return await create_payreq(msg) # next
|
|
179
|
+
builder = InlineKeyboardBuilder()
|
|
180
|
+
(
|
|
181
|
+
builder.button(text="1 мин", callback_data=cd.Time(minutes=1))
|
|
182
|
+
.button(text="5 мин", callback_data=cd.Time(minutes=5))
|
|
183
|
+
.button(text="30 мин", callback_data=cd.Time(minutes=30))
|
|
184
|
+
.button(text="3 часа", callback_data=cd.Time(minutes=180))
|
|
185
|
+
.button(text="сутки", callback_data=cd.Time(minutes=60 * 24))
|
|
186
|
+
.button(text="Назад к вводу платежей", callback_data=cd.PayNav(to=cd.PayStep.t_pm))
|
|
187
|
+
.button(text="Домой", callback_data=cd.PayNav(to=cd.PayStep.t_type))
|
|
188
|
+
.adjust(2, 2, 1, 1, 1)
|
|
189
|
+
)
|
|
190
|
+
return await edt(msg, "Сколько можешь ждать?", builder.as_markup())
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
async def create_payreq(msg: Message):
|
|
194
|
+
store: Store = msg.bot.store
|
|
195
|
+
pay_req, _ = await models.PayReq.update_or_create(
|
|
196
|
+
{"pay_until": datetime.now() + timedelta(minutes=store.pay.urg)},
|
|
197
|
+
amount=store.pay.amount,
|
|
198
|
+
parts=store.pay.ppo,
|
|
199
|
+
addr_id=store.pay.addr_id,
|
|
200
|
+
cred_id=store.pay.cred_id,
|
|
201
|
+
user=store.perm.user,
|
|
202
|
+
)
|
|
203
|
+
store.pay.pr_id = pay_req.id
|
|
204
|
+
inp, txt = await get_in(store)
|
|
149
205
|
rm = InlineKeyboardMarkup(
|
|
150
206
|
inline_keyboard=[
|
|
151
|
-
[
|
|
152
|
-
InlineKeyboardButton(text="Нет", callback_data="ppo:1"),
|
|
153
|
-
InlineKeyboardButton(text="Да", callback_data="ppo:2"),
|
|
154
|
-
],
|
|
155
|
-
[InlineKeyboardButton(text="Да хоть на 3", callback_data="ppo:3")],
|
|
207
|
+
[InlineKeyboardButton(text="Отправил", callback_data=cd.Action(act=cd.ActionType.sent).pack())],
|
|
156
208
|
]
|
|
157
209
|
)
|
|
158
|
-
await msg.
|
|
159
|
-
|
|
210
|
+
await edt(msg, f"Отправь {store.pay.amount}" + txt, rm.as_markup())
|
|
160
211
|
|
|
161
|
-
|
|
162
|
-
builder = InlineKeyboardBuilder()
|
|
163
|
-
builder.button(text="1 мин", callback_data=cd.Time(minutes=1))
|
|
164
|
-
builder.button(text="5 мин", callback_data=cd.Time(minutes=5))
|
|
165
|
-
builder.button(text="30 мин", callback_data=cd.Time(minutes=30))
|
|
166
|
-
builder.button(text="3 часа", callback_data=cd.Time(minutes=180))
|
|
167
|
-
builder.button(text="сутки", callback_data=cd.Time(minutes=60 * 24))
|
|
168
|
-
builder.button(text="Назад к вводу платежей", callback_data=cd.PayNav(to=cd.PayStep.t_pm))
|
|
169
|
-
builder.button(text="Домой", callback_data=cd.PayNav(to=cd.PayStep.t_type))
|
|
170
|
-
builder.adjust(2, 2, 1, 1, 1)
|
|
171
|
-
await msg.edit_text("Сколько можешь ждать?", reply_markup=builder.as_markup())
|
|
212
|
+
# create_task(window.run_timer(msg))
|
|
172
213
|
|
|
173
214
|
|
|
174
215
|
async def run_timer(message, state: FSMContext):
|
|
File without changes
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
from aiogram.types import Message
|
|
2
|
-
from tortoise.functions import Min
|
|
3
|
-
from x_model.func import ArrayAgg
|
|
4
|
-
from xync_schema import models
|
|
5
|
-
|
|
6
|
-
from xync_bot.routers.pay.dep import flags
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class SingleStore(type):
|
|
10
|
-
_store = None
|
|
11
|
-
|
|
12
|
-
async def __call__(cls):
|
|
13
|
-
if not cls._store:
|
|
14
|
-
cls._store = super(SingleStore, cls).__call__()
|
|
15
|
-
cls._store.coins = {k: v for k, v in await models.Coin.all().order_by("ticker").values_list("id", "ticker")}
|
|
16
|
-
curs = {
|
|
17
|
-
k: v
|
|
18
|
-
for k, v in await models.Cur.filter(ticker__in=flags.keys())
|
|
19
|
-
.order_by("ticker")
|
|
20
|
-
.values_list("id", "ticker")
|
|
21
|
-
}
|
|
22
|
-
cls._store.curs = curs
|
|
23
|
-
cls._store.exs = {k: v for k, v in await models.Ex.all().values_list("id", "name")}
|
|
24
|
-
cls._store.pms = {
|
|
25
|
-
k: v
|
|
26
|
-
for k, v in await models.Pmex.filter(pm__pmcurs__cur_id__in=cls._store.curs.keys())
|
|
27
|
-
.annotate(sname=Min("name"))
|
|
28
|
-
.group_by("pm__pmcurs__id")
|
|
29
|
-
.values_list("pm__pmcurs__id", "sname")
|
|
30
|
-
}
|
|
31
|
-
cls._store.coinexs = {
|
|
32
|
-
c.id: [ex.ex_id for ex in c.coinexs] for c in await models.Coin.all().prefetch_related("coinexs")
|
|
33
|
-
}
|
|
34
|
-
cls._store.curpms = {
|
|
35
|
-
cur_id: ids
|
|
36
|
-
for cur_id, ids in await models.Pmcur.filter(cur_id__in=curs.keys())
|
|
37
|
-
.annotate(ids=ArrayAgg("id"))
|
|
38
|
-
.group_by("cur_id")
|
|
39
|
-
.values_list("cur_id", "ids")
|
|
40
|
-
}
|
|
41
|
-
cls._store.curpms = {
|
|
42
|
-
cur_id: ids
|
|
43
|
-
for cur_id, ids in await models.Pmcur.filter(cur_id__in=curs.keys())
|
|
44
|
-
.annotate(ids=ArrayAgg("id"))
|
|
45
|
-
.group_by("cur_id")
|
|
46
|
-
.values_list("cur_id", "ids")
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return cls._store
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class Store:
|
|
53
|
-
class Global(metaclass=SingleStore):
|
|
54
|
-
coins: dict[int, str] # id:ticker
|
|
55
|
-
curs: dict[int, str] # id:ticker
|
|
56
|
-
exs: dict[int, str] # id:name
|
|
57
|
-
coinexs: dict[int, list[int]] # id:[ex_ids]
|
|
58
|
-
pms: dict[int, str] # pmcur_id:name
|
|
59
|
-
curpms: dict[int, list[int]] # id:[pmcur_ids]
|
|
60
|
-
|
|
61
|
-
class Permanent:
|
|
62
|
-
msg_id: int = None
|
|
63
|
-
user: models.User = None
|
|
64
|
-
actors: dict[int, models.Actor] = None # key=actor_id
|
|
65
|
-
ex_actors: dict[int, list[int]] = None # key=ex_id
|
|
66
|
-
creds: dict[int, models.Cred] = None # key=cred_id
|
|
67
|
-
cur_creds: dict[int, list[int]] = None # pmcur_id:[cred_ids]
|
|
68
|
-
|
|
69
|
-
class Current:
|
|
70
|
-
is_target: bool = True
|
|
71
|
-
is_fiat: bool = None
|
|
72
|
-
msg_to_del: Message = None
|
|
73
|
-
|
|
74
|
-
class Payment:
|
|
75
|
-
t_cur_id: int = None
|
|
76
|
-
s_cur_id: int = None
|
|
77
|
-
t_coin_id: int = None
|
|
78
|
-
s_coin_id: int = None
|
|
79
|
-
t_pmcur_id: int = None
|
|
80
|
-
s_pmcur_id: int = None
|
|
81
|
-
t_ex_id: int = None
|
|
82
|
-
s_ex_id: int = None
|
|
83
|
-
amount: int | float = None
|
|
84
|
-
ppo: int = None
|
|
85
|
-
addr_id: int = None
|
|
86
|
-
cred_dtl: str = None
|
|
87
|
-
cred_id: int = None
|
|
88
|
-
|
|
89
|
-
class Payreq:
|
|
90
|
-
id: int = None
|
|
91
|
-
created_at: int = None
|
|
92
|
-
payed_at: int = None
|
|
93
|
-
|
|
94
|
-
glob: Global
|
|
95
|
-
perm: Permanent = Permanent()
|
|
96
|
-
pay: Payment = Payment()
|
|
97
|
-
pr: Payreq = Payreq()
|
|
98
|
-
curr: Current = Current()
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
from asyncio import gather
|
|
2
|
-
from enum import IntEnum
|
|
3
|
-
|
|
4
|
-
from aiogram.exceptions import TelegramBadRequest
|
|
5
|
-
from aiogram.fsm.state import StatesGroup, State
|
|
6
|
-
from aiogram.types import Message, InlineKeyboardMarkup
|
|
7
|
-
from pyrogram.types import CallbackQuery
|
|
8
|
-
from x_model.func import ArrayAgg
|
|
9
|
-
from xync_schema import models
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class Report(StatesGroup):
|
|
13
|
-
text = State()
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class CredState(StatesGroup):
|
|
17
|
-
detail = State()
|
|
18
|
-
name = State()
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class PaymentState(StatesGroup):
|
|
22
|
-
amount = State()
|
|
23
|
-
timer = State()
|
|
24
|
-
timer_active = State()
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class ActionType(IntEnum):
|
|
28
|
-
"""Цель (назначение) платежа (target)"""
|
|
29
|
-
|
|
30
|
-
sent = 1 # Отправил
|
|
31
|
-
received = 2 # Получил
|
|
32
|
-
not_received = 3 # Не получил
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class PayStep(IntEnum):
|
|
36
|
-
"""Цель (назначение) платежа (target)"""
|
|
37
|
-
|
|
38
|
-
t_type = 1 # Выбор типа
|
|
39
|
-
t_cur = 2 # Выбор валюты
|
|
40
|
-
t_coin = 3 # Выбор монеты
|
|
41
|
-
t_pm = 4 # Выбор платежки
|
|
42
|
-
t_ex = 5 # Выбор биржи
|
|
43
|
-
t_cred_dtl = 6 # Ввод номера карты
|
|
44
|
-
t_cred_name = 7 # Ввод имени
|
|
45
|
-
# t_addr = 8 # todo: позже добавим: Выбор/ввод крипто кошелька
|
|
46
|
-
t_amount = 9 # Ввод суммы
|
|
47
|
-
""" Источник платежа (source) """
|
|
48
|
-
s_type = 10 # Выбор типа
|
|
49
|
-
s_cur = 11 # Выбор типа
|
|
50
|
-
s_pm = 12 # Выбор типа
|
|
51
|
-
s_coin = 13 # Выбор типа
|
|
52
|
-
s_ex = 14 # Выбор типа
|
|
53
|
-
ppo = 15 # Выбор возможности разбивки платежа
|
|
54
|
-
urgency = 16 # Выбор срочности получения платежа
|
|
55
|
-
pending_send = 17 # Ожидание отправки (если мы платим фиатом)
|
|
56
|
-
pending_confirm = 18 # Ожидание пока на той стороне подтвердят получение нашего фиата (если мы платим фиатом)
|
|
57
|
-
pending_receive = 19 # Ожидание поступления (если мы получаем фиат)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
flags = {
|
|
61
|
-
"RUB": "🇷🇺",
|
|
62
|
-
"THB": "🇹🇭",
|
|
63
|
-
"IDR": "🇮🇩",
|
|
64
|
-
"TRY": "🇹🇷",
|
|
65
|
-
"GEL": "🇬🇪",
|
|
66
|
-
"VND": "🇻🇳",
|
|
67
|
-
"AED": "🇦🇪",
|
|
68
|
-
"AMD": "🇦🇲",
|
|
69
|
-
"AZN": "🇦🇿",
|
|
70
|
-
"CNY": "🇨🇳",
|
|
71
|
-
"EUR": "🇪🇺",
|
|
72
|
-
"HKD": "🇭🇰",
|
|
73
|
-
"INR": "🇮🇳",
|
|
74
|
-
"PHP": "🇵🇭",
|
|
75
|
-
"USD": "🇺🇸",
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
async def fill_creds(person_id: int) -> tuple[dict[int, models.Cred], dict[int, list[int]]]:
|
|
80
|
-
cq = models.Cred.filter(person_id=person_id)
|
|
81
|
-
creds = {c.id: c for c in await cq}
|
|
82
|
-
cur_creds = {
|
|
83
|
-
pci: ids
|
|
84
|
-
for pci, ids in await cq.annotate(ids=ArrayAgg("id")).group_by("pmcur_id").values_list("pmcur_id", "ids")
|
|
85
|
-
}
|
|
86
|
-
return creds, cur_creds
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
async def fill_actors(person_id: int) -> tuple[dict[int, models.Actor], dict[int, list[int]]]:
|
|
90
|
-
aq = models.Actor.filter(person_id=person_id)
|
|
91
|
-
actors = {a.id: a for a in await aq}
|
|
92
|
-
ex_act_id = {
|
|
93
|
-
exi: ids[0]
|
|
94
|
-
for exi, ids in await aq.annotate(ids=ArrayAgg("id")) # todo: check len(ids) == 1
|
|
95
|
-
.group_by("ex_id")
|
|
96
|
-
.values_list("ex_id", "ids")
|
|
97
|
-
}
|
|
98
|
-
return actors, ex_act_id
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
async def edit(msg: Message, txt: str, rm: InlineKeyboardMarkup):
|
|
102
|
-
await gather(msg.edit_text(txt), msg.edit_reply_markup(reply_markup=rm))
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
async def ans(cbq: CallbackQuery, txt: str = None):
|
|
106
|
-
await cbq.answer(txt, cache_time=0)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
async def dlt(msg: Message):
|
|
110
|
-
await msg.delete()
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
async def edt(msg: Message, txt: str, rm: InlineKeyboardMarkup):
|
|
114
|
-
if msg.message_id == msg.bot.store.perm.msg_id:
|
|
115
|
-
await msg.edit_text(txt, reply_markup=rm)
|
|
116
|
-
else: # окно вызвано в ответ на текст, а не кнопку
|
|
117
|
-
try:
|
|
118
|
-
await msg.bot.edit_message_text(
|
|
119
|
-
txt, chat_id=msg.chat.id, message_id=msg.bot.store.perm.msg_id, reply_markup=rm
|
|
120
|
-
)
|
|
121
|
-
except TelegramBadRequest as e:
|
|
122
|
-
print(msg.bot.store.perm.msg_id, e)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/xync_bot-0.3.24.dev9/xync_bot/typs.py → /xync_bot-0.3.24.dev11/xync_bot/routers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|