telegrinder 0.3.1__py3-none-any.whl → 0.3.2__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.

Files changed (164) hide show
  1. telegrinder/__init__.py +144 -144
  2. telegrinder/api/__init__.py +8 -8
  3. telegrinder/api/api.py +93 -93
  4. telegrinder/api/error.py +16 -16
  5. telegrinder/api/response.py +20 -20
  6. telegrinder/api/token.py +36 -36
  7. telegrinder/bot/__init__.py +66 -66
  8. telegrinder/bot/bot.py +76 -76
  9. telegrinder/bot/cute_types/__init__.py +11 -11
  10. telegrinder/bot/cute_types/base.py +258 -234
  11. telegrinder/bot/cute_types/callback_query.py +382 -382
  12. telegrinder/bot/cute_types/chat_join_request.py +61 -61
  13. telegrinder/bot/cute_types/chat_member_updated.py +160 -160
  14. telegrinder/bot/cute_types/inline_query.py +53 -53
  15. telegrinder/bot/cute_types/message.py +2631 -2631
  16. telegrinder/bot/cute_types/update.py +75 -75
  17. telegrinder/bot/cute_types/utils.py +92 -92
  18. telegrinder/bot/dispatch/__init__.py +55 -55
  19. telegrinder/bot/dispatch/abc.py +77 -77
  20. telegrinder/bot/dispatch/context.py +92 -92
  21. telegrinder/bot/dispatch/dispatch.py +202 -201
  22. telegrinder/bot/dispatch/handler/__init__.py +13 -13
  23. telegrinder/bot/dispatch/handler/abc.py +24 -24
  24. telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
  25. telegrinder/bot/dispatch/handler/base.py +57 -57
  26. telegrinder/bot/dispatch/handler/document_reply.py +44 -44
  27. telegrinder/bot/dispatch/handler/func.py +128 -123
  28. telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
  29. telegrinder/bot/dispatch/handler/message_reply.py +36 -36
  30. telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
  31. telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
  32. telegrinder/bot/dispatch/handler/video_reply.py +44 -44
  33. telegrinder/bot/dispatch/middleware/__init__.py +3 -3
  34. telegrinder/bot/dispatch/middleware/abc.py +16 -16
  35. telegrinder/bot/dispatch/process.py +132 -132
  36. telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
  37. telegrinder/bot/dispatch/return_manager/abc.py +108 -108
  38. telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
  39. telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
  40. telegrinder/bot/dispatch/return_manager/message.py +36 -36
  41. telegrinder/bot/dispatch/view/__init__.py +13 -13
  42. telegrinder/bot/dispatch/view/abc.py +41 -41
  43. telegrinder/bot/dispatch/view/base.py +200 -211
  44. telegrinder/bot/dispatch/view/box.py +129 -129
  45. telegrinder/bot/dispatch/view/callback_query.py +17 -17
  46. telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
  47. telegrinder/bot/dispatch/view/chat_member.py +39 -39
  48. telegrinder/bot/dispatch/view/inline_query.py +17 -17
  49. telegrinder/bot/dispatch/view/message.py +44 -44
  50. telegrinder/bot/dispatch/view/raw.py +114 -118
  51. telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
  52. telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
  53. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
  54. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +57 -57
  55. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
  56. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +53 -53
  57. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
  58. telegrinder/bot/dispatch/waiter_machine/machine.py +168 -170
  59. telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
  60. telegrinder/bot/dispatch/waiter_machine/short_state.py +65 -65
  61. telegrinder/bot/polling/__init__.py +4 -4
  62. telegrinder/bot/polling/abc.py +25 -25
  63. telegrinder/bot/polling/polling.py +131 -131
  64. telegrinder/bot/rules/__init__.py +62 -62
  65. telegrinder/bot/rules/abc.py +238 -238
  66. telegrinder/bot/rules/adapter/__init__.py +9 -9
  67. telegrinder/bot/rules/adapter/abc.py +29 -29
  68. telegrinder/bot/rules/adapter/errors.py +5 -5
  69. telegrinder/bot/rules/adapter/event.py +76 -76
  70. telegrinder/bot/rules/adapter/node.py +48 -48
  71. telegrinder/bot/rules/adapter/raw_update.py +30 -30
  72. telegrinder/bot/rules/callback_data.py +171 -171
  73. telegrinder/bot/rules/chat_join.py +48 -48
  74. telegrinder/bot/rules/command.py +126 -126
  75. telegrinder/bot/rules/enum_text.py +36 -36
  76. telegrinder/bot/rules/func.py +26 -26
  77. telegrinder/bot/rules/fuzzy.py +24 -24
  78. telegrinder/bot/rules/inline.py +60 -60
  79. telegrinder/bot/rules/integer.py +20 -20
  80. telegrinder/bot/rules/is_from.py +146 -146
  81. telegrinder/bot/rules/markup.py +43 -43
  82. telegrinder/bot/rules/mention.py +14 -14
  83. telegrinder/bot/rules/message.py +17 -17
  84. telegrinder/bot/rules/message_entities.py +35 -35
  85. telegrinder/bot/rules/node.py +27 -27
  86. telegrinder/bot/rules/regex.py +37 -37
  87. telegrinder/bot/rules/rule_enum.py +72 -72
  88. telegrinder/bot/rules/start.py +42 -42
  89. telegrinder/bot/rules/state.py +37 -37
  90. telegrinder/bot/rules/text.py +33 -33
  91. telegrinder/bot/rules/update.py +15 -15
  92. telegrinder/bot/scenario/__init__.py +5 -5
  93. telegrinder/bot/scenario/abc.py +19 -19
  94. telegrinder/bot/scenario/checkbox.py +167 -147
  95. telegrinder/bot/scenario/choice.py +46 -44
  96. telegrinder/client/__init__.py +4 -4
  97. telegrinder/client/abc.py +75 -75
  98. telegrinder/client/aiohttp.py +130 -130
  99. telegrinder/model.py +244 -244
  100. telegrinder/modules.py +237 -237
  101. telegrinder/msgspec_json.py +14 -14
  102. telegrinder/msgspec_utils.py +410 -410
  103. telegrinder/node/__init__.py +20 -20
  104. telegrinder/node/attachment.py +92 -92
  105. telegrinder/node/base.py +143 -144
  106. telegrinder/node/callback_query.py +14 -14
  107. telegrinder/node/command.py +33 -33
  108. telegrinder/node/composer.py +196 -184
  109. telegrinder/node/container.py +27 -27
  110. telegrinder/node/event.py +71 -73
  111. telegrinder/node/me.py +16 -16
  112. telegrinder/node/message.py +14 -14
  113. telegrinder/node/polymorphic.py +48 -52
  114. telegrinder/node/rule.py +76 -76
  115. telegrinder/node/scope.py +38 -38
  116. telegrinder/node/source.py +71 -71
  117. telegrinder/node/text.py +21 -21
  118. telegrinder/node/tools/__init__.py +3 -3
  119. telegrinder/node/tools/generator.py +40 -40
  120. telegrinder/node/update.py +15 -15
  121. telegrinder/rules.py +0 -0
  122. telegrinder/tools/__init__.py +74 -74
  123. telegrinder/tools/buttons.py +79 -79
  124. telegrinder/tools/error_handler/__init__.py +7 -7
  125. telegrinder/tools/error_handler/abc.py +33 -33
  126. telegrinder/tools/error_handler/error.py +9 -9
  127. telegrinder/tools/error_handler/error_handler.py +193 -193
  128. telegrinder/tools/formatting/__init__.py +46 -46
  129. telegrinder/tools/formatting/html.py +308 -308
  130. telegrinder/tools/formatting/links.py +33 -33
  131. telegrinder/tools/formatting/spec_html_formats.py +111 -111
  132. telegrinder/tools/functional.py +12 -12
  133. telegrinder/tools/global_context/__init__.py +7 -7
  134. telegrinder/tools/global_context/abc.py +63 -63
  135. telegrinder/tools/global_context/global_context.py +412 -412
  136. telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
  137. telegrinder/tools/i18n/__init__.py +12 -12
  138. telegrinder/tools/i18n/abc.py +32 -32
  139. telegrinder/tools/i18n/middleware/__init__.py +3 -3
  140. telegrinder/tools/i18n/middleware/abc.py +25 -25
  141. telegrinder/tools/i18n/simple.py +43 -43
  142. telegrinder/tools/kb_set/__init__.py +4 -4
  143. telegrinder/tools/kb_set/base.py +15 -15
  144. telegrinder/tools/kb_set/yaml.py +63 -63
  145. telegrinder/tools/keyboard.py +128 -128
  146. telegrinder/tools/limited_dict.py +37 -37
  147. telegrinder/tools/loop_wrapper/__init__.py +4 -4
  148. telegrinder/tools/loop_wrapper/abc.py +15 -15
  149. telegrinder/tools/loop_wrapper/loop_wrapper.py +216 -216
  150. telegrinder/tools/magic.py +168 -168
  151. telegrinder/tools/parse_mode.py +6 -6
  152. telegrinder/tools/state_storage/__init__.py +4 -4
  153. telegrinder/tools/state_storage/abc.py +35 -35
  154. telegrinder/tools/state_storage/memory.py +25 -25
  155. telegrinder/types/__init__.py +6 -6
  156. telegrinder/types/enums.py +672 -672
  157. telegrinder/types/methods.py +4633 -4633
  158. telegrinder/types/objects.py +6317 -6317
  159. telegrinder/verification_utils.py +32 -32
  160. {telegrinder-0.3.1.dist-info → telegrinder-0.3.2.dist-info}/LICENSE +22 -22
  161. {telegrinder-0.3.1.dist-info → telegrinder-0.3.2.dist-info}/METADATA +1 -1
  162. telegrinder-0.3.2.dist-info/RECORD +164 -0
  163. telegrinder-0.3.1.dist-info/RECORD +0 -164
  164. {telegrinder-0.3.1.dist-info → telegrinder-0.3.2.dist-info}/WHEEL +0 -0
