maxkit 2.13.0__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.
- aiomax/__init__.py +9 -0
- aiomax/bot.py +1166 -0
- aiomax/buttons.py +303 -0
- aiomax/cache.py +31 -0
- aiomax/exceptions.py +85 -0
- aiomax/filters.py +179 -0
- aiomax/fsm.py +107 -0
- aiomax/router.py +383 -0
- aiomax/russian_trusted_root_ca.cer +33 -0
- aiomax/types.py +1512 -0
- aiomax/utils.py +125 -0
- maxkit-2.13.0.dist-info/METADATA +45 -0
- maxkit-2.13.0.dist-info/RECORD +16 -0
- maxkit-2.13.0.dist-info/WHEEL +5 -0
- maxkit-2.13.0.dist-info/licenses/LICENSE.md +22 -0
- maxkit-2.13.0.dist-info/top_level.txt +1 -0
aiomax/router.py
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
from typing import Callable, Optional
|
|
4
|
+
|
|
5
|
+
from . import exceptions
|
|
6
|
+
from .filters import normalize_filter
|
|
7
|
+
from .types import CommandHandler, Handler, MessageHandler
|
|
8
|
+
|
|
9
|
+
bot_logger = logging.getLogger("aiomax.bot")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Router:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
case_sensitive: bool = True,
|
|
16
|
+
):
|
|
17
|
+
"""
|
|
18
|
+
Router init
|
|
19
|
+
:param case_sensitive: If False the bot will respond to commands
|
|
20
|
+
regardless of case
|
|
21
|
+
"""
|
|
22
|
+
self._handlers: dict[str, list[Handler]] = {
|
|
23
|
+
"message_created": [],
|
|
24
|
+
"on_ready": [],
|
|
25
|
+
"bot_started": [],
|
|
26
|
+
"message_callback": [],
|
|
27
|
+
"message_chat_created": [],
|
|
28
|
+
"message_edited": [],
|
|
29
|
+
"message_removed": [],
|
|
30
|
+
"chat_title_changed": [],
|
|
31
|
+
"bot_added": [],
|
|
32
|
+
"bot_removed": [],
|
|
33
|
+
"user_added": [],
|
|
34
|
+
"user_removed": [],
|
|
35
|
+
} # handlers in this router
|
|
36
|
+
self._commands: dict[
|
|
37
|
+
str, list[CommandHandler]
|
|
38
|
+
] = {} # commands in this router
|
|
39
|
+
self.case_sensitive: bool = case_sensitive
|
|
40
|
+
self.parent: Router | None = None # Parent bot of this router
|
|
41
|
+
self.routers: list[Router] = []
|
|
42
|
+
self.filters: dict[str, list[Callable]] = {
|
|
43
|
+
"message_created": [],
|
|
44
|
+
"message_edited": [],
|
|
45
|
+
"message_removed": [],
|
|
46
|
+
"message_callback": [],
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def wrap_filters(
|
|
51
|
+
filters: tuple["Callable | str | None", ...], mode: str = "and"
|
|
52
|
+
) -> Callable:
|
|
53
|
+
"""
|
|
54
|
+
Normalize multiple filters into a single callable.
|
|
55
|
+
|
|
56
|
+
:param filters: filters to combine
|
|
57
|
+
:param mode: "and" (default) — all filters must pass,
|
|
58
|
+
"or" — at least one filter must pass.
|
|
59
|
+
"""
|
|
60
|
+
normalized_filters = []
|
|
61
|
+
|
|
62
|
+
for filter_ in filters:
|
|
63
|
+
if filter_ is None:
|
|
64
|
+
continue
|
|
65
|
+
normalized_filters.append(normalize_filter(filter_))
|
|
66
|
+
|
|
67
|
+
if not normalized_filters:
|
|
68
|
+
return lambda message: True
|
|
69
|
+
|
|
70
|
+
if mode == "and":
|
|
71
|
+
|
|
72
|
+
def combined_filter(message):
|
|
73
|
+
return all(f(message) for f in normalized_filters)
|
|
74
|
+
elif mode == "or":
|
|
75
|
+
|
|
76
|
+
def combined_filter(message):
|
|
77
|
+
return any(f(message) for f in normalized_filters)
|
|
78
|
+
else:
|
|
79
|
+
raise ValueError(f"Unsupported mode: {mode}. Use 'and' or 'or'.")
|
|
80
|
+
|
|
81
|
+
return combined_filter
|
|
82
|
+
|
|
83
|
+
# routers
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def handlers(self) -> dict[str, list[Handler]]:
|
|
87
|
+
"""
|
|
88
|
+
Returns all handlers in this and all the child routers.
|
|
89
|
+
"""
|
|
90
|
+
out = deepcopy(self._handlers)
|
|
91
|
+
|
|
92
|
+
for router in self.routers:
|
|
93
|
+
for handler_type in out:
|
|
94
|
+
out[handler_type].extend(router.handlers[handler_type])
|
|
95
|
+
|
|
96
|
+
return out
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def commands(self) -> dict[str, list[CommandHandler]]:
|
|
100
|
+
"""
|
|
101
|
+
Returns all commands in this and all the child routers.
|
|
102
|
+
"""
|
|
103
|
+
out = deepcopy(self._commands)
|
|
104
|
+
for router in self.routers:
|
|
105
|
+
# Merge (not overwrite): a command name defined in more than one
|
|
106
|
+
# router must keep every handler, mirroring the handlers property.
|
|
107
|
+
for name, handlers in router.commands.items():
|
|
108
|
+
out.setdefault(name, []).extend(handlers)
|
|
109
|
+
return out
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def bot(self):
|
|
113
|
+
"""
|
|
114
|
+
Returns the bot this router is attached to.
|
|
115
|
+
"""
|
|
116
|
+
# Walk up to the root so nesting deeper than two levels resolves to
|
|
117
|
+
# the actual Bot instead of an intermediate Router.
|
|
118
|
+
node = self
|
|
119
|
+
while node.parent is not None:
|
|
120
|
+
node = node.parent
|
|
121
|
+
return node if node is not self else None
|
|
122
|
+
|
|
123
|
+
def add_router(self, router: "Router"):
|
|
124
|
+
if router.parent is not None:
|
|
125
|
+
raise ValueError("Router already has a parent")
|
|
126
|
+
|
|
127
|
+
router.parent = self
|
|
128
|
+
self.routers.append(router)
|
|
129
|
+
|
|
130
|
+
def remove_router(self, router: "Router"):
|
|
131
|
+
if router not in self.routers:
|
|
132
|
+
raise ValueError("Router not found")
|
|
133
|
+
|
|
134
|
+
router.parent = None
|
|
135
|
+
self.routers.remove(router)
|
|
136
|
+
|
|
137
|
+
# decorators
|
|
138
|
+
|
|
139
|
+
def on_message(
|
|
140
|
+
self,
|
|
141
|
+
*filters: "Callable | str | None",
|
|
142
|
+
mode: str = "and",
|
|
143
|
+
detect_commands: bool = False,
|
|
144
|
+
):
|
|
145
|
+
"""
|
|
146
|
+
Decorator for receiving messages.
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
def decorator(func):
|
|
150
|
+
new_filter = self.wrap_filters(filters, mode=mode)
|
|
151
|
+
|
|
152
|
+
self._handlers["message_created"].append(
|
|
153
|
+
MessageHandler(
|
|
154
|
+
call=func,
|
|
155
|
+
deco_filter=new_filter,
|
|
156
|
+
router_filters=self.filters["message_created"],
|
|
157
|
+
detect_commands=detect_commands,
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
return func
|
|
161
|
+
|
|
162
|
+
return decorator
|
|
163
|
+
|
|
164
|
+
def on_message_edit(
|
|
165
|
+
self, *filters: "Callable | str | None", mode: str = "and"
|
|
166
|
+
):
|
|
167
|
+
"""
|
|
168
|
+
Decorator for editing messages.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
def decorator(func):
|
|
172
|
+
new_filter = self.wrap_filters(filters, mode=mode)
|
|
173
|
+
|
|
174
|
+
self._handlers["message_edited"].append(
|
|
175
|
+
Handler(
|
|
176
|
+
call=func,
|
|
177
|
+
deco_filter=new_filter,
|
|
178
|
+
router_filters=self.filters["message_edited"],
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
return func
|
|
182
|
+
|
|
183
|
+
return decorator
|
|
184
|
+
|
|
185
|
+
def on_message_delete(
|
|
186
|
+
self, *filters: "Callable | str | None", mode: str = "and"
|
|
187
|
+
):
|
|
188
|
+
"""
|
|
189
|
+
Decorator for deleted messages.
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
def decorator(func):
|
|
193
|
+
new_filter = self.wrap_filters(filters, mode=mode)
|
|
194
|
+
|
|
195
|
+
self._handlers["message_removed"].append(
|
|
196
|
+
Handler(
|
|
197
|
+
call=func,
|
|
198
|
+
deco_filter=new_filter,
|
|
199
|
+
router_filters=self.filters["message_removed"],
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
return func
|
|
203
|
+
|
|
204
|
+
return decorator
|
|
205
|
+
|
|
206
|
+
def on_bot_start(self):
|
|
207
|
+
"""
|
|
208
|
+
Decorator for handling bot start.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
def decorator(func):
|
|
212
|
+
self._handlers["bot_started"].append(func)
|
|
213
|
+
return func
|
|
214
|
+
|
|
215
|
+
return decorator
|
|
216
|
+
|
|
217
|
+
def on_chat_title_change(self):
|
|
218
|
+
"""
|
|
219
|
+
Decorator for handling chat title changes.
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
def decorator(func):
|
|
223
|
+
self._handlers["chat_title_changed"].append(func)
|
|
224
|
+
return func
|
|
225
|
+
|
|
226
|
+
return decorator
|
|
227
|
+
|
|
228
|
+
def on_bot_add(self):
|
|
229
|
+
"""
|
|
230
|
+
Decorator for handling bot invitations in groups.
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
def decorator(func):
|
|
234
|
+
self._handlers["bot_added"].append(func)
|
|
235
|
+
return func
|
|
236
|
+
|
|
237
|
+
return decorator
|
|
238
|
+
|
|
239
|
+
def on_bot_remove(self):
|
|
240
|
+
"""
|
|
241
|
+
Decorator for handling bot kicks from groups.
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
def decorator(func):
|
|
245
|
+
self._handlers["bot_removed"].append(func)
|
|
246
|
+
return func
|
|
247
|
+
|
|
248
|
+
return decorator
|
|
249
|
+
|
|
250
|
+
def on_user_add(self):
|
|
251
|
+
"""
|
|
252
|
+
Decorator for handling user joins.
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
def decorator(func):
|
|
256
|
+
self._handlers["user_added"].append(func)
|
|
257
|
+
return func
|
|
258
|
+
|
|
259
|
+
return decorator
|
|
260
|
+
|
|
261
|
+
def on_user_remove(self):
|
|
262
|
+
"""
|
|
263
|
+
Decorator for handling user leaves.
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
def decorator(func):
|
|
267
|
+
self._handlers["user_removed"].append(func)
|
|
268
|
+
return func
|
|
269
|
+
|
|
270
|
+
return decorator
|
|
271
|
+
|
|
272
|
+
def on_ready(self):
|
|
273
|
+
"""
|
|
274
|
+
Decorator for receiving messages.
|
|
275
|
+
"""
|
|
276
|
+
|
|
277
|
+
def decorator(func):
|
|
278
|
+
self._handlers["on_ready"].append(func)
|
|
279
|
+
return func
|
|
280
|
+
|
|
281
|
+
return decorator
|
|
282
|
+
|
|
283
|
+
def on_button_callback(
|
|
284
|
+
self, *filters: "Callable | str | None", mode: str = "and"
|
|
285
|
+
):
|
|
286
|
+
"""
|
|
287
|
+
Decorator for receiving button presses.
|
|
288
|
+
"""
|
|
289
|
+
|
|
290
|
+
def decorator(func):
|
|
291
|
+
new_filter = self.wrap_filters(filters, mode=mode)
|
|
292
|
+
|
|
293
|
+
self._handlers["message_callback"].append(
|
|
294
|
+
Handler(
|
|
295
|
+
call=func,
|
|
296
|
+
deco_filter=new_filter,
|
|
297
|
+
router_filters=self.filters["message_callback"],
|
|
298
|
+
)
|
|
299
|
+
)
|
|
300
|
+
return func
|
|
301
|
+
|
|
302
|
+
return decorator
|
|
303
|
+
|
|
304
|
+
def on_button_chat_create(self):
|
|
305
|
+
"""
|
|
306
|
+
Decorator for receiving button presses.
|
|
307
|
+
"""
|
|
308
|
+
|
|
309
|
+
def decorator(func):
|
|
310
|
+
self._handlers["message_chat_created"].append(func)
|
|
311
|
+
return func
|
|
312
|
+
|
|
313
|
+
return decorator
|
|
314
|
+
|
|
315
|
+
def on_command(
|
|
316
|
+
self,
|
|
317
|
+
name: "str | None" = None,
|
|
318
|
+
aliases: Optional[list[str]] = None,
|
|
319
|
+
as_message: bool = False,
|
|
320
|
+
):
|
|
321
|
+
"""
|
|
322
|
+
Decorator for receiving commands.
|
|
323
|
+
|
|
324
|
+
:param name: Command name
|
|
325
|
+
:param aliases: List of alternative names for this command
|
|
326
|
+
:param as_message: Whether to trigger on_message decorator
|
|
327
|
+
when this command is invoked
|
|
328
|
+
"""
|
|
329
|
+
|
|
330
|
+
if aliases is None:
|
|
331
|
+
aliases = []
|
|
332
|
+
|
|
333
|
+
def decorator(func):
|
|
334
|
+
# command name
|
|
335
|
+
if name is None:
|
|
336
|
+
command_name = func.__name__
|
|
337
|
+
else:
|
|
338
|
+
if " " in name:
|
|
339
|
+
raise exceptions.AiomaxException(
|
|
340
|
+
f'Command name "{name}" cannot contain spaces'
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
command_name = name
|
|
344
|
+
|
|
345
|
+
check_name = (
|
|
346
|
+
command_name.lower()
|
|
347
|
+
if not self.case_sensitive
|
|
348
|
+
else command_name
|
|
349
|
+
)
|
|
350
|
+
if check_name not in self._commands:
|
|
351
|
+
self._commands[check_name] = []
|
|
352
|
+
self._commands[check_name].append(CommandHandler(func, as_message))
|
|
353
|
+
|
|
354
|
+
# aliases
|
|
355
|
+
for i in aliases:
|
|
356
|
+
if " " in i:
|
|
357
|
+
raise exceptions.AiomaxException(
|
|
358
|
+
f'Command alias "{i}" cannot contain spaces'
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
check_name = i.lower() if not self.case_sensitive else i
|
|
362
|
+
if check_name not in self._commands:
|
|
363
|
+
self._commands[check_name] = []
|
|
364
|
+
self._commands[check_name].append(
|
|
365
|
+
CommandHandler(func, as_message)
|
|
366
|
+
)
|
|
367
|
+
return func
|
|
368
|
+
|
|
369
|
+
return decorator
|
|
370
|
+
|
|
371
|
+
# filters
|
|
372
|
+
|
|
373
|
+
def add_message_filter(self, filter: "Callable"):
|
|
374
|
+
self.filters["message_created"].append(filter)
|
|
375
|
+
|
|
376
|
+
def add_message_edit_filter(self, filter: "Callable"):
|
|
377
|
+
self.filters["message_edited"].append(filter)
|
|
378
|
+
|
|
379
|
+
def add_message_delete_filter(self, filter: "Callable"):
|
|
380
|
+
self.filters["message_removed"].append(filter)
|
|
381
|
+
|
|
382
|
+
def add_button_callback_filter(self, filter: "Callable"):
|
|
383
|
+
self.filters["message_callback"].append(filter)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIFwjCCA6qgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwcDELMAkGA1UEBhMCUlUx
|
|
3
|
+
PzA9BgNVBAoMNlRoZSBNaW5pc3RyeSBvZiBEaWdpdGFsIERldmVsb3BtZW50IGFu
|
|
4
|
+
ZCBDb21tdW5pY2F0aW9uczEgMB4GA1UEAwwXUnVzc2lhbiBUcnVzdGVkIFJvb3Qg
|
|
5
|
+
Q0EwHhcNMjIwMzAxMjEwNDE1WhcNMzIwMjI3MjEwNDE1WjBwMQswCQYDVQQGEwJS
|
|
6
|
+
VTE/MD0GA1UECgw2VGhlIE1pbmlzdHJ5IG9mIERpZ2l0YWwgRGV2ZWxvcG1lbnQg
|
|
7
|
+
YW5kIENvbW11bmljYXRpb25zMSAwHgYDVQQDDBdSdXNzaWFuIFRydXN0ZWQgUm9v
|
|
8
|
+
dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMfFOZ8pUAL3+r2n
|
|
9
|
+
qqE0Zp52selXsKGFYoG0GM5bwz1bSFtCt+AZQMhkWQheI3poZAToYJu69pHLKS6Q
|
|
10
|
+
XBiwBC1cvzYmUYKMYZC7jE5YhEU2bSL0mX7NaMxMDmH2/NwuOVRj8OImVa5s1F4U
|
|
11
|
+
zn4Kv3PFlDBjjSjXKVY9kmjUBsXQrIHeaqmUIsPIlNWUnimXS0I0abExqkbdrXbX
|
|
12
|
+
YwCOXhOO2pDUx3ckmJlCMUGacUTnylyQW2VsJIyIGA8V0xzdaeUXg0VZ6ZmNUr5Y
|
|
13
|
+
Ber/EAOLPb8NYpsAhJe2mXjMB/J9HNsoFMBFJ0lLOT/+dQvjbdRZoOT8eqJpWnVD
|
|
14
|
+
U+QL/qEZnz57N88OWM3rabJkRNdU/Z7x5SFIM9FrqtN8xewsiBWBI0K6XFuOBOTD
|
|
15
|
+
4V08o4TzJ8+Ccq5XlCUW2L48pZNCYuBDfBh7FxkB7qDgGDiaftEkZZfApRg2E+M9
|
|
16
|
+
G8wkNKTPLDc4wH0FDTijhgxR3Y4PiS1HL2Zhw7bD3CbslmEGgfnnZojNkJtcLeBH
|
|
17
|
+
BLa52/dSwNU4WWLubaYSiAmA9IUMX1/RpfpxOxd4Ykmhz97oFbUaDJFipIggx5sX
|
|
18
|
+
ePAlkTdWnv+RWBxlJwMQ25oEHmRguNYf4Zr/Rxr9cS93Y+mdXIZaBEE0KS2iLRqa
|
|
19
|
+
OiWBki9IMQU4phqPOBAaG7A+eP8PAgMBAAGjZjBkMB0GA1UdDgQWBBTh0YHlzlpf
|
|
20
|
+
BKrS6badZrHF+qwshzAfBgNVHSMEGDAWgBTh0YHlzlpfBKrS6badZrHF+qwshzAS
|
|
21
|
+
BgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
|
|
22
|
+
AAOCAgEAALIY1wkilt/urfEVM5vKzr6utOeDWCUczmWX/RX4ljpRdgF+5fAIS4vH
|
|
23
|
+
tmXkqpSCOVeWUrJV9QvZn6L227ZwuE15cWi8DCDal3Ue90WgAJJZMfTshN4OI8cq
|
|
24
|
+
W9E4EG9wglbEtMnObHlms8F3CHmrw3k6KmUkWGoa+/ENmcVl68u/cMRl1JbW2bM+
|
|
25
|
+
/3A+SAg2c6iPDlehczKx2oa95QW0SkPPWGuNA/CE8CpyANIhu9XFrj3RQ3EqeRcS
|
|
26
|
+
AQQod1RNuHpfETLU/A2gMmvn/w/sx7TB3W5BPs6rprOA37tutPq9u6FTZOcG1Oqj
|
|
27
|
+
C/B7yTqgI7rbyvox7DEXoX7rIiEqyNNUguTk/u3SZ4VXE2kmxdmSh3TQvybfbnXV
|
|
28
|
+
4JbCZVaqiZraqc7oZMnRoWrXRG3ztbnbes/9qhRGI7PqXqeKJBztxRTEVj8ONs1d
|
|
29
|
+
WN5szTwaPIvhkhO3CO5ErU2rVdUr89wKpNXbBODFKRtgxUT70YpmJ46VVaqdAhOZ
|
|
30
|
+
D9EUUn4YaeLaS8AjSF/h7UkjOibNc4qVDiPP+rkehFWM66PVnP1Msh93tc+taIfC
|
|
31
|
+
EYVMxjh8zNbFuoc7fzvvrFILLe7ifvEIUqSVIC/AzplM/Jxw7buXFeGP1qVCBEHq
|
|
32
|
+
391d/9RAfaZ12zkwFsl+IKwE/OZxW8AHa9i1p4GO0YSNuczzEm4=
|
|
33
|
+
-----END CERTIFICATE-----
|