telegrinder 0.4.2__py3-none-any.whl → 0.5.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 (233) hide show
  1. telegrinder/__init__.py +37 -55
  2. telegrinder/__meta__.py +1 -0
  3. telegrinder/api/__init__.py +6 -4
  4. telegrinder/api/api.py +100 -26
  5. telegrinder/api/error.py +42 -8
  6. telegrinder/api/response.py +4 -1
  7. telegrinder/api/token.py +2 -2
  8. telegrinder/bot/__init__.py +9 -25
  9. telegrinder/bot/bot.py +31 -25
  10. telegrinder/bot/cute_types/__init__.py +0 -0
  11. telegrinder/bot/cute_types/base.py +103 -61
  12. telegrinder/bot/cute_types/callback_query.py +447 -400
  13. telegrinder/bot/cute_types/chat_join_request.py +59 -62
  14. telegrinder/bot/cute_types/chat_member_updated.py +154 -157
  15. telegrinder/bot/cute_types/inline_query.py +41 -44
  16. telegrinder/bot/cute_types/message.py +2621 -2590
  17. telegrinder/bot/cute_types/pre_checkout_query.py +38 -42
  18. telegrinder/bot/cute_types/update.py +1 -8
  19. telegrinder/bot/cute_types/utils.py +1 -1
  20. telegrinder/bot/dispatch/__init__.py +10 -15
  21. telegrinder/bot/dispatch/abc.py +12 -11
  22. telegrinder/bot/dispatch/action.py +104 -0
  23. telegrinder/bot/dispatch/context.py +32 -26
  24. telegrinder/bot/dispatch/dispatch.py +61 -134
  25. telegrinder/bot/dispatch/handler/__init__.py +2 -0
  26. telegrinder/bot/dispatch/handler/abc.py +10 -8
  27. telegrinder/bot/dispatch/handler/audio_reply.py +2 -3
  28. telegrinder/bot/dispatch/handler/base.py +10 -33
  29. telegrinder/bot/dispatch/handler/document_reply.py +2 -3
  30. telegrinder/bot/dispatch/handler/func.py +55 -87
  31. telegrinder/bot/dispatch/handler/media_group_reply.py +2 -3
  32. telegrinder/bot/dispatch/handler/message_reply.py +2 -3
  33. telegrinder/bot/dispatch/handler/photo_reply.py +2 -3
  34. telegrinder/bot/dispatch/handler/sticker_reply.py +2 -3
  35. telegrinder/bot/dispatch/handler/video_reply.py +2 -3
  36. telegrinder/bot/dispatch/middleware/__init__.py +0 -0
  37. telegrinder/bot/dispatch/middleware/abc.py +79 -55
  38. telegrinder/bot/dispatch/middleware/global_middleware.py +18 -33
  39. telegrinder/bot/dispatch/process.py +84 -105
  40. telegrinder/bot/dispatch/return_manager/__init__.py +0 -0
  41. telegrinder/bot/dispatch/return_manager/abc.py +102 -65
  42. telegrinder/bot/dispatch/return_manager/callback_query.py +4 -5
  43. telegrinder/bot/dispatch/return_manager/inline_query.py +3 -4
  44. telegrinder/bot/dispatch/return_manager/message.py +8 -10
  45. telegrinder/bot/dispatch/return_manager/pre_checkout_query.py +4 -5
  46. telegrinder/bot/dispatch/view/__init__.py +4 -4
  47. telegrinder/bot/dispatch/view/abc.py +6 -16
  48. telegrinder/bot/dispatch/view/base.py +54 -178
  49. telegrinder/bot/dispatch/view/box.py +19 -18
  50. telegrinder/bot/dispatch/view/callback_query.py +4 -8
  51. telegrinder/bot/dispatch/view/chat_join_request.py +5 -6
  52. telegrinder/bot/dispatch/view/chat_member.py +5 -25
  53. telegrinder/bot/dispatch/view/error.py +9 -0
  54. telegrinder/bot/dispatch/view/inline_query.py +4 -8
  55. telegrinder/bot/dispatch/view/message.py +5 -25
  56. telegrinder/bot/dispatch/view/pre_checkout_query.py +4 -8
  57. telegrinder/bot/dispatch/view/raw.py +3 -109
  58. telegrinder/bot/dispatch/waiter_machine/__init__.py +2 -5
  59. telegrinder/bot/dispatch/waiter_machine/actions.py +6 -4
  60. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +1 -3
  61. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +1 -1
  62. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +11 -7
  63. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +0 -0
  64. telegrinder/bot/dispatch/waiter_machine/machine.py +43 -60
  65. telegrinder/bot/dispatch/waiter_machine/middleware.py +19 -23
  66. telegrinder/bot/dispatch/waiter_machine/short_state.py +6 -5
  67. telegrinder/bot/polling/__init__.py +0 -0
  68. telegrinder/bot/polling/abc.py +0 -0
  69. telegrinder/bot/polling/polling.py +209 -88
  70. telegrinder/bot/rules/__init__.py +3 -16
  71. telegrinder/bot/rules/abc.py +42 -122
  72. telegrinder/bot/rules/callback_data.py +29 -49
  73. telegrinder/bot/rules/chat_join.py +5 -23
  74. telegrinder/bot/rules/command.py +8 -4
  75. telegrinder/bot/rules/enum_text.py +3 -4
  76. telegrinder/bot/rules/func.py +7 -14
  77. telegrinder/bot/rules/fuzzy.py +3 -4
  78. telegrinder/bot/rules/inline.py +8 -20
  79. telegrinder/bot/rules/integer.py +2 -3
  80. telegrinder/bot/rules/is_from.py +12 -11
  81. telegrinder/bot/rules/logic.py +11 -5
  82. telegrinder/bot/rules/markup.py +22 -14
  83. telegrinder/bot/rules/mention.py +8 -7
  84. telegrinder/bot/rules/message_entities.py +8 -4
  85. telegrinder/bot/rules/node.py +23 -12
  86. telegrinder/bot/rules/payload.py +5 -4
  87. telegrinder/bot/rules/payment_invoice.py +6 -21
  88. telegrinder/bot/rules/regex.py +2 -4
  89. telegrinder/bot/rules/rule_enum.py +8 -7
  90. telegrinder/bot/rules/start.py +5 -6
  91. telegrinder/bot/rules/state.py +1 -1
  92. telegrinder/bot/rules/text.py +4 -15
  93. telegrinder/bot/rules/update.py +3 -4
  94. telegrinder/bot/scenario/__init__.py +0 -0
  95. telegrinder/bot/scenario/abc.py +6 -5
  96. telegrinder/bot/scenario/checkbox.py +1 -1
  97. telegrinder/bot/scenario/choice.py +30 -39
  98. telegrinder/client/__init__.py +3 -5
  99. telegrinder/client/abc.py +11 -6
  100. telegrinder/client/aiohttp.py +141 -27
  101. telegrinder/client/form_data.py +1 -1
  102. telegrinder/model.py +61 -89
  103. telegrinder/modules.py +325 -102
  104. telegrinder/msgspec_utils/__init__.py +40 -0
  105. telegrinder/msgspec_utils/abc.py +18 -0
  106. telegrinder/msgspec_utils/custom_types/__init__.py +6 -0
  107. telegrinder/msgspec_utils/custom_types/datetime.py +24 -0
  108. telegrinder/msgspec_utils/custom_types/enum_meta.py +43 -0
  109. telegrinder/msgspec_utils/custom_types/literal.py +25 -0
  110. telegrinder/msgspec_utils/custom_types/option.py +17 -0
  111. telegrinder/msgspec_utils/decoder.py +389 -0
  112. telegrinder/msgspec_utils/encoder.py +206 -0
  113. telegrinder/{msgspec_json.py → msgspec_utils/json.py} +6 -5
  114. telegrinder/msgspec_utils/tools.py +75 -0
  115. telegrinder/node/__init__.py +24 -7
  116. telegrinder/node/attachment.py +1 -0
  117. telegrinder/node/base.py +154 -72
  118. telegrinder/node/callback_query.py +5 -5
  119. telegrinder/node/collection.py +39 -0
  120. telegrinder/node/command.py +1 -2
  121. telegrinder/node/composer.py +121 -72
  122. telegrinder/node/container.py +11 -8
  123. telegrinder/node/context.py +48 -0
  124. telegrinder/node/either.py +27 -40
  125. telegrinder/node/error.py +41 -0
  126. telegrinder/node/event.py +37 -11
  127. telegrinder/node/exceptions.py +7 -0
  128. telegrinder/node/file.py +0 -0
  129. telegrinder/node/i18n.py +108 -0
  130. telegrinder/node/me.py +3 -2
  131. telegrinder/node/payload.py +1 -1
  132. telegrinder/node/polymorphic.py +63 -28
  133. telegrinder/node/reply_message.py +12 -0
  134. telegrinder/node/rule.py +6 -13
  135. telegrinder/node/scope.py +14 -5
  136. telegrinder/node/session.py +53 -0
  137. telegrinder/node/source.py +41 -9
  138. telegrinder/node/text.py +1 -2
  139. telegrinder/node/tools/__init__.py +0 -0
  140. telegrinder/node/tools/generator.py +3 -5
  141. telegrinder/node/utility.py +16 -0
  142. telegrinder/py.typed +0 -0
  143. telegrinder/rules.py +0 -0
  144. telegrinder/tools/__init__.py +48 -88
  145. telegrinder/tools/aio.py +103 -0
  146. telegrinder/tools/callback_data_serialization/__init__.py +5 -0
  147. telegrinder/tools/{callback_data_serilization → callback_data_serialization}/abc.py +0 -0
  148. telegrinder/tools/{callback_data_serilization → callback_data_serialization}/json_ser.py +2 -3
  149. telegrinder/tools/{callback_data_serilization → callback_data_serialization}/msgpack_ser.py +45 -27
  150. telegrinder/tools/final.py +21 -0
  151. telegrinder/tools/formatting/__init__.py +2 -18
  152. telegrinder/tools/formatting/deep_links/__init__.py +39 -0
  153. telegrinder/tools/formatting/{deep_links.py → deep_links/links.py} +12 -85
  154. telegrinder/tools/formatting/deep_links/parsing.py +90 -0
  155. telegrinder/tools/formatting/deep_links/validators.py +8 -0
  156. telegrinder/tools/formatting/html_formatter.py +18 -45
  157. telegrinder/tools/fullname.py +83 -0
  158. telegrinder/tools/global_context/__init__.py +4 -3
  159. telegrinder/tools/global_context/abc.py +17 -14
  160. telegrinder/tools/global_context/builtin_context.py +39 -0
  161. telegrinder/tools/global_context/global_context.py +138 -39
  162. telegrinder/tools/input_file_directory.py +0 -0
  163. telegrinder/tools/keyboard/__init__.py +39 -0
  164. telegrinder/tools/keyboard/abc.py +159 -0
  165. telegrinder/tools/keyboard/base.py +77 -0
  166. telegrinder/tools/keyboard/buttons/__init__.py +14 -0
  167. telegrinder/tools/keyboard/buttons/base.py +18 -0
  168. telegrinder/tools/{buttons.py → keyboard/buttons/buttons.py} +71 -23
  169. telegrinder/tools/keyboard/buttons/static_buttons.py +56 -0
  170. telegrinder/tools/keyboard/buttons/tools.py +18 -0
  171. telegrinder/tools/keyboard/data.py +20 -0
  172. telegrinder/tools/keyboard/keyboard.py +131 -0
  173. telegrinder/tools/keyboard/static_keyboard.py +83 -0
  174. telegrinder/tools/lifespan.py +87 -51
  175. telegrinder/tools/limited_dict.py +4 -1
  176. telegrinder/tools/loop_wrapper.py +332 -0
  177. telegrinder/tools/magic/__init__.py +32 -0
  178. telegrinder/tools/magic/annotations.py +165 -0
  179. telegrinder/tools/magic/dictionary.py +20 -0
  180. telegrinder/tools/magic/function.py +246 -0
  181. telegrinder/tools/magic/shortcut.py +111 -0
  182. telegrinder/tools/parse_mode.py +9 -3
  183. telegrinder/tools/singleton/__init__.py +4 -0
  184. telegrinder/tools/singleton/abc.py +14 -0
  185. telegrinder/tools/singleton/singleton.py +18 -0
  186. telegrinder/tools/state_storage/__init__.py +0 -0
  187. telegrinder/tools/state_storage/abc.py +6 -1
  188. telegrinder/tools/state_storage/memory.py +1 -1
  189. telegrinder/tools/strings.py +0 -0
  190. telegrinder/types/__init__.py +307 -268
  191. telegrinder/types/enums.py +64 -37
  192. telegrinder/types/input_file.py +3 -3
  193. telegrinder/types/methods.py +5699 -5055
  194. telegrinder/types/methods_utils.py +62 -0
  195. telegrinder/types/objects.py +7846 -7058
  196. telegrinder/verification_utils.py +3 -1
  197. telegrinder-0.5.0.dist-info/METADATA +162 -0
  198. telegrinder-0.5.0.dist-info/RECORD +200 -0
  199. {telegrinder-0.4.2.dist-info → telegrinder-0.5.0.dist-info}/licenses/LICENSE +2 -2
  200. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +0 -20
  201. telegrinder/bot/rules/id.py +0 -24
  202. telegrinder/bot/rules/message.py +0 -15
  203. telegrinder/client/sonic.py +0 -212
  204. telegrinder/msgspec_utils.py +0 -478
  205. telegrinder/tools/adapter/__init__.py +0 -19
  206. telegrinder/tools/adapter/abc.py +0 -49
  207. telegrinder/tools/adapter/dataclass.py +0 -56
  208. telegrinder/tools/adapter/errors.py +0 -5
  209. telegrinder/tools/adapter/event.py +0 -61
  210. telegrinder/tools/adapter/node.py +0 -46
  211. telegrinder/tools/adapter/raw_event.py +0 -27
  212. telegrinder/tools/adapter/raw_update.py +0 -30
  213. telegrinder/tools/callback_data_serilization/__init__.py +0 -5
  214. telegrinder/tools/error_handler/__init__.py +0 -10
  215. telegrinder/tools/error_handler/abc.py +0 -30
  216. telegrinder/tools/error_handler/error.py +0 -9
  217. telegrinder/tools/error_handler/error_handler.py +0 -179
  218. telegrinder/tools/formatting/spec_html_formats.py +0 -75
  219. telegrinder/tools/functional.py +0 -8
  220. telegrinder/tools/global_context/telegrinder_ctx.py +0 -27
  221. telegrinder/tools/i18n/__init__.py +0 -12
  222. telegrinder/tools/i18n/abc.py +0 -32
  223. telegrinder/tools/i18n/middleware/__init__.py +0 -3
  224. telegrinder/tools/i18n/middleware/abc.py +0 -22
  225. telegrinder/tools/i18n/simple.py +0 -43
  226. telegrinder/tools/keyboard.py +0 -132
  227. telegrinder/tools/loop_wrapper/__init__.py +0 -4
  228. telegrinder/tools/loop_wrapper/abc.py +0 -20
  229. telegrinder/tools/loop_wrapper/loop_wrapper.py +0 -169
  230. telegrinder/tools/magic.py +0 -344
  231. telegrinder-0.4.2.dist-info/METADATA +0 -151
  232. telegrinder-0.4.2.dist-info/RECORD +0 -182
  233. {telegrinder-0.4.2.dist-info → telegrinder-0.5.0.dist-info}/WHEEL +0 -0
