telegrinder 0.4.2__py3-none-any.whl → 0.5.1__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 +37 -55
- telegrinder/__meta__.py +1 -0
- telegrinder/api/__init__.py +6 -4
- telegrinder/api/api.py +100 -26
- telegrinder/api/error.py +42 -8
- telegrinder/api/response.py +4 -1
- telegrinder/api/token.py +2 -2
- telegrinder/bot/__init__.py +9 -25
- telegrinder/bot/bot.py +31 -25
- telegrinder/bot/cute_types/__init__.py +0 -0
- telegrinder/bot/cute_types/base.py +103 -61
- telegrinder/bot/cute_types/callback_query.py +447 -400
- telegrinder/bot/cute_types/chat_join_request.py +59 -62
- telegrinder/bot/cute_types/chat_member_updated.py +154 -157
- telegrinder/bot/cute_types/inline_query.py +41 -44
- telegrinder/bot/cute_types/message.py +98 -67
- telegrinder/bot/cute_types/pre_checkout_query.py +38 -42
- telegrinder/bot/cute_types/update.py +1 -8
- telegrinder/bot/cute_types/utils.py +1 -1
- telegrinder/bot/dispatch/__init__.py +10 -15
- telegrinder/bot/dispatch/abc.py +12 -11
- telegrinder/bot/dispatch/action.py +104 -0
- telegrinder/bot/dispatch/context.py +32 -26
- telegrinder/bot/dispatch/dispatch.py +61 -134
- telegrinder/bot/dispatch/handler/__init__.py +2 -0
- telegrinder/bot/dispatch/handler/abc.py +10 -8
- telegrinder/bot/dispatch/handler/audio_reply.py +2 -3
- telegrinder/bot/dispatch/handler/base.py +10 -33
- telegrinder/bot/dispatch/handler/document_reply.py +2 -3
- telegrinder/bot/dispatch/handler/func.py +55 -87
- telegrinder/bot/dispatch/handler/media_group_reply.py +2 -3
- telegrinder/bot/dispatch/handler/message_reply.py +2 -3
- telegrinder/bot/dispatch/handler/photo_reply.py +2 -3
- telegrinder/bot/dispatch/handler/sticker_reply.py +2 -3
- telegrinder/bot/dispatch/handler/video_reply.py +2 -3
- telegrinder/bot/dispatch/middleware/__init__.py +0 -0
- telegrinder/bot/dispatch/middleware/abc.py +79 -55
- telegrinder/bot/dispatch/middleware/global_middleware.py +18 -33
- telegrinder/bot/dispatch/process.py +84 -105
- telegrinder/bot/dispatch/return_manager/__init__.py +0 -0
- telegrinder/bot/dispatch/return_manager/abc.py +102 -65
- telegrinder/bot/dispatch/return_manager/callback_query.py +4 -5
- telegrinder/bot/dispatch/return_manager/inline_query.py +3 -4
- telegrinder/bot/dispatch/return_manager/message.py +8 -10
- telegrinder/bot/dispatch/return_manager/pre_checkout_query.py +4 -5
- telegrinder/bot/dispatch/view/__init__.py +4 -4
- telegrinder/bot/dispatch/view/abc.py +6 -16
- telegrinder/bot/dispatch/view/base.py +54 -178
- telegrinder/bot/dispatch/view/box.py +19 -18
- telegrinder/bot/dispatch/view/callback_query.py +4 -8
- telegrinder/bot/dispatch/view/chat_join_request.py +5 -6
- telegrinder/bot/dispatch/view/chat_member.py +5 -25
- telegrinder/bot/dispatch/view/error.py +9 -0
- telegrinder/bot/dispatch/view/inline_query.py +4 -8
- telegrinder/bot/dispatch/view/message.py +5 -25
- telegrinder/bot/dispatch/view/pre_checkout_query.py +4 -8
- telegrinder/bot/dispatch/view/raw.py +3 -109
- telegrinder/bot/dispatch/waiter_machine/__init__.py +2 -5
- telegrinder/bot/dispatch/waiter_machine/actions.py +6 -4
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +1 -3
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +1 -1
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +11 -7
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +0 -0
- telegrinder/bot/dispatch/waiter_machine/machine.py +43 -60
- telegrinder/bot/dispatch/waiter_machine/middleware.py +19 -23
- telegrinder/bot/dispatch/waiter_machine/short_state.py +6 -5
- telegrinder/bot/polling/__init__.py +0 -0
- telegrinder/bot/polling/abc.py +0 -0
- telegrinder/bot/polling/polling.py +209 -88
- telegrinder/bot/rules/__init__.py +3 -16
- telegrinder/bot/rules/abc.py +42 -122
- telegrinder/bot/rules/callback_data.py +29 -49
- telegrinder/bot/rules/chat_join.py +5 -23
- telegrinder/bot/rules/command.py +8 -4
- telegrinder/bot/rules/enum_text.py +3 -4
- telegrinder/bot/rules/func.py +7 -14
- telegrinder/bot/rules/fuzzy.py +3 -4
- telegrinder/bot/rules/inline.py +8 -20
- telegrinder/bot/rules/integer.py +2 -3
- telegrinder/bot/rules/is_from.py +12 -11
- telegrinder/bot/rules/logic.py +11 -5
- telegrinder/bot/rules/markup.py +22 -14
- telegrinder/bot/rules/mention.py +8 -7
- telegrinder/bot/rules/message_entities.py +8 -4
- telegrinder/bot/rules/node.py +23 -12
- telegrinder/bot/rules/payload.py +5 -4
- telegrinder/bot/rules/payment_invoice.py +6 -21
- telegrinder/bot/rules/regex.py +2 -4
- telegrinder/bot/rules/rule_enum.py +8 -7
- telegrinder/bot/rules/start.py +5 -6
- telegrinder/bot/rules/state.py +1 -1
- telegrinder/bot/rules/text.py +4 -15
- telegrinder/bot/rules/update.py +3 -4
- telegrinder/bot/scenario/__init__.py +0 -0
- telegrinder/bot/scenario/abc.py +6 -5
- telegrinder/bot/scenario/checkbox.py +1 -1
- telegrinder/bot/scenario/choice.py +30 -39
- telegrinder/client/__init__.py +3 -5
- telegrinder/client/abc.py +11 -6
- telegrinder/client/aiohttp.py +141 -27
- telegrinder/client/form_data.py +1 -1
- telegrinder/model.py +61 -89
- telegrinder/modules.py +325 -102
- telegrinder/msgspec_utils/__init__.py +40 -0
- telegrinder/msgspec_utils/abc.py +18 -0
- telegrinder/msgspec_utils/custom_types/__init__.py +6 -0
- telegrinder/msgspec_utils/custom_types/datetime.py +24 -0
- telegrinder/msgspec_utils/custom_types/enum_meta.py +43 -0
- telegrinder/msgspec_utils/custom_types/literal.py +25 -0
- telegrinder/msgspec_utils/custom_types/option.py +17 -0
- telegrinder/msgspec_utils/decoder.py +389 -0
- telegrinder/msgspec_utils/encoder.py +206 -0
- telegrinder/{msgspec_json.py → msgspec_utils/json.py} +6 -5
- telegrinder/msgspec_utils/tools.py +75 -0
- telegrinder/node/__init__.py +24 -7
- telegrinder/node/attachment.py +1 -0
- telegrinder/node/base.py +154 -72
- telegrinder/node/callback_query.py +5 -5
- telegrinder/node/collection.py +39 -0
- telegrinder/node/command.py +1 -2
- telegrinder/node/composer.py +121 -72
- telegrinder/node/container.py +11 -8
- telegrinder/node/context.py +48 -0
- telegrinder/node/either.py +27 -40
- telegrinder/node/error.py +41 -0
- telegrinder/node/event.py +37 -11
- telegrinder/node/exceptions.py +7 -0
- telegrinder/node/file.py +0 -0
- telegrinder/node/i18n.py +108 -0
- telegrinder/node/me.py +3 -2
- telegrinder/node/payload.py +1 -1
- telegrinder/node/polymorphic.py +63 -28
- telegrinder/node/reply_message.py +12 -0
- telegrinder/node/rule.py +6 -13
- telegrinder/node/scope.py +14 -5
- telegrinder/node/session.py +53 -0
- telegrinder/node/source.py +41 -9
- telegrinder/node/text.py +1 -2
- telegrinder/node/tools/__init__.py +0 -0
- telegrinder/node/tools/generator.py +3 -5
- telegrinder/node/utility.py +16 -0
- telegrinder/py.typed +0 -0
- telegrinder/rules.py +0 -0
- telegrinder/tools/__init__.py +48 -88
- telegrinder/tools/aio.py +103 -0
- telegrinder/tools/callback_data_serialization/__init__.py +5 -0
- telegrinder/tools/{callback_data_serilization → callback_data_serialization}/abc.py +0 -0
- telegrinder/tools/{callback_data_serilization → callback_data_serialization}/json_ser.py +2 -3
- telegrinder/tools/{callback_data_serilization → callback_data_serialization}/msgpack_ser.py +45 -27
- telegrinder/tools/final.py +21 -0
- telegrinder/tools/formatting/__init__.py +2 -18
- telegrinder/tools/formatting/deep_links/__init__.py +39 -0
- telegrinder/tools/formatting/{deep_links.py → deep_links/links.py} +12 -85
- telegrinder/tools/formatting/deep_links/parsing.py +90 -0
- telegrinder/tools/formatting/deep_links/validators.py +8 -0
- telegrinder/tools/formatting/html_formatter.py +18 -45
- telegrinder/tools/fullname.py +83 -0
- telegrinder/tools/global_context/__init__.py +4 -3
- telegrinder/tools/global_context/abc.py +17 -14
- telegrinder/tools/global_context/builtin_context.py +39 -0
- telegrinder/tools/global_context/global_context.py +138 -39
- telegrinder/tools/input_file_directory.py +0 -0
- telegrinder/tools/keyboard/__init__.py +39 -0
- telegrinder/tools/keyboard/abc.py +159 -0
- telegrinder/tools/keyboard/base.py +77 -0
- telegrinder/tools/keyboard/buttons/__init__.py +14 -0
- telegrinder/tools/keyboard/buttons/base.py +18 -0
- telegrinder/tools/{buttons.py → keyboard/buttons/buttons.py} +71 -23
- telegrinder/tools/keyboard/buttons/static_buttons.py +56 -0
- telegrinder/tools/keyboard/buttons/tools.py +18 -0
- telegrinder/tools/keyboard/data.py +20 -0
- telegrinder/tools/keyboard/keyboard.py +131 -0
- telegrinder/tools/keyboard/static_keyboard.py +83 -0
- telegrinder/tools/lifespan.py +87 -51
- telegrinder/tools/limited_dict.py +4 -1
- telegrinder/tools/loop_wrapper.py +332 -0
- telegrinder/tools/magic/__init__.py +32 -0
- telegrinder/tools/magic/annotations.py +165 -0
- telegrinder/tools/magic/dictionary.py +20 -0
- telegrinder/tools/magic/function.py +246 -0
- telegrinder/tools/magic/shortcut.py +111 -0
- telegrinder/tools/parse_mode.py +9 -3
- telegrinder/tools/singleton/__init__.py +4 -0
- telegrinder/tools/singleton/abc.py +14 -0
- telegrinder/tools/singleton/singleton.py +18 -0
- telegrinder/tools/state_storage/__init__.py +0 -0
- telegrinder/tools/state_storage/abc.py +6 -1
- telegrinder/tools/state_storage/memory.py +1 -1
- telegrinder/tools/strings.py +0 -0
- telegrinder/types/__init__.py +307 -268
- telegrinder/types/enums.py +68 -37
- telegrinder/types/input_file.py +3 -3
- telegrinder/types/methods.py +5699 -5055
- telegrinder/types/methods_utils.py +62 -0
- telegrinder/types/objects.py +1782 -994
- telegrinder/verification_utils.py +3 -1
- telegrinder-0.5.1.dist-info/METADATA +162 -0
- telegrinder-0.5.1.dist-info/RECORD +200 -0
- {telegrinder-0.4.2.dist-info → telegrinder-0.5.1.dist-info}/licenses/LICENSE +2 -2
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +0 -20
- telegrinder/bot/rules/id.py +0 -24
- telegrinder/bot/rules/message.py +0 -15
- telegrinder/client/sonic.py +0 -212
- telegrinder/msgspec_utils.py +0 -478
- telegrinder/tools/adapter/__init__.py +0 -19
- telegrinder/tools/adapter/abc.py +0 -49
- telegrinder/tools/adapter/dataclass.py +0 -56
- telegrinder/tools/adapter/errors.py +0 -5
- telegrinder/tools/adapter/event.py +0 -61
- telegrinder/tools/adapter/node.py +0 -46
- telegrinder/tools/adapter/raw_event.py +0 -27
- telegrinder/tools/adapter/raw_update.py +0 -30
- telegrinder/tools/callback_data_serilization/__init__.py +0 -5
- telegrinder/tools/error_handler/__init__.py +0 -10
- telegrinder/tools/error_handler/abc.py +0 -30
- telegrinder/tools/error_handler/error.py +0 -9
- telegrinder/tools/error_handler/error_handler.py +0 -179
- telegrinder/tools/formatting/spec_html_formats.py +0 -75
- telegrinder/tools/functional.py +0 -8
- telegrinder/tools/global_context/telegrinder_ctx.py +0 -27
- telegrinder/tools/i18n/__init__.py +0 -12
- telegrinder/tools/i18n/abc.py +0 -32
- telegrinder/tools/i18n/middleware/__init__.py +0 -3
- telegrinder/tools/i18n/middleware/abc.py +0 -22
- telegrinder/tools/i18n/simple.py +0 -43
- telegrinder/tools/keyboard.py +0 -132
- telegrinder/tools/loop_wrapper/__init__.py +0 -4
- telegrinder/tools/loop_wrapper/abc.py +0 -20
- telegrinder/tools/loop_wrapper/loop_wrapper.py +0 -169
- telegrinder/tools/magic.py +0 -344
- telegrinder-0.4.2.dist-info/METADATA +0 -151
- telegrinder-0.4.2.dist-info/RECORD +0 -182
- {telegrinder-0.4.2.dist-info → telegrinder-0.5.1.dist-info}/WHEEL +0 -0
telegrinder/bot/rules/is_from.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
4
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
3
5
|
from telegrinder.node.source import ChatSource, UserSource
|
|
4
6
|
from telegrinder.types.enums import ChatType, DiceEmoji
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
from .message import MessageRule
|
|
8
|
+
Message: typing.TypeAlias = MessageCute
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class IsBot(ABCRule):
|
|
@@ -71,12 +72,12 @@ class IsChat(ABCRule):
|
|
|
71
72
|
return chat.type in (ChatType.GROUP, ChatType.SUPERGROUP)
|
|
72
73
|
|
|
73
74
|
|
|
74
|
-
class IsDice(
|
|
75
|
+
class IsDice(ABCRule):
|
|
75
76
|
def check(self, message: Message) -> bool:
|
|
76
77
|
return bool(message.dice)
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
class IsDiceEmoji(
|
|
80
|
+
class IsDiceEmoji(ABCRule, requires=[IsDice()]):
|
|
80
81
|
def __init__(self, dice_emoji: DiceEmoji, /) -> None:
|
|
81
82
|
self.dice_emoji = dice_emoji
|
|
82
83
|
|
|
@@ -84,12 +85,12 @@ class IsDiceEmoji(MessageRule, requires=[IsDice()]):
|
|
|
84
85
|
return message.dice.unwrap().emoji == self.dice_emoji
|
|
85
86
|
|
|
86
87
|
|
|
87
|
-
class IsForward(
|
|
88
|
+
class IsForward(ABCRule):
|
|
88
89
|
def check(self, message: Message) -> bool:
|
|
89
90
|
return bool(message.forward_origin)
|
|
90
91
|
|
|
91
92
|
|
|
92
|
-
class IsForwardType(
|
|
93
|
+
class IsForwardType(ABCRule, requires=[IsForward()]):
|
|
93
94
|
def __init__(self, fwd_type: typing.Literal["user", "hidden_user", "chat", "channel"], /) -> None:
|
|
94
95
|
self.fwd_type = fwd_type
|
|
95
96
|
|
|
@@ -97,27 +98,27 @@ class IsForwardType(MessageRule, requires=[IsForward()]):
|
|
|
97
98
|
return message.forward_origin.unwrap().v.type == self.fwd_type
|
|
98
99
|
|
|
99
100
|
|
|
100
|
-
class IsReply(
|
|
101
|
+
class IsReply(ABCRule):
|
|
101
102
|
def check(self, message: Message) -> bool:
|
|
102
103
|
return bool(message.reply_to_message)
|
|
103
104
|
|
|
104
105
|
|
|
105
|
-
class IsSticker(
|
|
106
|
+
class IsSticker(ABCRule):
|
|
106
107
|
def check(self, message: Message) -> bool:
|
|
107
108
|
return bool(message.sticker)
|
|
108
109
|
|
|
109
110
|
|
|
110
|
-
class IsVideoNote(
|
|
111
|
+
class IsVideoNote(ABCRule):
|
|
111
112
|
def check(self, message: Message) -> bool:
|
|
112
113
|
return bool(message.video_note)
|
|
113
114
|
|
|
114
115
|
|
|
115
|
-
class IsDocument(
|
|
116
|
+
class IsDocument(ABCRule):
|
|
116
117
|
def check(self, message: Message) -> bool:
|
|
117
118
|
return bool(message.document)
|
|
118
119
|
|
|
119
120
|
|
|
120
|
-
class IsPhoto(
|
|
121
|
+
class IsPhoto(ABCRule):
|
|
121
122
|
def check(self, message: Message) -> bool:
|
|
122
123
|
return bool(message.photo)
|
|
123
124
|
|
telegrinder/bot/rules/logic.py
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
|
-
from .
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.rules.abc import ABCRule, Context, check_rule
|
|
5
|
+
from telegrinder.types.objects import Update
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
class If(ABCRule):
|
|
7
9
|
def __init__(self, condition: ABCRule) -> None:
|
|
8
10
|
self.conditions = [condition]
|
|
9
11
|
|
|
10
|
-
async def check(self, update:
|
|
12
|
+
async def check(self, update: Update, api: API, ctx: Context) -> bool:
|
|
11
13
|
for condition in self.conditions[:-1]:
|
|
12
|
-
if not await check_rule(
|
|
14
|
+
if not await check_rule(api, condition, update, ctx):
|
|
13
15
|
return True
|
|
14
|
-
return await check_rule(update.api, self.conditions[-1], update, ctx)
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
return await check_rule(api, self.conditions[-1], update, ctx)
|
|
18
|
+
|
|
19
|
+
def then(self, condition: ABCRule, /) -> typing.Self:
|
|
17
20
|
self.conditions.append(condition)
|
|
18
21
|
return self
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
__all__ = ("If",)
|
telegrinder/bot/rules/markup.py
CHANGED
|
@@ -1,41 +1,49 @@
|
|
|
1
|
+
import re
|
|
1
2
|
import typing
|
|
2
3
|
|
|
3
4
|
import vbml
|
|
4
5
|
|
|
5
6
|
from telegrinder.bot.dispatch.context import Context
|
|
6
|
-
from telegrinder.
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
7
8
|
from telegrinder.node.text import Caption, Text
|
|
8
|
-
from telegrinder.tools.global_context.
|
|
9
|
-
|
|
10
|
-
from .abc import ABCRule
|
|
9
|
+
from telegrinder.tools.global_context.builtin_context import TelegrinderContext
|
|
11
10
|
|
|
12
11
|
type PatternLike = str | vbml.Pattern
|
|
13
|
-
|
|
12
|
+
|
|
13
|
+
TELEGRINDER_CONTEXT: typing.Final[TelegrinderContext] = TelegrinderContext()
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def check_string(patterns: list[vbml.Pattern], s: str, ctx: Context) -> bool:
|
|
17
17
|
for pattern in patterns:
|
|
18
|
-
match
|
|
19
|
-
case None | False:
|
|
20
|
-
continue
|
|
18
|
+
match TELEGRINDER_CONTEXT.vbml_patcher.check(pattern, s):
|
|
21
19
|
case {**response}:
|
|
22
20
|
ctx |= response
|
|
21
|
+
case None | False:
|
|
22
|
+
continue
|
|
23
|
+
|
|
23
24
|
return True
|
|
25
|
+
|
|
24
26
|
return False
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
class Markup(ABCRule):
|
|
28
30
|
"""Markup Language. See the [vbml documentation](https://github.com/tesseradecade/vbml/blob/master/docs/index.md)."""
|
|
29
31
|
|
|
30
|
-
def __init__(
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
patterns: PatternLike | list[PatternLike],
|
|
35
|
+
/,
|
|
36
|
+
*,
|
|
37
|
+
flags: re.RegexFlag | None = None,
|
|
38
|
+
) -> None:
|
|
33
39
|
self.patterns = [
|
|
34
|
-
vbml.Pattern(pattern, flags=
|
|
35
|
-
|
|
40
|
+
vbml.Pattern(text=pattern, flags=flags or TELEGRINDER_CONTEXT.vbml_pattern_flags)
|
|
41
|
+
if isinstance(pattern, str)
|
|
42
|
+
else pattern
|
|
43
|
+
for pattern in ([patterns] if not isinstance(patterns, list) else patterns)
|
|
36
44
|
]
|
|
37
45
|
|
|
38
|
-
def check(self, text:
|
|
46
|
+
def check(self, text: Text | Caption, ctx: Context) -> bool:
|
|
39
47
|
return check_string(self.patterns, text, ctx)
|
|
40
48
|
|
|
41
49
|
|
telegrinder/bot/rules/mention.py
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
2
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
3
|
+
from telegrinder.bot.rules.text import HasText
|
|
1
4
|
from telegrinder.types.enums import MessageEntityType
|
|
2
5
|
|
|
3
|
-
from .message import Message, MessageRule
|
|
4
|
-
from .text import HasText
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if not
|
|
7
|
+
class HasMention(ABCRule, requires=[HasText()]):
|
|
8
|
+
def check(self, message: MessageCute) -> bool:
|
|
9
|
+
entities = message.entities.unwrap_or_none()
|
|
10
|
+
if not entities:
|
|
10
11
|
return False
|
|
11
|
-
return any(entity.type == MessageEntityType.MENTION for entity in
|
|
12
|
+
return any(entity.type == MessageEntityType.MENTION for entity in entities)
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
__all__ = ("HasMention",)
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
1
4
|
from telegrinder.bot.dispatch.context import Context
|
|
5
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
2
6
|
from telegrinder.types.enums import MessageEntityType
|
|
3
7
|
from telegrinder.types.objects import MessageEntity
|
|
4
8
|
|
|
5
|
-
from .message import Message, MessageRule
|
|
6
|
-
|
|
7
9
|
type Entity = str | MessageEntityType
|
|
8
10
|
|
|
11
|
+
Message: typing.TypeAlias = MessageCute
|
|
12
|
+
|
|
9
13
|
|
|
10
|
-
class HasEntities(
|
|
14
|
+
class HasEntities(ABCRule):
|
|
11
15
|
def check(self, message: Message) -> bool:
|
|
12
16
|
return bool(message.entities)
|
|
13
17
|
|
|
14
18
|
|
|
15
|
-
class MessageEntities(
|
|
19
|
+
class MessageEntities(ABCRule, requires=[HasEntities()]):
|
|
16
20
|
def __init__(self, entities: Entity | list[Entity], /) -> None:
|
|
17
21
|
self.entities = [entities] if not isinstance(entities, list) else entities
|
|
18
22
|
|
telegrinder/bot/rules/node.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
from fntypes.result import Ok
|
|
2
2
|
|
|
3
|
+
from telegrinder.api.api import API
|
|
3
4
|
from telegrinder.bot.dispatch.context import Context
|
|
4
|
-
from telegrinder.
|
|
5
|
-
from telegrinder.
|
|
6
|
-
|
|
7
|
-
from .
|
|
5
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
6
|
+
from telegrinder.node.base import IsNode, is_node
|
|
7
|
+
from telegrinder.node.composer import compose_nodes
|
|
8
|
+
from telegrinder.types.objects import Update
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class NodeRule(ABCRule):
|
|
@@ -19,14 +20,24 @@ class NodeRule(ABCRule):
|
|
|
19
20
|
self.nodes.append(node_t)
|
|
20
21
|
self.node_keys.append(node_key)
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
async def check(self, update: Update, api: API, context: Context) -> bool:
|
|
24
|
+
result = await compose_nodes(
|
|
25
|
+
nodes={f"node_{i}": node for i, node in enumerate(self.nodes)},
|
|
26
|
+
ctx=context,
|
|
27
|
+
data={Update: update, API: api},
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
match result:
|
|
31
|
+
case Ok(collection):
|
|
32
|
+
resolved_nodes = collection.sessions
|
|
33
|
+
case _:
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
for i, (node_key, node_value) in enumerate(resolved_nodes.items()):
|
|
37
|
+
if (key := self.node_keys[i]) and node_key == key:
|
|
38
|
+
context[key] = node_value
|
|
25
39
|
|
|
26
|
-
|
|
27
|
-
for i, node in enumerate(resolved_nodes):
|
|
28
|
-
if key := self.node_keys[i]:
|
|
29
|
-
ctx[key] = node
|
|
40
|
+
await collection.close_all()
|
|
30
41
|
return True
|
|
31
42
|
|
|
32
43
|
|
telegrinder/bot/rules/payload.py
CHANGED
|
@@ -7,11 +7,11 @@ import msgspec
|
|
|
7
7
|
from telegrinder.bot.dispatch.context import Context
|
|
8
8
|
from telegrinder.bot.rules.abc import ABCRule
|
|
9
9
|
from telegrinder.bot.rules.markup import Markup, PatternLike, check_string
|
|
10
|
-
from telegrinder.
|
|
10
|
+
from telegrinder.msgspec_utils.json import loads
|
|
11
11
|
from telegrinder.node.base import Node
|
|
12
12
|
from telegrinder.node.payload import Payload, PayloadData
|
|
13
|
-
from telegrinder.tools.
|
|
14
|
-
from telegrinder.tools.
|
|
13
|
+
from telegrinder.tools.callback_data_serialization.abc import ABCDataSerializer, ModelType
|
|
14
|
+
from telegrinder.tools.callback_data_serialization.json_ser import JSONSerializer
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class PayloadRule[Data](ABCRule):
|
|
@@ -35,10 +35,11 @@ class PayloadRule[Data](ABCRule):
|
|
|
35
35
|
return True
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class PayloadModelRule[Model: ModelType](PayloadRule
|
|
38
|
+
class PayloadModelRule[Model: ModelType](PayloadRule):
|
|
39
39
|
def __init__(
|
|
40
40
|
self,
|
|
41
41
|
model_t: type[Model],
|
|
42
|
+
/,
|
|
42
43
|
*,
|
|
43
44
|
serializer: type[ABCDataSerializer[Model]] | None = None,
|
|
44
45
|
alias: str | None = None,
|
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
import abc
|
|
2
|
-
import typing
|
|
3
|
-
|
|
4
1
|
from telegrinder.bot.cute_types.pre_checkout_query import PreCheckoutQueryCute
|
|
5
|
-
from telegrinder.bot.rules.abc import ABCRule
|
|
6
|
-
from telegrinder.
|
|
7
|
-
from telegrinder.types.enums import Currency, UpdateType
|
|
8
|
-
|
|
9
|
-
PreCheckoutQuery: typing.TypeAlias = PreCheckoutQueryCute
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class PaymentInvoiceRule(
|
|
13
|
-
ABCRule[PreCheckoutQuery],
|
|
14
|
-
abc.ABC,
|
|
15
|
-
adapter=EventAdapter(UpdateType.PRE_CHECKOUT_QUERY, PreCheckoutQuery),
|
|
16
|
-
):
|
|
17
|
-
@abc.abstractmethod
|
|
18
|
-
def check(self, *args: typing.Any, **kwargs: typing.Any) -> CheckResult: ...
|
|
2
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
3
|
+
from telegrinder.types.enums import Currency
|
|
19
4
|
|
|
20
5
|
|
|
21
|
-
class PaymentInvoiceCurrency(
|
|
22
|
-
def __init__(self, currency:
|
|
6
|
+
class PaymentInvoiceCurrency(ABCRule):
|
|
7
|
+
def __init__(self, currency: Currency, /) -> None:
|
|
23
8
|
self.currency = currency
|
|
24
9
|
|
|
25
|
-
def check(self, query:
|
|
10
|
+
def check(self, query: PreCheckoutQueryCute) -> bool:
|
|
26
11
|
return self.currency == query.currency
|
|
27
12
|
|
|
28
13
|
|
|
29
|
-
__all__ = ("PaymentInvoiceCurrency",
|
|
14
|
+
__all__ = ("PaymentInvoiceCurrency",)
|
telegrinder/bot/rules/regex.py
CHANGED
|
@@ -2,11 +2,9 @@ import re
|
|
|
2
2
|
import typing
|
|
3
3
|
|
|
4
4
|
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
from telegrinder.
|
|
5
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
6
6
|
from telegrinder.node.text import Caption, Text
|
|
7
7
|
|
|
8
|
-
from .abc import ABCRule
|
|
9
|
-
|
|
10
8
|
type PatternLike = str | typing.Pattern[str]
|
|
11
9
|
|
|
12
10
|
|
|
@@ -21,7 +19,7 @@ class Regex(ABCRule):
|
|
|
21
19
|
case _:
|
|
22
20
|
self.regexp.extend(re.compile(regexp) if isinstance(regexp, str) else regexp for regexp in regexp)
|
|
23
21
|
|
|
24
|
-
def check(self, text:
|
|
22
|
+
def check(self, text: Text | Caption, ctx: Context) -> bool:
|
|
25
23
|
for regexp in self.regexp:
|
|
26
24
|
response = re.match(regexp, text)
|
|
27
25
|
if response is not None:
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import typing
|
|
3
3
|
|
|
4
|
+
from telegrinder.api.api import API
|
|
4
5
|
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
|
|
6
|
-
from .
|
|
7
|
-
from .
|
|
6
|
+
from telegrinder.bot.rules.abc import ABCRule, check_rule
|
|
7
|
+
from telegrinder.bot.rules.func import FuncRule
|
|
8
|
+
from telegrinder.types.objects import Update
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
@dataclasses.dataclass(slots=True)
|
|
@@ -42,11 +43,11 @@ class RuleEnum(ABCRule):
|
|
|
42
43
|
|
|
43
44
|
@classmethod
|
|
44
45
|
def save_state(cls, ctx: Context, enum: RuleEnumState) -> None:
|
|
45
|
-
ctx.update({cls.
|
|
46
|
+
ctx.update({cls.__name__ + "_state": enum})
|
|
46
47
|
|
|
47
48
|
@classmethod
|
|
48
49
|
def check_state(cls, ctx: Context) -> RuleEnumState | None:
|
|
49
|
-
return ctx.get(cls.
|
|
50
|
+
return ctx.get(cls.__name__ + "_state")
|
|
50
51
|
|
|
51
52
|
@classmethod
|
|
52
53
|
def must_be_state(cls, ctx: Context, state: RuleEnumState) -> bool:
|
|
@@ -55,13 +56,13 @@ class RuleEnum(ABCRule):
|
|
|
55
56
|
return False
|
|
56
57
|
return real_state == state
|
|
57
58
|
|
|
58
|
-
async def check(self, event: Update, ctx: Context) -> bool:
|
|
59
|
+
async def check(self, event: Update, api: API, ctx: Context) -> bool:
|
|
59
60
|
if self.check_state(ctx):
|
|
60
61
|
return True
|
|
61
62
|
|
|
62
63
|
for enum in self.__enum__:
|
|
63
64
|
ctx_copy = ctx.copy()
|
|
64
|
-
if await check_rule(
|
|
65
|
+
if await check_rule(api, enum.rule, event, ctx_copy):
|
|
65
66
|
ctx.update(ctx_copy)
|
|
66
67
|
self.save_state(ctx, enum)
|
|
67
68
|
return True
|
telegrinder/bot/rules/start.py
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
3
|
from telegrinder.bot.dispatch.context import Context
|
|
4
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
5
|
+
from telegrinder.bot.rules.is_from import IsPrivate
|
|
6
|
+
from telegrinder.bot.rules.markup import Markup
|
|
7
|
+
from telegrinder.bot.rules.message_entities import MessageEntities
|
|
4
8
|
from telegrinder.types.enums import MessageEntityType
|
|
5
9
|
|
|
6
|
-
from .is_from import IsPrivate
|
|
7
|
-
from .markup import Markup
|
|
8
|
-
from .message import MessageRule
|
|
9
|
-
from .message_entities import MessageEntities
|
|
10
|
-
|
|
11
10
|
|
|
12
11
|
class StartCommand(
|
|
13
|
-
|
|
12
|
+
ABCRule,
|
|
14
13
|
requires=[
|
|
15
14
|
IsPrivate(),
|
|
16
15
|
MessageEntities(MessageEntityType.BOT_COMMAND),
|
telegrinder/bot/rules/state.py
CHANGED
telegrinder/bot/rules/text.py
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
1
|
from telegrinder import node
|
|
4
|
-
from telegrinder.
|
|
5
|
-
|
|
6
|
-
from .abc import ABCRule, with_caching_translations
|
|
7
|
-
from .node import NodeRule
|
|
2
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
3
|
+
from telegrinder.bot.rules.node import NodeRule
|
|
8
4
|
|
|
9
5
|
|
|
10
6
|
class HasText(NodeRule):
|
|
@@ -21,18 +17,11 @@ class Text(ABCRule):
|
|
|
21
17
|
def __init__(self, texts: str | list[str], /, *, ignore_case: bool = False) -> None:
|
|
22
18
|
if not isinstance(texts, list):
|
|
23
19
|
texts = [texts]
|
|
24
|
-
self.texts = texts if not ignore_case else
|
|
20
|
+
self.texts = set(texts) if not ignore_case else set(map(str.lower, texts))
|
|
25
21
|
self.ignore_case = ignore_case
|
|
26
22
|
|
|
27
|
-
def check(self, text: node.
|
|
23
|
+
def check(self, text: node.text.Text | node.text.Caption) -> bool:
|
|
28
24
|
return (text if not self.ignore_case else text.lower()) in self.texts
|
|
29
25
|
|
|
30
|
-
@with_caching_translations
|
|
31
|
-
async def translate(self, translator: ABCTranslator) -> typing.Self:
|
|
32
|
-
return self.__class__(
|
|
33
|
-
[translator.get(text) for text in self.texts],
|
|
34
|
-
ignore_case=self.ignore_case,
|
|
35
|
-
)
|
|
36
|
-
|
|
37
26
|
|
|
38
27
|
__all__ = ("HasCaption", "HasText", "Text")
|
telegrinder/bot/rules/update.py
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
from telegrinder.bot.
|
|
1
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
2
2
|
from telegrinder.types.enums import UpdateType
|
|
3
|
-
|
|
4
|
-
from .abc import ABCRule
|
|
3
|
+
from telegrinder.types.objects import Update
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class IsUpdateType(ABCRule):
|
|
8
7
|
def __init__(self, update_type: UpdateType, /) -> None:
|
|
9
8
|
self.update_type = update_type
|
|
10
9
|
|
|
11
|
-
def check(self, event:
|
|
10
|
+
def check(self, event: Update) -> bool:
|
|
12
11
|
return event.update_type == self.update_type
|
|
13
12
|
|
|
14
13
|
|
|
File without changes
|
telegrinder/bot/scenario/abc.py
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import typing
|
|
2
4
|
from abc import ABC, abstractmethod
|
|
3
5
|
|
|
4
|
-
from telegrinder.bot.cute_types.base import BaseCute
|
|
5
|
-
|
|
6
6
|
if typing.TYPE_CHECKING:
|
|
7
|
-
from telegrinder.api import API
|
|
8
|
-
from telegrinder.bot.
|
|
7
|
+
from telegrinder.api.api import API
|
|
8
|
+
from telegrinder.bot.cute_types.base import BaseCute
|
|
9
|
+
from telegrinder.bot.dispatch.waiter_machine.hasher.hasher import Hasher
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class ABCScenario[Event: BaseCute](ABC):
|
|
12
13
|
@abstractmethod
|
|
13
|
-
def wait(self,
|
|
14
|
+
def wait(self, hasher: Hasher, api: API) -> typing.Any:
|
|
14
15
|
pass
|
|
15
16
|
|
|
16
17
|
|
|
@@ -1,48 +1,39 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
|
+
from telegrinder.api.api import API
|
|
3
4
|
from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
|
|
4
5
|
from telegrinder.bot.dispatch.waiter_machine.hasher.hasher import Hasher
|
|
5
6
|
from telegrinder.bot.scenario.checkbox import Checkbox, ChoiceAction
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
reply_markup=self.get_markup(),
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
return True
|
|
40
|
-
|
|
41
|
-
async def wait(self, hasher, api):
|
|
42
|
-
if len(tuple(choice for choice in self.choices if choice.is_picked)) != 1:
|
|
43
|
-
raise ValueError("Exactly one choice must be picked.")
|
|
44
|
-
choices, m_id = await super().wait(hasher, api)
|
|
45
|
-
return tuple(choices.keys())[tuple(choices.values()).index(True)], m_id
|
|
8
|
+
|
|
9
|
+
class Choice[Key: typing.Hashable](Checkbox[Key]):
|
|
10
|
+
async def handle(self, cb: CallbackQueryCute) -> bool:
|
|
11
|
+
code = cb.data.unwrap().replace(self.random_code + "/", "", 1)
|
|
12
|
+
if code == ChoiceAction.READY:
|
|
13
|
+
return False
|
|
14
|
+
|
|
15
|
+
for choice in self.choices:
|
|
16
|
+
choice.is_picked = False
|
|
17
|
+
|
|
18
|
+
for i, choice in enumerate(self.choices):
|
|
19
|
+
if choice.code == code:
|
|
20
|
+
self.choices[i].is_picked = True
|
|
21
|
+
await cb.ctx_api.edit_message_text(
|
|
22
|
+
text=self.message,
|
|
23
|
+
chat_id=cb.message.unwrap().v.chat.id,
|
|
24
|
+
message_id=cb.message.unwrap().v.message_id,
|
|
25
|
+
parse_mode=self.PARSE_MODE,
|
|
26
|
+
reply_markup=self.get_markup(),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
async def wait(self, hasher: Hasher[CallbackQueryCute, int], api: API) -> tuple[Key, int]:
|
|
32
|
+
if len(tuple(choice for choice in self.choices if choice.is_picked)) != 1:
|
|
33
|
+
raise ValueError("Exactly one choice must be picked.")
|
|
34
|
+
|
|
35
|
+
choices, m_id = await super().wait(hasher, api)
|
|
36
|
+
return tuple(choices.keys())[tuple(choices.values()).index(True)], m_id
|
|
46
37
|
|
|
47
38
|
|
|
48
39
|
__all__ = ("Choice",)
|
telegrinder/client/__init__.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
from .abc import ABCClient
|
|
2
|
-
from .aiohttp import AiohttpClient
|
|
3
|
-
from .form_data import MultipartFormProto, encode_form_data
|
|
4
|
-
from .sonic import AiosonicClient
|
|
1
|
+
from telegrinder.client.abc import ABCClient
|
|
2
|
+
from telegrinder.client.aiohttp import AiohttpClient
|
|
3
|
+
from telegrinder.client.form_data import MultipartFormProto, encode_form_data
|
|
5
4
|
|
|
6
5
|
__all__ = (
|
|
7
6
|
"ABCClient",
|
|
8
7
|
"AiohttpClient",
|
|
9
|
-
"AiosonicClient",
|
|
10
8
|
"MultipartFormProto",
|
|
11
9
|
"encode_form_data",
|
|
12
10
|
)
|