xync-bot 0.3.24.dev12__py3-none-any.whl → 0.3.26.dev0__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.

@@ -0,0 +1,117 @@
1
+ from aiogram import Router
2
+ from aiogram.fsm.context import FSMContext
3
+ from aiogram.fsm.state import StatesGroup, State
4
+ from aiogram.types import Message
5
+ from aiogram.utils.keyboard import InlineKeyboardBuilder
6
+ from aiogram.filters import Command
7
+ from xync_schema import models
8
+ from aiogram.filters.callback_data import CallbackData
9
+ from aiogram import types
10
+
11
+ sd = Router()
12
+
13
+
14
+ class SendStates(StatesGroup):
15
+ waiting_for_recipient = State()
16
+ waiting_for_amount = State()
17
+
18
+
19
+ class Cur(CallbackData, prefix="Сur"):
20
+ id: int
21
+
22
+
23
+ @sd.message(Command("send"))
24
+ async def start(message: Message, state: FSMContext):
25
+ await message.answer(
26
+ "Введите ID/username получателя:",
27
+ )
28
+
29
+ await state.set_state(SendStates.waiting_for_recipient)
30
+
31
+
32
+ @sd.message(SendStates.waiting_for_recipient)
33
+ async def process_recipient(message: Message, state: FSMContext):
34
+ recipient = message.text
35
+
36
+ if recipient.isdigit():
37
+ user_id = int(recipient)
38
+ user_receiver = await models.User.get_or_none(username_id=user_id)
39
+
40
+ if not user_receiver:
41
+ my_id = message.from_user.id
42
+ await message.answer(
43
+ f"Такого пользователя еще нет в XyncPay, вот ссылка для регистрации с вашим реферальным бонусом: \n"
44
+ f"https://t.me/XyncPayBot?start={my_id}"
45
+ )
46
+ return
47
+ else:
48
+ await state.update_data(receiver=user_receiver)
49
+ else:
50
+ user_receiver = await models.User.get_or_none(username__username=recipient)
51
+
52
+ if not user_receiver:
53
+ my_id = message.from_user.id
54
+ await message.answer(
55
+ f"Такого пользователя еще нет в XyncPay, вот ссылка для регистрации с вашим реферальным бонусом: \n"
56
+ f"https://t.me/XyncPayBot?start={my_id}"
57
+ )
58
+ return
59
+ await state.update_data(receiver=user_receiver)
60
+
61
+ # Продолжаем процесс выбора валюты
62
+ builder = InlineKeyboardBuilder()
63
+ curs = await models.Cur.filter(
64
+ ticker__in=[
65
+ "CNY",
66
+ "HKD",
67
+ "USD",
68
+ "VND",
69
+ "MYR",
70
+ "TWD",
71
+ "RUB",
72
+ "AUD",
73
+ "CAD",
74
+ "SGD",
75
+ "GBP",
76
+ "EUR",
77
+ "PHP",
78
+ "INR",
79
+ "CHF",
80
+ "IDR",
81
+ "BRL",
82
+ "SAR",
83
+ "AED",
84
+ "TRY",
85
+ "THB",
86
+ ]
87
+ )
88
+
89
+ for cur in curs:
90
+ builder.button(text=cur.ticker, callback_data=Cur(id=cur.id).pack())
91
+
92
+ builder.adjust(3, 3, 3)
93
+ await message.answer("Выбери валюту", reply_markup=builder.as_markup())
94
+
95
+
96
+ @sd.callback_query(Cur.filter())
97
+ async def waiting_for_amount(query: types.CallbackQuery, state: FSMContext, callback_data: Cur):
98
+ await state.update_data(cur=callback_data.id)
99
+ await query.message.answer("Введите сумму: ")
100
+ await state.set_state(SendStates.waiting_for_amount)
101
+
102
+
103
+ @sd.message(SendStates.waiting_for_amount)
104
+ async def waiting_for_recipient(message: Message, state: FSMContext):
105
+ amount = int(message.text)
106
+ if amount < 0:
107
+ await message.answer("Введите положительное число")
108
+ else:
109
+ await state.update_data(amount=amount)
110
+ my_id = message.from_user.id
111
+ await state.update_data(sender=my_id)
112
+ data = await state.get_data()
113
+ await state.clear()
114
+ me = await models.User.get(username_id=my_id)
115
+ await models.Transfer.create(
116
+ amount=data["amount"], cur_id=data["cur"], receiver_id=data["receiver"].id, sender=me
117
+ )
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,151 @@
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
+ actors: dict[int, int] = None # key=ex_id
66
+ creds: dict[int, Cred] = None # key=cred_id
67
+ cur_creds: dict[int, list[int]] = None # pmcur_id:[cred_ids]
68
+
69
+ def __init__(self, user: User):
70
+ self.user: User = user
71
+ self.curr = self.Current()
72
+
73
+ class Pr:
74
+ t_cur_id: int = None
75
+ s_cur_id: int = None
76
+ t_coin_id: int = None
77
+ s_coin_id: int = None
78
+ t_pmcur_id: int = None
79
+ s_pmcur_id: int = None
80
+ t_ex_id: int = None
81
+ s_ex_id: int = None
82
+ amount: int | float = None
83
+ ppo: int = 1
84
+ addr_id: int = None
85
+ cred_dtl: str = None
86
+ cred_id: int = None
87
+ urg: int = 5
88
+ pr_id: int = None
89
+
90
+ def __init__(self, uid: int):
91
+ self.uid = uid
92
+
93
+ async def xync_have_coin_amount(self) -> bool:
94
+ assets = await Asset.filter(
95
+ addr__coin_id=self.t_coin_id, addr__ex_id=self.t_ex_id, addr__actor__user__role__in=Role.ADMIN
96
+ )
97
+ return self.amount <= sum(a.free for a in assets)
98
+
99
+ async def client_have_coin_amount(self) -> bool:
100
+ assets = await Asset.filter(addr__coin_id=self.t_coin_id, addr__actor_id__in=self.perm.actors.values())
101
+ return self.amount <= sum(a.free for a in assets)
102
+
103
+ async def need_ppo(self):
104
+ cur_id = getattr(self, ("t" if self.curr.is_target else "s") + "_cur_id")
105
+ usd_amount = self.amount * self.glob.curs[cur_id].rate
106
+ if usd_amount < 50:
107
+ return 0
108
+ elif usd_amount > 100:
109
+ return 2
110
+ else:
111
+ return 1
112
+
113
+ async def client_target_repr(self) -> tuple[Addr | Cred, str]:
114
+ if self.t_ex_id:
115
+ addr_to = (
116
+ await Addr.filter(actor__ex_id=self.t_ex_id, coin_id=self.t_coin_id, actor__user=self.perm.user)
117
+ .prefetch_related("actor")
118
+ .first()
119
+ )
120
+ ex, coin = self.glob.exs[self.s_ex_id], self.glob.coins[self.s_coin_id]
121
+ if not addr_to:
122
+ logging.error(f"No {coin} addr in {ex} for user: {self.perm.user.username_id}")
123
+ return addr_to, f"{coin} на {ex} по id: `{addr_to.actor.exid}`"
124
+ # иначе: реквизиты для фиата
125
+ cur, pm = self.glob.curs[self.t_cur_id], self.glob.pmcurs[self.t_pmcur_id]
126
+ cred = self.perm.creds[self.cred_id]
127
+ return cred, f"{cur.ticker} на {pm} по номеру: {cred.repr()}"
128
+
129
+ async def get_merch_target(self) -> tuple[Addr | Cred, str]:
130
+ if self.s_ex_id:
131
+ addr_in = (
132
+ await Addr.filter(
133
+ actor__ex_id=self.s_ex_id, coin_id=self.s_coin_id, actor__user__role__gte=Role.ADMIN
134
+ )
135
+ .prefetch_related("actor")
136
+ .first()
137
+ )
138
+ ex, coin = self.glob.exs[self.s_ex_id], self.glob.coins[self.s_coin_id]
139
+ if not addr_in:
140
+ logging.error(f"No {coin} addr in {ex}")
141
+ return addr_in, f"{coin} на {ex} по id: `{addr_in.actor.exid}`"
142
+ # иначе: реквизиты для фиатной оплаты
143
+ s_pmcur = await Pmcur.get(id=self.s_pmcur_id).prefetch_related("pm__grp")
144
+ cred = await Cred.filter(
145
+ **({"pmcur__pm__grp": s_pmcur.pm.grp} if s_pmcur.pm.grp else {"pmcur_id": self.s_pmcur_id}),
146
+ person__user__role__gte=Role.ADMIN,
147
+ ).first() # todo: payreq by fiat.target-fiat.amount
148
+ cur, pm = self.glob.curs[self.s_cur_id], self.glob.pmcurs[self.s_pmcur_id]
149
+ if not cred:
150
+ logging.error(f"No {cur.ticker} cred for {pm}")
151
+ return cred, f"{cur.ticker} на {pm} по номеру: {cred.repr()}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-bot
3
- Version: 0.3.24.dev12
3
+ Version: 0.3.26.dev0
4
4
  Summary: Telegram bot with web app for xync net