@@ -1,219 +1,102 @@
1
1
  import typing
2
- from abc import ABC, abstractmethod
3
- from functools import cached_property
4
-
5
- from fntypes.option import Nothing, Some
2
+ from collections import deque
6
3
 
7
4
  from telegrinder.api.api import API
8
- from telegrinder.bot.cute_types.base import BaseCute
9
5
  from telegrinder.bot.dispatch.context import Context
10
6
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
11
- from telegrinder.bot.dispatch.handler.func import Func, FuncHandler
7
+ from telegrinder.bot.dispatch.handler.func import FuncHandler, Function
12
8
  from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
13
9
  from telegrinder.bot.dispatch.process import process_inner
14
10
  from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
15
- from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
16
- from telegrinder.bot.rules.abc import ABCRule
17
- from telegrinder.model import Model
18
- from telegrinder.msgspec_utils import Option
19
- from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
11
+ from telegrinder.bot.dispatch.view.abc import ABCView
12
+ from telegrinder.bot.rules.abc import ABCRule, Always
13
+ from telegrinder.types.enums import UpdateType
20
14
  from telegrinder.types.objects import Update
21
15
 
16
+ type Func[**P, T] = typing.Callable[P, typing.Coroutine[typing.Any, typing.Any, T]]
22
17
 
