telegrinder 0.2.0.post2__py3-none-any.whl → 0.2.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 (70) hide show
  1. telegrinder/__init__.py +26 -7
  2. telegrinder/bot/__init__.py +16 -4
  3. telegrinder/bot/cute_types/chat_member_updated.py +1 -1
  4. telegrinder/bot/cute_types/message.py +18 -11
  5. telegrinder/bot/dispatch/__init__.py +18 -2
  6. telegrinder/bot/dispatch/abc.py +1 -1
  7. telegrinder/bot/dispatch/context.py +2 -2
  8. telegrinder/bot/dispatch/dispatch.py +1 -1
  9. telegrinder/bot/dispatch/handler/__init__.py +17 -1
  10. telegrinder/bot/dispatch/handler/audio_reply.py +44 -0
  11. telegrinder/bot/dispatch/handler/base.py +57 -0
  12. telegrinder/bot/dispatch/handler/document_reply.py +44 -0
  13. telegrinder/bot/dispatch/handler/func.py +3 -3
  14. telegrinder/bot/dispatch/handler/media_group_reply.py +43 -0
  15. telegrinder/bot/dispatch/handler/message_reply.py +12 -35
  16. telegrinder/bot/dispatch/handler/photo_reply.py +44 -0
  17. telegrinder/bot/dispatch/handler/sticker_reply.py +37 -0
  18. telegrinder/bot/dispatch/handler/video_reply.py +44 -0
  19. telegrinder/bot/dispatch/process.py +2 -2
  20. telegrinder/bot/dispatch/return_manager/abc.py +11 -8
  21. telegrinder/bot/dispatch/return_manager/callback_query.py +2 -2
  22. telegrinder/bot/dispatch/return_manager/inline_query.py +2 -2
  23. telegrinder/bot/dispatch/return_manager/message.py +3 -3
  24. telegrinder/bot/dispatch/view/__init__.py +2 -1
  25. telegrinder/bot/dispatch/view/abc.py +2 -181
  26. telegrinder/bot/dispatch/view/base.py +200 -0
  27. telegrinder/bot/dispatch/view/callback_query.py +3 -3
  28. telegrinder/bot/dispatch/view/chat_join_request.py +2 -2
  29. telegrinder/bot/dispatch/view/chat_member.py +2 -3
  30. telegrinder/bot/dispatch/view/inline_query.py +2 -2
  31. telegrinder/bot/dispatch/view/message.py +5 -4
  32. telegrinder/bot/dispatch/view/raw.py +4 -3
  33. telegrinder/bot/dispatch/waiter_machine/machine.py +18 -7
  34. telegrinder/bot/dispatch/waiter_machine/middleware.py +0 -8
  35. telegrinder/bot/dispatch/waiter_machine/short_state.py +1 -1
  36. telegrinder/bot/polling/polling.py +5 -2
  37. telegrinder/bot/rules/__init__.py +5 -2
  38. telegrinder/bot/rules/abc.py +6 -5
  39. telegrinder/bot/rules/adapter/__init__.py +1 -1
  40. telegrinder/bot/rules/integer.py +1 -1
  41. telegrinder/bot/rules/is_from.py +19 -0
  42. telegrinder/bot/rules/state.py +37 -0
  43. telegrinder/bot/scenario/checkbox.py +3 -3
  44. telegrinder/bot/scenario/choice.py +2 -2
  45. telegrinder/client/aiohttp.py +5 -7
  46. telegrinder/model.py +1 -8
  47. telegrinder/modules.py +16 -25
  48. telegrinder/msgspec_utils.py +5 -5
  49. telegrinder/node/base.py +2 -2
  50. telegrinder/node/composer.py +5 -9
  51. telegrinder/node/container.py +6 -1
  52. telegrinder/node/polymorphic.py +7 -7
  53. telegrinder/node/rule.py +6 -4
  54. telegrinder/node/scope.py +3 -3
  55. telegrinder/node/source.py +4 -2
  56. telegrinder/node/tools/generator.py +7 -6
  57. telegrinder/rules.py +2 -2
  58. telegrinder/tools/__init__.py +11 -7
  59. telegrinder/tools/loop_wrapper/loop_wrapper.py +4 -5
  60. telegrinder/tools/magic.py +17 -19
  61. telegrinder/tools/state_storage/__init__.py +4 -0
  62. telegrinder/tools/state_storage/abc.py +35 -0
  63. telegrinder/tools/state_storage/memory.py +25 -0
  64. telegrinder/types/__init__.py +1 -0
  65. telegrinder/types/methods.py +12 -4
  66. telegrinder/types/objects.py +57 -6
  67. {telegrinder-0.2.0.post2.dist-info → telegrinder-0.2.2.dist-info}/METADATA +3 -4
  68. {telegrinder-0.2.0.post2.dist-info → telegrinder-0.2.2.dist-info}/RECORD +70 -58
  69. {telegrinder-0.2.0.post2.dist-info → telegrinder-0.2.2.dist-info}/LICENSE +0 -0
  70. {telegrinder-0.2.0.post2.dist-info → telegrinder-0.2.2.dist-info}/WHEEL +0 -0
