telegrinder 0.3.3.post1__py3-none-any.whl → 0.3.4.post1__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 telegrinder might be problematic. Click here for more details.
- telegrinder/__init__.py +144 -144
- telegrinder/api/__init__.py +8 -8
- telegrinder/api/api.py +93 -93
- telegrinder/api/error.py +16 -16
- telegrinder/api/response.py +20 -20
- telegrinder/api/token.py +36 -36
- telegrinder/bot/__init__.py +66 -66
- telegrinder/bot/bot.py +76 -76
- telegrinder/bot/cute_types/__init__.py +17 -17
- telegrinder/bot/cute_types/base.py +258 -258
- telegrinder/bot/cute_types/callback_query.py +385 -385
- telegrinder/bot/cute_types/chat_join_request.py +61 -61
- telegrinder/bot/cute_types/chat_member_updated.py +160 -160
- telegrinder/bot/cute_types/inline_query.py +43 -43
- telegrinder/bot/cute_types/message.py +2637 -2637
- telegrinder/bot/cute_types/update.py +104 -109
- telegrinder/bot/cute_types/utils.py +95 -95
- telegrinder/bot/dispatch/__init__.py +55 -55
- telegrinder/bot/dispatch/abc.py +77 -77
- telegrinder/bot/dispatch/context.py +98 -98
- telegrinder/bot/dispatch/dispatch.py +202 -202
- telegrinder/bot/dispatch/handler/__init__.py +13 -13
- telegrinder/bot/dispatch/handler/abc.py +24 -24
- telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
- telegrinder/bot/dispatch/handler/base.py +57 -57
- telegrinder/bot/dispatch/handler/document_reply.py +44 -44
- telegrinder/bot/dispatch/handler/func.py +135 -135
- telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
- telegrinder/bot/dispatch/handler/message_reply.py +36 -36
- telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
- telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
- telegrinder/bot/dispatch/handler/video_reply.py +44 -44
- telegrinder/bot/dispatch/middleware/__init__.py +3 -3
- telegrinder/bot/dispatch/middleware/abc.py +22 -16
- telegrinder/bot/dispatch/process.py +157 -132
- telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
- telegrinder/bot/dispatch/return_manager/abc.py +108 -108
- telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
- telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
- telegrinder/bot/dispatch/return_manager/message.py +36 -36
- telegrinder/bot/dispatch/view/__init__.py +13 -13
- telegrinder/bot/dispatch/view/abc.py +41 -41
- telegrinder/bot/dispatch/view/base.py +200 -200
- telegrinder/bot/dispatch/view/box.py +129 -129
- telegrinder/bot/dispatch/view/callback_query.py +17 -17
- telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
- telegrinder/bot/dispatch/view/chat_member.py +39 -39
- telegrinder/bot/dispatch/view/inline_query.py +17 -17
- telegrinder/bot/dispatch/view/message.py +44 -44
- telegrinder/bot/dispatch/view/raw.py +114 -114
- telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
- telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +55 -55
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +51 -51
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
- telegrinder/bot/dispatch/waiter_machine/machine.py +172 -167
- telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
- telegrinder/bot/dispatch/waiter_machine/short_state.py +68 -68
- telegrinder/bot/polling/__init__.py +4 -4
- telegrinder/bot/polling/abc.py +25 -25
- telegrinder/bot/polling/polling.py +131 -131
- telegrinder/bot/rules/__init__.py +62 -62
- telegrinder/bot/rules/abc.py +213 -213
- telegrinder/bot/rules/adapter/__init__.py +12 -9
- telegrinder/bot/rules/adapter/abc.py +31 -29
- telegrinder/bot/rules/adapter/errors.py +5 -5
- telegrinder/bot/rules/adapter/event.py +65 -67
- telegrinder/bot/rules/adapter/node.py +48 -48
- telegrinder/bot/rules/adapter/raw_event.py +27 -0
- telegrinder/bot/rules/adapter/raw_update.py +30 -30
- telegrinder/bot/rules/callback_data.py +170 -170
- telegrinder/bot/rules/chat_join.py +46 -46
- telegrinder/bot/rules/command.py +126 -126
- telegrinder/bot/rules/enum_text.py +36 -36
- telegrinder/bot/rules/func.py +26 -26
- telegrinder/bot/rules/fuzzy.py +24 -24
- telegrinder/bot/rules/inline.py +60 -60
- telegrinder/bot/rules/integer.py +20 -20
- telegrinder/bot/rules/is_from.py +127 -127
- telegrinder/bot/rules/markup.py +43 -43
- telegrinder/bot/rules/mention.py +14 -14
- telegrinder/bot/rules/message.py +17 -17
- telegrinder/bot/rules/message_entities.py +35 -35
- telegrinder/bot/rules/node.py +27 -27
- telegrinder/bot/rules/regex.py +37 -37
- telegrinder/bot/rules/rule_enum.py +72 -72
- telegrinder/bot/rules/start.py +42 -42
- telegrinder/bot/rules/state.py +37 -37
- telegrinder/bot/rules/text.py +33 -33
- telegrinder/bot/rules/update.py +15 -15
- telegrinder/bot/scenario/__init__.py +5 -5
- telegrinder/bot/scenario/abc.py +19 -19
- telegrinder/bot/scenario/checkbox.py +176 -167
- telegrinder/bot/scenario/choice.py +51 -46
- telegrinder/client/__init__.py +4 -4
- telegrinder/client/abc.py +75 -75
- telegrinder/client/aiohttp.py +130 -130
- telegrinder/model.py +320 -295
- telegrinder/modules.py +237 -237
- telegrinder/msgspec_json.py +14 -14
- telegrinder/msgspec_utils.py +410 -410
- telegrinder/node/__init__.py +0 -0
- telegrinder/node/attachment.py +87 -87
- telegrinder/node/base.py +166 -166
- telegrinder/node/callback_query.py +53 -53
- telegrinder/node/command.py +33 -33
- telegrinder/node/composer.py +198 -198
- telegrinder/node/container.py +27 -27
- telegrinder/node/event.py +65 -65
- telegrinder/node/me.py +16 -16
- telegrinder/node/message.py +14 -14
- telegrinder/node/polymorphic.py +48 -48
- telegrinder/node/rule.py +76 -76
- telegrinder/node/scope.py +38 -38
- telegrinder/node/source.py +71 -71
- telegrinder/node/text.py +41 -41
- telegrinder/node/tools/__init__.py +3 -3
- telegrinder/node/tools/generator.py +40 -40
- telegrinder/node/update.py +15 -15
- telegrinder/rules.py +0 -0
- telegrinder/tools/__init__.py +74 -74
- telegrinder/tools/buttons.py +79 -79
- telegrinder/tools/error_handler/__init__.py +7 -7
- telegrinder/tools/error_handler/abc.py +33 -33
- telegrinder/tools/error_handler/error.py +9 -9
- telegrinder/tools/error_handler/error_handler.py +193 -193
- telegrinder/tools/formatting/__init__.py +46 -46
- telegrinder/tools/formatting/html.py +283 -283
- telegrinder/tools/formatting/links.py +33 -33
- telegrinder/tools/formatting/spec_html_formats.py +111 -111
- telegrinder/tools/functional.py +12 -12
- telegrinder/tools/global_context/__init__.py +7 -7
- telegrinder/tools/global_context/abc.py +63 -63
- telegrinder/tools/global_context/global_context.py +412 -412
- telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
- telegrinder/tools/i18n/__init__.py +7 -7
- telegrinder/tools/i18n/abc.py +30 -30
- telegrinder/tools/i18n/middleware/__init__.py +3 -3
- telegrinder/tools/i18n/middleware/abc.py +25 -25
- telegrinder/tools/i18n/simple.py +43 -43
- telegrinder/tools/kb_set/__init__.py +4 -4
- telegrinder/tools/kb_set/base.py +15 -15
- telegrinder/tools/kb_set/yaml.py +63 -63
- telegrinder/tools/keyboard.py +132 -132
- telegrinder/tools/limited_dict.py +37 -37
- telegrinder/tools/loop_wrapper/__init__.py +4 -4
- telegrinder/tools/loop_wrapper/abc.py +15 -15
- telegrinder/tools/loop_wrapper/loop_wrapper.py +224 -224
- telegrinder/tools/magic.py +157 -157
- telegrinder/tools/parse_mode.py +6 -6
- telegrinder/tools/state_storage/__init__.py +4 -4
- telegrinder/tools/state_storage/abc.py +35 -35
- telegrinder/tools/state_storage/memory.py +25 -25
- telegrinder/types/__init__.py +260 -260
- telegrinder/types/enums.py +701 -701
- telegrinder/types/methods.py +4633 -4633
- telegrinder/types/objects.py +6950 -8561
- telegrinder/verification_utils.py +32 -32
- {telegrinder-0.3.3.post1.dist-info → telegrinder-0.3.4.post1.dist-info}/LICENSE +22 -22
- {telegrinder-0.3.3.post1.dist-info → telegrinder-0.3.4.post1.dist-info}/METADATA +1 -1
- telegrinder-0.3.4.post1.dist-info/RECORD +165 -0
- telegrinder-0.3.3.post1.dist-info/RECORD +0 -164
- {telegrinder-0.3.3.post1.dist-info → telegrinder-0.3.4.post1.dist-info}/WHEEL +0 -0
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from telegrinder.api.api import API
|
|
4
|
-
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
-
from telegrinder.bot.dispatch.context import Context
|
|
6
|
-
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
-
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
-
from telegrinder.types.objects import InputFile
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class PhotoReplyHandler(BaseReplyHandler):
|
|
12
|
-
def __init__(
|
|
13
|
-
self,
|
|
14
|
-
photo: InputFile | str,
|
|
15
|
-
*rules: ABCRule,
|
|
16
|
-
caption: str | None = None,
|
|
17
|
-
parse_mode: str | None = None,
|
|
18
|
-
is_blocking: bool = True,
|
|
19
|
-
as_reply: bool = False,
|
|
20
|
-
preset_context: Context | None = None,
|
|
21
|
-
**default_params: typing.Any,
|
|
22
|
-
) -> None:
|
|
23
|
-
self.photo = photo
|
|
24
|
-
self.parse_mode = parse_mode
|
|
25
|
-
self.caption = caption
|
|
26
|
-
super().__init__(
|
|
27
|
-
*rules,
|
|
28
|
-
is_blocking=is_blocking,
|
|
29
|
-
as_reply=as_reply,
|
|
30
|
-
preset_context=preset_context,
|
|
31
|
-
**default_params,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
35
|
-
method = event.answer_photo if not self.as_reply else event.reply_photo
|
|
36
|
-
await method(
|
|
37
|
-
photo=self.photo,
|
|
38
|
-
parse_mode=self.parse_mode,
|
|
39
|
-
caption=self.caption,
|
|
40
|
-
**self.default_params,
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
__all__ = ("PhotoReplyHandler",)
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
+
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
+
from telegrinder.types.objects import InputFile
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PhotoReplyHandler(BaseReplyHandler):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
photo: InputFile | str,
|
|
15
|
+
*rules: ABCRule,
|
|
16
|
+
caption: str | None = None,
|
|
17
|
+
parse_mode: str | None = None,
|
|
18
|
+
is_blocking: bool = True,
|
|
19
|
+
as_reply: bool = False,
|
|
20
|
+
preset_context: Context | None = None,
|
|
21
|
+
**default_params: typing.Any,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.photo = photo
|
|
24
|
+
self.parse_mode = parse_mode
|
|
25
|
+
self.caption = caption
|
|
26
|
+
super().__init__(
|
|
27
|
+
*rules,
|
|
28
|
+
is_blocking=is_blocking,
|
|
29
|
+
as_reply=as_reply,
|
|
30
|
+
preset_context=preset_context,
|
|
31
|
+
**default_params,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
35
|
+
method = event.answer_photo if not self.as_reply else event.reply_photo
|
|
36
|
+
await method(
|
|
37
|
+
photo=self.photo,
|
|
38
|
+
parse_mode=self.parse_mode,
|
|
39
|
+
caption=self.caption,
|
|
40
|
+
**self.default_params,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
__all__ = ("PhotoReplyHandler",)
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from telegrinder.api.api import API
|
|
4
|
-
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
-
from telegrinder.bot.dispatch.context import Context
|
|
6
|
-
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
-
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
-
from telegrinder.types.objects import InputFile
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class StickerReplyHandler(BaseReplyHandler):
|
|
12
|
-
def __init__(
|
|
13
|
-
self,
|
|
14
|
-
sticker: InputFile | str,
|
|
15
|
-
*rules: ABCRule,
|
|
16
|
-
emoji: str | None = None,
|
|
17
|
-
is_blocking: bool = True,
|
|
18
|
-
as_reply: bool = False,
|
|
19
|
-
preset_context: Context | None = None,
|
|
20
|
-
**default_params: typing.Any,
|
|
21
|
-
) -> None:
|
|
22
|
-
self.sticker = sticker
|
|
23
|
-
self.emoji = emoji
|
|
24
|
-
super().__init__(
|
|
25
|
-
*rules,
|
|
26
|
-
is_blocking=is_blocking,
|
|
27
|
-
as_reply=as_reply,
|
|
28
|
-
preset_context=preset_context,
|
|
29
|
-
**default_params,
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
33
|
-
method = event.answer_sticker if not self.as_reply else event.reply_sticker
|
|
34
|
-
await method(sticker=self.sticker, emoji=self.emoji, **self.default_params)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
__all__ = ("StickerReplyHandler",)
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
+
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
+
from telegrinder.types.objects import InputFile
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class StickerReplyHandler(BaseReplyHandler):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
sticker: InputFile | str,
|
|
15
|
+
*rules: ABCRule,
|
|
16
|
+
emoji: str | None = None,
|
|
17
|
+
is_blocking: bool = True,
|
|
18
|
+
as_reply: bool = False,
|
|
19
|
+
preset_context: Context | None = None,
|
|
20
|
+
**default_params: typing.Any,
|
|
21
|
+
) -> None:
|
|
22
|
+
self.sticker = sticker
|
|
23
|
+
self.emoji = emoji
|
|
24
|
+
super().__init__(
|
|
25
|
+
*rules,
|
|
26
|
+
is_blocking=is_blocking,
|
|
27
|
+
as_reply=as_reply,
|
|
28
|
+
preset_context=preset_context,
|
|
29
|
+
**default_params,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
33
|
+
method = event.answer_sticker if not self.as_reply else event.reply_sticker
|
|
34
|
+
await method(sticker=self.sticker, emoji=self.emoji, **self.default_params)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
__all__ = ("StickerReplyHandler",)
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from telegrinder.api.api import API
|
|
4
|
-
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
-
from telegrinder.bot.dispatch.context import Context
|
|
6
|
-
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
-
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
-
from telegrinder.types.objects import InputFile
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class VideoReplyHandler(BaseReplyHandler):
|
|
12
|
-
def __init__(
|
|
13
|
-
self,
|
|
14
|
-
video: InputFile | str,
|
|
15
|
-
*rules: ABCRule,
|
|
16
|
-
caption: str | None = None,
|
|
17
|
-
parse_mode: str | None = None,
|
|
18
|
-
is_blocking: bool = True,
|
|
19
|
-
as_reply: bool = False,
|
|
20
|
-
preset_context: Context | None = None,
|
|
21
|
-
**default_params: typing.Any,
|
|
22
|
-
) -> None:
|
|
23
|
-
self.video = video
|
|
24
|
-
self.parse_mode = parse_mode
|
|
25
|
-
self.caption = caption
|
|
26
|
-
super().__init__(
|
|
27
|
-
*rules,
|
|
28
|
-
is_blocking=is_blocking,
|
|
29
|
-
as_reply=as_reply,
|
|
30
|
-
preset_context=preset_context,
|
|
31
|
-
**default_params,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
35
|
-
method = event.answer_video if not self.as_reply else event.reply_video
|
|
36
|
-
await method(
|
|
37
|
-
video=self.video,
|
|
38
|
-
parse_mode=self.parse_mode,
|
|
39
|
-
caption=self.caption,
|
|
40
|
-
**self.default_params,
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
__all__ = ("VideoReplyHandler",)
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
+
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
+
from telegrinder.types.objects import InputFile
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class VideoReplyHandler(BaseReplyHandler):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
video: InputFile | str,
|
|
15
|
+
*rules: ABCRule,
|
|
16
|
+
caption: str | None = None,
|
|
17
|
+
parse_mode: str | None = None,
|
|
18
|
+
is_blocking: bool = True,
|
|
19
|
+
as_reply: bool = False,
|
|
20
|
+
preset_context: Context | None = None,
|
|
21
|
+
**default_params: typing.Any,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.video = video
|
|
24
|
+
self.parse_mode = parse_mode
|
|
25
|
+
self.caption = caption
|
|
26
|
+
super().__init__(
|
|
27
|
+
*rules,
|
|
28
|
+
is_blocking=is_blocking,
|
|
29
|
+
as_reply=as_reply,
|
|
30
|
+
preset_context=preset_context,
|
|
31
|
+
**default_params,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
35
|
+
method = event.answer_video if not self.as_reply else event.reply_video
|
|
36
|
+
await method(
|
|
37
|
+
video=self.video,
|
|
38
|
+
parse_mode=self.parse_mode,
|
|
39
|
+
caption=self.caption,
|
|
40
|
+
**self.default_params,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
__all__ = ("VideoReplyHandler",)
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
|
|
2
|
-
|
|
3
|
-
__all__ = ("ABCMiddleware",)
|
|
1
|
+
from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
|
|
2
|
+
|
|
3
|
+
__all__ = ("ABCMiddleware",)
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
from abc import ABC
|
|
3
|
-
|
|
4
|
-
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
from telegrinder.model import Model
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import typing
|
|
2
|
+
from abc import ABC
|
|
3
|
+
|
|
4
|
+
from telegrinder.bot.dispatch.context import Context
|
|
5
|
+
from telegrinder.model import Model
|
|
6
|
+
from telegrinder.types.objects import Update
|
|
7
|
+
|
|
8
|
+
if typing.TYPE_CHECKING:
|
|
9
|
+
from telegrinder.bot.rules.adapter.abc import ABCAdapter
|
|
10
|
+
|
|
11
|
+
Event = typing.TypeVar("Event", bound=Model)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ABCMiddleware(ABC, typing.Generic[Event]):
|
|
15
|
+
adapter: "ABCAdapter[Update, Event] | None" = None
|
|
16
|
+
|
|
17
|
+
async def pre(self, event: Event, ctx: Context) -> bool: ...
|
|
18
|
+
|
|
19
|
+
async def post(self, event: Event, responses: list[typing.Any], ctx: Context) -> None: ...
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = ("ABCMiddleware",)
|
|
@@ -1,132 +1,157 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from
|
|
6
|
-
|
|
7
|
-
from telegrinder.
|
|
8
|
-
from telegrinder.bot.
|
|
9
|
-
from telegrinder.bot.dispatch.
|
|
10
|
-
from telegrinder.
|
|
11
|
-
from telegrinder.
|
|
12
|
-
from telegrinder.
|
|
13
|
-
from telegrinder.
|
|
14
|
-
from telegrinder.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
await middleware.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
1
|
+
import inspect
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
from fntypes.option import Nothing, Option, Some
|
|
5
|
+
from fntypes.result import Error, Ok
|
|
6
|
+
|
|
7
|
+
from telegrinder.api.api import API
|
|
8
|
+
from telegrinder.bot.cute_types.update import UpdateCute
|
|
9
|
+
from telegrinder.bot.dispatch.context import Context
|
|
10
|
+
from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
|
|
11
|
+
from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
|
|
12
|
+
from telegrinder.model import Model
|
|
13
|
+
from telegrinder.modules import logger
|
|
14
|
+
from telegrinder.node.composer import CONTEXT_STORE_NODES_KEY, NodeScope, compose_nodes
|
|
15
|
+
from telegrinder.tools.i18n.abc import I18nEnum
|
|
16
|
+
from telegrinder.types.objects import Update
|
|
17
|
+
|
|
18
|
+
if typing.TYPE_CHECKING:
|
|
19
|
+
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
20
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
21
|
+
from telegrinder.bot.rules.adapter.abc import ABCAdapter
|
|
22
|
+
|
|
23
|
+
T = typing.TypeVar("T")
|
|
24
|
+
Event = typing.TypeVar("Event", bound=Model)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
async def run_adapter(
|
|
28
|
+
adapter: "ABCAdapter[Update, T]",
|
|
29
|
+
api: API,
|
|
30
|
+
update: Update,
|
|
31
|
+
context: Context,
|
|
32
|
+
) -> Option[T]:
|
|
33
|
+
adapt_result = adapter.adapt(api, update, context)
|
|
34
|
+
match await adapt_result if inspect.isawaitable(adapt_result) else adapt_result:
|
|
35
|
+
case Ok(value):
|
|
36
|
+
return Some(value)
|
|
37
|
+
case Error(err):
|
|
38
|
+
logger.debug("Adapter failed with error message: {!r}", str(err))
|
|
39
|
+
return Nothing()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
async def process_inner(
|
|
43
|
+
api: API,
|
|
44
|
+
event: Event,
|
|
45
|
+
raw_event: Update,
|
|
46
|
+
middlewares: list[ABCMiddleware[Event]],
|
|
47
|
+
handlers: list["ABCHandler[Event]"],
|
|
48
|
+
return_manager: ABCReturnManager[Event] | None = None,
|
|
49
|
+
) -> bool:
|
|
50
|
+
logger.debug("Processing {!r}...", event.__class__.__name__)
|
|
51
|
+
ctx = Context(raw_update=raw_event)
|
|
52
|
+
ctx[CONTEXT_STORE_NODES_KEY] = {} # For per-event shared nodes
|
|
53
|
+
|
|
54
|
+
logger.debug("Run pre middlewares...")
|
|
55
|
+
for middleware in middlewares:
|
|
56
|
+
if middleware.adapter is not None:
|
|
57
|
+
match await run_adapter(middleware.adapter, api, raw_event, ctx):
|
|
58
|
+
case Some(val):
|
|
59
|
+
event = val
|
|
60
|
+
case Nothing():
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
middleware_result = await middleware.pre(event, ctx)
|
|
64
|
+
logger.debug("Middleware {!r} returned: {!r}", middleware.__class__.__qualname__, middleware_result)
|
|
65
|
+
if middleware_result is False:
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
found = False
|
|
69
|
+
responses = []
|
|
70
|
+
ctx_copy = ctx.copy()
|
|
71
|
+
|
|
72
|
+
for handler in handlers:
|
|
73
|
+
if await handler.check(api, raw_event, ctx):
|
|
74
|
+
logger.debug("Handler {!r} matched, run...", handler)
|
|
75
|
+
found = True
|
|
76
|
+
response = await handler.run(api, event, ctx)
|
|
77
|
+
logger.debug("Handler {!r} returned: {!r}", handler, response)
|
|
78
|
+
responses.append(response)
|
|
79
|
+
if return_manager is not None:
|
|
80
|
+
await return_manager.run(response, event, ctx)
|
|
81
|
+
if handler.is_blocking:
|
|
82
|
+
break
|
|
83
|
+
|
|
84
|
+
ctx = ctx_copy
|
|
85
|
+
|
|
86
|
+
logger.debug("Run post middlewares...")
|
|
87
|
+
for middleware in middlewares:
|
|
88
|
+
logger.debug("Run post middleware {!r}", middleware.__class__.__qualname__)
|
|
89
|
+
await middleware.post(event, responses, ctx)
|
|
90
|
+
|
|
91
|
+
for session in ctx.get(CONTEXT_STORE_NODES_KEY, {}).values():
|
|
92
|
+
await session.close(scopes=(NodeScope.PER_EVENT,))
|
|
93
|
+
|
|
94
|
+
logger.debug(
|
|
95
|
+
"{} handlers, returns {!r}",
|
|
96
|
+
"No found" if not found else "Found",
|
|
97
|
+
found,
|
|
98
|
+
)
|
|
99
|
+
return found
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
async def check_rule(
|
|
103
|
+
api: API,
|
|
104
|
+
rule: "ABCRule",
|
|
105
|
+
update: Update,
|
|
106
|
+
ctx: Context,
|
|
107
|
+
) -> bool:
|
|
108
|
+
"""Checks requirements, adapts update.
|
|
109
|
+
Returns check result."""
|
|
110
|
+
|
|
111
|
+
# Running adapter
|
|
112
|
+
match await run_adapter(rule.adapter, api, update, ctx):
|
|
113
|
+
case Some(val):
|
|
114
|
+
adapted_value = val
|
|
115
|
+
case Nothing():
|
|
116
|
+
return False
|
|
117
|
+
|
|
118
|
+
# Preparing update
|
|
119
|
+
if isinstance(adapted_val := ctx.get(rule.adapter.ADAPTED_VALUE_KEY or ""), UpdateCute):
|
|
120
|
+
update = adapted_val
|
|
121
|
+
elif isinstance(adapted_value, UpdateCute):
|
|
122
|
+
update = adapted_value
|
|
123
|
+
else:
|
|
124
|
+
update = UpdateCute.from_update(update, bound_api=api)
|
|
125
|
+
|
|
126
|
+
# Running subrules to fetch requirements
|
|
127
|
+
ctx_copy = ctx.copy()
|
|
128
|
+
for requirement in rule.requires:
|
|
129
|
+
if not await check_rule(api, requirement, update, ctx_copy):
|
|
130
|
+
return False
|
|
131
|
+
|
|
132
|
+
# Translating translatable rules
|
|
133
|
+
if I18nEnum.I18N in ctx:
|
|
134
|
+
rule = await rule.translate(ctx[I18nEnum.I18N])
|
|
135
|
+
|
|
136
|
+
ctx |= ctx_copy
|
|
137
|
+
|
|
138
|
+
# Composing required nodes
|
|
139
|
+
nodes = rule.required_nodes
|
|
140
|
+
node_col = None
|
|
141
|
+
if nodes:
|
|
142
|
+
result = await compose_nodes(nodes, ctx, data={Update: update, API: api})
|
|
143
|
+
if not result:
|
|
144
|
+
return False
|
|
145
|
+
node_col = result.value
|
|
146
|
+
|
|
147
|
+
# Running check
|
|
148
|
+
result = await rule.bounding_check(adapted_value, ctx, node_col=node_col)
|
|
149
|
+
|
|
150
|
+
# Closing node sessions if there are any
|
|
151
|
+
if node_col is not None:
|
|
152
|
+
await node_col.close_all()
|
|
153
|
+
|
|
154
|
+
return result
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
__all__ = ("check_rule", "process_inner")
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
from telegrinder.bot.dispatch.return_manager.abc import (
|
|
2
|
-
ABCReturnManager,
|
|
3
|
-
BaseReturnManager,
|
|
4
|
-
Manager,
|
|
5
|
-
register_manager,
|
|
6
|
-
)
|
|
7
|
-
from telegrinder.bot.dispatch.return_manager.callback_query import CallbackQueryReturnManager
|
|
8
|
-
from telegrinder.bot.dispatch.return_manager.inline_query import InlineQueryReturnManager
|
|
9
|
-
from telegrinder.bot.dispatch.return_manager.message import MessageReturnManager
|
|
10
|
-
|
|
11
|
-
__all__ = (
|
|
1
|
+
from telegrinder.bot.dispatch.return_manager.abc import (
|
|
2
|
+
ABCReturnManager,
|
|
3
|
+
BaseReturnManager,
|
|
4
|
+
Manager,
|
|
5
|
+
register_manager,
|
|
6
|
+
)
|
|
7
|
+
from telegrinder.bot.dispatch.return_manager.callback_query import CallbackQueryReturnManager
|
|
8
|
+
from telegrinder.bot.dispatch.return_manager.inline_query import InlineQueryReturnManager
|
|
9
|
+
from telegrinder.bot.dispatch.return_manager.message import MessageReturnManager
|
|
10
|
+
|
|
11
|
+
__all__ = (
|
|
12
12
|
"ABCReturnManager",
|
|
13
13
|
"BaseReturnManager",
|
|
14
14
|
"CallbackQueryReturnManager",
|
|
15
15
|
"InlineQueryReturnManager",
|
|
16
16
|
"Manager",
|
|
17
17
|
"MessageReturnManager",
|
|
18
|
-
"register_manager",
|
|
19
|
-
)
|
|
18
|
+
"register_manager",
|
|
19
|
+
)
|