23
- def get_event_model_class[Event: BaseCute](
24
- view: "BaseView[Event] | type[BaseView[Event]]",
25
- ) -> Option[type[Event]]:
26
- view_class = view if isinstance(view, typing.Type) else view.__class__
27
- for base in view.__class__.__bases__ + (view_class,):
28
- if "__orig_bases__" not in base.__dict__:
29
- continue
30
-
31
- for orig_base in base.__dict__["__orig_bases__"]:
32
- origin_base = typing.get_origin(orig_base) or orig_base
33
- if not isinstance(origin_base, type) and not issubclass(origin_base, object):
34
- continue
35
-
36
- for generic_type in typing.get_args(orig_base):
37
- orig_generic_type = typing.get_origin(generic_type) or generic_type
38
- if isinstance(orig_generic_type, type) and issubclass(orig_generic_type, BaseCute):
39
- return Some(generic_type)
40
18
 
41
- return Nothing()
19
+ class BaseView(ABCView):
20
+ def __init__(self, update_type: UpdateType | None = None) -> None:
21
+ self.handlers: deque[ABCHandler] = deque()
22
+ self.middlewares: deque[ABCMiddleware] = deque()
23
+ self.return_manager: ABCReturnManager | None = None
24
+ self.update_type = update_type
25
+ self._auto_rules: ABCRule = Always()
42
26
 
