xync-bot 0.3.24.dev12__py3-none-any.whl → 0.3.25.dev1__py3-none-any.whl
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/__main__.py +36 -0
- xync_bot/routers/__init__.py +41 -0
- xync_bot/routers/cond/__init__.py +1 -7
- xync_bot/routers/main/__init__.py +0 -0
- xync_bot/routers/{main.py → main/handler.py} +28 -60
- xync_bot/routers/pay/dep.py +0 -171
- xync_bot/routers/pay/handler.py +88 -93
- xync_bot/routers/pay/window.py +19 -37
- xync_bot/shared.py +19 -0
- xync_bot/store.py +157 -0
- {xync_bot-0.3.24.dev12.dist-info → xync_bot-0.3.25.dev1.dist-info}/METADATA +1 -1
- xync_bot-0.3.25.dev1.dist-info/RECORD +22 -0
- xync_bot/__init__.py +0 -26
- xync_bot-0.3.24.dev12.dist-info/RECORD +0 -20
- {xync_bot-0.3.24.dev12.dist-info → xync_bot-0.3.25.dev1.dist-info}/WHEEL +0 -0
- {xync_bot-0.3.24.dev12.dist-info → xync_bot-0.3.25.dev1.dist-info}/top_level.txt +0 -0
xync_bot/__main__.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from asyncio import run
|
|
3
|
+
|
|
4
|
+
from PGram import Bot
|
|
5
|
+
from aiogram.client.default import DefaultBotProperties
|
|
6
|
+
from aiogram.enums import UpdateType
|
|
7
|
+
from x_model import init_db
|
|
8
|
+
|
|
9
|
+
from xync_bot.routers.main.handler import mr
|
|
10
|
+
from xync_bot.routers.cond import cr
|
|
11
|
+
from xync_bot.routers.pay.handler import pr
|
|
12
|
+
from xync_bot.routers import last
|
|
13
|
+
from xync_bot.store import Store
|
|
14
|
+
|
|
15
|
+
au = [
|
|
16
|
+
UpdateType.MESSAGE,
|
|
17
|
+
UpdateType.CALLBACK_QUERY,
|
|
18
|
+
UpdateType.CHAT_MEMBER,
|
|
19
|
+
UpdateType.MY_CHAT_MEMBER,
|
|
20
|
+
] # , UpdateType.CHAT_JOIN_REQUEST
|
|
21
|
+
bot = Bot([cr, pr, mr, last], Store(), au, default=DefaultBotProperties(parse_mode="HTML"))
|
|
22
|
+
|
|
23
|
+
if __name__ == "__main__":
|
|
24
|
+
from xync_bot.loader import TOKEN, TORM
|
|
25
|
+
|
|
26
|
+
logging.basicConfig(level=logging.INFO)
|
|
27
|
+
|
|
28
|
+
async def main() -> None:
|
|
29
|
+
cn = await init_db(TORM)
|
|
30
|
+
bot.dp.workflow_data["store"].glob = await Store.Global() # todo: refact store loading
|
|
31
|
+
await bot.start(
|
|
32
|
+
TOKEN,
|
|
33
|
+
cn,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
run(main())
|
xync_bot/routers/__init__.py
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from aiogram import Router, F
|
|
4
|
+
from aiogram.enums import ContentType
|
|
5
|
+
from aiogram.exceptions import TelegramBadRequest
|
|
6
|
+
from aiogram.types import Message
|
|
7
|
+
|
|
8
|
+
last = Router(name="last")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@last.message(
|
|
12
|
+
F.content_type.not_in(
|
|
13
|
+
{
|
|
14
|
+
ContentType.NEW_CHAT_MEMBERS,
|
|
15
|
+
# ContentType.LEFT_CHAT_MEMBER,
|
|
16
|
+
# ContentType.SUPERGROUP_CHAT_CREATED,
|
|
17
|
+
# ContentType.NEW_CHAT_PHOTO,
|
|
18
|
+
# ContentType.FORUM_TOPIC_CREATED,
|
|
19
|
+
# ContentType.FORUM_TOPIC_EDITED,
|
|
20
|
+
ContentType.FORUM_TOPIC_CLOSED,
|
|
21
|
+
# ContentType.GENERAL_FORUM_TOPIC_HIDDEN, # deletable
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
async def del_cbq(msg: Message):
|
|
26
|
+
try:
|
|
27
|
+
await msg.delete()
|
|
28
|
+
logging.info({"DELETED": msg.model_dump(exclude_none=True)})
|
|
29
|
+
except TelegramBadRequest:
|
|
30
|
+
logging.error({"NOT_DELETED": msg.model_dump(exclude_none=True)})
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@last.message()
|
|
34
|
+
async def all_rest(msg: Message):
|
|
35
|
+
logging.warning(
|
|
36
|
+
{
|
|
37
|
+
"NO_HANDLED": msg.model_dump(
|
|
38
|
+
exclude_none=True,
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
)
|
|
@@ -8,7 +8,7 @@ from xync_schema.enums import SynonymType
|
|
|
8
8
|
|
|
9
9
|
from xync_bot.routers.cond.func import wrap_cond, get_val, btns, rkm, ikm, SynTypeCd, CondCd
|
|
10
10
|
|
|
11
|
-
cr = Router()
|
|
11
|
+
cr = Router(name="cond")
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@cr.message(Command("cond"))
|
|
@@ -89,9 +89,3 @@ async def got_action(cbq: CallbackQuery, callback_data: CondCd, state: FSMContex
|
|
|
89
89
|
await (await state.get_value("cmsg")).delete()
|
|
90
90
|
await show_cond(cbq.message, cond)
|
|
91
91
|
return await cbq.answer(callback_data.act)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
@cr.message()
|
|
95
|
-
async def unknown(msg: Message):
|
|
96
|
-
# user = await User.get(username_id=msg.from_user.id)
|
|
97
|
-
await msg.delete()
|
|
File without changes
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
3
|
from aiogram import Router, F
|
|
4
|
-
from aiogram.enums import ContentType
|
|
5
|
-
from aiogram.exceptions import TelegramBadRequest
|
|
6
4
|
from aiogram.filters import CommandStart, CommandObject, ChatMemberUpdatedFilter, JOIN_TRANSITION, LEAVE_TRANSITION
|
|
7
5
|
from aiogram.filters.callback_data import CallbackData
|
|
8
6
|
from aiogram.types import (
|
|
@@ -18,8 +16,9 @@ from aiogram.utils.deep_linking import create_start_link
|
|
|
18
16
|
from xync_schema import models
|
|
19
17
|
|
|
20
18
|
from xync_bot.shared import NavCallbackData
|
|
19
|
+
from xync_bot.store import Store
|
|
21
20
|
|
|
22
|
-
mr = Router()
|
|
21
|
+
mr = Router(name="main")
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
class RrCallbackData(CallbackData, prefix="reg_res"): # registration response
|
|
@@ -30,6 +29,7 @@ class RrCallbackData(CallbackData, prefix="reg_res"): # registration response
|
|
|
30
29
|
home_btns = InlineKeyboardMarkup(
|
|
31
30
|
inline_keyboard=[
|
|
32
31
|
[
|
|
32
|
+
InlineKeyboardButton(text="Transfer", callback_data=NavCallbackData(to="transfer").pack()),
|
|
33
33
|
InlineKeyboardButton(text="Invite", callback_data=NavCallbackData(to="ref_link").pack()),
|
|
34
34
|
InlineKeyboardButton(text="Get VPN", callback_data=NavCallbackData(to="get_vpn").pack()),
|
|
35
35
|
]
|
|
@@ -41,7 +41,7 @@ home_btns = InlineKeyboardMarkup(
|
|
|
41
41
|
async def start_handler(msg: Message, command: CommandObject):
|
|
42
42
|
me: User = msg.from_user
|
|
43
43
|
ref_id: int = command.args.isnumeric() and int(command.args)
|
|
44
|
-
user = await models.User.
|
|
44
|
+
user = await models.User.get(username_id=me.id, blocked=False)
|
|
45
45
|
rm = None
|
|
46
46
|
logging.info(msg, {"src": "start"})
|
|
47
47
|
if user:
|
|
@@ -66,6 +66,27 @@ async def start_handler(msg: Message, command: CommandObject):
|
|
|
66
66
|
return await msg.answer(rs, reply_markup=rm)
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
@mr.message(CommandStart(deep_link=True)) # attempt to reg by fake link
|
|
70
|
+
async def fraud_handler(msg: Message):
|
|
71
|
+
logging.warning(f"Start: {msg.from_user.id}. Msg: {msg}")
|
|
72
|
+
# todo: alert to admins! Fraud attempt!
|
|
73
|
+
await msg.answer("🤔")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@mr.message(CommandStart()) # обычный /start
|
|
77
|
+
async def home(msg: Message, store: Store):
|
|
78
|
+
me = msg.from_user
|
|
79
|
+
user, is_new = await models.User.tg_upsert(me, False)
|
|
80
|
+
|
|
81
|
+
rr = "сначала вы должны найти поручителя, и перейти по его реферальной ссылке.\nhttps://telegra.ph/XyncNet-02-13"
|
|
82
|
+
if is_new: # has ref and created now
|
|
83
|
+
await msg.answer(f"Здравствуйте {me.full_name}, что бы использовать возможности нашей сети, {rr}")
|
|
84
|
+
elif not user.ref_id:
|
|
85
|
+
await msg.answer(rr.capitalize())
|
|
86
|
+
else:
|
|
87
|
+
await msg.answer(f"{me.full_name}, не балуйтесь, вы и так уже активный участник👌🏼", reply_markup=home_btns)
|
|
88
|
+
|
|
89
|
+
|
|
69
90
|
@mr.callback_query(RrCallbackData.filter())
|
|
70
91
|
async def phrases_input_request(cb: CallbackQuery, callback_data: RrCallbackData) -> None:
|
|
71
92
|
protege = await models.User[callback_data.to]
|
|
@@ -83,27 +104,7 @@ async def phrases_input_request(cb: CallbackQuery, callback_data: RrCallbackData
|
|
|
83
104
|
await cb.message.edit_text(rs)
|
|
84
105
|
|
|
85
106
|
|
|
86
|
-
@mr.
|
|
87
|
-
async def fraud_handler(msg: Message):
|
|
88
|
-
logging.warning(f"Start: {msg.from_user.id}. Msg: {msg}")
|
|
89
|
-
# todo: alert to admins! Fraud attempt!
|
|
90
|
-
await msg.answer("🤔")
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@mr.message(CommandStart())
|
|
94
|
-
async def start_no_ref_handler(msg: Message):
|
|
95
|
-
me = msg.from_user
|
|
96
|
-
user, cr = await models.User.tg2in(me, False)
|
|
97
|
-
rr = "сначала вы должны найти поручителя, и перейти по его реферальной ссылке.\nhttps://telegra.ph/XyncNet-02-13"
|
|
98
|
-
if cr: # has ref and created now
|
|
99
|
-
await msg.answer(f"Здравствуйте {me.full_name}, что бы использовать возможности нашей сети, {rr}")
|
|
100
|
-
elif not user.ref_id:
|
|
101
|
-
await msg.answer(rr.capitalize())
|
|
102
|
-
else:
|
|
103
|
-
await msg.answer(f"{me.full_name}, не балуйтесь, вы и так уже активный участник👌🏼", reply_markup=home_btns)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@mr.callback_query(NavCallbackData.filter(F.to == "ref_link"))
|
|
107
|
+
@mr.callback_query(NavCallbackData.filter(F.to.__eq__("ref_link")))
|
|
107
108
|
async def ref_link_handler(cbq: CallbackQuery):
|
|
108
109
|
me = cbq.from_user
|
|
109
110
|
if not (u := await models.User.get_or_none(id=me.id, blocked=False).prefetch_related("ref")):
|
|
@@ -118,7 +119,7 @@ async def ref_link_handler(cbq: CallbackQuery):
|
|
|
118
119
|
await cbq.answer("Wait for your protege request..")
|
|
119
120
|
|
|
120
121
|
|
|
121
|
-
@mr.my_chat_member(F.chat.type == "private") # my_chat_member is fired on
|
|
122
|
+
@mr.my_chat_member(F.chat.type == "private") # my_chat_member is fired on adding bot to any chat. filter for preventing
|
|
122
123
|
async def my_user_set_status(my_chat_member: ChatMemberUpdated):
|
|
123
124
|
logging.info({"my_chat_member": my_chat_member.model_dump(exclude_none=True)})
|
|
124
125
|
u: User = my_chat_member.from_user
|
|
@@ -128,7 +129,7 @@ async def my_user_set_status(my_chat_member: ChatMemberUpdated):
|
|
|
128
129
|
|
|
129
130
|
@mr.my_chat_member()
|
|
130
131
|
async def user_set_status(my_chat_member: ChatMemberUpdated):
|
|
131
|
-
if my_chat_member.new_chat_member.user.username == "XyncNetBot": # удалена
|
|
132
|
+
if my_chat_member.new_chat_member.user.username == "XyncNetBot": # удалена группа, где бот был добавлен админом
|
|
132
133
|
if forum := await models.Forum.get_or_none(id=my_chat_member.chat.id):
|
|
133
134
|
await forum.delete()
|
|
134
135
|
res = f"I {my_chat_member.new_chat_member.status} from {my_chat_member.chat.id}:{my_chat_member.chat.title}"
|
|
@@ -186,36 +187,3 @@ async def order_msg(msg: Message):
|
|
|
186
187
|
await models.Msg.create(tgid=msg.message_id, txt=msg.text, order_id=order.id, receiver=receiver)
|
|
187
188
|
logging.info(msg, {"src": "order_msg"})
|
|
188
189
|
return await msg.send_copy(receiver.forum, message_thread_id=rcv_topic)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
@mr.message(
|
|
192
|
-
F.content_type.not_in(
|
|
193
|
-
{
|
|
194
|
-
ContentType.NEW_CHAT_MEMBERS,
|
|
195
|
-
# ContentType.LEFT_CHAT_MEMBER,
|
|
196
|
-
# ContentType.SUPERGROUP_CHAT_CREATED,
|
|
197
|
-
# ContentType.NEW_CHAT_PHOTO,
|
|
198
|
-
# ContentType.FORUM_TOPIC_CREATED,
|
|
199
|
-
# ContentType.FORUM_TOPIC_EDITED,
|
|
200
|
-
ContentType.FORUM_TOPIC_CLOSED,
|
|
201
|
-
# ContentType.GENERAL_FORUM_TOPIC_HIDDEN, # deletable
|
|
202
|
-
}
|
|
203
|
-
)
|
|
204
|
-
)
|
|
205
|
-
async def del_cbq(msg: Message):
|
|
206
|
-
try:
|
|
207
|
-
await msg.delete()
|
|
208
|
-
logging.info({"DELETED": msg.model_dump(exclude_none=True)})
|
|
209
|
-
except TelegramBadRequest:
|
|
210
|
-
logging.error({"NOT_DELETED": msg.model_dump(exclude_none=True)})
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
@mr.message()
|
|
214
|
-
async def all_rest(msg: Message):
|
|
215
|
-
logging.warning(
|
|
216
|
-
{
|
|
217
|
-
"NO_HANDLED": msg.model_dump(
|
|
218
|
-
exclude_none=True,
|
|
219
|
-
)
|
|
220
|
-
}
|
|
221
|
-
)
|
xync_bot/routers/pay/dep.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
from asyncio import gather
|
|
3
2
|
from enum import IntEnum
|
|
4
3
|
|
|
@@ -6,8 +5,6 @@ from aiogram.exceptions import TelegramBadRequest
|
|
|
6
5
|
from aiogram.fsm.state import StatesGroup, State
|
|
7
6
|
from aiogram.types import Message, InlineKeyboardMarkup
|
|
8
7
|
from pyrogram.types import CallbackQuery
|
|
9
|
-
from tortoise.functions import Min
|
|
10
|
-
from x_auth.enums import Role
|
|
11
8
|
from x_model.func import ArrayAgg
|
|
12
9
|
from xync_schema import models
|
|
13
10
|
|
|
@@ -60,107 +57,6 @@ class PayStep(IntEnum):
|
|
|
60
57
|
pending_receive = 19 # Ожидание поступления (если мы получаем фиат)
|
|
61
58
|
|
|
62
59
|
|
|
63
|
-
flags = {
|
|
64
|
-
"RUB": "🇷🇺",
|
|
65
|
-
"THB": "🇹🇭",
|
|
66
|
-
"IDR": "🇮🇩",
|
|
67
|
-
"TRY": "🇹🇷",
|
|
68
|
-
"GEL": "🇬🇪",
|
|
69
|
-
"VND": "🇻🇳",
|
|
70
|
-
"AED": "🇦🇪",
|
|
71
|
-
"AMD": "🇦🇲",
|
|
72
|
-
"AZN": "🇦🇿",
|
|
73
|
-
"CNY": "🇨🇳",
|
|
74
|
-
"EUR": "🇪🇺",
|
|
75
|
-
"HKD": "🇭🇰",
|
|
76
|
-
"INR": "🇮🇳",
|
|
77
|
-
"PHP": "🇵🇭",
|
|
78
|
-
"USD": "🇺🇸",
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class SingleStore(type):
|
|
83
|
-
_store = None
|
|
84
|
-
|
|
85
|
-
async def __call__(cls):
|
|
86
|
-
if not cls._store:
|
|
87
|
-
cls._store = super(SingleStore, cls).__call__()
|
|
88
|
-
cls._store.coins = {k: v for k, v in await models.Coin.all().order_by("ticker").values_list("id", "ticker")}
|
|
89
|
-
curs = {c.id: c for c in await models.Cur.filter(ticker__in=flags.keys()).order_by("ticker")}
|
|
90
|
-
cls._store.curs = curs
|
|
91
|
-
cls._store.exs = {k: v for k, v in await models.Ex.all().values_list("id", "name")}
|
|
92
|
-
cls._store.pmcurs = {
|
|
93
|
-
k: v
|
|
94
|
-
for k, v in await models.Pmex.filter(pm__pmcurs__cur_id__in=cls._store.curs.keys())
|
|
95
|
-
.annotate(sname=Min("name"))
|
|
96
|
-
.group_by("pm__pmcurs__id")
|
|
97
|
-
.values_list("pm__pmcurs__id", "sname")
|
|
98
|
-
}
|
|
99
|
-
cls._store.coinexs = {
|
|
100
|
-
c.id: [ex.ex_id for ex in c.coinexs] for c in await models.Coin.all().prefetch_related("coinexs")
|
|
101
|
-
}
|
|
102
|
-
cls._store.curpms = {
|
|
103
|
-
cur_id: ids
|
|
104
|
-
for cur_id, ids in await models.Pmcur.filter(cur_id__in=curs.keys())
|
|
105
|
-
.annotate(ids=ArrayAgg("id"))
|
|
106
|
-
.group_by("cur_id")
|
|
107
|
-
.values_list("cur_id", "ids")
|
|
108
|
-
}
|
|
109
|
-
cls._store.curpms = {
|
|
110
|
-
cur_id: ids
|
|
111
|
-
for cur_id, ids in await models.Pmcur.filter(cur_id__in=curs.keys())
|
|
112
|
-
.annotate(ids=ArrayAgg("id"))
|
|
113
|
-
.group_by("cur_id")
|
|
114
|
-
.values_list("cur_id", "ids")
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return cls._store
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class Store:
|
|
121
|
-
class Global(metaclass=SingleStore):
|
|
122
|
-
coins: dict[int, str] # id:ticker
|
|
123
|
-
curs: dict[int, models.Cur] # id:Cur
|
|
124
|
-
exs: dict[int, str] # id:name
|
|
125
|
-
coinexs: dict[int, list[int]] # id:[ex_ids]
|
|
126
|
-
pmcurs: dict[int, str] # pmcur_id:name
|
|
127
|
-
curpms: dict[int, list[int]] # id:[pmcur_ids]
|
|
128
|
-
|
|
129
|
-
class Permanent:
|
|
130
|
-
msg_id: int = None
|
|
131
|
-
user: models.User = None
|
|
132
|
-
actors: dict[int, int] = None # key=ex_id
|
|
133
|
-
creds: dict[int, models.Cred] = None # key=cred_id
|
|
134
|
-
cur_creds: dict[int, list[int]] = None # pmcur_id:[cred_ids]
|
|
135
|
-
|
|
136
|
-
class Current:
|
|
137
|
-
is_target: bool = True
|
|
138
|
-
is_fiat: bool = None
|
|
139
|
-
msg_to_del: Message = None
|
|
140
|
-
|
|
141
|
-
class Payment:
|
|
142
|
-
t_cur_id: int = None
|
|
143
|
-
s_cur_id: int = None
|
|
144
|
-
t_coin_id: int = None
|
|
145
|
-
s_coin_id: int = None
|
|
146
|
-
t_pmcur_id: int = None
|
|
147
|
-
s_pmcur_id: int = None
|
|
148
|
-
t_ex_id: int = None
|
|
149
|
-
s_ex_id: int = None
|
|
150
|
-
amount: int | float = None
|
|
151
|
-
ppo: int = 1
|
|
152
|
-
addr_id: int = None
|
|
153
|
-
cred_dtl: str = None
|
|
154
|
-
cred_id: int = None
|
|
155
|
-
urg: int = 5
|
|
156
|
-
pr_id: int = None
|
|
157
|
-
|
|
158
|
-
glob: Global
|
|
159
|
-
perm: Permanent = Permanent()
|
|
160
|
-
pay: Payment = Payment()
|
|
161
|
-
curr: Current = Current()
|
|
162
|
-
|
|
163
|
-
|
|
164
60
|
async def fill_creds(person_id: int) -> tuple[dict[int, models.Cred], dict[int, list[int]]]:
|
|
165
61
|
cq = models.Cred.filter(person_id=person_id)
|
|
166
62
|
creds = {c.id: c for c in await cq}
|
|
@@ -207,73 +103,6 @@ async def edt(msg: Message, txt: str, rm: InlineKeyboardMarkup):
|
|
|
207
103
|
print(msg.bot.store.perm.msg_id, e)
|
|
208
104
|
|
|
209
105
|
|
|
210
|
-
async def xync_have_coin_amount(store: Store) -> bool:
|
|
211
|
-
assets = await models.Asset.filter(
|
|
212
|
-
addr__coin_id=store.pay.t_coin_id, addr__ex_id=store.pay.t_ex_id, addr__actor__user__role__in=Role.ADMIN
|
|
213
|
-
)
|
|
214
|
-
return store.pay.amount <= sum(a.free for a in assets)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
async def client_have_coin_amount(store: Store) -> bool:
|
|
218
|
-
assets = await models.Asset.filter(addr__coin_id=store.pay.t_coin_id, addr__actor_id__in=store.perm.actors.values())
|
|
219
|
-
return store.pay.amount <= sum(a.free for a in assets)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
async def need_ppo(store: Store):
|
|
223
|
-
cur_id = getattr(store.pay, ("t" if store.curr.is_target else "s") + "_cur_id")
|
|
224
|
-
usd_amount = store.pay.amount * store.glob.curs[cur_id].rate
|
|
225
|
-
if usd_amount < 50:
|
|
226
|
-
return 0
|
|
227
|
-
elif usd_amount > 100:
|
|
228
|
-
return 2
|
|
229
|
-
else:
|
|
230
|
-
return 1
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
async def client_target_repr(store: Store) -> tuple[models.Addr | models.Cred, str]:
|
|
234
|
-
if store.pay.t_ex_id:
|
|
235
|
-
addr_to = (
|
|
236
|
-
await models.Addr.filter(
|
|
237
|
-
actor__ex_id=store.pay.t_ex_id, coin_id=store.pay.t_coin_id, actor__user=store.perm.user
|
|
238
|
-
)
|
|
239
|
-
.prefetch_related("actor")
|
|
240
|
-
.first()
|
|
241
|
-
)
|
|
242
|
-
ex, coin = store.glob.exs[store.pay.s_ex_id], store.glob.coins[store.pay.s_coin_id]
|
|
243
|
-
if not addr_to:
|
|
244
|
-
logging.error(f"No {coin} addr in {ex} for user: {store.perm.user.username_id}")
|
|
245
|
-
return addr_to, f"{coin} на {ex} по id: `{addr_to.actor.exid}`"
|
|
246
|
-
# иначе: реквизиты для фиата
|
|
247
|
-
cur, pm = store.glob.curs[store.pay.t_cur_id], store.glob.pmcurs[store.pay.t_pmcur_id]
|
|
248
|
-
cred = store.perm.creds[store.pay.cred_id]
|
|
249
|
-
return cred, f"{cur.ticker} на {pm} по номеру: {cred.repr()}"
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
async def get_merch_target(store: Store) -> tuple[models.Addr | models.Cred, str]:
|
|
253
|
-
if store.pay.s_ex_id:
|
|
254
|
-
addr_in = (
|
|
255
|
-
await models.Addr.filter(
|
|
256
|
-
actor__ex_id=store.pay.s_ex_id, coin_id=store.pay.s_coin_id, actor__user__role__gte=Role.ADMIN
|
|
257
|
-
)
|
|
258
|
-
.prefetch_related("actor")
|
|
259
|
-
.first()
|
|
260
|
-
)
|
|
261
|
-
ex, coin = store.glob.exs[store.pay.s_ex_id], store.glob.coins[store.pay.s_coin_id]
|
|
262
|
-
if not addr_in:
|
|
263
|
-
logging.error(f"No {coin} addr in {ex}")
|
|
264
|
-
return addr_in, f"{coin} на {ex} по id: `{addr_in.actor.exid}`"
|
|
265
|
-
# иначе: реквизиты для фиатной оплаты
|
|
266
|
-
s_pmcur = await models.Pmcur.get(id=store.pay.s_pmcur_id).prefetch_related("pm__grp")
|
|
267
|
-
cred = await models.Cred.filter(
|
|
268
|
-
**({"pmcur__pm__grp": s_pmcur.pm.grp} if s_pmcur.pm.grp else {"pmcur_id": store.pay.s_pmcur_id}),
|
|
269
|
-
person__user__role__gte=Role.ADMIN,
|
|
270
|
-
).first() # todo: order by fiat.target-fiat.amount
|
|
271
|
-
cur, pm = store.glob.curs[store.pay.s_cur_id], store.glob.pmcurs[store.pay.s_pmcur_id]
|
|
272
|
-
if not cred:
|
|
273
|
-
logging.error(f"No {cur.ticker} cred for {pm}")
|
|
274
|
-
return cred, f"{cur.ticker} на {pm} по номеру: {cred.repr()}"
|
|
275
|
-
|
|
276
|
-
|
|
277
106
|
def fmt_sec(sec: int):
|
|
278
107
|
days = sec // (24 * 3600)
|
|
279
108
|
sec %= 24 * 3600
|
xync_bot/routers/pay/handler.py
CHANGED
|
@@ -1,88 +1,86 @@
|
|
|
1
1
|
from asyncio import gather
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
|
|
4
|
-
import PGram
|
|
5
4
|
from aiogram import Router, F
|
|
6
5
|
from aiogram.filters import Command
|
|
7
6
|
from aiogram.types import Message, CallbackQuery
|
|
8
7
|
from aiogram.fsm.context import FSMContext
|
|
9
|
-
from xync_bot.routers.pay.dep import fill_creds, fill_actors, dlt, ans
|
|
8
|
+
from xync_bot.routers.pay.dep import fill_creds, fill_actors, dlt, ans
|
|
10
9
|
from xync_schema import models
|
|
11
10
|
|
|
12
11
|
from xync_bot.routers.pay import cd, dep, window
|
|
12
|
+
from xync_bot.store import Store
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
pr = Router(name="pay")
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
@
|
|
18
|
-
async def h_start(msg: Message):
|
|
19
|
-
"""Step 1: Select target type"""
|
|
20
|
-
store: Store = msg.bot.store
|
|
17
|
+
@pr.message(Command("pay"))
|
|
18
|
+
async def h_start(msg: Message, store: Store):
|
|
19
|
+
"""Step 1: Select a target type"""
|
|
21
20
|
store.curr.is_target = True
|
|
22
|
-
await gather(window.type_select(msg), dlt(msg))
|
|
21
|
+
await gather(window.type_select(msg, store), dlt(msg))
|
|
23
22
|
store.perm.user = await models.User.get(username_id=msg.from_user.id)
|
|
24
23
|
store.perm.creds, store.perm.cur_creds = await fill_creds(store.perm.user.person_id)
|
|
25
24
|
store.perm.actors = await fill_actors(store.perm.user.person_id)
|
|
26
25
|
|
|
27
26
|
|
|
28
|
-
@
|
|
29
|
-
async def h_got_fiat_type(query: CallbackQuery,
|
|
27
|
+
@pr.callback_query(cd.MoneyType.filter(F.is_fiat))
|
|
28
|
+
async def h_got_fiat_type(query: CallbackQuery, store: Store):
|
|
30
29
|
"""Step 2f: Select cur"""
|
|
31
|
-
|
|
32
|
-
await gather(window.cur_select(query.message), ans(query, "Понял, фиат"))
|
|
30
|
+
store.curr.is_fiat = True
|
|
31
|
+
await gather(window.cur_select(query.message, store), ans(query, "Понял, фиат"))
|
|
33
32
|
|
|
34
33
|
|
|
35
|
-
@
|
|
36
|
-
async def h_got_crypto_type(query: CallbackQuery,
|
|
34
|
+
@pr.callback_query(cd.MoneyType.filter(F.is_fiat.__eq__(0)))
|
|
35
|
+
async def h_got_crypto_type(query: CallbackQuery, store: Store):
|
|
37
36
|
"""Step 2c: Select coin"""
|
|
38
|
-
|
|
39
|
-
await gather(window.coin_select(query.message), ans(query, "Понял, крипта"))
|
|
37
|
+
store.curr.is_fiat = False
|
|
38
|
+
await gather(window.coin_select(query.message, store), ans(query, "Понял, крипта"))
|
|
40
39
|
|
|
41
40
|
|
|
42
|
-
@
|
|
43
|
-
async def h_got_coin(query: CallbackQuery, callback_data: cd.Coin,
|
|
41
|
+
@pr.callback_query(cd.Coin.filter())
|
|
42
|
+
async def h_got_coin(query: CallbackQuery, callback_data: cd.Coin, store: Store):
|
|
44
43
|
"""Step 3c: Select target ex"""
|
|
45
|
-
setattr(
|
|
46
|
-
await gather(window.ex_select(query.message), ans(query, "Эта монета есть на следующих биржах"))
|
|
44
|
+
setattr(store.pay, ("t" if store.curr.is_target else "s") + "_coin_id", callback_data.id)
|
|
45
|
+
await gather(window.ex_select(query.message, store), ans(query, "Эта монета есть на следующих биржах"))
|
|
47
46
|
|
|
48
47
|
|
|
49
|
-
@
|
|
50
|
-
async def h_got_cur(query: CallbackQuery, callback_data: cd.Cur,
|
|
48
|
+
@pr.callback_query(cd.Cur.filter())
|
|
49
|
+
async def h_got_cur(query: CallbackQuery, callback_data: cd.Cur, store: Store):
|
|
51
50
|
"""Step 3f: Select target pm"""
|
|
52
|
-
setattr(
|
|
53
|
-
await gather(window.pm(query.message), ans(query, "Вот платежные системы доступные для этой валюты"))
|
|
51
|
+
setattr(store.pay, ("t" if store.curr.is_target else "s") + "_cur_id", callback_data.id)
|
|
52
|
+
await gather(window.pm(query.message, store), ans(query, "Вот платежные системы доступные для этой валюты"))
|
|
54
53
|
|
|
55
54
|
|
|
56
|
-
@
|
|
57
|
-
async def h_got_target_pm(query: CallbackQuery, callback_data: cd.Pm, state: FSMContext):
|
|
55
|
+
@pr.callback_query(cd.Pm.filter(F.is_target))
|
|
56
|
+
async def h_got_target_pm(query: CallbackQuery, callback_data: cd.Pm, state: FSMContext, store: Store):
|
|
58
57
|
"""Step 4f: Fill target cred.detail"""
|
|
59
|
-
|
|
58
|
+
store.pay.t_pmcur_id = callback_data.pmcur_id
|
|
60
59
|
await gather(
|
|
61
|
-
window.fill_cred_dtl(query.message),
|
|
60
|
+
window.fill_cred_dtl(query.message, store),
|
|
62
61
|
ans(query, "Теперь нужны реквизиты"),
|
|
63
62
|
state.set_state(dep.CredState.detail),
|
|
64
63
|
)
|
|
65
64
|
|
|
66
65
|
|
|
67
|
-
@
|
|
68
|
-
async def h_got_cred(query: CallbackQuery, callback_data: cd.Cred, state: FSMContext):
|
|
69
|
-
|
|
66
|
+
@pr.callback_query(cd.Cred.filter())
|
|
67
|
+
async def h_got_cred(query: CallbackQuery, callback_data: cd.Cred, state: FSMContext, store: Store):
|
|
68
|
+
store.pay.cred_id = callback_data.id
|
|
70
69
|
await gather(
|
|
71
|
-
window.amount(query.message), ans(query, "Теперь нужна сумма"), state.set_state(dep.PaymentState.amount)
|
|
70
|
+
window.amount(query.message, store), ans(query, "Теперь нужна сумма"), state.set_state(dep.PaymentState.amount)
|
|
72
71
|
)
|
|
73
72
|
|
|
74
73
|
|
|
75
|
-
@
|
|
76
|
-
async def h_got_cred_dtl(msg: Message, state: FSMContext):
|
|
74
|
+
@pr.message(dep.CredState.detail)
|
|
75
|
+
async def h_got_cred_dtl(msg: Message, state: FSMContext, store: Store):
|
|
77
76
|
"""Step 4.1f: Fill target cred.name"""
|
|
78
|
-
|
|
79
|
-
await gather(window.fill_cred_name(msg), dlt(msg), state.set_state(dep.CredState.name))
|
|
77
|
+
store.pay.cred_dtl = msg.text
|
|
78
|
+
await gather(window.fill_cred_name(msg, store), dlt(msg), state.set_state(dep.CredState.name))
|
|
80
79
|
|
|
81
80
|
|
|
82
|
-
@
|
|
83
|
-
async def h_got_cred_name(msg: Message, state: FSMContext):
|
|
81
|
+
@pr.message(dep.CredState.name)
|
|
82
|
+
async def h_got_cred_name(msg: Message, state: FSMContext, store: Store):
|
|
84
83
|
"""Step 5f: Save target cred"""
|
|
85
|
-
store: Store = msg.bot.store
|
|
86
84
|
cred, _ = await models.Cred.update_or_create(
|
|
87
85
|
{"name": msg.text},
|
|
88
86
|
detail=store.pay.cred_dtl,
|
|
@@ -91,30 +89,28 @@ async def h_got_cred_name(msg: Message, state: FSMContext):
|
|
|
91
89
|
)
|
|
92
90
|
store.pay.cred_id = cred.id
|
|
93
91
|
store.perm.creds[cred.id] = cred
|
|
94
|
-
await gather(window.amount(msg), dlt(msg), state.set_state(dep.PaymentState.amount))
|
|
92
|
+
await gather(window.amount(msg, store), dlt(msg), state.set_state(dep.PaymentState.amount))
|
|
95
93
|
|
|
96
94
|
|
|
97
|
-
@
|
|
98
|
-
async def h_got_ex(query: CallbackQuery, callback_data: cd.Ex, state: FSMContext):
|
|
95
|
+
@pr.callback_query(cd.Ex.filter())
|
|
96
|
+
async def h_got_ex(query: CallbackQuery, callback_data: cd.Ex, state: FSMContext, store: Store):
|
|
99
97
|
"""Step 4c: Save target"""
|
|
100
|
-
store: Store = query.message.bot.store
|
|
101
98
|
ist = store.curr.is_target
|
|
102
99
|
setattr(store.pay, ("t" if ist else "s") + "_ex_id", callback_data.id)
|
|
103
100
|
if ist:
|
|
104
|
-
await window.amount(query.message)
|
|
101
|
+
await window.amount(query.message, store)
|
|
105
102
|
actor_id = store.perm.actors[store.pay.t_ex_id]
|
|
106
103
|
addr = await models.Addr.get(coin_id=store.pay.t_coin_id, actor_id=actor_id)
|
|
107
104
|
store.pay.addr_id = addr.id
|
|
108
105
|
else:
|
|
109
|
-
await window.set_ppo(query.message)
|
|
106
|
+
await window.set_ppo(query.message, store)
|
|
110
107
|
await ans(query, f"Биржа {store.glob.exs[callback_data.id]} выбрана")
|
|
111
108
|
await state.set_state(dep.PaymentState.amount)
|
|
112
109
|
|
|
113
110
|
|
|
114
|
-
@
|
|
115
|
-
async def h_got_amount(msg: Message, state: FSMContext):
|
|
116
|
-
"""Step 6: Save target amount"""
|
|
117
|
-
store: Store = msg.bot.store
|
|
111
|
+
@pr.message(dep.PaymentState.amount)
|
|
112
|
+
async def h_got_amount(msg: Message, state: FSMContext, store: Store):
|
|
113
|
+
"""Step 6: Save a target amount"""
|
|
118
114
|
if not msg.text.isnumeric():
|
|
119
115
|
store.curr.msg_to_del = await msg.answer("Пожалуйста, введите корректное число")
|
|
120
116
|
return
|
|
@@ -123,34 +119,33 @@ async def h_got_amount(msg: Message, state: FSMContext):
|
|
|
123
119
|
store.pay.amount = float(msg.text)
|
|
124
120
|
"""Step 7: Select source type"""
|
|
125
121
|
store.curr.is_target = False
|
|
126
|
-
await gather((window.type_select if store.curr.is_fiat else window.cur_select)(msg), dlt(msg), state.clear())
|
|
122
|
+
await gather((window.type_select if store.curr.is_fiat else window.cur_select)(msg, store), dlt(msg), state.clear())
|
|
127
123
|
|
|
128
124
|
|
|
129
|
-
@
|
|
130
|
-
async def h_got_source_pm(query: CallbackQuery, callback_data: cd.Pm):
|
|
131
|
-
store: Store = query.message.bot.store
|
|
125
|
+
@pr.callback_query(cd.Pm.filter(F.is_target.__eq__(0)))
|
|
126
|
+
async def h_got_source_pm(query: CallbackQuery, callback_data: cd.Pm, store: Store):
|
|
132
127
|
store.pay.s_pmcur_id = callback_data.pmcur_id
|
|
133
128
|
await gather(
|
|
134
|
-
window.set_ppo(query.message),
|
|
129
|
+
window.set_ppo(query.message, store),
|
|
135
130
|
ans(query, store.glob.pmcurs[callback_data.pmcur_id]),
|
|
136
131
|
)
|
|
137
132
|
|
|
138
133
|
|
|
139
|
-
@
|
|
140
|
-
async def h_got_ppo(query: CallbackQuery, callback_data: cd.Ppo):
|
|
141
|
-
|
|
142
|
-
await gather(window.set_urgency(query.message), ans(query, str(callback_data.num)))
|
|
134
|
+
@pr.callback_query(cd.Ppo.filter())
|
|
135
|
+
async def h_got_ppo(query: CallbackQuery, callback_data: cd.Ppo, store: Store):
|
|
136
|
+
store.pay.ppo = callback_data.num
|
|
137
|
+
await gather(window.set_urgency(query.message, store), ans(query, str(callback_data.num)))
|
|
143
138
|
|
|
144
139
|
|
|
145
|
-
@
|
|
146
|
-
async def h_got_urgency(query: CallbackQuery, callback_data: cd.Time):
|
|
147
|
-
|
|
148
|
-
await window.create_payreq(query.message)
|
|
140
|
+
@pr.callback_query(cd.Time.filter())
|
|
141
|
+
async def h_got_urgency(query: CallbackQuery, callback_data: cd.Time, store: Store):
|
|
142
|
+
store.pay.urg = callback_data.minutes
|
|
143
|
+
await window.create_payreq(query.message, store)
|
|
149
144
|
await ans(query, f"Ok {callback_data.minutes} min.")
|
|
150
145
|
|
|
151
146
|
|
|
152
147
|
# ACTIONS
|
|
153
|
-
@
|
|
148
|
+
@pr.callback_query(cd.Action.filter(F.act.__eq__(cd.ActionType.received)))
|
|
154
149
|
async def payment_confirmed(query: CallbackQuery, state: FSMContext):
|
|
155
150
|
await ans(query, None)
|
|
156
151
|
payed_at = datetime.now()
|
|
@@ -164,7 +159,7 @@ async def payment_confirmed(query: CallbackQuery, state: FSMContext):
|
|
|
164
159
|
await window.success(query.message)
|
|
165
160
|
|
|
166
161
|
|
|
167
|
-
@
|
|
162
|
+
@pr.callback_query(cd.Action.filter(F.act.__eq__(cd.ActionType.not_received)))
|
|
168
163
|
async def no_payment(query: CallbackQuery, state: FSMContext):
|
|
169
164
|
await ans(query, None)
|
|
170
165
|
await state.update_data(timer_active=False)
|
|
@@ -174,80 +169,80 @@ async def no_payment(query: CallbackQuery, state: FSMContext):
|
|
|
174
169
|
await state.set_state(dep.Report.text)
|
|
175
170
|
|
|
176
171
|
|
|
177
|
-
@
|
|
172
|
+
@pr.message(dep.Report.text)
|
|
178
173
|
async def payment_not_specified(msg: Message, state: FSMContext):
|
|
179
174
|
await state.update_data(text=msg.text)
|
|
180
175
|
data = await state.get_data()
|
|
181
176
|
complaint_text = (
|
|
182
177
|
f"Жалоба на неполученный платеж:\n"
|
|
183
178
|
f"Пользователь: @{msg.from_user.username or msg.from_user.id}\n"
|
|
184
|
-
f"Детали платежа: {data[
|
|
179
|
+
f"Детали платежа: {data['text']}\n"
|
|
185
180
|
f"Время: {msg.date.strftime('%Y-%m-%d %H:%M:%S')}"
|
|
186
181
|
)
|
|
187
182
|
await msg.bot.send_message(chat_id="xyncpay", text=complaint_text)
|
|
188
183
|
|
|
189
184
|
|
|
190
185
|
# NAVIGATION
|
|
191
|
-
@
|
|
192
|
-
async def handle_home(query: CallbackQuery, state: FSMContext):
|
|
193
|
-
await gather(window.type_select(query.message), state.clear(), ans(query, "Создаем платеж заново"))
|
|
186
|
+
@pr.callback_query(cd.PayNav.filter(F.to.in_([cd.PayStep.t_type, cd.PayStep.s_type])))
|
|
187
|
+
async def handle_home(query: CallbackQuery, state: FSMContext, store: Store):
|
|
188
|
+
await gather(window.type_select(query.message, store), state.clear(), ans(query, "Создаем платеж заново"))
|
|
194
189
|
|
|
195
190
|
|
|
196
|
-
@
|
|
197
|
-
async def to_coin_select(query: CallbackQuery, state: FSMContext):
|
|
191
|
+
@pr.callback_query(cd.PayNav.filter(F.to.in_([cd.PayStep.t_coin, cd.PayStep.s_coin])))
|
|
192
|
+
async def to_coin_select(query: CallbackQuery, state: FSMContext, store: Store):
|
|
198
193
|
await ans(query, None)
|
|
199
194
|
is_target = await state.get_value("is_target")
|
|
200
195
|
pref = "t" if is_target else "s"
|
|
201
196
|
await state.update_data({pref + "_ex_id": None, pref + "_coin_id": None})
|
|
202
|
-
await window.coin_select(query.message)
|
|
197
|
+
await window.coin_select(query.message, store)
|
|
203
198
|
|
|
204
199
|
|
|
205
|
-
@
|
|
206
|
-
async def to_cur_select(query: CallbackQuery, state: FSMContext):
|
|
200
|
+
@pr.callback_query(cd.PayNav.filter(F.to.in_([cd.PayStep.t_cur, cd.PayStep.s_cur])))
|
|
201
|
+
async def to_cur_select(query: CallbackQuery, state: FSMContext, store: Store):
|
|
207
202
|
await ans(query, None)
|
|
208
203
|
is_target = await state.get_value("is_target")
|
|
209
204
|
pref = "t" if is_target else "s"
|
|
210
205
|
await state.update_data({pref + "_pmcur_id": None, pref + "_cur_id": None})
|
|
211
|
-
await window.cur_select(query.message)
|
|
206
|
+
await window.cur_select(query.message, store)
|
|
212
207
|
|
|
213
208
|
|
|
214
|
-
@
|
|
215
|
-
async def to_pm_select(query: CallbackQuery,
|
|
209
|
+
@pr.callback_query(cd.PayNav.filter(F.to.in_([cd.PayStep.t_pm, cd.PayStep.s_pm])))
|
|
210
|
+
async def to_pm_select(query: CallbackQuery, store: Store):
|
|
216
211
|
await ans(query, None)
|
|
217
|
-
await window.pm(query.message)
|
|
212
|
+
await window.pm(query.message, store)
|
|
218
213
|
|
|
219
214
|
|
|
220
|
-
@
|
|
221
|
-
async def back_to_cred_detail(query: CallbackQuery, state: FSMContext):
|
|
215
|
+
@pr.callback_query(cd.PayNav.filter(F.to.__eq__(cd.PayStep.t_cred_dtl)))
|
|
216
|
+
async def back_to_cred_detail(query: CallbackQuery, state: FSMContext, store: Store):
|
|
222
217
|
await ans(query, None)
|
|
223
218
|
await state.update_data(detail=None)
|
|
224
|
-
await window.fill_cred_dtl(query.message)
|
|
219
|
+
await window.fill_cred_dtl(query.message, store)
|
|
225
220
|
|
|
226
221
|
|
|
227
|
-
@
|
|
228
|
-
async def back_to_cred_name(query: CallbackQuery, state: FSMContext):
|
|
222
|
+
@pr.callback_query(cd.PayNav.filter(F.to.__eq__(cd.PayStep.t_cred_name)))
|
|
223
|
+
async def back_to_cred_name(query: CallbackQuery, state: FSMContext, store: Store):
|
|
229
224
|
await ans(query, None)
|
|
230
225
|
await state.update_data(name=None)
|
|
231
|
-
await window.fill_cred_name(query.message)
|
|
226
|
+
await window.fill_cred_name(query.message, store)
|
|
232
227
|
|
|
233
228
|
|
|
234
|
-
@
|
|
235
|
-
async def back_to_ex_select(query: CallbackQuery, state: FSMContext):
|
|
229
|
+
@pr.callback_query(cd.PayNav.filter(F.to.in_([cd.PayStep.t_ex, cd.PayStep.s_ex])))
|
|
230
|
+
async def back_to_ex_select(query: CallbackQuery, state: FSMContext, store: Store):
|
|
236
231
|
await ans(query, None)
|
|
237
232
|
await state.update_data({("t" if await state.get_value("is_target") else "s") + "ex_id": None})
|
|
238
|
-
await window.ex_select(query.message)
|
|
233
|
+
await window.ex_select(query.message, store)
|
|
239
234
|
|
|
240
235
|
|
|
241
|
-
@
|
|
242
|
-
async def back_to_amount(query: CallbackQuery, state: FSMContext):
|
|
236
|
+
@pr.callback_query(cd.PayNav.filter(F.to.__eq__(cd.PayStep.t_amount)))
|
|
237
|
+
async def back_to_amount(query: CallbackQuery, state: FSMContext, store: Store):
|
|
243
238
|
await ans(query, None)
|
|
244
239
|
await state.update_data(amount=None)
|
|
245
|
-
await window.amount(query.message)
|
|
240
|
+
await window.amount(query.message, store)
|
|
246
241
|
await state.set_state(dep.PaymentState.amount)
|
|
247
242
|
|
|
248
243
|
|
|
249
|
-
@
|
|
250
|
-
async def back_to_payment(query: CallbackQuery, state: FSMContext):
|
|
244
|
+
@pr.callback_query(cd.PayNav.filter(F.to.in_([cd.PayStep.t_pm])))
|
|
245
|
+
async def back_to_payment(query: CallbackQuery, state: FSMContext, store: Store):
|
|
251
246
|
await ans(query, None)
|
|
252
247
|
await state.update_data(payment=None)
|
|
253
|
-
await window.pm(query.message)
|
|
248
|
+
await window.pm(query.message, store)
|
xync_bot/routers/pay/window.py
CHANGED
|
@@ -6,22 +6,13 @@ from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
|
|
|
6
6
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
|
7
7
|
from xync_schema import models
|
|
8
8
|
|
|
9
|
-
from xync_bot.routers.pay.dep import
|
|
10
|
-
edt,
|
|
11
|
-
need_ppo,
|
|
12
|
-
Store,
|
|
13
|
-
get_merch_target,
|
|
14
|
-
fmt_sec,
|
|
15
|
-
client_have_coin_amount,
|
|
16
|
-
client_target_repr,
|
|
17
|
-
)
|
|
18
|
-
|
|
9
|
+
from xync_bot.routers.pay.dep import edt, fmt_sec
|
|
19
10
|
from xync_bot.routers.pay import cd, dep
|
|
11
|
+
from xync_bot.store import Store
|
|
20
12
|
|
|
21
13
|
|
|
22
|
-
async def type_select(msg: Message):
|
|
14
|
+
async def type_select(msg: Message, store: Store):
|
|
23
15
|
"""Step 1: Select type"""
|
|
24
|
-
store: Store = msg.bot.store
|
|
25
16
|
ist: bool = store.curr.is_target
|
|
26
17
|
rm = InlineKeyboardMarkup(
|
|
27
18
|
inline_keyboard=[
|
|
@@ -52,11 +43,11 @@ async def type_select(msg: Message):
|
|
|
52
43
|
store.perm.msg_id = msg.message_id
|
|
53
44
|
|
|
54
45
|
|
|
55
|
-
async def cur_select(msg: Message):
|
|
46
|
+
async def cur_select(msg: Message, store: Store):
|
|
56
47
|
"""Common using cur func"""
|
|
57
48
|
builder = InlineKeyboardBuilder()
|
|
58
|
-
ist: bool =
|
|
59
|
-
for cur_id, cur in
|
|
49
|
+
ist: bool = store.curr.is_target
|
|
50
|
+
for cur_id, cur in store.glob.curs.items():
|
|
60
51
|
builder.button(text=cur.ticker + dep.flags[cur.ticker], callback_data=cd.Cur(id=cur_id, is_target=ist))
|
|
61
52
|
builder.button(text="Назад к выбору типа", callback_data=cd.PayNav(to=cd.PayStep.t_type))
|
|
62
53
|
builder.adjust(3, 3, 3, 3, 3, 1)
|
|
@@ -64,10 +55,9 @@ async def cur_select(msg: Message):
|
|
|
64
55
|
await edt(msg, "Выбери валюту котор" + sfx, builder.as_markup())
|
|
65
56
|
|
|
66
57
|
|
|
67
|
-
async def coin_select(msg: Message):
|
|
58
|
+
async def coin_select(msg: Message, store: Store):
|
|
68
59
|
"""Common using coin func"""
|
|
69
60
|
builder = InlineKeyboardBuilder()
|
|
70
|
-
store: Store = msg.bot.store
|
|
71
61
|
for coin_id, ticker in store.glob.coins.items():
|
|
72
62
|
builder.button(text=ticker, callback_data=cd.Coin(id=coin_id, is_target=store.curr.is_target))
|
|
73
63
|
builder.button(
|
|
@@ -79,8 +69,7 @@ async def coin_select(msg: Message):
|
|
|
79
69
|
await msg.edit_text("Выберите монету котор" + sfx, reply_markup=builder.as_markup())
|
|
80
70
|
|
|
81
71
|
|
|
82
|
-
async def ex_select(msg: Message):
|
|
83
|
-
store: Store = msg.bot.store
|
|
72
|
+
async def ex_select(msg: Message, store: Store):
|
|
84
73
|
ist = store.curr.is_target
|
|
85
74
|
coin_id = getattr(store.pay, ("t" if ist else "s") + "_coin_id")
|
|
86
75
|
builder = InlineKeyboardBuilder()
|
|
@@ -95,8 +84,7 @@ async def ex_select(msg: Message):
|
|
|
95
84
|
await msg.edit_text("На какую биржу?" if ist else "С какой биржи?", reply_markup=keyboard)
|
|
96
85
|
|
|
97
86
|
|
|
98
|
-
async def pm(msg: Message):
|
|
99
|
-
store: Store = msg.bot.store
|
|
87
|
+
async def pm(msg: Message, store: Store):
|
|
100
88
|
ist = store.curr.is_target
|
|
101
89
|
cur_id = getattr(store.pay, ("t" if ist else "s") + "_cur_id")
|
|
102
90
|
builder = InlineKeyboardBuilder()
|
|
@@ -111,9 +99,8 @@ async def pm(msg: Message):
|
|
|
111
99
|
await msg.edit_text("На какую платежную систему?" if ist else "C какой платежной системы?", reply_markup=keyboard)
|
|
112
100
|
|
|
113
101
|
|
|
114
|
-
async def fill_cred_dtl(msg: Message):
|
|
102
|
+
async def fill_cred_dtl(msg: Message, store: Store):
|
|
115
103
|
builder = InlineKeyboardBuilder()
|
|
116
|
-
store: Store = msg.bot.store
|
|
117
104
|
txt = "В"
|
|
118
105
|
if cred_ids := store.perm.cur_creds.get(store.pay.t_pmcur_id):
|
|
119
106
|
for cred_id in cred_ids:
|
|
@@ -130,22 +117,20 @@ async def fill_cred_dtl(msg: Message):
|
|
|
130
117
|
)
|
|
131
118
|
|
|
132
119
|
|
|
133
|
-
async def fill_cred_name(msg: Message):
|
|
120
|
+
async def fill_cred_name(msg: Message, store: Store):
|
|
134
121
|
builder = InlineKeyboardBuilder()
|
|
135
122
|
builder.button(text="Назад к вводу реквизитов", callback_data=cd.PayNav(to=cd.PayStep.t_cred_dtl))
|
|
136
123
|
builder.button(text="Домой", callback_data=cd.PayNav(to=cd.PayStep.t_type))
|
|
137
124
|
builder.adjust(2)
|
|
138
|
-
store: Store = msg.bot.store
|
|
139
125
|
cur = store.glob.curs[store.pay.t_cur_id]
|
|
140
126
|
payment = store.glob.pmcurs[store.pay.t_pmcur_id]
|
|
141
127
|
detail = store.pay.cred_dtl
|
|
142
128
|
await edt(msg, f"{cur.ticker}:{payment}:{detail}: Введите имя получателя", builder.as_markup())
|
|
143
129
|
|
|
144
130
|
|
|
145
|
-
async def amount(msg: Message):
|
|
131
|
+
async def amount(msg: Message, store: Store):
|
|
146
132
|
"""Step 5: Filling target amount"""
|
|
147
133
|
builder = InlineKeyboardBuilder()
|
|
148
|
-
store: Store = msg.bot.store
|
|
149
134
|
if store.curr.is_fiat:
|
|
150
135
|
cur_coin = store.glob.curs[store.pay.t_cur_id].ticker
|
|
151
136
|
builder.button(text="Назад к вводу имени", callback_data=cd.PayNav(to=cd.PayStep.t_cred_name))
|
|
@@ -161,10 +146,9 @@ async def amount(msg: Message):
|
|
|
161
146
|
await edt(msg, f"Введите нужную сумму {cur_coin} для {t_name}", builder.as_markup())
|
|
162
147
|
|
|
163
148
|
|
|
164
|
-
async def set_ppo(msg: Message):
|
|
165
|
-
store: Store = msg.bot.store
|
|
149
|
+
async def set_ppo(msg: Message, store: Store):
|
|
166
150
|
ist = store.curr.is_target
|
|
167
|
-
if nppo := await need_ppo(
|
|
151
|
+
if nppo := await store.need_ppo():
|
|
168
152
|
builder = InlineKeyboardBuilder()
|
|
169
153
|
builder.button(text="Нет", callback_data=cd.Ppo(num=1, is_target=ist)).button(
|
|
170
154
|
text="Да", callback_data=cd.Ppo(num=2, is_target=ist)
|
|
@@ -180,9 +164,8 @@ async def set_ppo(msg: Message):
|
|
|
180
164
|
await set_urgency(msg)
|
|
181
165
|
|
|
182
166
|
|
|
183
|
-
async def set_urgency(msg: Message):
|
|
184
|
-
store
|
|
185
|
-
if not store.curr.is_fiat or await client_have_coin_amount(store):
|
|
167
|
+
async def set_urgency(msg: Message, store: Store):
|
|
168
|
+
if not store.curr.is_fiat or await store.client_have_coin_amount():
|
|
186
169
|
return await create_payreq(msg) # next
|
|
187
170
|
builder = InlineKeyboardBuilder()
|
|
188
171
|
(
|
|
@@ -198,8 +181,7 @@ async def set_urgency(msg: Message):
|
|
|
198
181
|
return await edt(msg, "Сколько можешь ждать?", builder.as_markup())
|
|
199
182
|
|
|
200
183
|
|
|
201
|
-
async def create_payreq(msg: Message):
|
|
202
|
-
store: Store = msg.bot.store
|
|
184
|
+
async def create_payreq(msg: Message, store: Store):
|
|
203
185
|
pay_req, _ = await models.PayReq.update_or_create(
|
|
204
186
|
{"pay_until": datetime.now() + timedelta(minutes=store.pay.urg)},
|
|
205
187
|
amount=store.pay.amount,
|
|
@@ -209,8 +191,8 @@ async def create_payreq(msg: Message):
|
|
|
209
191
|
user=store.perm.user,
|
|
210
192
|
)
|
|
211
193
|
store.pay.pr_id = pay_req.id
|
|
212
|
-
inp, txt = await get_merch_target(
|
|
213
|
-
ccred, ctxt = await client_target_repr(
|
|
194
|
+
inp, txt = await store.get_merch_target()
|
|
195
|
+
ccred, ctxt = await store.client_target_repr()
|
|
214
196
|
txt += f"\nИ получите {store.pay.amount} {ctxt} в течение {fmt_sec(store.pay.urg * 60)}"
|
|
215
197
|
if store.pay.ppo > 1:
|
|
216
198
|
txt += f" максимум {store.pay.ppo} платежами"
|
xync_bot/shared.py
CHANGED
|
@@ -3,3 +3,22 @@ from aiogram.filters.callback_data import CallbackData
|
|
|
3
3
|
|
|
4
4
|
class NavCallbackData(CallbackData, prefix="nav"): # navigate menu
|
|
5
5
|
to: str
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
flags = {
|
|
9
|
+
"RUB": "🇷🇺",
|
|
10
|
+
"THB": "🇹🇭",
|
|
11
|
+
"IDR": "🇮🇩",
|
|
12
|
+
"TRY": "🇹🇷",
|
|
13
|
+
"GEL": "🇬🇪",
|
|
14
|
+
"VND": "🇻🇳",
|
|
15
|
+
"AED": "🇦🇪",
|
|
16
|
+
"AMD": "🇦🇲",
|
|
17
|
+
"AZN": "🇦🇿",
|
|
18
|
+
"CNY": "🇨🇳",
|
|
19
|
+
"EUR": "🇪🇺",
|
|
20
|
+
"HKD": "🇭🇰",
|
|
21
|
+
"INR": "🇮🇳",
|
|
22
|
+
"PHP": "🇵🇭",
|
|
23
|
+
"USD": "🇺🇸",
|
|
24
|
+
}
|
xync_bot/store.py
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from aiogram.types import Message
|
|
3
|
+
from tortoise.functions import Min
|
|
4
|
+
from x_model.func import ArrayAgg
|
|
5
|
+
from x_auth.enums import Role
|
|
6
|
+
from xync_schema.models import Addr, Asset, Cred, Coin, Pmcur, Cur, User, Ex, Pmex
|
|
7
|
+
|
|
8
|
+
from xync_bot.shared import flags
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SingleStore(type):
|
|
12
|
+
_store = None
|
|
13
|
+
|
|
14
|
+
async def __call__(cls):
|
|
15
|
+
if not cls._store:
|
|
16
|
+
cls._store = super(SingleStore, cls).__call__()
|
|
17
|
+
cls._store.coins = {k: v for k, v in await Coin.all().order_by("ticker").values_list("id", "ticker")}
|
|
18
|
+
curs = {c.id: c for c in await Cur.filter(ticker__in=flags.keys()).order_by("ticker")}
|
|
19
|
+
cls._store.curs = curs
|
|
20
|
+
cls._store.exs = {k: v for k, v in await Ex.all().values_list("id", "name")}
|
|
21
|
+
cls._store.pmcurs = {
|
|
22
|
+
k: v
|
|
23
|
+
for k, v in await Pmex.filter(pm__pmcurs__cur_id__in=cls._store.curs.keys())
|
|
24
|
+
.annotate(sname=Min("name"))
|
|
25
|
+
.group_by("pm__pmcurs__id")
|
|
26
|
+
.values_list("pm__pmcurs__id", "sname")
|
|
27
|
+
}
|
|
28
|
+
cls._store.coinexs = {
|
|
29
|
+
c.id: [ex.ex_id for ex in c.coinexs] for c in await Coin.all().prefetch_related("coinexs")
|
|
30
|
+
}
|
|
31
|
+
cls._store.curpms = {
|
|
32
|
+
cur_id: ids
|
|
33
|
+
for cur_id, ids in await Pmcur.filter(cur_id__in=curs.keys())
|
|
34
|
+
.annotate(ids=ArrayAgg("id"))
|
|
35
|
+
.group_by("cur_id")
|
|
36
|
+
.values_list("cur_id", "ids")
|
|
37
|
+
}
|
|
38
|
+
cls._store.curpms = {
|
|
39
|
+
cur_id: ids
|
|
40
|
+
for cur_id, ids in await Pmcur.filter(cur_id__in=curs.keys())
|
|
41
|
+
.annotate(ids=ArrayAgg("id"))
|
|
42
|
+
.group_by("cur_id")
|
|
43
|
+
.values_list("cur_id", "ids")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return cls._store
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class Store:
|
|
50
|
+
class Global(metaclass=SingleStore):
|
|
51
|
+
coins: dict[int, str] # id:ticker
|
|
52
|
+
curs: dict[int, Cur] # id:Cur
|
|
53
|
+
exs: dict[int, str] # id:name
|
|
54
|
+
coinexs: dict[int, list[int]] # id:[ex_ids]
|
|
55
|
+
pmcurs: dict[int, str] # pmcur_id:name
|
|
56
|
+
curpms: dict[int, list[int]] # id:[pmcur_ids]
|
|
57
|
+
|
|
58
|
+
class Personal:
|
|
59
|
+
class Current:
|
|
60
|
+
is_target: bool = True
|
|
61
|
+
is_fiat: bool = None
|
|
62
|
+
msg_to_del: Message = None
|
|
63
|
+
|
|
64
|
+
msg_id: int = None
|
|
65
|
+
user: User = None
|
|
66
|
+
actors: dict[int, int] = None # key=ex_id
|
|
67
|
+
creds: dict[int, Cred] = None # key=cred_id
|
|
68
|
+
cur_creds: dict[int, list[int]] = None # pmcur_id:[cred_ids]
|
|
69
|
+
|
|
70
|
+
def __init__(self, order_id: int):
|
|
71
|
+
self.order_id = order_id
|
|
72
|
+
|
|
73
|
+
curr: Current = Current()
|
|
74
|
+
|
|
75
|
+
class PayReq:
|
|
76
|
+
t_cur_id: int = None
|
|
77
|
+
s_cur_id: int = None
|
|
78
|
+
t_coin_id: int = None
|
|
79
|
+
s_coin_id: int = None
|
|
80
|
+
t_pmcur_id: int = None
|
|
81
|
+
s_pmcur_id: int = None
|
|
82
|
+
t_ex_id: int = None
|
|
83
|
+
s_ex_id: int = None
|
|
84
|
+
amount: int | float = None
|
|
85
|
+
ppo: int = 1
|
|
86
|
+
addr_id: int = None
|
|
87
|
+
cred_dtl: str = None
|
|
88
|
+
cred_id: int = None
|
|
89
|
+
urg: int = 5
|
|
90
|
+
pr_id: int = None
|
|
91
|
+
|
|
92
|
+
def __init__(self, uid: int):
|
|
93
|
+
self.uid = uid
|
|
94
|
+
|
|
95
|
+
async def xync_have_coin_amount(self) -> bool:
|
|
96
|
+
assets = await Asset.filter(
|
|
97
|
+
addr__coin_id=self.t_coin_id, addr__ex_id=self.t_ex_id, addr__actor__user__role__in=Role.ADMIN
|
|
98
|
+
)
|
|
99
|
+
return self.amount <= sum(a.free for a in assets)
|
|
100
|
+
|
|
101
|
+
async def client_have_coin_amount(self) -> bool:
|
|
102
|
+
assets = await Asset.filter(addr__coin_id=self.t_coin_id, addr__actor_id__in=self.perm.actors.values())
|
|
103
|
+
return self.amount <= sum(a.free for a in assets)
|
|
104
|
+
|
|
105
|
+
async def need_ppo(self):
|
|
106
|
+
cur_id = getattr(self, ("t" if self.curr.is_target else "s") + "_cur_id")
|
|
107
|
+
usd_amount = self.amount * self.glob.curs[cur_id].rate
|
|
108
|
+
if usd_amount < 50:
|
|
109
|
+
return 0
|
|
110
|
+
elif usd_amount > 100:
|
|
111
|
+
return 2
|
|
112
|
+
else:
|
|
113
|
+
return 1
|
|
114
|
+
|
|
115
|
+
async def client_target_repr(self) -> tuple[Addr | Cred, str]:
|
|
116
|
+
if self.t_ex_id:
|
|
117
|
+
addr_to = (
|
|
118
|
+
await Addr.filter(actor__ex_id=self.t_ex_id, coin_id=self.t_coin_id, actor__user=self.perm.user)
|
|
119
|
+
.prefetch_related("actor")
|
|
120
|
+
.first()
|
|
121
|
+
)
|
|
122
|
+
ex, coin = self.glob.exs[self.s_ex_id], self.glob.coins[self.s_coin_id]
|
|
123
|
+
if not addr_to:
|
|
124
|
+
logging.error(f"No {coin} addr in {ex} for user: {self.perm.user.username_id}")
|
|
125
|
+
return addr_to, f"{coin} на {ex} по id: `{addr_to.actor.exid}`"
|
|
126
|
+
# иначе: реквизиты для фиата
|
|
127
|
+
cur, pm = self.glob.curs[self.t_cur_id], self.glob.pmcurs[self.t_pmcur_id]
|
|
128
|
+
cred = self.perm.creds[self.cred_id]
|
|
129
|
+
return cred, f"{cur.ticker} на {pm} по номеру: {cred.repr()}"
|
|
130
|
+
|
|
131
|
+
async def get_merch_target(self) -> tuple[Addr | Cred, str]:
|
|
132
|
+
if self.s_ex_id:
|
|
133
|
+
addr_in = (
|
|
134
|
+
await Addr.filter(
|
|
135
|
+
actor__ex_id=self.s_ex_id, coin_id=self.s_coin_id, actor__user__role__gte=Role.ADMIN
|
|
136
|
+
)
|
|
137
|
+
.prefetch_related("actor")
|
|
138
|
+
.first()
|
|
139
|
+
)
|
|
140
|
+
ex, coin = self.glob.exs[self.s_ex_id], self.glob.coins[self.s_coin_id]
|
|
141
|
+
if not addr_in:
|
|
142
|
+
logging.error(f"No {coin} addr in {ex}")
|
|
143
|
+
return addr_in, f"{coin} на {ex} по id: `{addr_in.actor.exid}`"
|
|
144
|
+
# иначе: реквизиты для фиатной оплаты
|
|
145
|
+
s_pmcur = await Pmcur.get(id=self.s_pmcur_id).prefetch_related("pm__grp")
|
|
146
|
+
cred = await Cred.filter(
|
|
147
|
+
**({"pmcur__pm__grp": s_pmcur.pm.grp} if s_pmcur.pm.grp else {"pmcur_id": self.s_pmcur_id}),
|
|
148
|
+
person__user__role__gte=Role.ADMIN,
|
|
149
|
+
).first() # todo: payreq by fiat.target-fiat.amount
|
|
150
|
+
cur, pm = self.glob.curs[self.s_cur_id], self.glob.pmcurs[self.s_pmcur_id]
|
|
151
|
+
if not cred:
|
|
152
|
+
logging.error(f"No {cur.ticker} cred for {pm}")
|
|
153
|
+
return cred, f"{cur.ticker} на {pm} по номеру: {cred.repr()}"
|
|
154
|
+
|
|
155
|
+
glob: Global
|
|
156
|
+
pers: dict[int, Personal] = {}
|
|
157
|
+
payreq: dict[int, PayReq] = {}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
xync_bot/__main__.py,sha256=OvUQ9A4YZajOgs8CoRhjFzXQnZvNnH8l8MV_brZCOpo,991
|
|
2
|
+
xync_bot/loader.py,sha256=4ZeR-yVMoOmswdLS0UEBG19K7JVcuvH6WpP-_0yAK3I,573
|
|
3
|
+
xync_bot/shared.py,sha256=PPzvt1ewowCInKE1bk2CWHPjnrV2eQJzKxgyxe3h7vk,496
|
|
4
|
+
xync_bot/store.py,sha256=NhUMl0Zr4PKiukQKH8HDA6KRjghjtIcDioNLZArmdhg,6385
|
|
5
|
+
xync_bot/typs.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
xync_bot/routers/__init__.py,sha256=30W7PmD3stkRebGh5J-9CJIlY5P-Ixrtlxb_W9usSo4,1083
|
|
7
|
+
xync_bot/routers/order.py,sha256=ZKWDLyiWrXzcR-aHKLBTBCACwp-P0Vvnr22T-EuLHaM,274
|
|
8
|
+
xync_bot/routers/photo.py,sha256=aq6ImIOoZQYTW-lEy26qjgj5TYAuk4bQjgiCv64mPJs,1203
|
|
9
|
+
xync_bot/routers/vpn.py,sha256=qKK55UrjEZeDvu7ljWXNUFBFgXTPTIEaCT2OAmKWky4,2219
|
|
10
|
+
xync_bot/routers/xicon.png,sha256=O57_kvzhVcCXSoGYZ61m0dW9pizY6gxR8Yj5aeCP0RQ,429283
|
|
11
|
+
xync_bot/routers/cond/__init__.py,sha256=AUP_V1TGUIa8GFTC_V2LF5YYEBrXdfrSm_O8ew5sXU8,4214
|
|
12
|
+
xync_bot/routers/cond/func.py,sha256=m0NWDKunbqDJQmhv_5UnpjxjRzn78GFG94ThOFLVlQo,4720
|
|
13
|
+
xync_bot/routers/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
xync_bot/routers/main/handler.py,sha256=IDvHPcj1Z-MpL6DSlgibxxCZmaaVN3OhByIZZyrK2FM,8758
|
|
15
|
+
xync_bot/routers/pay/cd.py,sha256=yu5U0j8f1RncfagiuycCeUFWwZtLmbT-Mx8G8whfdg8,927
|
|
16
|
+
xync_bot/routers/pay/dep.py,sha256=WvIkLsMHsy6Z8qeQYB0uvHi9xgJ-pCjRad0dSp_GQS0,3956
|
|
17
|
+
xync_bot/routers/pay/handler.py,sha256=7kb3ubkvolJPM9Sd51pnw9tlR9QxblNrIJN4QScgZQ8,10341
|
|
18
|
+
xync_bot/routers/pay/window.py,sha256=HQWDDvknMMbTEt5Zu7cXsr6SaDnFlV43xZU4CF4S2Ps,10987
|
|
19
|
+
xync_bot-0.3.25.dev1.dist-info/METADATA,sha256=QgjczDpDF437LM-dzo3MlstW0Fx6e0264dSQNYWF-yE,751
|
|
20
|
+
xync_bot-0.3.25.dev1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
21
|
+
xync_bot-0.3.25.dev1.dist-info/top_level.txt,sha256=O2IjMc1ryAf0rwIXWohSNT5Kzcs9johgKRDz8lCC0rs,9
|
|
22
|
+
xync_bot-0.3.25.dev1.dist-info/RECORD,,
|
xync_bot/__init__.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from asyncio import run
|
|
3
|
-
|
|
4
|
-
from PGram import Bot
|
|
5
|
-
from aiogram.client.default import DefaultBotProperties
|
|
6
|
-
from x_model import init_db
|
|
7
|
-
|
|
8
|
-
from xync_bot.routers.cond import cr as cr
|
|
9
|
-
from xync_bot.routers.pay.dep import Store
|
|
10
|
-
|
|
11
|
-
# from xync_bot.routers.main import mr
|
|
12
|
-
from xync_bot.routers.pay.handler import pay as pay
|
|
13
|
-
|
|
14
|
-
if __name__ == "__main__":
|
|
15
|
-
from xync_bot.loader import TOKEN, TORM
|
|
16
|
-
|
|
17
|
-
logging.basicConfig(level=logging.INFO)
|
|
18
|
-
|
|
19
|
-
async def main() -> None:
|
|
20
|
-
cn = await init_db(TORM)
|
|
21
|
-
store = Store()
|
|
22
|
-
store.glob = await Store.Global()
|
|
23
|
-
bot = Bot(TOKEN, [pay], cn, default=DefaultBotProperties(parse_mode="HTML"), store=store)
|
|
24
|
-
await bot.start()
|
|
25
|
-
|
|
26
|
-
run(main())
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
xync_bot/__init__.py,sha256=NSwTrA6NoOWDQK1L7M4qFcbLcCj1od8pgFM-arNv0AQ,713
|
|
2
|
-
xync_bot/loader.py,sha256=4ZeR-yVMoOmswdLS0UEBG19K7JVcuvH6WpP-_0yAK3I,573
|
|
3
|
-
xync_bot/shared.py,sha256=MlKkTrsT29l7fF6-qAN9FO14cSuXuOuYxbNY5F4S2w4,137
|
|
4
|
-
xync_bot/typs.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
xync_bot/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
xync_bot/routers/main.py,sha256=FumWa48ORhV77Df6NbEosHfgmFIe_Y2ci6IkJCvU4Zs,9535
|
|
7
|
-
xync_bot/routers/order.py,sha256=ZKWDLyiWrXzcR-aHKLBTBCACwp-P0Vvnr22T-EuLHaM,274
|
|
8
|
-
xync_bot/routers/photo.py,sha256=aq6ImIOoZQYTW-lEy26qjgj5TYAuk4bQjgiCv64mPJs,1203
|
|
9
|
-
xync_bot/routers/vpn.py,sha256=qKK55UrjEZeDvu7ljWXNUFBFgXTPTIEaCT2OAmKWky4,2219
|
|
10
|
-
xync_bot/routers/xicon.png,sha256=O57_kvzhVcCXSoGYZ61m0dW9pizY6gxR8Yj5aeCP0RQ,429283
|
|
11
|
-
xync_bot/routers/cond/__init__.py,sha256=It4djVO8AxXL1I76buRz8yYF12dsjXaa4WNtPdb7CFc,4333
|
|
12
|
-
xync_bot/routers/cond/func.py,sha256=m0NWDKunbqDJQmhv_5UnpjxjRzn78GFG94ThOFLVlQo,4720
|
|
13
|
-
xync_bot/routers/pay/cd.py,sha256=yu5U0j8f1RncfagiuycCeUFWwZtLmbT-Mx8G8whfdg8,927
|
|
14
|
-
xync_bot/routers/pay/dep.py,sha256=u1RCKl3gultJ509W9gbl-ixCCS6B9lgkrDYa_I8Uu2g,10249
|
|
15
|
-
xync_bot/routers/pay/handler.py,sha256=aT_Oc_q-h_dX3pU2KhmX7PdRZUeLIuIpagTbBY45GJs,10207
|
|
16
|
-
xync_bot/routers/pay/window.py,sha256=-scDDorW2qy9K1gNuGHZVBTaNIdd-7Hh64ZHCFizNVs,11256
|
|
17
|
-
xync_bot-0.3.24.dev12.dist-info/METADATA,sha256=MhjS0p9XZSsZJBIwSCYrrr-h8oWNXx2a_0cctuB9FF8,752
|
|
18
|
-
xync_bot-0.3.24.dev12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
19
|
-
xync_bot-0.3.24.dev12.dist-info/top_level.txt,sha256=O2IjMc1ryAf0rwIXWohSNT5Kzcs9johgKRDz8lCC0rs,9
|
|
20
|
-
xync_bot-0.3.24.dev12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|