telegrinder 0.3.4__py3-none-any.whl → 0.4.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.

Potentially problematic release.


This version of telegrinder might be problematic. Click here for more details.

Files changed (192) hide show
  1. telegrinder/__init__.py +148 -149
  2. telegrinder/api/__init__.py +9 -8
  3. telegrinder/api/api.py +101 -93
  4. telegrinder/api/error.py +20 -16
  5. telegrinder/api/response.py +20 -20
  6. telegrinder/api/token.py +36 -36
  7. telegrinder/bot/__init__.py +72 -66
  8. telegrinder/bot/bot.py +83 -76
  9. telegrinder/bot/cute_types/__init__.py +19 -17
  10. telegrinder/bot/cute_types/base.py +184 -258
  11. telegrinder/bot/cute_types/callback_query.py +400 -385
  12. telegrinder/bot/cute_types/chat_join_request.py +62 -61
  13. telegrinder/bot/cute_types/chat_member_updated.py +157 -160
  14. telegrinder/bot/cute_types/inline_query.py +44 -43
  15. telegrinder/bot/cute_types/message.py +2590 -2637
  16. telegrinder/bot/cute_types/pre_checkout_query.py +42 -0
  17. telegrinder/bot/cute_types/update.py +112 -104
  18. telegrinder/bot/cute_types/utils.py +62 -95
  19. telegrinder/bot/dispatch/__init__.py +59 -55
  20. telegrinder/bot/dispatch/abc.py +76 -77
  21. telegrinder/bot/dispatch/context.py +96 -98
  22. telegrinder/bot/dispatch/dispatch.py +254 -202
  23. telegrinder/bot/dispatch/handler/__init__.py +13 -13
  24. telegrinder/bot/dispatch/handler/abc.py +23 -24
  25. telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
  26. telegrinder/bot/dispatch/handler/base.py +57 -57
  27. telegrinder/bot/dispatch/handler/document_reply.py +44 -44
  28. telegrinder/bot/dispatch/handler/func.py +129 -135
  29. telegrinder/bot/dispatch/handler/media_group_reply.py +44 -43
  30. telegrinder/bot/dispatch/handler/message_reply.py +36 -36
  31. telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
  32. telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
  33. telegrinder/bot/dispatch/handler/video_reply.py +44 -44
  34. telegrinder/bot/dispatch/middleware/__init__.py +3 -3
  35. telegrinder/bot/dispatch/middleware/abc.py +97 -22
  36. telegrinder/bot/dispatch/middleware/global_middleware.py +70 -0
  37. telegrinder/bot/dispatch/process.py +151 -157
  38. telegrinder/bot/dispatch/return_manager/__init__.py +15 -13
  39. telegrinder/bot/dispatch/return_manager/abc.py +104 -108
  40. telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
  41. telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
  42. telegrinder/bot/dispatch/return_manager/message.py +36 -36
  43. telegrinder/bot/dispatch/return_manager/pre_checkout_query.py +20 -0
  44. telegrinder/bot/dispatch/view/__init__.py +15 -13
  45. telegrinder/bot/dispatch/view/abc.py +45 -41
  46. telegrinder/bot/dispatch/view/base.py +231 -200
  47. telegrinder/bot/dispatch/view/box.py +140 -129
  48. telegrinder/bot/dispatch/view/callback_query.py +16 -17
  49. telegrinder/bot/dispatch/view/chat_join_request.py +11 -16
  50. telegrinder/bot/dispatch/view/chat_member.py +37 -39
  51. telegrinder/bot/dispatch/view/inline_query.py +16 -17
  52. telegrinder/bot/dispatch/view/message.py +43 -44
  53. telegrinder/bot/dispatch/view/pre_checkout_query.py +16 -0
  54. telegrinder/bot/dispatch/view/raw.py +116 -114
  55. telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
  56. telegrinder/bot/dispatch/waiter_machine/actions.py +14 -13
  57. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
  58. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +55 -55
  59. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +59 -57
  60. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +51 -51
  61. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +20 -19
  62. telegrinder/bot/dispatch/waiter_machine/machine.py +251 -172
  63. telegrinder/bot/dispatch/waiter_machine/middleware.py +94 -89
  64. telegrinder/bot/dispatch/waiter_machine/short_state.py +57 -68
  65. telegrinder/bot/polling/__init__.py +4 -4
  66. telegrinder/bot/polling/abc.py +25 -25
  67. telegrinder/bot/polling/polling.py +139 -131
  68. telegrinder/bot/rules/__init__.py +85 -62
  69. telegrinder/bot/rules/abc.py +213 -206
  70. telegrinder/bot/rules/callback_data.py +122 -163
  71. telegrinder/bot/rules/chat_join.py +45 -43
  72. telegrinder/bot/rules/command.py +126 -126
  73. telegrinder/bot/rules/enum_text.py +33 -36
  74. telegrinder/bot/rules/func.py +28 -26
  75. telegrinder/bot/rules/fuzzy.py +24 -24
  76. telegrinder/bot/rules/id.py +24 -0
  77. telegrinder/bot/rules/inline.py +58 -56
  78. telegrinder/bot/rules/integer.py +21 -20
  79. telegrinder/bot/rules/is_from.py +127 -127
  80. telegrinder/bot/rules/logic.py +18 -0
  81. telegrinder/bot/rules/markup.py +42 -43
  82. telegrinder/bot/rules/mention.py +14 -14
  83. telegrinder/bot/rules/message.py +15 -17
  84. telegrinder/bot/rules/message_entities.py +33 -35
  85. telegrinder/bot/rules/node.py +33 -27
  86. telegrinder/bot/rules/payload.py +81 -0
  87. telegrinder/bot/rules/payment_invoice.py +29 -0
  88. telegrinder/bot/rules/regex.py +36 -37
  89. telegrinder/bot/rules/rule_enum.py +72 -72
  90. telegrinder/bot/rules/start.py +42 -42
  91. telegrinder/bot/rules/state.py +35 -37
  92. telegrinder/bot/rules/text.py +38 -33
  93. telegrinder/bot/rules/update.py +15 -15
  94. telegrinder/bot/scenario/__init__.py +5 -5
  95. telegrinder/bot/scenario/abc.py +17 -19
  96. telegrinder/bot/scenario/checkbox.py +174 -176
  97. telegrinder/bot/scenario/choice.py +48 -51
  98. telegrinder/client/__init__.py +12 -4
  99. telegrinder/client/abc.py +100 -75
  100. telegrinder/client/aiohttp.py +134 -130
  101. telegrinder/client/form_data.py +31 -0
  102. telegrinder/client/sonic.py +212 -0
  103. telegrinder/model.py +208 -315
  104. telegrinder/modules.py +239 -237
  105. telegrinder/msgspec_json.py +14 -14
  106. telegrinder/msgspec_utils.py +478 -410
  107. telegrinder/node/__init__.py +86 -25
  108. telegrinder/node/attachment.py +163 -87
  109. telegrinder/node/base.py +288 -160
  110. telegrinder/node/callback_query.py +54 -53
  111. telegrinder/node/command.py +34 -33
  112. telegrinder/node/composer.py +163 -198
  113. telegrinder/node/container.py +33 -27
  114. telegrinder/node/either.py +82 -0
  115. telegrinder/node/event.py +54 -65
  116. telegrinder/node/file.py +51 -0
  117. telegrinder/node/me.py +15 -16
  118. telegrinder/node/payload.py +78 -0
  119. telegrinder/node/polymorphic.py +67 -48
  120. telegrinder/node/rule.py +72 -76
  121. telegrinder/node/scope.py +36 -38
  122. telegrinder/node/source.py +87 -71
  123. telegrinder/node/text.py +53 -41
  124. telegrinder/node/tools/__init__.py +3 -3
  125. telegrinder/node/tools/generator.py +36 -40
  126. telegrinder/py.typed +0 -0
  127. telegrinder/rules.py +1 -62
  128. telegrinder/tools/__init__.py +152 -93
  129. telegrinder/tools/adapter/__init__.py +19 -0
  130. telegrinder/tools/adapter/abc.py +49 -0
  131. telegrinder/tools/adapter/dataclass.py +56 -0
  132. telegrinder/{bot/rules → tools}/adapter/errors.py +5 -5
  133. telegrinder/{bot/rules → tools}/adapter/event.py +63 -65
  134. telegrinder/{bot/rules → tools}/adapter/node.py +46 -48
  135. telegrinder/{bot/rules → tools}/adapter/raw_event.py +27 -27
  136. telegrinder/{bot/rules → tools}/adapter/raw_update.py +30 -30
  137. telegrinder/tools/buttons.py +106 -80
  138. telegrinder/tools/callback_data_serilization/__init__.py +5 -0
  139. telegrinder/tools/callback_data_serilization/abc.py +51 -0
  140. telegrinder/tools/callback_data_serilization/json_ser.py +60 -0
  141. telegrinder/tools/callback_data_serilization/msgpack_ser.py +172 -0
  142. telegrinder/tools/error_handler/__init__.py +7 -7
  143. telegrinder/tools/error_handler/abc.py +30 -33
  144. telegrinder/tools/error_handler/error.py +9 -9
  145. telegrinder/tools/error_handler/error_handler.py +179 -193
  146. telegrinder/tools/formatting/__init__.py +83 -63
  147. telegrinder/tools/formatting/deep_links.py +541 -0
  148. telegrinder/tools/formatting/{html.py → html_formatter.py} +266 -294
  149. telegrinder/tools/formatting/spec_html_formats.py +71 -117
  150. telegrinder/tools/functional.py +8 -12
  151. telegrinder/tools/global_context/__init__.py +7 -7
  152. telegrinder/tools/global_context/abc.py +63 -63
  153. telegrinder/tools/global_context/global_context.py +387 -412
  154. telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
  155. telegrinder/tools/i18n/__init__.py +7 -7
  156. telegrinder/tools/i18n/abc.py +30 -30
  157. telegrinder/tools/i18n/middleware/__init__.py +3 -3
  158. telegrinder/tools/i18n/middleware/abc.py +22 -25
  159. telegrinder/tools/i18n/simple.py +43 -43
  160. telegrinder/tools/input_file_directory.py +30 -0
  161. telegrinder/tools/keyboard.py +128 -128
  162. telegrinder/tools/lifespan.py +105 -0
  163. telegrinder/tools/limited_dict.py +32 -37
  164. telegrinder/tools/loop_wrapper/__init__.py +4 -4
  165. telegrinder/tools/loop_wrapper/abc.py +20 -15
  166. telegrinder/tools/loop_wrapper/loop_wrapper.py +169 -224
  167. telegrinder/tools/magic.py +307 -157
  168. telegrinder/tools/parse_mode.py +6 -6
  169. telegrinder/tools/state_storage/__init__.py +4 -4
  170. telegrinder/tools/state_storage/abc.py +31 -35
  171. telegrinder/tools/state_storage/memory.py +25 -25
  172. telegrinder/tools/strings.py +13 -0
  173. telegrinder/types/__init__.py +268 -260
  174. telegrinder/types/enums.py +711 -701
  175. telegrinder/types/input_file.py +51 -0
  176. telegrinder/types/methods.py +5055 -4633
  177. telegrinder/types/objects.py +7058 -6950
  178. telegrinder/verification_utils.py +30 -32
  179. {telegrinder-0.3.4.dist-info → telegrinder-0.4.0.dist-info}/LICENSE +22 -22
  180. telegrinder-0.4.0.dist-info/METADATA +144 -0
  181. telegrinder-0.4.0.dist-info/RECORD +182 -0
  182. {telegrinder-0.3.4.dist-info → telegrinder-0.4.0.dist-info}/WHEEL +1 -1
  183. telegrinder/bot/rules/adapter/__init__.py +0 -17
  184. telegrinder/bot/rules/adapter/abc.py +0 -31
  185. telegrinder/node/message.py +0 -14
  186. telegrinder/node/update.py +0 -15
  187. telegrinder/tools/formatting/links.py +0 -38
  188. telegrinder/tools/kb_set/__init__.py +0 -4
  189. telegrinder/tools/kb_set/base.py +0 -15
  190. telegrinder/tools/kb_set/yaml.py +0 -63
  191. telegrinder-0.3.4.dist-info/METADATA +0 -110
  192. telegrinder-0.3.4.dist-info/RECORD +0 -165