43
-
44
- class BaseView[Event: BaseCute](ABCView):
45
- def __init__(self) -> None:
46
- self.handlers: list[ABCHandler[Event]] = []
47
- self.middlewares: list[ABCMiddleware[Event]] = []
48
- self.return_manager: ABCReturnManager[Event] | None = None
49
- self._auto_rules: ABCRule | None = None
27
+ def __repr__(self) -> str:
28
+ return "<{}>".format(type(self).__name__)
50
29
 
51
30
  @property
52
- def auto_rules(self) -> tuple[ABCRule] | tuple[()]:
53
- return (self._auto_rules,) if self._auto_rules else ()
31
+ def auto_rules(self) -> ABCRule:
32
+ return self._auto_rules
54
33
 
55
34
  @auto_rules.setter
56
- def auto_rules(self, value: ABCRule | None) -> None:
35
+ def auto_rules(self, value: ABCRule | list[ABCRule], /) -> None:
57
36
  """Example usage:
58
37
 
59
38
  ```python
60
39
  view.auto_rules = Rule1() & Rule2() | Rule3() & Rule4()
61
- view.auto_rules # (<OrRule>,)
40
+ view.auto_rules # <OrRule>
62
41
 
63
- view.auto_rules = None
64
- view.auto_rules # ()
42
+ view.auto_rules = [Rule1(), Rule2()]
43
+ view.auto_rules # <AndRule>
65
44
  ```
66
45
  """
67
- self._auto_rules = value
68
-
69
- @staticmethod
70
- def get_raw_event(update: Update) -> Option[Model]:
71
- return getattr(update, update.update_type.value)
46
+ if isinstance(value, list):
47
+ for rule in value:
48
+ self._auto_rules = self._auto_rules & rule
49
+ else:
50
+ self._auto_rules = value
72
51
 