@@ -3,57 +3,34 @@ import typing
3
3
  from telegrinder.api.api import API
4
4
  from telegrinder.bot.cute_types.message import MessageCute
5
5
  from telegrinder.bot.dispatch.context import Context
6
- from telegrinder.bot.dispatch.handler.abc import ABCHandler
7
- from telegrinder.bot.dispatch.process import check_rule
6
+ from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
8
7
  from telegrinder.bot.rules.abc import ABCRule
9
- from telegrinder.modules import logger
10
- from telegrinder.types.objects import ReplyParameters, Update
11
8
 
12
9
 
13
- class MessageReplyHandler(ABCHandler[MessageCute]):
10
+ class MessageReplyHandler(BaseReplyHandler):
14
11
  def __init__(
15
12
  self,
16
13
  text: str,
17
14
  *rules: ABCRule,
15
+ parse_mode: str | None = None,
18
16
  is_blocking: bool = True,
19
17
  as_reply: bool = False,
20
18
  preset_context: Context | None = None,
21
19
  **default_params: typing.Any,
22
20
  ) -> None:
23
21
  self.text = text
24
- self.rules = list(rules)
25
- self.as_reply = as_reply
26
- self.is_blocking = is_blocking
27
- self.default_params = default_params
28
- self.preset_context = preset_context or Context()
29
-
30
- def __repr__(self) -> str:
31
- return "<{}: with rules={!r}, {}: {!r}>".format(
32
- ("blocking " if self.is_blocking else "") + self.__class__.__name__,
33
- self.rules,
34
- "answer text as reply" if self.as_reply else "answer text",
35
- self.text,
22
+ self.parse_mode = parse_mode
23
+ super().__init__(
24
+ *rules,
25
+ is_blocking=is_blocking,
26
+ as_reply=as_reply,
27
+ preset_context=preset_context,
28
+ **default_params,
36
29
  )
37
30
 
38
- async def check(self, api: API, event: Update, ctx: Context | None = None) -> bool:
39
- ctx = Context(raw_update=event) if ctx is None else ctx
40
- temp_ctx = ctx.copy()
41
- temp_ctx |= self.preset_context
42
-
43
- for rule in self.rules:
44
- if not await check_rule(api, rule, event, ctx):
45
- logger.debug("Rule {!r} failed!", rule)
46
- return False
47
-
48
- ctx |= temp_ctx
49
- return True
50
-
51
31
  async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
52
- await event.answer(
53
- text=self.text,
54
- reply_parameters=ReplyParameters(event.message_id) if self.as_reply else None,
55
- **self.default_params,
56
- )
32
+ method = event.answer if not self.as_reply else event.reply
33
+ await method(text=self.text, parse_mode=self.parse_mode, **self.default_params)
57
34
 
58
35
 
59
36
  __all__ = ("MessageReplyHandler",)
@@ -0,0 +1,44 @@
1
+ import typing
2
+
3
+ from telegrinder.api.api import API
4
+ from telegrinder.bot.cute_types.message import MessageCute
5
+ from telegrinder.bot.dispatch.context import Context
6
+ from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
7
+ from telegrinder.bot.rules.abc import ABCRule
8
+ from telegrinder.types.objects import InputFile
9
+
10
+
11
+ class PhotoReplyHandler(BaseReplyHandler):
12
+ def __init__(
13
+ self,
14
+ photo: InputFile | str,
15
+ *rules: ABCRule,
16
+ caption: str | None = None,
17
+ parse_mode: str | None = None,
18
+ is_blocking: bool = True,
19
+ as_reply: bool = False,
20
+ preset_context: Context | None = None,
21
+ **default_params: typing.Any,
22
+ ) -> None:
23
+ self.photo = photo
24
+ self.parse_mode = parse_mode
25
+ self.caption = caption
26
+ super().__init__(
27
+ *rules,
28
+ is_blocking=is_blocking,
29
+ as_reply=as_reply,
30
+ preset_context=preset_context,
31
+ **default_params,
32
+ )
33
+
34
+ async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
35
+ method = event.answer_photo if not self.as_reply else event.reply_photo
36
+ await method(
37
+ photo=self.photo,
38
+ parse_mode=self.parse_mode,
39
+ caption=self.caption,
40
+ **self.default_params,
41
+ )
42
+
43
+
44
+ __all__ = ("PhotoReplyHandler",)
@@ -0,0 +1,37 @@
1
+ import typing
2
+
3
+ from telegrinder.api.api import API
4
+ from telegrinder.bot.cute_types.message import MessageCute
5
+ from telegrinder.bot.dispatch.context import Context
6
+ from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
7
+ from telegrinder.bot.rules.abc import ABCRule
8
+ from telegrinder.types.objects import InputFile
9
+
10
+
11
+ class StickerReplyHandler(BaseReplyHandler):
12
+ def __init__(
13
+ self,
14
+ sticker: InputFile | str,
15
+ *rules: ABCRule,
16
+ emoji: str | None = None,
17
+ is_blocking: bool = True,
18
+ as_reply: bool = False,
19
+ preset_context: Context | None = None,
20
+ **default_params: typing.Any,
21
+ ) -> None:
22
+ self.sticker = sticker
23
+ self.emoji = emoji
24
+ super().__init__(
25
+ *rules,
26
+ is_blocking=is_blocking,
27
+ as_reply=as_reply,
28
+ preset_context=preset_context,
29
+ **default_params,
30
+ )
31
+
32
+ async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
33
+ method = event.answer_sticker if not self.as_reply else event.reply_sticker
34
+ await method(sticker=self.sticker, emoji=self.emoji, **self.default_params)
35
+
36
+
37
+ __all__ = ("StickerReplyHandler",)
@@ -0,0 +1,44 @@
1
+ import typing
2
+
3
+ from telegrinder.api.api import API
4
+ from telegrinder.bot.cute_types.message import MessageCute
5
+ from telegrinder.bot.dispatch.context import Context
6
+ from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
7
+ from telegrinder.bot.rules.abc import ABCRule
8
+ from telegrinder.types.objects import InputFile
9
+
10
+
11
+ class VideoReplyHandler(BaseReplyHandler):
12
+ def __init__(
13
+ self,
14
+ video: InputFile | str,
15
+ *rules: ABCRule,
16
+ caption: str | None = None,
17
+ parse_mode: str | None = None,
18
+ is_blocking: bool = True,
19
+ as_reply: bool = False,
20
+ preset_context: Context | None = None,
21
+ **default_params: typing.Any,
22
+ ) -> None:
23
+ self.video = video
24
+ self.parse_mode = parse_mode
25
+ self.caption = caption
26
+ super().__init__(
27
+ *rules,
28
+ is_blocking=is_blocking,
29
+ as_reply=as_reply,
30
+ preset_context=preset_context,
31
+ **default_params,
32
+ )
33
+
34
+ async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
35
+ method = event.answer_video if not self.as_reply else event.reply_video
36
+ await method(
37
+ video=self.video,
38
+ parse_mode=self.parse_mode,
39
+ caption=self.caption,
40
+ **self.default_params,
41
+ )
42
+
43
+
44
+ __all__ = ("VideoReplyHandler",)
@@ -35,7 +35,7 @@ async def process_inner(
35
35
  logger.debug("Run pre middlewares...")
36
36
  for middleware in middlewares:
37
37
  middleware_result = await middleware.pre(event, ctx)
38
- logger.debug("Middleware {!r} returned {!r}", middleware.__class__.__name__, middleware_result)
38
+ logger.debug("Middleware {!r} returned: {!r}", middleware.__class__.__qualname__, middleware_result)
39
39
  if middleware_result is False:
40
40
  return False
41
41
 
@@ -59,7 +59,7 @@ async def process_inner(
59
59
 
60
60
  logger.debug("Run post middlewares...")
61
61
  for middleware in middlewares:
62
- logger.debug("Run post middleware {!r}", middleware.__class__.__name__)
62
+ logger.debug("Run post middleware {!r}", middleware.__class__.__qualname__)
63
63
  await middleware.post(event, responses, ctx)
64
64
 
65
65
  for session in ctx.get(CONTEXT_STORE_NODES_KEY, {}).values():
@@ -27,13 +27,10 @@ def register_manager(return_type: type[typing.Any] | types.UnionType):
27
27
  @dataclasses.dataclass(frozen=True, slots=True)
28
28
  class Manager:
29
29
  types: tuple[type, ...]
30
- callback: typing.Callable[..., typing.Awaitable]
30
+ callback: typing.Callable[..., typing.Awaitable[typing.Any]]
31
31
 
32
32
  async def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> None:
33
- try:
34
- await self.callback(*args, **kwargs)
35
- except BaseException as ex:
36
- logger.exception(ex)
33
+ await self.callback(*args, **kwargs)
37
34
 
38
35
 
39
36
  class ABCReturnManager(ABC, typing.Generic[Event]):
@@ -51,11 +48,16 @@ class BaseReturnManager(ABCReturnManager[Event]):
51
48
 
52
49
  @property
53
50
  def managers(self) -> list[Manager]:
54
- return [
51
+ managers = self.__dict__.get("managers")
52
+ if managers is not None:
53
+ return managers
54
+ managers_lst = [
55
55
  manager
56
56
  for manager in (vars(BaseReturnManager) | vars(self.__class__)).values()
57
57
  if isinstance(manager, Manager)
58
58
  ]
59
+ self.__dict__["managers"] = managers_lst
60
+ return managers_lst
59
61
 
60
62
  @register_manager(Context)
61
63
  @staticmethod
@@ -73,7 +75,8 @@ class BaseReturnManager(ABCReturnManager[Event]):
73
75
 
74
76
  @typing.overload
75
77
  def register_manager(
76
- self, return_type: type[T]
78
+ self,
79
+ return_type: type[T],
77
80
  ) -> typing.Callable[[typing.Callable[[T, Event, Context], typing.Awaitable[typing.Any]]], Manager]: ...
78
81
 
79
82
  @typing.overload
@@ -94,7 +97,7 @@ class BaseReturnManager(ABCReturnManager[Event]):
94
97
  ]:
95
98
  def wrapper(func: typing.Callable[[T, Event, Context], typing.Awaitable]) -> Manager:
96
99
  manager = Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
97
- setattr(self.__class__, func.__name__, manager)
100
+ self.managers.append(manager)
98
101
  return manager
99
102
 
100
103
  return wrapper
@@ -1,6 +1,6 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types import CallbackQueryCute
3
+ from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
5
  from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
6
6
 
@@ -11,7 +11,7 @@ class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
11
11
  async def str_manager(value: str, event: CallbackQueryCute, ctx: Context) -> None:
12
12
  await event.answer(value)
13
13
 
14
- @register_manager(dict)
14
+ @register_manager(dict[str, typing.Any])
15
15
  @staticmethod
16
16
  async def dict_manager(value: dict[str, typing.Any], event: CallbackQueryCute, ctx: Context) -> None:
17
17
  await event.answer(**value)
@@ -1,12 +1,12 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types import InlineQueryCute
3
+ from telegrinder.bot.cute_types.inline_query import InlineQueryCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
5
  from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
6
6
 
7
7
 
8
8
  class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
9
- @register_manager(dict)
9
+ @register_manager(dict[str, typing.Any])
10
10
  @staticmethod
11
11
  async def dict_manager(value: dict[str, typing.Any], event: InlineQueryCute, ctx: Context) -> None:
12
12
  await event.answer(**value)
@@ -1,6 +1,6 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types import MessageCute
3
+ from telegrinder.bot.cute_types.message import MessageCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
5
  from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
6
6
  from telegrinder.tools.formatting import HTMLFormatter
@@ -12,7 +12,7 @@ class MessageReturnManager(BaseReturnManager[MessageCute]):
12
12
  async def str_manager(value: str, event: MessageCute, ctx: Context) -> None:
13
13
  await event.answer(value)
14
14
 
15
- @register_manager(list | tuple)
15
+ @register_manager(list[str] | tuple[str, ...])
16
16
  @staticmethod
17
17
  async def seq_manager(
18
18
  value: list[str] | tuple[str, ...],
@@ -22,7 +22,7 @@ class MessageReturnManager(BaseReturnManager[MessageCute]):
22
22
  for message in value:
23
23
  await event.answer(message)
24
24
 
25
- @register_manager(dict)
25
+ @register_manager(dict[str, typing.Any])
26
26
  @staticmethod
27
27
  async def dict_manager(value: dict[str, typing.Any], event: MessageCute, ctx: Context) -> None:
28
28
  await event.answer(**value)
@@ -1,4 +1,5 @@
1
- from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView, BaseStateView, BaseView
1
+ from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
2
+ from telegrinder.bot.dispatch.view.base import BaseStateView, BaseView
2
3
  from telegrinder.bot.dispatch.view.box import ViewBox
3
4
  from telegrinder.bot.dispatch.view.callback_query import CallbackQueryView
4
5
  from telegrinder.bot.dispatch.view.chat_join_request import ChatJoinRequestView
@@ -1,30 +1,12 @@
1
1
  import typing
2
2
  from abc import ABC, abstractmethod
3
- from functools import cached_property
4
3
 
5
- from fntypes.co import Nothing, Some
6
-
7
- from telegrinder.api import API
4
+ from telegrinder.api.api import API
8
5
  from telegrinder.bot.cute_types.base import BaseCute
9
6
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
10
- from telegrinder.bot.dispatch.handler.func import FuncHandler
11
- from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
12
- from telegrinder.bot.dispatch.process import process_inner
13
- from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
14
- from telegrinder.bot.rules.abc import ABCRule
15
- from telegrinder.model import Model
16
- from telegrinder.msgspec_utils import Option
17
- from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
18
7
  from telegrinder.types.objects import Update
19
8
 
20
9
  Event = typing.TypeVar("Event", bound=BaseCute)
21
- ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler)
22
- MiddlewareT = typing.TypeVar("MiddlewareT", bound=ABCMiddleware)
23
-
24
- FuncType: typing.TypeAlias = typing.Callable[
25
- typing.Concatenate[Event, ...],
26
- typing.Coroutine[typing.Any, typing.Any, typing.Any],
27
- ]
28
10
 
29
11
 
30
12
  class ABCView(ABC):
@@ -54,169 +36,8 @@ class ABCStateView(ABCView, typing.Generic[Event]):
54
36
  pass
55
37
 
56
38
 
57
- class BaseView(ABCView, typing.Generic[Event]):
58
- auto_rules: list[ABCRule]
59
- handlers: list[ABCHandler[Event]]
60
- middlewares: list[ABCMiddleware[Event]]
61
- return_manager: ABCReturnManager[Event] | None = None
62
-
63
- @staticmethod
64
- def get_raw_event(update: Update) -> Option[Model]:
65
- return getattr(update, update.update_type.value)
66
-
67
- @cached_property
68
- def get_event_type(self) -> Option[type[Event]]:
69
- for base in self.__class__.__dict__.get("__orig_bases__", ()):
70
- if issubclass(typing.get_origin(base) or base, ABCView):
71
- for generic_type in typing.get_args(base):
72
- if issubclass(typing.get_origin(generic_type) or generic_type, BaseCute):
73
- return Some(generic_type)
74
- return Nothing()
75
-
76
- @typing.overload
77
- @classmethod
78
- def to_handler(
79
- cls,
80
- *rules: ABCRule,
81
- ) -> typing.Callable[
82
- [FuncType[Event]],
83
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
84
- ]: ...
85
-
86
- @typing.overload
87
- @classmethod
88
- def to_handler(
89
- cls,
90
- *rules: ABCRule,
91
- error_handler: ErrorHandlerT,
92
- is_blocking: bool = True,
93
- ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
94
-
95
- @typing.overload
96
- @classmethod
97
- def to_handler(
98
- cls,
99
- *rules: ABCRule,
100
- error_handler: typing.Literal[None] = None,
101
- is_blocking: bool = True,
102
- ) -> typing.Callable[
103
- [FuncType[Event]],
104
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
105
- ]: ...
106
-
107
- @classmethod
108
- def to_handler( # type: ignore
109
- cls,
110
- *rules: ABCRule,
111
- error_handler: ABCErrorHandler | None = None,
112
- is_blocking: bool = True,
113
- ):
114
- def wrapper(func: FuncType[Event]):
115
- return FuncHandler(
116
- func,
117
- list(rules),
118
- is_blocking=is_blocking,
119
- dataclass=None,
120
- error_handler=error_handler or ErrorHandler(),
121
- )
122
-
123
- return wrapper
124
-
125
- @typing.overload
126
- def __call__(
127
- self,
128
- *rules: ABCRule,
129
- ) -> typing.Callable[
130
- [FuncType[Event]],
131
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
132
- ]: ...
133
-
134
- @typing.overload
135
- def __call__( # type: ignore
136
- self,
137
- *rules: ABCRule,
138
- error_handler: ErrorHandlerT,
139
- is_blocking: bool = True,
140
- ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
141
-
142
- @typing.overload
143
- def __call__(
144
- self,
145
- *rules: ABCRule,
146
- error_handler: typing.Literal[None] = None,
147
- is_blocking: bool = True,
148
- ) -> typing.Callable[
149
- [FuncType[Event]],
150
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
151
- ]: ...
152
-
153
- def __call__( # type: ignore
154
- self,
155
- *rules: ABCRule,
156
- error_handler: ABCErrorHandler | None = None,
157
- is_blocking: bool = True,
158
- ):
159
- def wrapper(func: FuncType[Event]):
160
- func_handler = FuncHandler(
161
- func,
162
- [*self.auto_rules, *rules],
163
- is_blocking=is_blocking,
164
- dataclass=None,
165
- error_handler=error_handler or ErrorHandler(),
166
- )
167
- self.handlers.append(func_handler)
168
- return func_handler
169
-
170
- return wrapper
171
-
172
- def register_middleware(self, *args: typing.Any, **kwargs: typing.Any):
173
- def wrapper(cls: type[MiddlewareT]) -> type[MiddlewareT]:
174
- self.middlewares.append(cls(*args, **kwargs))
175
- return cls
176
-
177
- return wrapper
178
-
179
- async def check(self, event: Update) -> bool:
180
- match self.get_raw_event(event):
181
- case Some(e) if issubclass(
182
- self.get_event_type.expect(
183
- "{!r} has no event type in generic.".format(self.__class__.__name__),
184
- ),
185
- e.__class__,
186
- ) and (self.handlers or self.middlewares):
187
- return True
188
- case _:
189
- return False
190
-
191
- async def process(self, event: Update, api: API) -> bool:
192
- return await process_inner(
193
- api,
194
- self.get_event_type.unwrap().from_update(
195
- update=self.get_raw_event(event).unwrap(),
196
- bound_api=api,
197
- ),
198
- event,
199
- self.middlewares,
200
- self.handlers,
201
- self.return_manager,
202
- )
203
-
204
- def load(self, external: typing.Self) -> None:
205
- self.auto_rules.extend(external.auto_rules)
206
- self.handlers.extend(external.handlers)
207
- self.middlewares.extend(external.middlewares)
208
-
209
-
210
- class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Event]):
211
- @abstractmethod
212
- def get_state_key(self, event: Event) -> int | None:
213
- pass
214
-
215
-
216
39
  __all__ = (
217
- "ABCStateView",
218
40
  "ABCEventRawView",
41
+ "ABCStateView",
219
42
  "ABCView",
220
- "BaseStateView",
221
- "BaseView",
222
43
  )