5
5
  Author-email: Artemiev <mixartemev@gmail.com>
6
6
  License-Expression: GPL-3.0-or-later
@@ -0,0 +1,23 @@
1
+ xync_bot/__main__.py,sha256=uZH7tEJ1GQtLMKYG9ttiI6mTyXvLCs5bc_JiQd_2I0o,1032
2
+ xync_bot/loader.py,sha256=4ZeR-yVMoOmswdLS0UEBG19K7JVcuvH6WpP-_0yAK3I,573
3
+ xync_bot/shared.py,sha256=PPzvt1ewowCInKE1bk2CWHPjnrV2eQJzKxgyxe3h7vk,496
4
+ xync_bot/store.py,sha256=_au6CKx0sTjdDk2yTofLS9RyT7adTcFJQ4CXpembQc0,6266
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=3YI6GVug3A4QNhEpmA_Nuf13YgdYGHLEd4qBINWZwkk,10992
18
+ xync_bot/routers/pay/window.py,sha256=YKRwhw6J7gQVABgVEgUs-JmpvGoEyKMgbPtSCnuXQmE,11163
19
+ xync_bot/routers/send/__init__.py,sha256=Mccf__w_nF7CbDN7gndqXEQ985oCcKX4j7NCcgvq2Ok,3793
20
+ xync_bot-0.3.26.dev0.dist-info/METADATA,sha256=AWDq44RGmVUUeR99U9NMx7EnLWY3kr69ltvdFvYlB0w,751
21
+ xync_bot-0.3.26.dev0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
+ xync_bot-0.3.26.dev0.dist-info/top_level.txt,sha256=O2IjMc1ryAf0rwIXWohSNT5Kzcs9johgKRDz8lCC0rs,9
23
+ xync_bot-0.3.26.dev0.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,,