73
- @cached_property
74
- def event_model_class(self) -> Option[type[Event]]:
75
- return get_event_model_class(self)
76
-
77
- @typing.overload
78
- @classmethod
79
- def to_handler[**P, R](
80
- cls,
81
- *rules: ABCRule,
82
- ) -> typing.Callable[
83
- [Func[P, R]],
84
- FuncHandler[Event, Func[P, R], ErrorHandler[Event]],
85
- ]: ...
86
-
87
- @typing.overload
88
52
  @classmethod
89
- def to_handler[**P, Dataclass, R](
90
- cls,
91
- *rules: ABCRule,
92
- dataclass: type[Dataclass],
93
- final: bool = True,
94
- ) -> typing.Callable[
95
- [Func[P, R]],
96
- FuncHandler[Dataclass, Func[P, R], ErrorHandler[Dataclass]],
97
- ]: ...
98
-
99
- @typing.overload
100
- @classmethod
101
- def to_handler[**P, ErrorHandlerT: ABCErrorHandler, R](
102
- cls,
103
- *rules: ABCRule,
104
- error_handler: ErrorHandlerT,
105
- final: bool = True,
106
- ) -> typing.Callable[[Func[P, R]], FuncHandler[Event, Func[P, R], ErrorHandlerT]]: ...
107
-
108
- @typing.overload
109
- @classmethod
110
- def to_handler[**P, Dataclass, ErrorHandlerT: ABCErrorHandler, R](
111
- cls,
112
- *rules: ABCRule,
113
- dataclass: type[Dataclass],
114
- error_handler: ErrorHandlerT,
115
- final: bool = True,
116
- ) -> typing.Callable[[Func[P, R]], FuncHandler[Dataclass, Func[P, R], ErrorHandlerT]]: ...
117
-
118
- @classmethod
119
- def to_handler(
120
- cls,
121
- *rules: ABCRule,
122
- dataclass: type[typing.Any] | None = None,
123
- error_handler: ABCErrorHandler | None = None,
124
- final: bool = True,
125
- ) -> typing.Callable[..., typing.Any]:
126
- def wrapper(func):
53
+ def to_handler[T: Function](cls, *rules: ABCRule, final: bool = True) -> typing.Callable[[T], FuncHandler[T]]:
54
+ def wrapper(func: T, /) -> FuncHandler[T]:
127
55
  return FuncHandler(
128
- func,
129
- list(rules),
56
+ function=func,
57
+ rules=list(rules),
130
58
  final=final,
131
- dataclass=dataclass,
132
- error_handler=error_handler or ErrorHandler(),
133
59
  )
134
60
 
135
61
  return wrapper
136
62
 
137
- @typing.overload
138
- def __call__[**P, R](
139
- self,
140
- *rules: ABCRule,
141
- final: bool = True,
142
- ) -> typing.Callable[
143
- [Func[P, R]],
144
- FuncHandler[Event, Func[P, R], ErrorHandler[Event]],
145
- ]: ...
63
+ def __call__[T: Function](self, *rules: ABCRule, final: bool = True) -> typing.Callable[[T], T]:
64
+ def wrapper(func: T, /) -> T:
65
+ self.handlers.append(
66
+ FuncHandler(
67
+ function=func,
68
+ rules=[self.auto_rules, *rules],
69
+ final=final,
70
+ ),
71
+ )
72
+ return func
73
+
74
+ return wrapper
146
75
 
147
76
  @typing.overload
148
- def __call__[**P, Dataclass, R](
149
- self,
150
- *rules: ABCRule,
151
- dataclass: type[Dataclass],
152
- final: bool = True,
153
- ) -> typing.Callable[
154
- [Func[P, R]],
155
- FuncHandler[Dataclass, Func[P, R], ErrorHandler[Dataclass]],
156
- ]: ...
77
+ def register_middleware[T: ABCMiddleware](self, middleware_cls: type[T], /) -> type[T]: ...
157
78
 
158
79
  @typing.overload
159
- def __call__[**P, ErrorHandlerT: ABCErrorHandler, R](
160
- self,
161
- *rules: ABCRule,
162
- error_handler: ErrorHandlerT,
163
- final: bool = True,
164
- ) -> typing.Callable[[Func[P, R]], FuncHandler[Event, Func[P, R], ErrorHandlerT]]: ...
80
+ def register_middleware(self, middleware: ABCMiddleware, /) -> None: ...
165
81
 
166
- def __call__[**P, R](
82
+ def register_middleware(
167
83
  self,
168
- *rules: ABCRule,
169
- dataclass: type[typing.Any] | None = None,
170
- error_handler: ABCErrorHandler | None = None,
171
- final: bool = True,
172
- ) -> typing.Callable[..., typing.Any]:
173
- def wrapper(func: typing.Callable[..., typing.Any]):
174
- func_handler = FuncHandler(
175
- func,
176
- [*self.auto_rules, *rules],
177
- final=final,
178
- dataclass=dataclass,
179
- error_handler=error_handler or ErrorHandler(),
180
- )
181
- self.handlers.append(func_handler)
182
- return func_handler
183
-
184
- return wrapper
185
-
186
- def register_middleware[Middleware: ABCMiddleware](self, *args: typing.Any, **kwargs: typing.Any):
187
- def wrapper(cls: type[Middleware]) -> type[Middleware]:
188
- self.middlewares.append(cls(*args, **kwargs))
189
- return cls
190
-
191
- return wrapper
84
+ middleware: type[ABCMiddleware] | ABCMiddleware,
85
+ ) -> typing.Callable[..., typing.Any] | None:
86
+ self.middlewares.append(middleware() if isinstance(middleware, type) else middleware)
87
+ return middleware if isinstance(middleware, type) else None
192
88
 