@@ -1,36 +1,33 @@
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
+
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 EnumTextRule[T: enum.Enum](ABCRule):
10
+ def __init__(self, enum_t: type[T], *, lower_case: bool = True) -> None:
11
+ self.enum_t = enum_t
12
+ self.texts = list(
13
+ map(
14
+ lambda x: x.value.lower() if lower_case else x.value,
15
+ self.enum_t,
16
+ )
17
+ )
18
+
19
+ def find(self, s: str) -> T:
20
+ for enumeration in self.enum_t:
21
+ if enumeration.value.lower() == s:
22
+ return enumeration
23
+ raise KeyError("Enumeration is undefined.")
24
+
25
+ def check(self, text: Text, ctx: Context) -> bool:
26
+ text = text.lower() # type: ignore
27
+ if text not in self.texts:
28
+ return False
29
+ ctx.enum_text = self.find(text)
30
+ return True
31
+
32
+
33
+ __all__ = ("EnumTextRule",)
@@ -1,26 +1,28 @@
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.tools.adapter.abc import ABCAdapter
6
+ from telegrinder.tools.adapter.raw_update import RawUpdateAdapter
7
+ from telegrinder.types.objects import Update
8
+
9
+ from .abc import ABCRule, AdaptTo
10
+
11
+
12
+ class FuncRule(ABCRule, typing.Generic[AdaptTo]):
13
+ def __init__(
14
+ self,
15
+ func: typing.Callable[[AdaptTo, Context], typing.Awaitable[bool] | bool],
16
+ adapter: ABCAdapter[Update, AdaptTo] | None = None,
17
+ ) -> None:
18
+ self.func = func
19
+ self.adapter = adapter or RawUpdateAdapter() # type: ignore
20
+
21
+ async def check(self, event: AdaptTo, ctx: Context) -> bool:
22
+ result = self.func(event, ctx)
23
+ if inspect.isawaitable(result):
24
+ result = await result
25
+ return result
26
+
27
+
28
+ __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",)
@@ -0,0 +1,24 @@
1
+ import typing
2
+
3
+ from telegrinder.types.objects import Update
4
+
5
+ from .abc import ABCRule
6
+
7
+ if typing.TYPE_CHECKING:
8
+ from telegrinder.tools.adapter.abc import ABCAdapter
9
+
10
+
11
+ class IdRule[Identifier](ABCRule[Identifier]):
12
+ def __init__(
13
+ self,
14
+ adapter: "ABCAdapter[Update, Identifier]",
15
+ tracked_identifiers: set[Identifier] | None = None,
16
+ ):
17
+ self.tracked_identifiers = tracked_identifiers or set()
18
+ self.adapter = adapter
19
+
20
+ async def check(self, event: Identifier) -> bool:
21
+ return event in self.tracked_identifiers
22
+
23
+
24
+ __all__ = ("IdRule",)
@@ -1,60 +1,62 @@
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, *args: typing.Any, **kwargs: typing.Any) -> 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__ = (
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.tools.adapter.event 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(
16
+ ABCRule[InlineQuery],
17
+ abc.ABC,
18
+ adapter=EventAdapter(UpdateType.INLINE_QUERY, InlineQuery),
19
+ ):
20
+ @abc.abstractmethod
21
+ def check(self, *args: typing.Any, **kwargs: typing.Any) -> CheckResult: ...
22
+
23
+
24
+ class HasLocation(InlineQueryRule):
25
+ def check(self, query: InlineQuery) -> bool:
26
+ return bool(query.location)
27
+
28
+
29
+ class InlineQueryChatType(InlineQueryRule):
30
+ def __init__(self, chat_type: ChatType, /) -> None:
31
+ self.chat_type = chat_type
32
+
33
+ def check(self, query: InlineQuery) -> bool:
34
+ return query.chat_type.map(lambda x: x == self.chat_type).unwrap_or(False)
35
+
36
+
37
+ class InlineQueryText(InlineQueryRule):
38
+ def __init__(self, texts: str | list[str], *, lower_case: bool = False) -> None:
39
+ self.texts = [
40
+ text.lower() if lower_case else text for text in ([texts] if isinstance(texts, str) else texts)
41
+ ]
42
+ self.lower_case = lower_case
43
+
44
+ def check(self, query: InlineQuery) -> bool:
45
+ return (query.query.lower() if self.lower_case else query.query) in self.texts
46
+
47
+
48
+ class InlineQueryMarkup(InlineQueryRule):
49
+ def __init__(self, patterns: PatternLike | list[PatternLike], /) -> None:
50
+ self.patterns = Markup(patterns).patterns
51
+
52
+ def check(self, query: InlineQuery, ctx: Context) -> bool:
53
+ return check_string(self.patterns, query.query, ctx)
54
+
55
+
56
+ __all__ = (
55
57
  "HasLocation",
56
58
  "InlineQueryChatType",
57
59
  "InlineQueryMarkup",
58
60
  "InlineQueryRule",
59
- "InlineQueryText",
60
- )
61
+ "InlineQueryText",
62
+ )
@@ -1,20 +1,21 @@
1
- from telegrinder.node.text import TextInteger
2
-
3
- from .abc import ABCRule
4
- from .node import NodeRule
5
-
6
-
7
- class IsInteger(NodeRule):
8
- def __init__(self) -> None:
9
- super().__init__(TextInteger)
10
-
11
-
12
- class IntegerInRange(ABCRule):
13
- def __init__(self, rng: range) -> None:
14
- self.rng = rng
15
-
16
- def check(self, integer: TextInteger) -> bool:
17
- return integer in self.rng
18
-
19
-
20
- __all__ = ("IntegerInRange", "IsInteger")
1
+ from telegrinder.node.base import as_node
2
+ from telegrinder.node.text import TextInteger
3
+
4
+ from .abc import ABCRule
5
+ from .node import NodeRule
6
+
7
+
8
+ class IsInteger(NodeRule):
9
+ def __init__(self) -> None:
10
+ super().__init__(as_node(TextInteger))
11
+
12
+
13
+ class IntegerInRange(ABCRule):
14
+ def __init__(self, rng: range) -> None:
15
+ self.rng = rng
16
+
17
+ def check(self, integer: TextInteger) -> bool:
18
+ return integer in self.rng
19
+
20
+
21
+ __all__ = ("IntegerInRange", "IsInteger")
@@ -1,128 +1,128 @@
1
- import typing
2
-
3
- from telegrinder.node.source import ChatSource, UserSource
4
- from telegrinder.types.enums import ChatType, DiceEmoji
5
-
6
- from .abc import ABCRule, Message
7
- from .message import MessageRule
8
-
9
-
10
- class IsBot(ABCRule):
11
- def check(self, user: UserSource) -> bool:
12
- return user.is_bot
13
-
14
-
15
- class IsUser(ABCRule):
16
- def check(self, user: UserSource) -> bool:
17
- return not user.is_bot
18
-
19
-
20
- class IsPremium(ABCRule):
21
- def check(self, user: UserSource) -> bool:
22
- return user.is_premium.unwrap_or(False)
23
-
24
-
25
- class IsLanguageCode(ABCRule):
26
- def __init__(self, lang_codes: str | list[str], /) -> None:
27
- self.lang_codes = [lang_codes] if isinstance(lang_codes, str) else lang_codes
28
-
29
- def check(self, user: UserSource) -> bool:
30
- return user.language_code.unwrap_or_none() in self.lang_codes
31
-
32
-
33
- class IsUserId(ABCRule):
34
- def __init__(self, user_ids: int | list[int], /) -> None:
35
- self.user_ids = [user_ids] if isinstance(user_ids, int) else user_ids
36
-
37
- def check(self, user: UserSource) -> bool:
38
- return user.id in self.user_ids
39
-
40
-
41
- class IsForum(ABCRule):
42
- def check(self, chat: ChatSource) -> bool:
43
- return chat.is_forum.unwrap_or(False)
44
-
45
-
46
- class IsChatId(ABCRule):
47
- def __init__(self, chat_ids: int | list[int], /) -> None:
48
- self.chat_ids = [chat_ids] if isinstance(chat_ids, int) else chat_ids
49
-
50
- def check(self, chat: ChatSource) -> bool:
51
- return chat.id in self.chat_ids
52
-
53
-
54
- class IsPrivate(ABCRule):
55
- def check(self, chat: ChatSource) -> bool:
56
- return chat.type == ChatType.PRIVATE
57
-
58
-
59
- class IsGroup(ABCRule):
60
- def check(self, chat: ChatSource) -> bool:
61
- return chat.type == ChatType.GROUP
62
-
63
-
64
- class IsSuperGroup(ABCRule):
65
- def check(self, chat: ChatSource) -> bool:
66
- return chat.type == ChatType.SUPERGROUP
67
-
68
-
69
- class IsChat(ABCRule):
70
- def check(self, chat: ChatSource) -> bool:
71
- return chat.type in (ChatType.GROUP, ChatType.SUPERGROUP)
72
-
73
-
74
- class IsDice(MessageRule):
75
- def check(self, message: Message) -> bool:
76
- return bool(message.dice)
77
-
78
-
79
- class IsDiceEmoji(MessageRule, requires=[IsDice()]):
80
- def __init__(self, dice_emoji: DiceEmoji, /) -> None:
81
- self.dice_emoji = dice_emoji
82
-
83
- def check(self, message: Message) -> bool:
84
- return message.dice.unwrap().emoji == self.dice_emoji
85
-
86
-
87
- class IsForward(MessageRule):
88
- def check(self, message: Message) -> bool:
89
- return bool(message.forward_origin)
90
-
91
-
92
- class IsForwardType(MessageRule, requires=[IsForward()]):
93
- def __init__(self, fwd_type: typing.Literal["user", "hidden_user", "chat", "channel"], /) -> None:
94
- self.fwd_type = fwd_type
95
-
96
- def check(self, message: Message) -> bool:
97
- return message.forward_origin.unwrap().v.type == self.fwd_type
98
-
99
-
100
- class IsReply(MessageRule):
101
- def check(self, message: Message) -> bool:
102
- return bool(message.reply_to_message)
103
-
104
-
105
- class IsSticker(MessageRule):
106
- def check(self, message: Message) -> bool:
107
- return bool(message.sticker)
108
-
109
-
110
- class IsVideoNote(MessageRule):
111
- def check(self, message: Message) -> bool:
112
- return bool(message.video_note)
113
-
114
-
115
- class IsDocument(MessageRule):
116
- def check(self, message: Message) -> bool:
117
- return bool(message.document)
118
-
119
-
120
- class IsPhoto(MessageRule):
121
- def check(self, message: Message) -> bool:
122
- return bool(message.photo)
123
-
124
-
125
- __all__ = (
1
+ import typing
2
+
3
+ from telegrinder.node.source import ChatSource, UserSource
4
+ from telegrinder.types.enums import ChatType, DiceEmoji
5
+
6
+ from .abc import ABCRule, Message
7
+ from .message import MessageRule
8
+
9
+
10
+ class IsBot(ABCRule):
11
+ def check(self, user: UserSource) -> bool:
12
+ return user.is_bot
13
+
14
+
15
+ class IsUser(ABCRule):
16
+ def check(self, user: UserSource) -> bool:
17
+ return not user.is_bot
18
+
19
+
20
+ class IsPremium(ABCRule):
21
+ def check(self, user: UserSource) -> bool:
22
+ return user.is_premium.unwrap_or(False)
23
+
24
+
25
+ class IsLanguageCode(ABCRule):
26
+ def __init__(self, lang_codes: str | list[str], /) -> None:
27
+ self.lang_codes = [lang_codes] if isinstance(lang_codes, str) else lang_codes
28
+
29
+ def check(self, user: UserSource) -> bool:
30
+ return user.language_code.unwrap_or_none() in self.lang_codes
31
+
32
+
33
+ class IsUserId(ABCRule):
34
+ def __init__(self, user_ids: int | list[int], /) -> None:
35
+ self.user_ids = [user_ids] if isinstance(user_ids, int) else user_ids
36
+
37
+ def check(self, user: UserSource) -> bool:
38
+ return user.id in self.user_ids
39
+
40
+
41
+ class IsForum(ABCRule):
42
+ def check(self, chat: ChatSource) -> bool:
43
+ return chat.is_forum.unwrap_or(False)
44
+
45
+
46
+ class IsChatId(ABCRule):
47
+ def __init__(self, chat_ids: int | list[int], /) -> None:
48
+ self.chat_ids = [chat_ids] if isinstance(chat_ids, int) else chat_ids
49
+
50
+ def check(self, chat: ChatSource) -> bool:
51
+ return chat.id in self.chat_ids
52
+
53
+
54
+ class IsPrivate(ABCRule):
55
+ def check(self, chat: ChatSource) -> bool:
56
+ return chat.type == ChatType.PRIVATE
57
+
58
+
59
+ class IsGroup(ABCRule):
60
+ def check(self, chat: ChatSource) -> bool:
61
+ return chat.type == ChatType.GROUP
62
+
63
+
64
+ class IsSuperGroup(ABCRule):
65
+ def check(self, chat: ChatSource) -> bool:
66
+ return chat.type == ChatType.SUPERGROUP
67
+
68
+
69
+ class IsChat(ABCRule):
70
+ def check(self, chat: ChatSource) -> bool:
71
+ return chat.type in (ChatType.GROUP, ChatType.SUPERGROUP)
72
+
73
+
74
+ class IsDice(MessageRule):
75
+ def check(self, message: Message) -> bool:
76
+ return bool(message.dice)
77
+
78
+
79
+ class IsDiceEmoji(MessageRule, requires=[IsDice()]):
80
+ def __init__(self, dice_emoji: DiceEmoji, /) -> None:
81
+ self.dice_emoji = dice_emoji
82
+
83
+ def check(self, message: Message) -> bool:
84
+ return message.dice.unwrap().emoji == self.dice_emoji
85
+
86
+
87
+ class IsForward(MessageRule):
88
+ def check(self, message: Message) -> bool:
89
+ return bool(message.forward_origin)
90
+
91
+
92
+ class IsForwardType(MessageRule, requires=[IsForward()]):
93
+ def __init__(self, fwd_type: typing.Literal["user", "hidden_user", "chat", "channel"], /) -> None:
94
+ self.fwd_type = fwd_type
95
+
96
+ def check(self, message: Message) -> bool:
97
+ return message.forward_origin.unwrap().v.type == self.fwd_type
98
+
99
+
100
+ class IsReply(MessageRule):
101
+ def check(self, message: Message) -> bool:
102
+ return bool(message.reply_to_message)
103
+
104
+
105
+ class IsSticker(MessageRule):
106
+ def check(self, message: Message) -> bool:
107
+ return bool(message.sticker)
108
+
109
+
110
+ class IsVideoNote(MessageRule):
111
+ def check(self, message: Message) -> bool:
112
+ return bool(message.video_note)
113
+
114
+
115
+ class IsDocument(MessageRule):
116
+ def check(self, message: Message) -> bool:
117
+ return bool(message.document)
118
+
119
+
120
+ class IsPhoto(MessageRule):
121
+ def check(self, message: Message) -> bool:
122
+ return bool(message.photo)
123
+
124
+
125
+ __all__ = (
126
126
  "IsBot",
127
127
  "IsChat",
128
128
  "IsChatId",
@@ -142,5 +142,5 @@ __all__ = (
142
142
  "IsSuperGroup",
143
143
  "IsUser",
144
144
  "IsUserId",
145
- "IsVideoNote",
146
- )
145
+ "IsVideoNote",
146
+ )
@@ -0,0 +1,18 @@
1
+ import typing
2
+
3
+ from .abc import ABCRule, Context, UpdateCute, check_rule
4
+
5
+
6
+ class If(ABCRule):
7
+ def __init__(self, condition: ABCRule) -> None:
8
+ self.conditions = [condition]
9
+
10
+ async def check(self, update: UpdateCute, ctx: Context) -> bool:
11
+ for condition in self.conditions[:-1]:
12
+ if not await check_rule(update.api, condition, update, ctx):
13
+ return True
14
+ return await check_rule(update.api, self.conditions[-1], update, ctx)
15
+
16
+ def then(self, condition: ABCRule) -> typing.Self:
17
+ self.conditions.append(condition)
18
+ return self