@@ -1,48 +1,48 @@
1
- import abc
2
- import typing
3
-
4
- from telegrinder.bot.cute_types import ChatJoinRequestCute
5
- from telegrinder.bot.dispatch.context import Context
6
- from telegrinder.bot.rules.adapter import EventAdapter
7
- from telegrinder.types.enums import UpdateType
8
-
9
- from .abc import ABCRule, CheckResult
10
-
11
- ChatJoinRequest: typing.TypeAlias = ChatJoinRequestCute
12
-
13
-
14
- class ChatJoinRequestRule(ABCRule[ChatJoinRequest], requires=[]):
15
- adapter: EventAdapter[ChatJoinRequest] = EventAdapter(UpdateType.CHAT_JOIN_REQUEST, ChatJoinRequest)
16
-
17
- @abc.abstractmethod
18
- def check(self, event: ChatJoinRequest, context: Context) -> CheckResult:
19
- pass
20
-
21
-
22
- class HasInviteLink(ChatJoinRequestRule):
23
- def check(self, event: ChatJoinRequest) -> bool:
24
- return bool(event.invite_link)
25
-
26
-
27
- class InviteLinkName(ChatJoinRequestRule, requires=[HasInviteLink()]):
28
- def __init__(self, name: str, /) -> None:
29
- self.name = name
30
-
31
- def check(self, event: ChatJoinRequest) -> bool:
32
- return event.invite_link.unwrap().name.unwrap_or_none() == self.name
33
-
34
-
35
- class InviteLinkByCreator(ChatJoinRequestRule, requires=[HasInviteLink()]):
36
- def __init__(self, creator_id: int, /) -> None:
37
- self.creator_id = creator_id
38
-
39
- def check(self, event: ChatJoinRequest) -> bool:
40
- return event.invite_link.unwrap().creator.id == self.creator_id
41
-
42
-
43
- __all__ = (
44
- "ChatJoinRequestRule",
45
- "HasInviteLink",
46
- "InviteLinkByCreator",
47
- "InviteLinkName",
48
- )
1
+ import abc
2
+ import typing
3
+
4
+ from telegrinder.bot.cute_types import ChatJoinRequestCute
5
+ from telegrinder.bot.dispatch.context import Context
6
+ from telegrinder.bot.rules.adapter import EventAdapter
7
+ from telegrinder.types.enums import UpdateType
8
+
9
+ from .abc import ABCRule, CheckResult
10
+
11
+ ChatJoinRequest: typing.TypeAlias = ChatJoinRequestCute
12
+
13
+
14
+ class ChatJoinRequestRule(ABCRule[ChatJoinRequest], requires=[]):
15
+ adapter: EventAdapter[ChatJoinRequest] = EventAdapter(UpdateType.CHAT_JOIN_REQUEST, ChatJoinRequest)
16
+
17
+ @abc.abstractmethod
18
+ def check(self, event: ChatJoinRequest, context: Context) -> CheckResult:
19
+ pass
20
+
21
+
22
+ class HasInviteLink(ChatJoinRequestRule):
23
+ def check(self, event: ChatJoinRequest) -> bool:
24
+ return bool(event.invite_link)
25
+
26
+
27
+ class InviteLinkName(ChatJoinRequestRule, requires=[HasInviteLink()]):
28
+ def __init__(self, name: str, /) -> None:
29
+ self.name = name
30
+
31
+ def check(self, event: ChatJoinRequest) -> bool:
32
+ return event.invite_link.unwrap().name.unwrap_or_none() == self.name
33
+
34
+
35
+ class InviteLinkByCreator(ChatJoinRequestRule, requires=[HasInviteLink()]):
36
+ def __init__(self, creator_id: int, /) -> None:
37
+ self.creator_id = creator_id
38
+
39
+ def check(self, event: ChatJoinRequest) -> bool:
40
+ return event.invite_link.unwrap().creator.id == self.creator_id
41
+
42
+
43
+ __all__ = (
44
+ "ChatJoinRequestRule",
45
+ "HasInviteLink",
46
+ "InviteLinkByCreator",
47
+ "InviteLinkName",
48
+ )
@@ -1,126 +1,126 @@
1
- import dataclasses
2
- import typing
3
-
4
- from telegrinder.bot.dispatch.context import Context
5
- from telegrinder.node.command import CommandInfo, single_split
6
- from telegrinder.node.me import Me
7
- from telegrinder.node.source import Source
8
- from telegrinder.types.enums import ChatType
9
-
10
- from .abc import ABCRule
11
-
12
- Validator: typing.TypeAlias = typing.Callable[[str], typing.Any | None]
13
-
14
-
15
- @dataclasses.dataclass(frozen=True, slots=True)
16
- class Argument:
17
- name: str
18
- validators: list[Validator] = dataclasses.field(default_factory=lambda: [])
19
- optional: bool = dataclasses.field(default=False, kw_only=True)
20
-
21
- def check(self, data: str) -> typing.Any | None:
22
- for validator in self.validators:
23
- data = validator(data) # type: ignore
24
- if data is None:
25
- return None
26
- return data
27
-
28
-
29
- class Command(ABCRule):
30
- def __init__(
31
- self,
32
- names: str | typing.Iterable[str],
33
- *arguments: Argument,
34
- prefixes: tuple[str, ...] = ("/",),
35
- separator: str = " ",
36
- lazy: bool = False,
37
- validate_mention: bool = True,
38
- mention_needed_in_chat: bool = False,
39
- ) -> None:
40
- self.names = [names] if isinstance(names, str) else names
41
- self.arguments = arguments
42
- self.prefixes = prefixes
43
- self.separator = separator
44
- self.lazy = lazy
45
- self.validate_mention = validate_mention
46
-
47
- # if true then we'll check for mention when message is from a group
48
- self.mention_needed_in_chat = mention_needed_in_chat
49
-
50
- def remove_prefix(self, text: str) -> str | None:
51
- for prefix in self.prefixes:
52
- if text.startswith(prefix):
53
- return text.removeprefix(prefix)
54
- return None
55
-
56
- def parse_argument(
57
- self,
58
- arguments: list[Argument],
59
- data_s: str,
60
- new_s: str,
61
- s: str,
62
- ) -> dict | None:
63
- argument = arguments[0]
64
- data = argument.check(data_s)
65
- if data is None and not argument.optional:
66
- return None
67
-
68
- if data is None:
69
- return self.parse_arguments(arguments[1:], s)
70
-
71
- with_argument = self.parse_arguments(arguments[1:], new_s)
72
- if with_argument is not None:
73
- return {argument.name: data, **with_argument}
74
-
75
- if not argument.optional:
76
- return None
77
-
78
- return self.parse_arguments(arguments[1:], s)
79
-
80
- def parse_arguments(self, arguments: list[Argument], s: str) -> dict[str, typing.Any] | None:
81
- if not arguments:
82
- return {} if not s else None
83
-
84
- if self.lazy:
85
- return self.parse_argument(arguments, *single_split(s, self.separator), s)
86
-
87
- all_split = s.split(self.separator)
88
- for i in range(1, len(all_split) + 1):
89
- ctx = self.parse_argument(
90
- arguments,
91
- self.separator.join(all_split[:i]),
92
- self.separator.join(all_split[i:]),
93
- s,
94
- )
95
- if ctx is not None:
96
- return ctx
97
-
98
- return None
99
-
100
- def check(self, command: CommandInfo, me: Me, src: Source, ctx: Context) -> bool:
101
- name = self.remove_prefix(command.name)
102
- if name is None:
103
- return False
104
-
105
- if name not in self.names:
106
- return False
107
-
108
- if not command.mention and self.mention_needed_in_chat and src.chat.type is not ChatType.PRIVATE:
109
- return False
110
-
111
- if command.mention and self.validate_mention: # noqa
112
- if command.mention.unwrap().lower() != me.username.unwrap().lower():
113
- return False
114
-
115
- if not self.arguments:
116
- return not command.arguments
117
-
118
- result = self.parse_arguments(list(self.arguments), command.arguments)
119
- if result is None:
120
- return False
121
-
122
- ctx.update(result)
123
- return True
124
-
125
-
126
- __all__ = ("Argument", "Command", "single_split")
1
+ import dataclasses
2
+ import typing
3
+
4
+ from telegrinder.bot.dispatch.context import Context
5
+ from telegrinder.node.command import CommandInfo, single_split
6
+ from telegrinder.node.me import Me
7
+ from telegrinder.node.source import Source
8
+ from telegrinder.types.enums import ChatType
9
+
10
+ from .abc import ABCRule
11
+
12
+ Validator: typing.TypeAlias = typing.Callable[[str], typing.Any | None]
13
+
14
+
15
+ @dataclasses.dataclass(frozen=True, slots=True)
16
+ class Argument:
17
+ name: str
18
+ validators: list[Validator] = dataclasses.field(default_factory=lambda: [])
19
+ optional: bool = dataclasses.field(default=False, kw_only=True)
20
+
21
+ def check(self, data: str) -> typing.Any | None:
22
+ for validator in self.validators:
23
+ data = validator(data) # type: ignore
24
+ if data is None:
25
+ return None
26
+ return data
27
+
28
+
29
+ class Command(ABCRule):
30
+ def __init__(
31
+ self,
32
+ names: str | typing.Iterable[str],
33
+ *arguments: Argument,
34
+ prefixes: tuple[str, ...] = ("/",),
35
+ separator: str = " ",
36
+ lazy: bool = False,
37
+ validate_mention: bool = True,
38
+ mention_needed_in_chat: bool = False,
39
+ ) -> None:
40
+ self.names = [names] if isinstance(names, str) else names
41
+ self.arguments = arguments
42
+ self.prefixes = prefixes
43
+ self.separator = separator
44
+ self.lazy = lazy
45
+ self.validate_mention = validate_mention
46
+
47
+ # if true then we'll check for mention when message is from a group
48
+ self.mention_needed_in_chat = mention_needed_in_chat
49
+
50
+ def remove_prefix(self, text: str) -> str | None:
51
+ for prefix in self.prefixes:
52
+ if text.startswith(prefix):
53
+ return text.removeprefix(prefix)
54
+ return None
55
+
56
+ def parse_argument(
57
+ self,
58
+ arguments: list[Argument],
59
+ data_s: str,
60
+ new_s: str,
61
+ s: str,
62
+ ) -> dict | None:
63
+ argument = arguments[0]
64
+ data = argument.check(data_s)
65
+ if data is None and not argument.optional:
66
+ return None
67
+
68
+ if data is None:
69
+ return self.parse_arguments(arguments[1:], s)
70
+
71
+ with_argument = self.parse_arguments(arguments[1:], new_s)
72
+ if with_argument is not None:
73
+ return {argument.name: data, **with_argument}
74
+
75
+ if not argument.optional:
76
+ return None
77
+
78
+ return self.parse_arguments(arguments[1:], s)
79
+
80
+ def parse_arguments(self, arguments: list[Argument], s: str) -> dict[str, typing.Any] | None:
81
+ if not arguments:
82
+ return {} if not s else None
83
+
84
+ if self.lazy:
85
+ return self.parse_argument(arguments, *single_split(s, self.separator), s)
86
+
87
+ all_split = s.split(self.separator)
88
+ for i in range(1, len(all_split) + 1):
89
+ ctx = self.parse_argument(
90
+ arguments,
91
+ self.separator.join(all_split[:i]),
92
+ self.separator.join(all_split[i:]),
93
+ s,
94
+ )
95
+ if ctx is not None:
96
+ return ctx
97
+
98
+ return None
99
+
100
+ def check(self, command: CommandInfo, me: Me, src: Source, ctx: Context) -> bool:
101
+ name = self.remove_prefix(command.name)
102
+ if name is None:
103
+ return False
104
+
105
+ if name not in self.names:
106
+ return False
107
+
108
+ if not command.mention and self.mention_needed_in_chat and src.chat.type is not ChatType.PRIVATE:
109
+ return False
110
+
111
+ if command.mention and self.validate_mention: # noqa
112
+ if command.mention.unwrap().lower() != me.username.unwrap().lower():
113
+ return False
114
+
115
+ if not self.arguments:
116
+ return not command.arguments
117
+
118
+ result = self.parse_arguments(list(self.arguments), command.arguments)
119
+ if result is None:
120
+ return False
121
+
122
+ ctx.update(result)
123
+ return True
124
+
125
+
126
+ __all__ = ("Argument", "Command", "single_split")
@@ -1,36 +1,36 @@
1
- import enum
2
- import typing
3
-
4
- from telegrinder.bot.dispatch.context import Context
5
- from telegrinder.node.text import Text
6
-
7
- from .abc import ABCRule
8
-
9
- T = typing.TypeVar("T", bound=enum.Enum)
10
-
11
-
12
- class EnumTextRule(ABCRule, typing.Generic[T]):
13
- def __init__(self, enum_t: type[T], *, lower_case: bool = True) -> None:
14
- self.enum_t = enum_t
15
- self.texts = list(
16
- map(
17
- lambda x: x.value.lower() if lower_case else x.value,
18
- self.enum_t,
19
- )
20
- )
21
-
22
- def find(self, s: str) -> T:
23
- for enumeration in self.enum_t:
24
- if enumeration.value.lower() == s:
25
- return enumeration
26
- raise KeyError("Enumeration is undefined.")
27
-
28
- def check(self, text: Text, ctx: Context) -> bool:
29
- text = text.lower() # type: ignore
30
- if text not in self.texts:
31
- return False
32
- ctx.enum_text = self.find(text)
33
- return True
34
-
35
-
36
- __all__ = ("EnumTextRule",)
1
+ import enum
2
+ import typing
3
+
4
+ from telegrinder.bot.dispatch.context import Context
5
+ from telegrinder.node.text import Text
6
+
7
+ from .abc import ABCRule
8
+
9
+ T = typing.TypeVar("T", bound=enum.Enum)
10
+
11
+
12
+ class EnumTextRule(ABCRule, typing.Generic[T]):
13
+ def __init__(self, enum_t: type[T], *, lower_case: bool = True) -> None:
14
+ self.enum_t = enum_t
15
+ self.texts = list(
16
+ map(
17
+ lambda x: x.value.lower() if lower_case else x.value,
18
+ self.enum_t,
19
+ )
20
+ )
21
+
22
+ def find(self, s: str) -> T:
23
+ for enumeration in self.enum_t:
24
+ if enumeration.value.lower() == s:
25
+ return enumeration
26
+ raise KeyError("Enumeration is undefined.")
27
+
28
+ def check(self, text: Text, ctx: Context) -> bool:
29
+ text = text.lower() # type: ignore
30
+ if text not in self.texts:
31
+ return False
32
+ ctx.enum_text = self.find(text)
33
+ return True
34
+
35
+
36
+ __all__ = ("EnumTextRule",)
@@ -1,26 +1,26 @@
1
- import inspect
2
- import typing
3
-
4
- from telegrinder.bot.dispatch.context import Context
5
- from telegrinder.types.objects import Update
6
-
7
- from .abc import ABCAdapter, ABCRule, AdaptTo, RawUpdateAdapter
8
-
9
-
10
- class FuncRule(ABCRule, typing.Generic[AdaptTo]):
11
- def __init__(
12
- self,
13
- func: typing.Callable[[AdaptTo, Context], typing.Awaitable[bool] | bool],
14
- adapter: ABCAdapter[Update, AdaptTo] | None = None,
15
- ) -> None:
16
- self.func = func
17
- self.adapter = adapter or RawUpdateAdapter() # type: ignore
18
-
19
- async def check(self, event: AdaptTo, ctx: Context) -> bool:
20
- result = self.func(event, ctx)
21
- if inspect.isawaitable(result):
22
- return await result
23
- return result # type: ignore
24
-
25
-
26
- __all__ = ("FuncRule",)
1
+ import inspect
2
+ import typing
3
+
4
+ from telegrinder.bot.dispatch.context import Context
5
+ from telegrinder.types.objects import Update
6
+
7
+ from .abc import ABCAdapter, ABCRule, AdaptTo, RawUpdateAdapter
8
+
9
+
10
+ class FuncRule(ABCRule, typing.Generic[AdaptTo]):
11
+ def __init__(
12
+ self,
13
+ func: typing.Callable[[AdaptTo, Context], typing.Awaitable[bool] | bool],
14
+ adapter: ABCAdapter[Update, AdaptTo] | None = None,
15
+ ) -> None:
16
+ self.func = func
17
+ self.adapter = adapter or RawUpdateAdapter() # type: ignore
18
+
19
+ async def check(self, event: AdaptTo, ctx: Context) -> bool:
20
+ result = self.func(event, ctx)
21
+ if inspect.isawaitable(result):
22
+ return await result
23
+ return result # type: ignore
24
+
25
+
26
+ __all__ = ("FuncRule",)
@@ -1,24 +1,24 @@
1
- import difflib
2
-
3
- from telegrinder.bot.dispatch.context import Context
4
- from telegrinder.node.text import Text
5
-
6
- from .abc import ABCRule
7
-
8
-
9
- class FuzzyText(ABCRule):
10
- def __init__(self, texts: str | list[str], min_ratio: float = 0.7) -> None:
11
- if isinstance(texts, str):
12
- texts = [texts]
13
- self.texts = texts
14
- self.min_ratio = min_ratio
15
-
16
- def check(self, message_text: Text, ctx: Context) -> bool:
17
- match = max(difflib.SequenceMatcher(a=message_text, b=text).ratio() for text in self.texts)
18
- if match < self.min_ratio:
19
- return False
20
- ctx.fuzzy_ratio = match
21
- return True
22
-
23
-
24
- __all__ = ("FuzzyText",)
1
+ import difflib
2
+
3
+ from telegrinder.bot.dispatch.context import Context
4
+ from telegrinder.node.text import Text
5
+
6
+ from .abc import ABCRule
7
+
8
+
9
+ class FuzzyText(ABCRule):
10
+ def __init__(self, texts: str | list[str], min_ratio: float = 0.7) -> None:
11
+ if isinstance(texts, str):
12
+ texts = [texts]
13
+ self.texts = texts
14
+ self.min_ratio = min_ratio
15
+
16
+ def check(self, message_text: Text, ctx: Context) -> bool:
17
+ match = max(difflib.SequenceMatcher(a=message_text, b=text).ratio() for text in self.texts)
18
+ if match < self.min_ratio:
19
+ return False
20
+ ctx.fuzzy_ratio = match
21
+ return True
22
+
23
+
24
+ __all__ = ("FuzzyText",)
@@ -1,60 +1,60 @@
1
- import abc
2
- import typing
3
-
4
- from telegrinder.bot.cute_types import InlineQueryCute
5
- from telegrinder.bot.dispatch.context import Context
6
- from telegrinder.bot.rules.abc import ABCRule, CheckResult
7
- from telegrinder.bot.rules.adapter import EventAdapter
8
- from telegrinder.types.enums import ChatType, UpdateType
9
-
10
- from .markup import Markup, PatternLike, check_string
11
-
12
- InlineQuery: typing.TypeAlias = InlineQueryCute
13
-
14
-
15
- class InlineQueryRule(ABCRule[InlineQuery], abc.ABC):
16
- adapter: EventAdapter[InlineQuery] = EventAdapter(UpdateType.INLINE_QUERY, InlineQuery)
17
-
18
- @abc.abstractmethod
19
- def check(self, query: InlineQuery, ctx: Context) -> CheckResult: ...
20
-
21
-
22
- class HasLocation(InlineQueryRule):
23
- def check(self, query: InlineQuery) -> bool:
24
- return bool(query.location)
25
-
26
-
27
- class InlineQueryChatType(InlineQueryRule):
28
- def __init__(self, chat_type: ChatType, /) -> None:
29
- self.chat_type = chat_type
30
-
31
- def check(self, query: InlineQuery) -> bool:
32
- return query.chat_type.map(lambda x: x == self.chat_type).unwrap_or(False)
33
-
34
-
35
- class InlineQueryText(InlineQueryRule):
36
- def __init__(self, texts: str | list[str], *, lower_case: bool = False) -> None:
37
- self.texts = [
38
- text.lower() if lower_case else text for text in ([texts] if isinstance(texts, str) else texts)
39
- ]
40
- self.lower_case = lower_case
41
-
42
- def check(self, query: InlineQuery) -> bool:
43
- return (query.query.lower() if self.lower_case else query.query) in self.texts
44
-
45
-
46
- class InlineQueryMarkup(InlineQueryRule):
47
- def __init__(self, patterns: PatternLike | list[PatternLike], /) -> None:
48
- self.patterns = Markup(patterns).patterns
49
-
50
- def check(self, query: InlineQuery, ctx: Context) -> bool:
51
- return check_string(self.patterns, query.query, ctx)
52
-
53
-
54
- __all__ = (
55
- "HasLocation",
56
- "InlineQueryChatType",
57
- "InlineQueryMarkup",
58
- "InlineQueryRule",
59
- "InlineQueryText",
60
- )
1
+ import abc
2
+ import typing
3
+
4
+ from telegrinder.bot.cute_types import InlineQueryCute
5
+ from telegrinder.bot.dispatch.context import Context
6
+ from telegrinder.bot.rules.abc import ABCRule, CheckResult
7
+ from telegrinder.bot.rules.adapter import EventAdapter
8
+ from telegrinder.types.enums import ChatType, UpdateType
9
+
10
+ from .markup import Markup, PatternLike, check_string
11
+
12
+ InlineQuery: typing.TypeAlias = InlineQueryCute
13
+
14
+
15
+ class InlineQueryRule(ABCRule[InlineQuery], abc.ABC):
16
+ adapter: EventAdapter[InlineQuery] = EventAdapter(UpdateType.INLINE_QUERY, InlineQuery)
17
+
18
+ @abc.abstractmethod
19
+ def check(self, query: InlineQuery, ctx: Context) -> CheckResult: ...
20
+
21
+
22
+ class HasLocation(InlineQueryRule):
23
+ def check(self, query: InlineQuery) -> bool:
24
+ return bool(query.location)
25
+
26
+
27
+ class InlineQueryChatType(InlineQueryRule):
28
+ def __init__(self, chat_type: ChatType, /) -> None:
29
+ self.chat_type = chat_type
30
+
31
+ def check(self, query: InlineQuery) -> bool:
32
+ return query.chat_type.map(lambda x: x == self.chat_type).unwrap_or(False)
33
+
34
+
35
+ class InlineQueryText(InlineQueryRule):
36
+ def __init__(self, texts: str | list[str], *, lower_case: bool = False) -> None:
37
+ self.texts = [
38
+ text.lower() if lower_case else text for text in ([texts] if isinstance(texts, str) else texts)
39
+ ]
40
+ self.lower_case = lower_case
41
+
42
+ def check(self, query: InlineQuery) -> bool:
43
+ return (query.query.lower() if self.lower_case else query.query) in self.texts
44
+
45
+
46
+ class InlineQueryMarkup(InlineQueryRule):
47
+ def __init__(self, patterns: PatternLike | list[PatternLike], /) -> None:
48
+ self.patterns = Markup(patterns).patterns
49
+
50
+ def check(self, query: InlineQuery, ctx: Context) -> bool:
51
+ return check_string(self.patterns, query.query, ctx)
52
+
53
+
54
+ __all__ = (
55
+ "HasLocation",
56
+ "InlineQueryChatType",
57
+ "InlineQueryMarkup",
58
+ "InlineQueryRule",
59
+ "InlineQueryText",
60
+ )