xync-bot 0.3.6__py3-none-any.whl → 0.3.7.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/__init__.py +3 -3
- xync_bot/loader.py +0 -5
- xync_bot/routers/cond/__init__.py +63 -37
- xync_bot/routers/main.py +1 -1
- {xync_bot-0.3.6.dist-info → xync_bot-0.3.7.dev1.dist-info}/METADATA +1 -1
- xync_bot-0.3.7.dev1.dist-info/RECORD +16 -0
- xync_bot-0.3.6.dist-info/RECORD +0 -16
- {xync_bot-0.3.6.dist-info → xync_bot-0.3.7.dev1.dist-info}/WHEEL +0 -0
- {xync_bot-0.3.6.dist-info → xync_bot-0.3.7.dev1.dist-info}/top_level.txt +0 -0
xync_bot/__init__.py
CHANGED
|
@@ -7,14 +7,14 @@ from x_model import init_db
|
|
|
7
7
|
|
|
8
8
|
from xync_bot.routers.cond import r
|
|
9
9
|
|
|
10
|
-
if __name__ ==
|
|
11
|
-
from xync_bot.loader import
|
|
10
|
+
if __name__ == "__main__":
|
|
11
|
+
from xync_bot.loader import TOKEN, TORM
|
|
12
12
|
|
|
13
13
|
logging.basicConfig(level=logging.INFO)
|
|
14
14
|
|
|
15
15
|
async def main() -> None:
|
|
16
16
|
cn = await init_db(TORM)
|
|
17
|
-
bot = Bot(TOKEN, [r], cn, default=DefaultBotProperties(parse_mode=
|
|
17
|
+
bot = Bot(TOKEN, [r], cn, default=DefaultBotProperties(parse_mode="HTML"))
|
|
18
18
|
await bot.start()
|
|
19
19
|
|
|
20
20
|
run(main())
|
xync_bot/loader.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from aiogram import Bot, Dispatcher
|
|
2
|
-
# from aiogram.client.default import DefaultBotProperties
|
|
3
1
|
from dotenv import load_dotenv
|
|
4
2
|
from os import getenv as env
|
|
5
3
|
|
|
@@ -15,9 +13,6 @@ TOKEN = env("TOKEN")
|
|
|
15
13
|
# API_URL = "https://" + env("API_DOMAIN")
|
|
16
14
|
# WH_URL = API_URL + "/wh/" + TOKEN
|
|
17
15
|
|
|
18
|
-
bot: Bot = Bot(token=TOKEN) # , default=DefaultBotProperties(parse_mode="HTML")
|
|
19
|
-
dp: Dispatcher = Dispatcher(bot=bot)
|
|
20
|
-
|
|
21
16
|
TORM = {
|
|
22
17
|
"connections": {"default": PG_DSN},
|
|
23
18
|
"apps": {"models": {"models": [models, "aerich.models"]}},
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import re
|
|
2
|
-
from asyncio import iscoroutinefunction
|
|
3
2
|
from enum import IntEnum
|
|
4
3
|
from inspect import isclass
|
|
5
4
|
from typing import Coroutine
|
|
@@ -7,38 +6,49 @@ from typing import Coroutine
|
|
|
7
6
|
from aiogram import Router, F
|
|
8
7
|
from aiogram.filters import CommandStart
|
|
9
8
|
from aiogram.fsm.context import FSMContext
|
|
10
|
-
from aiogram.types import
|
|
11
|
-
|
|
9
|
+
from aiogram.types import (
|
|
10
|
+
Message,
|
|
11
|
+
ReplyKeyboardMarkup,
|
|
12
|
+
KeyboardButton,
|
|
13
|
+
InlineKeyboardMarkup,
|
|
14
|
+
InlineKeyboardButton,
|
|
15
|
+
CallbackQuery,
|
|
16
|
+
# ReplyKeyboardRemove,
|
|
17
|
+
)
|
|
12
18
|
from cyrtranslit import to_latin
|
|
13
19
|
from xync_schema import models
|
|
14
20
|
from xync_schema.enums import SynonymType, Party, Slip, AbuserType, NameType, Boundary
|
|
15
21
|
|
|
16
22
|
r = Router()
|
|
17
23
|
|
|
24
|
+
|
|
18
25
|
async def wrap_cond(txt: str):
|
|
19
26
|
bnks = await models.Synonym.filter(typ=SynonymType.bank)
|
|
20
|
-
bnks =
|
|
27
|
+
bnks = "|".join("\\b" + b.txt + ("\\b" if b.boundary & Boundary.right else "") for b in bnks)
|
|
21
28
|
for syn in await models.Synonym.all():
|
|
22
|
-
lb, rb = "\\b" if syn.boundary&Boundary.left else "", "\\b" if syn.boundary&Boundary.right else ""
|
|
29
|
+
lb, rb = "\\b" if syn.boundary & Boundary.left else "", "\\b" if syn.boundary & Boundary.right else ""
|
|
23
30
|
if syn.typ == SynonymType.bank_side:
|
|
24
|
-
syn.txt.replace(
|
|
31
|
+
syn.txt.replace("#banks#", f"({bnks})")
|
|
25
32
|
if syn.is_re or syn.txt in txt:
|
|
26
|
-
pattern = re.compile(lb+syn.txt+rb)
|
|
33
|
+
pattern = re.compile(lb + syn.txt + rb)
|
|
27
34
|
if match := re.search(pattern, txt):
|
|
28
35
|
g = match.group()
|
|
29
36
|
val, hval = await get_val(syn.typ, syn.val)
|
|
30
|
-
val = syn.typ.name + (f'="{hval}"' if hval else
|
|
37
|
+
val = syn.typ.name + (f'="{hval}"' if hval else "")
|
|
31
38
|
txt = re.sub(pattern, f"<code>{g}</code><tg-spoiler>[{val}]</tg-spoiler>", txt)
|
|
32
39
|
return txt
|
|
33
40
|
|
|
41
|
+
|
|
34
42
|
async def cbanks(bnid: str) -> list[tuple[int, str]]:
|
|
35
|
-
beginning = to_latin(bnid[:2], lang_code=
|
|
36
|
-
return await models.Pm.filter(norm__startswith=beginning, bank=True).values_list(
|
|
43
|
+
beginning = to_latin(bnid[:2], lang_code="ru")
|
|
44
|
+
return await models.Pm.filter(norm__startswith=beginning, bank=True).values_list("id", "norm")
|
|
45
|
+
|
|
37
46
|
|
|
38
47
|
async def cppo(txt: str) -> list[tuple[int, str]]:
|
|
39
|
-
opts = re.findall(r
|
|
48
|
+
opts = re.findall(r"\d+", txt) or [1, 2, 3, 5, 10]
|
|
40
49
|
return [(o, str(o)) for o in opts]
|
|
41
50
|
|
|
51
|
+
|
|
42
52
|
synopts: dict[SynonymType, list[str] | type(IntEnum) | None | Coroutine] = {
|
|
43
53
|
SynonymType.name: ["not_slavic", "slavic"],
|
|
44
54
|
SynonymType.ppo: cppo,
|
|
@@ -53,41 +63,47 @@ synopts: dict[SynonymType, list[str] | type(IntEnum) | None | Coroutine] = {
|
|
|
53
63
|
SynonymType.bank: cbanks,
|
|
54
64
|
SynonymType.bank_side: ["except", "only"],
|
|
55
65
|
}
|
|
56
|
-
rkm = ReplyKeyboardMarkup(
|
|
57
|
-
[
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
rkm = ReplyKeyboardMarkup(
|
|
67
|
+
keyboard=[
|
|
68
|
+
[KeyboardButton(text="ppo"), KeyboardButton(text="abuser")],
|
|
69
|
+
[KeyboardButton(text="from_party"), KeyboardButton(text="to_party")],
|
|
70
|
+
[KeyboardButton(text="slip_send"), KeyboardButton(text="slip_req")],
|
|
71
|
+
[KeyboardButton(text="name"), KeyboardButton(text="slavic")],
|
|
72
|
+
[KeyboardButton(text="scale"), KeyboardButton(text="mtl_like")],
|
|
73
|
+
[KeyboardButton(text="bank"), KeyboardButton(text="bank_side")],
|
|
74
|
+
],
|
|
75
|
+
one_time_keyboard=True,
|
|
76
|
+
)
|
|
77
|
+
|
|
64
78
|
|
|
65
79
|
async def get_val(typ: SynonymType.__class__, val: str) -> tuple[SynonymType | int | bool, str]:
|
|
66
80
|
if isinstance(val, str) and val.isnumeric():
|
|
67
81
|
val = int(val)
|
|
68
82
|
if isclass(lst := synopts[typ]) and issubclass(lst, IntEnum):
|
|
69
|
-
return (v:=lst(val)), v.name
|
|
83
|
+
return (v := lst(val)), v.name
|
|
70
84
|
elif isinstance(lst, list):
|
|
71
85
|
return val, lst[val]
|
|
72
86
|
elif typ == SynonymType.bank:
|
|
73
87
|
return val, (await models.Pm[val]).norm
|
|
74
88
|
return val, val
|
|
75
89
|
|
|
90
|
+
|
|
76
91
|
async def btns(typ: SynonymType.__class__, txt: str = None) -> InlineKeyboardMarkup | None:
|
|
77
92
|
if lst := synopts[typ]:
|
|
78
93
|
if isinstance(lst, list):
|
|
79
|
-
kb = [[InlineKeyboardButton(text=n, callback_data=f
|
|
94
|
+
kb = [[InlineKeyboardButton(text=n, callback_data=f"st:{typ.name}:{i}")] for i, n in enumerate(lst)]
|
|
80
95
|
elif isclass(lst) and issubclass(lst, IntEnum):
|
|
81
|
-
kb = [[InlineKeyboardButton(text=i.name, callback_data=f
|
|
96
|
+
kb = [[InlineKeyboardButton(text=i.name, callback_data=f"st:{typ.name}:{i.value}")] for i in lst]
|
|
82
97
|
else:
|
|
83
|
-
kb = [[InlineKeyboardButton(text=n, callback_data=f
|
|
98
|
+
kb = [[InlineKeyboardButton(text=n, callback_data=f"st:{typ.name}:{i}")] for i, n in await lst(txt)]
|
|
84
99
|
return InlineKeyboardMarkup(inline_keyboard=kb)
|
|
85
100
|
else:
|
|
86
101
|
return lst
|
|
87
102
|
|
|
103
|
+
|
|
88
104
|
@r.message(CommandStart())
|
|
89
105
|
async def start(msg: Message, state: FSMContext):
|
|
90
|
-
cond = await models.Cond.filter(parsed__isnull=True).order_by("-created_at").first().prefetch_related(
|
|
106
|
+
cond = await models.Cond.filter(parsed__isnull=True).order_by("-created_at").first().prefetch_related("parsed")
|
|
91
107
|
await state.set_data({"cid": cond.id, "cond_txt": cond.raw_txt})
|
|
92
108
|
await msg.reply(await wrap_cond(cond.raw_txt), reply_markup=rkm)
|
|
93
109
|
|
|
@@ -95,58 +111,68 @@ async def start(msg: Message, state: FSMContext):
|
|
|
95
111
|
@r.message(F.quote)
|
|
96
112
|
async def got_synonym(msg: Message, state: FSMContext):
|
|
97
113
|
if not (msg.text in {st.name for st in SynonymType} and SynonymType[msg.text]):
|
|
98
|
-
return await msg.reply_text(
|
|
99
|
-
|
|
114
|
+
return await msg.reply_text(
|
|
115
|
+
f'Нет раздела "{msg.text}", не пиши текст сам, выдели кусок из моего сообщения,'
|
|
116
|
+
f"ответь на него, выбери кнопку раздела"
|
|
117
|
+
)
|
|
100
118
|
if not msg.quote:
|
|
101
|
-
return await msg.reply_text(f
|
|
119
|
+
return await msg.reply_text(f"Вы забыли выделить кусок текста для {msg.text}")
|
|
102
120
|
if typ := SynonymType[msg.text]:
|
|
103
121
|
await state.update_data({"syntext": msg.quote.text, "cmsg": msg.reply_to_message})
|
|
104
122
|
await models.Synonym.update_or_create({"typ": typ}, txt=msg.quote.text)
|
|
105
123
|
if rm := await btns(typ, msg.quote.text):
|
|
106
124
|
return await msg.answer("Уточните", reply_markup=rm, reply_to_message_id=msg.message_id)
|
|
107
|
-
await syn_result(msg, f
|
|
125
|
+
await syn_result(msg, f"st:{typ.name}:1", state)
|
|
108
126
|
return None
|
|
109
127
|
|
|
128
|
+
|
|
110
129
|
@r.callback_query()
|
|
111
130
|
async def got_synonym_val(cbq: CallbackQuery, state: FSMContext):
|
|
112
131
|
await syn_result(cbq.message, cbq.data, state)
|
|
113
132
|
|
|
133
|
+
|
|
114
134
|
async def syn_result(msg: Message, data: str, state: FSMContext):
|
|
115
|
-
t, st, sv = data.split(
|
|
135
|
+
t, st, sv = data.split(":")
|
|
116
136
|
if t == "st":
|
|
117
137
|
typ = SynonymType[st]
|
|
118
138
|
val, hval = await get_val(typ, sv)
|
|
119
|
-
syntext = await state.get_value(
|
|
120
|
-
cid = await state.get_value(
|
|
139
|
+
syntext = await state.get_value("syntext")
|
|
140
|
+
cid = await state.get_value("cid")
|
|
121
141
|
syn, _ = await models.Synonym.update_or_create({"val": val}, typ=typ, txt=syntext)
|
|
122
142
|
await models.CondParsed.update_or_create({typ.name: val}, cond_id=cid)
|
|
123
143
|
await msg.reply(
|
|
124
144
|
f'Текст "{syntext}" определен как синоним для `{typ.name}` со значением {hval}',
|
|
125
|
-
reply_markup=InlineKeyboardMarkup(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
145
|
+
reply_markup=InlineKeyboardMarkup(
|
|
146
|
+
inline_keyboard=[
|
|
147
|
+
[
|
|
148
|
+
InlineKeyboardButton(text="Готово! Давай новый", callback_data=f"cond:complete:{cid}"),
|
|
149
|
+
InlineKeyboardButton(text="Продолжить с этим текстом", callback_data=f"cond:process:{cid}"),
|
|
150
|
+
]
|
|
151
|
+
]
|
|
152
|
+
),
|
|
129
153
|
)
|
|
130
154
|
# await msg.reply_to_message.delete()
|
|
131
155
|
# await msg.delete()
|
|
132
156
|
# await cmsg.edit_text(wrapped_txt)
|
|
133
157
|
|
|
134
158
|
elif t == "cond":
|
|
135
|
-
if st ==
|
|
159
|
+
if st == "complete":
|
|
136
160
|
await models.CondParsed.update_or_create({"parsed": True}, cond_id=int(sv))
|
|
137
161
|
await start(msg, state)
|
|
138
162
|
else:
|
|
139
|
-
wrapped_txt = await wrap_cond(await state.get_value(
|
|
163
|
+
wrapped_txt = await wrap_cond(await state.get_value("cond_txt"))
|
|
140
164
|
# cmsg: Message = await state.get_value('cmsg')
|
|
141
165
|
await msg.reply(wrapped_txt, reply_markup=rkm)
|
|
142
166
|
else:
|
|
143
167
|
await msg.reply("Где я?")
|
|
144
168
|
|
|
169
|
+
|
|
145
170
|
@r.message(F.reply_to_message)
|
|
146
171
|
async def clear(msg: Message):
|
|
147
172
|
await msg.reply_to_message.delete_reply_markup()
|
|
148
173
|
await msg.delete()
|
|
149
174
|
|
|
175
|
+
|
|
150
176
|
@r.message()
|
|
151
177
|
async def unknown(msg: Message):
|
|
152
178
|
# user = await User.get(username_id=msg.from_user.id)
|
xync_bot/routers/main.py
CHANGED
|
@@ -15,9 +15,9 @@ from aiogram.types import (
|
|
|
15
15
|
WebAppInfo,
|
|
16
16
|
)
|
|
17
17
|
from aiogram.utils.deep_linking import create_start_link
|
|
18
|
-
from xync_bot.handlers import user_upsert
|
|
19
18
|
from xync_schema.models import User, Order, Msg, Forum
|
|
20
19
|
|
|
20
|
+
from xync_bot.routers import user_upsert
|
|
21
21
|
from xync_bot.shared import NavCallbackData
|
|
22
22
|
|
|
23
23
|
main = Router()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
xync_bot/__init__.py,sha256=DxSf_OvNstlmK9_-z7Q-3ld1SC6Hd6gWxBlFffd7Cjo,490
|
|
2
|
+
xync_bot/loader.py,sha256=wnhRRMJ6KSFAFZnDBGg9mbbktq34VHtcNSt89WuPn04,558
|
|
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=0CwHTSgAWzKRZ7PtsaLGA8PtjWQtZqsEXKyncNbCKLA,374
|
|
6
|
+
xync_bot/routers/main.py,sha256=ZfgEX17_QaZ8CVEQqNZnNFt8RLfr6xfZ_A2ZGJoe-Oo,9520
|
|
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=n9MLqu0tENaA3n2-WSh7XAelXxyFJtCQGdd6lqP7GmI,7248
|
|
12
|
+
xync_bot/routers/cond/cond.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
xync_bot-0.3.7.dev1.dist-info/METADATA,sha256=g2DghtBKWq9Igmbx6p_sKymDH473mWvq-fdogyuu980,700
|
|
14
|
+
xync_bot-0.3.7.dev1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
+
xync_bot-0.3.7.dev1.dist-info/top_level.txt,sha256=O2IjMc1ryAf0rwIXWohSNT5Kzcs9johgKRDz8lCC0rs,9
|
|
16
|
+
xync_bot-0.3.7.dev1.dist-info/RECORD,,
|
xync_bot-0.3.6.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
xync_bot/__init__.py,sha256=_x9GUhAIfaovmgeptj1Y5z7HI32oQhqc1Bg6mXhIsyc,494
|
|
2
|
-
xync_bot/loader.py,sha256=FJNVcBr4K475Bbfe8kQapr87pMVD9H-TH4j2NFkbFok,771
|
|
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=0CwHTSgAWzKRZ7PtsaLGA8PtjWQtZqsEXKyncNbCKLA,374
|
|
6
|
-
xync_bot/routers/main.py,sha256=eIgorrJXzRJfsO7fx1XxVHFJDfMiJyWt7myS4qSqS8U,9521
|
|
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=UuOw71_8EQaVfJaj0EoxXNj6o19Am2lho8RdB3QYoSE,7101
|
|
12
|
-
xync_bot/routers/cond/cond.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
xync_bot-0.3.6.dist-info/METADATA,sha256=9opPDdum0Kx-tJXJnuFL8lxc7G1qVbeGckX7Im7Jc1w,695
|
|
14
|
-
xync_bot-0.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
-
xync_bot-0.3.6.dist-info/top_level.txt,sha256=O2IjMc1ryAf0rwIXWohSNT5Kzcs9johgKRDz8lCC0rs,9
|
|
16
|
-
xync_bot-0.3.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|