193
89
  async def check(self, event: Update) -> bool:
194
- match self.get_raw_event(event):
195
- case Some(e) if issubclass(
196
- self.event_model_class.expect(
197
- "{!r} has no event model class in generic.".format(self.__class__.__qualname__),
198
- ),
199
- e.__class__,
200
- ) and (self.handlers or self.middlewares):
201
- return True
202
- case _:
203
- return False
90
+ if self.update_type is not None and event.update_type != self.update_type:
91
+ return False
92
+ return bool(self.handlers or self.middlewares)
204
93
 
205
94
  async def process(self, event: Update, api: API, context: Context) -> bool:
206
95
  return await process_inner(
207
96
  api,
208
- self.event_model_class.unwrap().from_update(
209
- update=self.get_raw_event(event).unwrap(),
210
- bound_api=api,
211
- ),
212
97
  event,
213
98
  context,
214
- self.middlewares,
215
- self.handlers,
216
- self.return_manager,
99
+ self,
217
100
  )
218
101
 
219
102
  def load(self, external: typing.Self, /) -> None:
@@ -221,11 +104,4 @@ class BaseView[Event: BaseCute](ABCView):
221
104
  self.middlewares.extend(external.middlewares)
222
105
 
223
106
 
224
- class BaseStateView[Event: BaseCute](ABCStateView[Event], BaseView[Event], ABC):
225
- @classmethod
226
- @abstractmethod
227
- def get_state_key(cls, event: Event) -> int | None:
228
- pass
229
-
230
-
231
- __all__ = ("ABCStateView", "ABCView", "BaseStateView", "BaseView")
107
+ __all__ = ("BaseView",)
@@ -6,6 +6,7 @@ from telegrinder.bot.dispatch.view import (
6
6
  callback_query,
7
7
  chat_join_request,
8
8
  chat_member,
9
+ error,
9
10
  inline_query,
10
11
  message,
11
12
  pre_checkout_query,
@@ -33,6 +34,7 @@ ChatMemberView = typing.TypeVar("ChatMemberView", bound=ABCView, default=chat_me
33
34
  InlineQueryView = typing.TypeVar("InlineQueryView", bound=ABCView, default=inline_query.InlineQueryView)
34
35
  MessageView = typing.TypeVar("MessageView", bound=ABCView, default=message.MessageView)
35
36
  RawEventView = typing.TypeVar("RawEventView", bound=ABCEventRawView, default=raw.RawEventView)
37
+ ErrorView = typing.TypeVar("ErrorView", bound=ABCView, default=error.ErrorView)
36
38
 
37
39
 
38
40
  @dataclasses.dataclass(kw_only=True)
@@ -45,6 +47,7 @@ class ViewBox(
45
47
  MessageView,
46
48
  PreCheckoutQueryView,
47
49
  RawEventView,
50
+ ErrorView,
48
51
  ],
49
52
  ):
50
53
  callback_query_view: dataclasses.InitVar[CallbackQueryView | None] = None
@@ -62,6 +65,7 @@ class ViewBox(
62
65
  any_message_view: dataclasses.InitVar[MessageView | None] = None
63
66
  chat_member_updated_view: dataclasses.InitVar[ChatMemberView | None] = None
64
67
  raw_event_view: dataclasses.InitVar[RawEventView | None] = None
68
+ error_view: dataclasses.InitVar[ErrorView | None] = None
65
69
 
66
70
  def __post_init__(
67
71
  self,
@@ -80,61 +84,58 @@ class ViewBox(
80
84
  chat_member_updated_view: ChatMemberView | None = None,
81
85
  pre_checkout_query_view: PreCheckoutQueryView | None = None,
82
86
  raw_event_view: RawEventView | None = None,
87
+ error_view: ErrorView | None = None,
83
88
  ) -> None:
84
89
  self.callback_query = typing.cast(
85
- CallbackQueryView,
90
+ "CallbackQueryView",
86
91
  callback_query_view or callback_query.CallbackQueryView(),
87
92
  )
88
93
  self.chat_join_request = typing.cast(
89
- ChatJoinRequestView,
94
+ "ChatJoinRequestView",
90
95
  chat_join_request_view or chat_join_request.ChatJoinRequestView(),
91
96
  )
92
97
  self.chat_member = typing.cast(
93
- ChatMemberView,
98
+ "ChatMemberView",
94
99
  chat_member_view or chat_member.ChatMemberView(update_type=UpdateType.CHAT_MEMBER),
95
100
  )
96
101
  self.my_chat_member = typing.cast(
97
- ChatMemberView,
102
+ "ChatMemberView",
98
103
  my_chat_member_view or chat_member.ChatMemberView(update_type=UpdateType.MY_CHAT_MEMBER),
99
104
  )
100
105
  self.inline_query = typing.cast(
101
- InlineQueryView,
106
+ "InlineQueryView",
102
107
  inline_query_view or inline_query.InlineQueryView(),
103
108
  )
104
109
  self.message = typing.cast(
105
- MessageView,
110
+ "MessageView",
106
111
  message_view or message.MessageView(update_type=UpdateType.MESSAGE),
107
112
  )
108
113
  self.business_message = typing.cast(
109
- MessageView,
114
+ "MessageView",
110
115
  business_message_view or message.MessageView(update_type=UpdateType.BUSINESS_MESSAGE),
111
116
  )
112
117
  self.channel_post = typing.cast(
113
- MessageView,
118
+ "MessageView",
114
119
  channel_post_view or message.MessageView(update_type=UpdateType.CHANNEL_POST),
115
120
  )
116
121
  self.edited_message = typing.cast(
117
- MessageView,
122
+ "MessageView",
118
123
  edited_message_view or message.MessageView(update_type=UpdateType.EDITED_MESSAGE),
119
124
  )
120
125
  self.edited_business_message = typing.cast(
121
- MessageView,
126
+ "MessageView",
122
127
  edited_business_message_view or message.MessageView(update_type=UpdateType.EDITED_BUSINESS_MESSAGE),
123
128
  )
124
129
  self.edited_channel_post = typing.cast(
125
- MessageView,
130
+ "MessageView",
126
131
  edited_channel_post_view or message.MessageView(update_type=UpdateType.EDITED_CHANNEL_POST),
127
132
  )
128
133
  self.pre_checkout_query = typing.cast(
129
- PreCheckoutQueryView,
134
+ "PreCheckoutQueryView",
130
135
  pre_checkout_query_view or pre_checkout_query.PreCheckoutQueryView(),
131
136
  )
132
- self.any_message = typing.cast(MessageView, any_message_view or message.MessageView())
133
- self.chat_member_updated = typing.cast(
134
- ChatMemberView,
135
- chat_member_updated_view or chat_member.ChatMemberView(),
136
- )
137
- self.raw_event = typing.cast(RawEventView, raw_event_view or raw.RawEventView())
137
+ self.raw_event = typing.cast("RawEventView", raw_event_view or raw.RawEventView())
138
+ self.error = typing.cast("ErrorView", error_view or error.ErrorView())
138
139
 
139
140
 
140
141
  __all__ = ("ViewBox",)
@@ -1,16 +1,12 @@
1
- from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
2
1
  from telegrinder.bot.dispatch.return_manager.callback_query import CallbackQueryReturnManager
3
- from telegrinder.bot.dispatch.view.base import BaseStateView
2
+ from telegrinder.bot.dispatch.view.base import BaseView
3
+ from telegrinder.types.enums import UpdateType
4
4
 
5
5
 
6
- class CallbackQueryView(BaseStateView[CallbackQueryCute]):
6
+ class CallbackQueryView(BaseView):
7
7
  def __init__(self) -> None:
8
- super().__init__()
8
+ super().__init__(UpdateType.CALLBACK_QUERY)
9
9
  self.return_manager = CallbackQueryReturnManager()
10
10
 
11
- @classmethod
12
- def get_state_key(cls, event: CallbackQueryCute) -> int | None:
13
- return event.message_id.unwrap_or_none()
14
-
15
11
 
16
12
  __all__ = ("CallbackQueryView",)
@@ -1,11 +1,10 @@
1
- from telegrinder.bot.cute_types.chat_join_request import ChatJoinRequestCute
2
- from telegrinder.bot.dispatch.view.base import BaseStateView
1
+ from telegrinder.bot.dispatch.view.base import BaseView
2
+ from telegrinder.types.enums import UpdateType
3
3
 
4
4
 
5
- class ChatJoinRequestView(BaseStateView[ChatJoinRequestCute]):
6
- @classmethod
7
- def get_state_key(cls, event: ChatJoinRequestCute) -> int | None:
8
- return event.chat_id
5
+ class ChatJoinRequestView(BaseView):
6
+ def __init__(self) -> None:
7
+ super().__init__(UpdateType.CHAT_JOIN_REQUEST)
9
8
 
10
9
 
11
10
  __all__ = ("ChatJoinRequestView",)
@@ -1,37 +1,17 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types.chat_member_updated import ChatMemberUpdatedCute
4
- from telegrinder.bot.dispatch.view.base import BaseStateView
3
+ from telegrinder.bot.dispatch.view.base import BaseView
5
4
  from telegrinder.types.enums import UpdateType
6
- from telegrinder.types.objects import Update
7
5
 
8
- ChatMemberUpdateType: typing.TypeAlias = typing.Literal[
6
+ type ChatMemberUpdateType = typing.Literal[
9
7
  UpdateType.CHAT_MEMBER,
10
8
  UpdateType.MY_CHAT_MEMBER,
11
9
  ]
12
10
 
13
11
 
14
- class ChatMemberView(BaseStateView[ChatMemberUpdatedCute]):
15
- def __init__(self, *, update_type: ChatMemberUpdateType | None = None) -> None:
16
- super().__init__()
17
- self.update_type = update_type
18
-
19
- def __repr__(self) -> str:
20
- return "<{}: {!r}>".format(
21
- self.__class__.__name__,
22
- "chat_member_updated" if self.update_type is None else self.update_type.value,
23
- )
24
-
25
- @classmethod
26
- def get_state_key(cls, event: ChatMemberUpdatedCute) -> int | None:
27
- return event.chat_id
28
-
29
- async def check(self, event: Update) -> bool:
30
- return not (
31
- self.update_type is not None
32
- and self.update_type != event.update_type
33
- or not await super().check(event)
34
- )
12
+ class ChatMemberView(BaseView):
13
+ def __init__(self, update_type: ChatMemberUpdateType) -> None:
14
+ super().__init__(update_type)
35
15
 
36
16
 
37
17
  __all__ = ("ChatMemberView",)
@@ -0,0 +1,9 @@
1
+ from telegrinder.bot.dispatch.view.base import BaseView
2
+
3
+
4
+ class ErrorView(BaseView):
5
+ def __init__(self) -> None:
6
+ super().__init__()
7
+
8
+
9
+ __all__ = ("ErrorView",)
@@ -1,16 +1,12 @@
1
- from telegrinder.bot.cute_types.inline_query import InlineQueryCute
2
1
  from telegrinder.bot.dispatch.return_manager import InlineQueryReturnManager
3
- from telegrinder.bot.dispatch.view.base import BaseStateView
2
+ from telegrinder.bot.dispatch.view.base import BaseView
3
+ from telegrinder.types.enums import UpdateType
4
4
 
5
5
 
6
- class InlineQueryView(BaseStateView[InlineQueryCute]):
6
+ class InlineQueryView(BaseView):
7
7
  def __init__(self) -> None:
8
- super().__init__()
8
+ super().__init__(UpdateType.INLINE_QUERY)
9
9
  self.return_manager = InlineQueryReturnManager()
10
10
 
11
- @classmethod
12
- def get_state_key(cls, event: InlineQueryCute) -> int | None:
13
- return event.from_user.id
14
-
15
11
 
16
12
  __all__ = ("InlineQueryView",)
@@ -1,12 +1,10 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types.message import MessageCute
4
3
  from telegrinder.bot.dispatch.return_manager.message import MessageReturnManager
5
- from telegrinder.bot.dispatch.view.base import BaseStateView
4
+ from telegrinder.bot.dispatch.view.base import BaseView
6
5
  from telegrinder.types.enums import UpdateType
7
- from telegrinder.types.objects import Update
8
6
 
9
- MessageUpdateType: typing.TypeAlias = typing.Literal[
7
+ type MessageUpdateType = typing.Literal[
10
8
  UpdateType.MESSAGE,
11
9
  UpdateType.BUSINESS_MESSAGE,
12
10
  UpdateType.CHANNEL_POST,
@@ -16,28 +14,10 @@ MessageUpdateType: typing.TypeAlias = typing.Literal[
16
14
  ]
17
15
 
18
16
 
19
- class MessageView(BaseStateView[MessageCute]):
20
- def __init__(self, *, update_type: MessageUpdateType | None = None) -> None:
21
- super().__init__()
22
- self.update_type = update_type
17
+ class MessageView(BaseView):
18
+ def __init__(self, update_type: MessageUpdateType) -> None:
19
+ super().__init__(update_type)
23
20
  self.return_manager = MessageReturnManager()
24
21
 
25
- def __repr__(self) -> str:
26
- return "<{}: {!r}>".format(
27
- self.__class__.__name__,
28
- "any message update" if self.update_type is None else self.update_type.value,
29
- )
30
-
31
- @classmethod
32
- def get_state_key(cls, event: MessageCute) -> int | None:
33
- return event.chat_id
34
-
35
- async def check(self, event: Update) -> bool:
36
- return not (
37
- self.update_type is not None
38
- and self.update_type != event.update_type
39
- or not await super().check(event)
40
- )
41
-
42
22
 
43
23
  __all__ = ("MessageView",)
@@ -1,16 +1,12 @@
1
- from telegrinder.bot.cute_types.pre_checkout_query import PreCheckoutQueryCute
2
1
  from telegrinder.bot.dispatch.return_manager.pre_checkout_query import PreCheckoutQueryManager
3
- from telegrinder.bot.dispatch.view.base import BaseStateView
2
+ from telegrinder.bot.dispatch.view.base import BaseView
3
+ from telegrinder.types.enums import UpdateType
4
4
 
5
5
 
6
- class PreCheckoutQueryView(BaseStateView[PreCheckoutQueryCute]):
6
+ class PreCheckoutQueryView(BaseView):
7
7
  def __init__(self) -> None:
8
- super().__init__()
8
+ super().__init__(UpdateType.PRE_CHECKOUT_QUERY)
9
9
  self.return_manager = PreCheckoutQueryManager()
10
10
 
11
- @classmethod
12
- def get_state_key(cls, event: PreCheckoutQueryCute) -> int | None:
13
- return event.from_user.id
14
-
15
11
 
16
12
  __all__ = ("PreCheckoutQueryView",)