telegrinder 0.1.dev170__py3-none-any.whl → 0.2.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 (116) hide show
  1. telegrinder/__init__.py +2 -2
  2. telegrinder/api/__init__.py +1 -2
  3. telegrinder/api/api.py +15 -6
  4. telegrinder/api/error.py +2 -1
  5. telegrinder/api/token.py +36 -0
  6. telegrinder/bot/__init__.py +12 -6
  7. telegrinder/bot/bot.py +18 -6
  8. telegrinder/bot/cute_types/__init__.py +7 -7
  9. telegrinder/bot/cute_types/base.py +122 -20
  10. telegrinder/bot/cute_types/callback_query.py +10 -6
  11. telegrinder/bot/cute_types/chat_join_request.py +4 -5
  12. telegrinder/bot/cute_types/chat_member_updated.py +4 -6
  13. telegrinder/bot/cute_types/inline_query.py +3 -4
  14. telegrinder/bot/cute_types/message.py +32 -21
  15. telegrinder/bot/cute_types/update.py +51 -4
  16. telegrinder/bot/cute_types/utils.py +3 -466
  17. telegrinder/bot/dispatch/__init__.py +10 -11
  18. telegrinder/bot/dispatch/abc.py +8 -5
  19. telegrinder/bot/dispatch/context.py +17 -8
  20. telegrinder/bot/dispatch/dispatch.py +71 -48
  21. telegrinder/bot/dispatch/handler/__init__.py +3 -3
  22. telegrinder/bot/dispatch/handler/abc.py +4 -4
  23. telegrinder/bot/dispatch/handler/func.py +46 -22
  24. telegrinder/bot/dispatch/handler/message_reply.py +6 -7
  25. telegrinder/bot/dispatch/middleware/__init__.py +1 -1
  26. telegrinder/bot/dispatch/middleware/abc.py +2 -2
  27. telegrinder/bot/dispatch/process.py +38 -19
  28. telegrinder/bot/dispatch/return_manager/__init__.py +4 -4
  29. telegrinder/bot/dispatch/return_manager/abc.py +3 -3
  30. telegrinder/bot/dispatch/return_manager/callback_query.py +1 -2
  31. telegrinder/bot/dispatch/return_manager/inline_query.py +1 -2
  32. telegrinder/bot/dispatch/return_manager/message.py +1 -2
  33. telegrinder/bot/dispatch/view/__init__.py +8 -8
  34. telegrinder/bot/dispatch/view/abc.py +18 -16
  35. telegrinder/bot/dispatch/view/box.py +75 -64
  36. telegrinder/bot/dispatch/view/callback_query.py +1 -2
  37. telegrinder/bot/dispatch/view/chat_join_request.py +1 -2
  38. telegrinder/bot/dispatch/view/chat_member.py +16 -2
  39. telegrinder/bot/dispatch/view/inline_query.py +1 -2
  40. telegrinder/bot/dispatch/view/message.py +12 -5
  41. telegrinder/bot/dispatch/view/raw.py +9 -8
  42. telegrinder/bot/dispatch/waiter_machine/__init__.py +3 -3
  43. telegrinder/bot/dispatch/waiter_machine/machine.py +12 -8
  44. telegrinder/bot/dispatch/waiter_machine/middleware.py +1 -1
  45. telegrinder/bot/dispatch/waiter_machine/short_state.py +4 -3
  46. telegrinder/bot/polling/abc.py +1 -1
  47. telegrinder/bot/polling/polling.py +6 -6
  48. telegrinder/bot/rules/__init__.py +20 -20
  49. telegrinder/bot/rules/abc.py +57 -43
  50. telegrinder/bot/rules/adapter/__init__.py +5 -5
  51. telegrinder/bot/rules/adapter/abc.py +6 -3
  52. telegrinder/bot/rules/adapter/errors.py +2 -1
  53. telegrinder/bot/rules/adapter/event.py +28 -13
  54. telegrinder/bot/rules/adapter/node.py +28 -22
  55. telegrinder/bot/rules/adapter/raw_update.py +13 -5
  56. telegrinder/bot/rules/callback_data.py +4 -4
  57. telegrinder/bot/rules/chat_join.py +4 -4
  58. telegrinder/bot/rules/command.py +5 -7
  59. telegrinder/bot/rules/func.py +2 -2
  60. telegrinder/bot/rules/fuzzy.py +1 -1
  61. telegrinder/bot/rules/inline.py +3 -3
  62. telegrinder/bot/rules/integer.py +1 -2
  63. telegrinder/bot/rules/markup.py +5 -3
  64. telegrinder/bot/rules/message_entities.py +2 -2
  65. telegrinder/bot/rules/node.py +2 -2
  66. telegrinder/bot/rules/regex.py +1 -1
  67. telegrinder/bot/rules/rule_enum.py +1 -1
  68. telegrinder/bot/rules/text.py +1 -2
  69. telegrinder/bot/rules/update.py +1 -2
  70. telegrinder/bot/scenario/abc.py +2 -2
  71. telegrinder/bot/scenario/checkbox.py +3 -4
  72. telegrinder/bot/scenario/choice.py +1 -2
  73. telegrinder/model.py +89 -45
  74. telegrinder/modules.py +3 -3
  75. telegrinder/msgspec_utils.py +85 -57
  76. telegrinder/node/__init__.py +17 -10
  77. telegrinder/node/attachment.py +19 -16
  78. telegrinder/node/base.py +46 -22
  79. telegrinder/node/callback_query.py +5 -9
  80. telegrinder/node/command.py +6 -2
  81. telegrinder/node/composer.py +102 -77
  82. telegrinder/node/container.py +3 -3
  83. telegrinder/node/event.py +68 -0
  84. telegrinder/node/me.py +3 -0
  85. telegrinder/node/message.py +6 -10
  86. telegrinder/node/polymorphic.py +15 -10
  87. telegrinder/node/rule.py +20 -6
  88. telegrinder/node/scope.py +9 -1
  89. telegrinder/node/source.py +21 -11
  90. telegrinder/node/text.py +4 -4
  91. telegrinder/node/update.py +7 -4
  92. telegrinder/py.typed +0 -0
  93. telegrinder/rules.py +59 -0
  94. telegrinder/tools/__init__.py +2 -2
  95. telegrinder/tools/buttons.py +5 -10
  96. telegrinder/tools/error_handler/abc.py +2 -2
  97. telegrinder/tools/error_handler/error.py +2 -0
  98. telegrinder/tools/error_handler/error_handler.py +6 -6
  99. telegrinder/tools/formatting/spec_html_formats.py +10 -10
  100. telegrinder/tools/global_context/__init__.py +2 -2
  101. telegrinder/tools/global_context/global_context.py +3 -3
  102. telegrinder/tools/global_context/telegrinder_ctx.py +4 -4
  103. telegrinder/tools/keyboard.py +3 -3
  104. telegrinder/tools/loop_wrapper/loop_wrapper.py +47 -13
  105. telegrinder/tools/magic.py +96 -18
  106. telegrinder/types/__init__.py +1 -0
  107. telegrinder/types/enums.py +2 -0
  108. telegrinder/types/methods.py +91 -15
  109. telegrinder/types/objects.py +49 -24
  110. telegrinder/verification_utils.py +1 -3
  111. {telegrinder-0.1.dev170.dist-info → telegrinder-0.2.0.dist-info}/METADATA +2 -2
  112. telegrinder-0.2.0.dist-info/RECORD +145 -0
  113. telegrinder/api/abc.py +0 -73
  114. telegrinder-0.1.dev170.dist-info/RECORD +0 -143
  115. {telegrinder-0.1.dev170.dist-info → telegrinder-0.2.0.dist-info}/LICENSE +0 -0
  116. {telegrinder-0.1.dev170.dist-info → telegrinder-0.2.0.dist-info}/WHEEL +0 -0
@@ -2,27 +2,26 @@ import typing
2
2
 
3
3
  from fntypes.result import Error, Ok
4
4
 
5
- from telegrinder.api.abc import ABCAPI
6
- from telegrinder.bot.cute_types import BaseCute
5
+ from telegrinder.api.api import API
7
6
  from telegrinder.bot.cute_types.update import UpdateCute
8
7
  from telegrinder.bot.dispatch.context import Context
8
+ from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
9
+ from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
10
+ from telegrinder.model import Model
9
11
  from telegrinder.modules import logger
10
12
  from telegrinder.node.composer import CONTEXT_STORE_NODES_KEY, NodeScope, compose_nodes
11
13
  from telegrinder.tools.i18n.base import I18nEnum
12
- from telegrinder.types import Update
13
-
14
- from .middleware.abc import ABCMiddleware
15
- from .return_manager.abc import ABCReturnManager
14
+ from telegrinder.types.objects import Update
16
15
 
17
16
  if typing.TYPE_CHECKING:
18
17
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
19
18
  from telegrinder.bot.rules.abc import ABCRule
20
19
 
21
- Event = typing.TypeVar("Event", bound=BaseCute)
22
- _: typing.TypeAlias = typing.Any
20
+ Event = typing.TypeVar("Event", bound=Model)
23
21
 
24
22
 
25
23
  async def process_inner(
24
+ api: API,
26
25
  event: Event,
27
26
  raw_event: Update,
28
27
  middlewares: list[ABCMiddleware[Event]],
@@ -31,10 +30,13 @@ async def process_inner(
31
30
  ) -> bool:
32
31
  logger.debug("Processing {!r}...", event.__class__.__name__)
33
32
  ctx = Context(raw_update=raw_event)
34
- ctx[CONTEXT_STORE_NODES_KEY] = {} # for per-event shared nodes
33
+ ctx[CONTEXT_STORE_NODES_KEY] = {} # For per-event shared nodes
35
34
 
35
+ logger.debug("Run pre middlewares...")
36
36
  for middleware in middlewares:
37
- if await middleware.pre(event, ctx) is False:
37
+ middleware_result = await middleware.pre(event, ctx)
38
+ logger.debug("Middleware {!r} returned {!r}", middleware.__class__.__name__, middleware_result)
39
+ if middleware_result is False:
38
40
  return False
39
41
 
40
42
  found = False
@@ -42,9 +44,10 @@ async def process_inner(
42
44
  ctx_copy = ctx.copy()
43
45
 
44
46
  for handler in handlers:
45
- if await handler.check(event.api, raw_event, ctx):
47
+ if await handler.check(api, raw_event, ctx):
48
+ logger.debug("Handler {!r} matched, run...", handler)
46
49
  found = True
47
- response = await handler.run(event, ctx)
50
+ response = await handler.run(api, event, ctx)
48
51
  logger.debug("Handler {!r} returned: {!r}", handler, response)
49
52
  responses.append(response)
50
53
  if return_manager is not None:
@@ -54,17 +57,24 @@ async def process_inner(
54
57
 
55
58
  ctx = ctx_copy
56
59
 
60
+ logger.debug("Run post middlewares...")
57
61
  for middleware in middlewares:
62
+ logger.debug("Run post middleware {!r}", middleware.__class__.__name__)
58
63
  await middleware.post(event, responses, ctx)
59
64
 
60
65
  for session in ctx.get(CONTEXT_STORE_NODES_KEY, {}).values():
61
66
  await session.close(scopes=(NodeScope.PER_EVENT,))
62
67
 
68
+ logger.debug(
69
+ "{} handlers, returns {!r}",
70
+ "No found" if not found else "Found",
71
+ found,
72
+ )
63
73
  return found
64
74
 
65
75
 
66
76
  async def check_rule(
67
- api: ABCAPI,
77
+ api: API,
68
78
  rule: "ABCRule",
69
79
  update: Update,
70
80
  ctx: Context,
@@ -73,13 +83,21 @@ async def check_rule(
73
83
  Returns check result."""
74
84
 
75
85
  # Running adapter
76
- match await rule.adapter.adapt(api, update):
86
+ match await rule.adapter.adapt(api, update, ctx):
77
87
  case Ok(value):
78
88
  adapted_value = value
79
89
  case Error(err):
80
90
  logger.debug("Adapter failed with error message: {!r}", str(err))
81
91
  return False
82
92
 
93
+ # Preparing update
94
+ if isinstance(adapted_val := ctx.get(rule.adapter.ADAPTED_VALUE_KEY or ""), UpdateCute):
95
+ update = adapted_val
96
+ elif isinstance(adapted_value, UpdateCute):
97
+ update = adapted_value
98
+ else:
99
+ update = UpdateCute.from_update(update, bound_api=api)
100
+
83
101
  # Running subrules to fetch requirements
84
102
  ctx_copy = ctx.copy()
85
103
  for requirement in rule.requires:
@@ -88,20 +106,21 @@ async def check_rule(
88
106
 
89
107
  # Translating translatable rules
90
108
  if I18nEnum.I18N in ctx:
91
- rule = await rule.translate(ctx.get(I18nEnum.I18N))
109
+ rule = await rule.translate(ctx[I18nEnum.I18N])
92
110
 
93
111
  ctx |= ctx_copy
94
112
 
95
113
  # Composing required nodes
96
- nodes = rule.get_required_nodes()
114
+ nodes = rule.required_nodes
97
115
  node_col = None
98
116
  if nodes:
99
- node_col = await compose_nodes(nodes, UpdateCute.from_update(update, api), ctx)
100
- if node_col is None:
117
+ result = await compose_nodes(nodes, ctx, data={Update: update, API: api})
118
+ if not result:
101
119
  return False
120
+ node_col = result.value
102
121
 
103
122
  # Running check
104
- result = await rule.bounding_check(adapted_value, ctx, node_col)
123
+ result = await rule.bounding_check(adapted_value, ctx, node_col=node_col)
105
124
 
106
125
  # Closing node sessions if there are any
107
126
  if node_col is not None:
@@ -1,12 +1,12 @@
1
- from .abc import (
1
+ from telegrinder.bot.dispatch.return_manager.abc import (
2
2
  ABCReturnManager,
3
3
  BaseReturnManager,
4
4
  Manager,
5
5
  register_manager,
6
6
  )
7
- from .callback_query import CallbackQueryReturnManager
8
- from .inline_query import InlineQueryReturnManager
9
- from .message import MessageReturnManager
7
+ from telegrinder.bot.dispatch.return_manager.callback_query import CallbackQueryReturnManager
8
+ from telegrinder.bot.dispatch.return_manager.inline_query import InlineQueryReturnManager
9
+ from telegrinder.bot.dispatch.return_manager.message import MessageReturnManager
10
10
 
11
11
  __all__ = (
12
12
  "ABCReturnManager",
@@ -3,12 +3,12 @@ import types
3
3
  import typing
4
4
  from abc import ABC, abstractmethod
5
5
 
6
- from telegrinder.bot.cute_types import BaseCute
7
6
  from telegrinder.bot.dispatch.context import Context
7
+ from telegrinder.model import Model
8
8
  from telegrinder.modules import logger
9
9
 
10
10
  T = typing.TypeVar("T")
11
- Event = typing.TypeVar("Event", bound=BaseCute, contravariant=True)
11
+ Event = typing.TypeVar("Event", bound=Model, contravariant=True)
12
12
 
13
13
 
14
14
  def get_union_types(t: types.UnionType) -> tuple[type, ...] | None:
@@ -24,7 +24,7 @@ def register_manager(return_type: type[typing.Any] | types.UnionType):
24
24
  return wrapper
25
25
 
26
26
 
27
- @dataclasses.dataclass(frozen=True)
27
+ @dataclasses.dataclass(frozen=True, slots=True)
28
28
  class Manager:
29
29
  types: tuple[type, ...]
30
30
  callback: typing.Callable[..., typing.Awaitable]
@@ -2,8 +2,7 @@ import typing
2
2
 
3
3
  from telegrinder.bot.cute_types import CallbackQueryCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
-
6
- from .abc import BaseReturnManager, register_manager
5
+ from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
7
6
 
8
7
 
9
8
  class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
@@ -2,8 +2,7 @@ import typing
2
2
 
3
3
  from telegrinder.bot.cute_types import InlineQueryCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
-
6
- from .abc import BaseReturnManager, register_manager
5
+ from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
7
6
 
8
7
 
9
8
  class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
@@ -2,10 +2,9 @@ import typing
2
2
 
3
3
  from telegrinder.bot.cute_types import MessageCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
+ from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
5
6
  from telegrinder.tools.formatting import HTMLFormatter
6
7
 
7
- from .abc import BaseReturnManager, register_manager
8
-
9
8
 
10
9
  class MessageReturnManager(BaseReturnManager[MessageCute]):
11
10
  @register_manager(str)
@@ -1,11 +1,11 @@
1
- from .abc import ABCStateView, ABCView, BaseStateView, BaseView
2
- from .box import ViewBox
3
- from .callback_query import CallbackQueryView
4
- from .chat_join_request import ChatJoinRequestView
5
- from .chat_member import ChatMemberView
6
- from .inline_query import InlineQueryView
7
- from .message import MessageView
8
- from .raw import RawEventView
1
+ from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView, BaseStateView, BaseView
2
+ from telegrinder.bot.dispatch.view.box import ViewBox
3
+ from telegrinder.bot.dispatch.view.callback_query import CallbackQueryView
4
+ from telegrinder.bot.dispatch.view.chat_join_request import ChatJoinRequestView
5
+ from telegrinder.bot.dispatch.view.chat_member import ChatMemberView
6
+ from telegrinder.bot.dispatch.view.inline_query import InlineQueryView
7
+ from telegrinder.bot.dispatch.view.message import MessageView
8
+ from telegrinder.bot.dispatch.view.raw import RawEventView
9
9
 
10
10
  __all__ = (
11
11
  "ABCStateView",
@@ -1,9 +1,10 @@
1
1
  import typing
2
2
  from abc import ABC, abstractmethod
3
+ from functools import cached_property
3
4
 
4
5
  from fntypes.co import Nothing, Some
5
6
 
6
- from telegrinder.api.abc import ABCAPI
7
+ from telegrinder.api import API
7
8
  from telegrinder.bot.cute_types.base import BaseCute
8
9
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
9
10
  from telegrinder.bot.dispatch.handler.func import FuncHandler
@@ -28,17 +29,14 @@ FuncType: typing.TypeAlias = typing.Callable[
28
29
 
29
30
  class ABCView(ABC):
30
31
  def __repr__(self) -> str:
31
- return "<{!r}: {}>".format(
32
- self.__class__.__name__,
33
- ", ".join(f"{k}={v!r}" for k, v in self.__dict__.items()),
34
- )
32
+ return "<{}>".format(self.__class__.__name__)
35
33
 
36
34
  @abstractmethod
37
35
  async def check(self, event: Update) -> bool:
38
36
  pass
39
37
 
40
38
  @abstractmethod
41
- async def process(self, event: Update, api: ABCAPI) -> None:
39
+ async def process(self, event: Update, api: API) -> bool:
42
40
  pass
43
41
 
44
42
  @abstractmethod
@@ -46,6 +44,10 @@ class ABCView(ABC):
46
44
  pass
47
45
 
48
46
 
47
+ class ABCEventRawView(ABCView, ABC, typing.Generic[Event]):
48
+ handlers: list[ABCHandler[Event]]
49
+
50
+
49
51
  class ABCStateView(ABCView, typing.Generic[Event]):
50
52
  @abstractmethod
51
53
  def get_state_key(self, event: Event) -> int | None:
@@ -62,9 +64,9 @@ class BaseView(ABCView, typing.Generic[Event]):
62
64
  def get_raw_event(update: Update) -> Option[Model]:
63
65
  return getattr(update, update.update_type.value)
64
66
 
65
- @classmethod
66
- def get_event_type(cls) -> Option[type[Event]]:
67
- for base in cls.__dict__.get("__orig_bases__", ()):
67
+ @cached_property
68
+ def get_event_type(self) -> Option[type[Event]]:
69
+ for base in self.__class__.__dict__.get("__orig_bases__", ()):
68
70
  if issubclass(typing.get_origin(base) or base, ABCView):
69
71
  for generic_type in typing.get_args(base):
70
72
  if issubclass(typing.get_origin(generic_type) or generic_type, BaseCute):
@@ -177,20 +179,19 @@ class BaseView(ABCView, typing.Generic[Event]):
177
179
  async def check(self, event: Update) -> bool:
178
180
  match self.get_raw_event(event):
179
181
  case Some(e) if issubclass(
180
- self.get_event_type().expect(
182
+ self.get_event_type.expect(
181
183
  "{!r} has no event type in generic.".format(self.__class__.__name__),
182
184
  ),
183
185
  e.__class__,
184
- ):
186
+ ) and (self.handlers or self.middlewares):
185
187
  return True
186
188
  case _:
187
189
  return False
188
190
 
189
- async def process(self, event: Update, api: ABCAPI) -> None:
190
- await process_inner(
191
- self.get_event_type()
192
- .unwrap()
193
- .from_update(
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(
194
195
  update=self.get_raw_event(event).unwrap(),
195
196
  bound_api=api,
196
197
  ),
@@ -214,6 +215,7 @@ class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Ev
214
215
 
215
216
  __all__ = (
216
217
  "ABCStateView",
218
+ "ABCEventRawView",
217
219
  "ABCView",
218
220
  "BaseStateView",
219
221
  "BaseView",
@@ -10,7 +10,7 @@ from telegrinder.bot.dispatch.view import (
10
10
  message,
11
11
  raw,
12
12
  )
13
- from telegrinder.bot.dispatch.view.abc import ABCView
13
+ from telegrinder.bot.dispatch.view.abc import ABCEventRawView, ABCView
14
14
  from telegrinder.types.enums import UpdateType
15
15
 
16
16
  CallbackQueryView = typing.TypeVar(
@@ -22,7 +22,7 @@ ChatJoinRequestView = typing.TypeVar(
22
22
  ChatMemberView = typing.TypeVar("ChatMemberView", bound=ABCView, default=chat_member.ChatMemberView)
23
23
  InlineQueryView = typing.TypeVar("InlineQueryView", bound=ABCView, default=inline_query.InlineQueryView)
24
24
  MessageView = typing.TypeVar("MessageView", bound=ABCView, default=message.MessageView)
25
- RawEventView = typing.TypeVar("RawEventView", bound=ABCView, default=raw.RawEventView)
25
+ RawEventView = typing.TypeVar("RawEventView", bound=ABCEventRawView, default=raw.RawEventView)
26
26
 
27
27
 
28
28
  @dataclasses.dataclass(kw_only=True)
@@ -36,78 +36,89 @@ class ViewBox(
36
36
  RawEventView,
37
37
  ],
38
38
  ):
39
- callback_query: CallbackQueryView = dataclasses.field(
40
- default_factory=lambda: typing.cast(
39
+ callback_query_view: dataclasses.InitVar[CallbackQueryView | None] = None
40
+ chat_join_request_view: dataclasses.InitVar[ChatJoinRequestView | None] = None
41
+ chat_member_view: dataclasses.InitVar[ChatMemberView | None] = None
42
+ my_chat_member_view: dataclasses.InitVar[ChatMemberView | None] = None
43
+ inline_query_view: dataclasses.InitVar[InlineQueryView | None] = None
44
+ message_view: dataclasses.InitVar[MessageView | None] = None
45
+ business_message_view: dataclasses.InitVar[MessageView | None] = None
46
+ channel_post_view: dataclasses.InitVar[MessageView | None] = None
47
+ edited_message_view: dataclasses.InitVar[MessageView | None] = None
48
+ edited_business_message_view: dataclasses.InitVar[MessageView | None] = None
49
+ edited_channel_post_view: dataclasses.InitVar[MessageView | None] = None
50
+ any_message_view: dataclasses.InitVar[MessageView | None] = None
51
+ chat_member_updated_view: dataclasses.InitVar[ChatMemberView | None] = None
52
+ raw_event_view: dataclasses.InitVar[RawEventView | None] = None
53
+
54
+ def __post_init__(
55
+ self,
56
+ callback_query_view: CallbackQueryView | None = None,
57
+ chat_join_request_view: ChatJoinRequestView | None = None,
58
+ chat_member_view: ChatMemberView | None = None,
59
+ my_chat_member_view: ChatMemberView | None = None,
60
+ inline_query_view: InlineQueryView | None = None,
61
+ message_view: MessageView | None = None,
62
+ business_message_view: MessageView | None = None,
63
+ channel_post_view: MessageView | None = None,
64
+ edited_message_view: MessageView | None = None,
65
+ edited_business_message_view: MessageView | None = None,
66
+ edited_channel_post_view: MessageView | None = None,
67
+ any_message_view: MessageView | None = None,
68
+ chat_member_updated_view: ChatMemberView | None = None,
69
+ raw_event_view: RawEventView | None = None,
70
+ ) -> None:
71
+ self.callback_query = typing.cast(
41
72
  CallbackQueryView,
42
- callback_query.CallbackQueryView(),
43
- ),
44
- )
45
- chat_join_request: ChatJoinRequestView = dataclasses.field(
46
- default_factory=lambda: typing.cast(
73
+ callback_query_view or callback_query.CallbackQueryView(),
74
+ )
75
+ self.chat_join_request = typing.cast(
47
76
  ChatJoinRequestView,
48
- chat_join_request.ChatJoinRequestView(),
49
- ),
50
- )
51
- chat_member: ChatMemberView = dataclasses.field(
52
- default_factory=lambda: typing.cast(
77
+ chat_join_request_view or chat_join_request.ChatJoinRequestView(),
78
+ )
79
+ self.chat_member = typing.cast(
53
80
  ChatMemberView,
54
- chat_member.ChatMemberView(update_type=UpdateType.CHAT_MEMBER),
55
- ),
56
- )
57
- my_chat_member: ChatMemberView = dataclasses.field(
58
- default_factory=lambda: typing.cast(
81
+ chat_member_view or chat_member.ChatMemberView(update_type=UpdateType.CHAT_MEMBER),
82
+ )
83
+ self.my_chat_member = typing.cast(
59
84
  ChatMemberView,
60
- chat_member.ChatMemberView(update_type=UpdateType.MY_CHAT_MEMBER),
61
- ),
62
- )
63
- inline_query: InlineQueryView = dataclasses.field(
64
- default_factory=lambda: typing.cast(InlineQueryView, inline_query.InlineQueryView()),
65
- )
66
- message: MessageView = dataclasses.field(
67
- default_factory=lambda: typing.cast(
85
+ my_chat_member_view or chat_member.ChatMemberView(update_type=UpdateType.MY_CHAT_MEMBER),
86
+ )
87
+ self.inline_query = typing.cast(
88
+ InlineQueryView,
89
+ inline_query_view or inline_query.InlineQueryView(),
90
+ )
91
+ self.message = typing.cast(
68
92
  MessageView,
69
- message.MessageView(update_type=UpdateType.MESSAGE),
70
- ),
71
- )
72
- business_message: MessageView = dataclasses.field(
73
- default_factory=lambda: typing.cast(
93
+ message_view or message.MessageView(update_type=UpdateType.MESSAGE),
94
+ )
95
+ self.business_message = typing.cast(
74
96
  MessageView,
75
- message.MessageView(update_type=UpdateType.BUSINESS_MESSAGE),
76
- ),
77
- )
78
- channel_post: MessageView = dataclasses.field(
79
- default_factory=lambda: typing.cast(
97
+ business_message_view or message.MessageView(update_type=UpdateType.BUSINESS_MESSAGE),
98
+ )
99
+ self.channel_post = typing.cast(
80
100
  MessageView,
81
- message.MessageView(update_type=UpdateType.CHANNEL_POST),
82
- ),
83
- )
84
- edited_message: MessageView = dataclasses.field(
85
- default_factory=lambda: typing.cast(
101
+ channel_post_view or message.MessageView(update_type=UpdateType.CHANNEL_POST),
102
+ )
103
+ self.edited_message = typing.cast(
86
104
  MessageView,
87
- message.MessageView(update_type=UpdateType.EDITED_MESSAGE),
88
- ),
89
- )
90
- edited_business_message: MessageView = dataclasses.field(
91
- default_factory=lambda: typing.cast(
105
+ edited_message_view or message.MessageView(update_type=UpdateType.EDITED_MESSAGE),
106
+ )
107
+ self.edited_business_message = typing.cast(
92
108
  MessageView,
93
- message.MessageView(update_type=UpdateType.EDITED_BUSINESS_MESSAGE),
94
- ),
95
- )
96
- edited_channel_post: MessageView = dataclasses.field(
97
- default_factory=lambda: typing.cast(
109
+ edited_business_message_view
110
+ or message.MessageView(update_type=UpdateType.EDITED_BUSINESS_MESSAGE),
111
+ )
112
+ self.edited_channel_post = typing.cast(
98
113
  MessageView,
99
- message.MessageView(update_type=UpdateType.EDITED_CHANNEL_POST),
100
- ),
101
- )
102
- any_message: MessageView = dataclasses.field(
103
- default_factory=lambda: typing.cast(MessageView, message.MessageView()),
104
- )
105
- chat_member_updated: ChatMemberView = dataclasses.field(
106
- default_factory=lambda: typing.cast(ChatMemberView, chat_member.ChatMemberView()),
107
- )
108
- raw_event: RawEventView = dataclasses.field(
109
- default_factory=lambda: typing.cast(RawEventView, raw.RawEventView()),
110
- )
114
+ edited_channel_post_view or message.MessageView(update_type=UpdateType.EDITED_CHANNEL_POST),
115
+ )
116
+ self.any_message = typing.cast(MessageView, any_message_view or message.MessageView())
117
+ self.chat_member_updated = typing.cast(
118
+ ChatMemberView,
119
+ chat_member_updated_view or chat_member.ChatMemberView(),
120
+ )
121
+ self.raw_event = typing.cast(RawEventView, raw_event_view or raw.RawEventView())
111
122
 
112
123
  def get_views(self) -> dict[str, ABCView]:
113
124
  """Get all views."""
@@ -1,7 +1,6 @@
1
1
  from telegrinder.bot.cute_types import CallbackQueryCute
2
2
  from telegrinder.bot.dispatch.return_manager import CallbackQueryReturnManager
3
-
4
- from .abc import BaseStateView
3
+ from telegrinder.bot.dispatch.view.abc import BaseStateView
5
4
 
6
5
 
7
6
  class CallbackQueryView(BaseStateView[CallbackQueryCute]):
@@ -1,6 +1,5 @@
1
1
  from telegrinder.bot.cute_types import ChatJoinRequestCute
2
-
3
- from .abc import BaseStateView
2
+ from telegrinder.bot.dispatch.view.abc import BaseStateView
4
3
 
5
4
 
6
5
  class ChatJoinRequestView(BaseStateView[ChatJoinRequestCute]):
@@ -1,9 +1,9 @@
1
1
  import typing
2
2
 
3
3
  from telegrinder.bot.cute_types import ChatMemberUpdatedCute
4
+ from telegrinder.bot.dispatch.view.abc import BaseStateView
4
5
  from telegrinder.types.enums import UpdateType
5
-
6
- from .abc import BaseStateView
6
+ from telegrinder.types.objects import Update
7
7
 
8
8
  ChatMemberUpdateType: typing.TypeAlias = typing.Literal[
9
9
  UpdateType.CHAT_MEMBER,
@@ -19,8 +19,22 @@ class ChatMemberView(BaseStateView[ChatMemberUpdatedCute]):
19
19
  self.return_manager = None
20
20
  self.update_type = update_type
21
21
 
22
+ def __repr__(self) -> str:
23
+ return "<{}: {!r}>".format(
24
+ self.__class__.__name__,
25
+ "chat_member_updated" if self.update_type is None else self.update_type.value,
26
+ )
27
+
22
28
  def get_state_key(self, event: ChatMemberUpdatedCute) -> int | None:
23
29
  return event.chat_id
24
30
 
25
31
 
32
+ async def check(self, event: Update) -> bool:
33
+ return not (
34
+ self.update_type is not None
35
+ and self.update_type != event.update_type
36
+ or not await super().check(event)
37
+ )
38
+
39
+
26
40
  __all__ = ("ChatMemberView",)
@@ -1,7 +1,6 @@
1
1
  from telegrinder.bot.cute_types import InlineQueryCute
2
2
  from telegrinder.bot.dispatch.return_manager import InlineQueryReturnManager
3
-
4
- from .abc import BaseStateView
3
+ from telegrinder.bot.dispatch.view.abc import BaseStateView
5
4
 
6
5
 
7
6
  class InlineQueryView(BaseStateView[InlineQueryCute]):
@@ -2,10 +2,9 @@ import typing
2
2
 
3
3
  from telegrinder.bot.cute_types import MessageCute
4
4
  from telegrinder.bot.dispatch.return_manager import MessageReturnManager
5
+ from telegrinder.bot.dispatch.view.abc import BaseStateView
5
6
  from telegrinder.types import Update, UpdateType
6
7
 
7
- from .abc import BaseStateView
8
-
9
8
  MessageUpdateType: typing.TypeAlias = typing.Literal[
10
9
  UpdateType.MESSAGE,
11
10
  UpdateType.BUSINESS_MESSAGE,
@@ -24,13 +23,21 @@ class MessageView(BaseStateView[MessageCute]):
24
23
  self.middlewares = []
25
24
  self.return_manager = MessageReturnManager()
26
25
 
26
+ def __repr__(self) -> str:
27
+ return "<{}: {!r}>".format(
28
+ self.__class__.__name__,
29
+ "any message update" if self.update_type is None else self.update_type.value,
30
+ )
31
+
27
32
  def get_state_key(self, event: MessageCute) -> int | None:
28
33
  return event.chat_id
29
34
 
30
35
  async def check(self, event: Update) -> bool:
31
- if not await super().check(event):
32
- return False
33
- return True if self.update_type is None else self.update_type == event.update_type
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
+ )
34
41
 
35
42
 
36
43
  __all__ = ("MessageView",)
@@ -1,14 +1,14 @@
1
1
  import typing
2
2
 
3
- from telegrinder.api.abc import ABCAPI
3
+ from telegrinder.api import API
4
4
  from telegrinder.bot.cute_types import UpdateCute
5
5
  from telegrinder.bot.dispatch.handler.func import FuncHandler
6
6
  from telegrinder.bot.dispatch.process import process_inner
7
+ from telegrinder.bot.dispatch.view.abc import ABCEventRawView, BaseView, ErrorHandlerT
7
8
  from telegrinder.bot.rules.abc import ABCRule
8
9
  from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
9
- from telegrinder.types import Update, UpdateType
10
-
11
- from .abc import BaseView, ErrorHandlerT
10
+ from telegrinder.types.enums import UpdateType
11
+ from telegrinder.types.objects import Update
12
12
 
13
13
  T = typing.TypeVar("T")
14
14
 
@@ -18,7 +18,7 @@ FuncType: typing.TypeAlias = typing.Callable[
18
18
  ]
19
19
 
20
20
 
21
- class RawEventView(BaseView[UpdateCute]):
21
+ class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
22
22
  def __init__(self) -> None:
23
23
  self.auto_rules = []
24
24
  self.handlers = []
@@ -88,7 +88,7 @@ class RawEventView(BaseView[UpdateCute]):
88
88
  def wrapper(func: FuncType[typing.Any]):
89
89
  func_handler = FuncHandler(
90
90
  func,
91
- [*self.auto_rules, *rules],
91
+ rules=[*self.auto_rules, *rules],
92
92
  is_blocking=is_blocking,
93
93
  dataclass=dataclass,
94
94
  error_handler=error_handler or ErrorHandler(),
@@ -100,10 +100,11 @@ class RawEventView(BaseView[UpdateCute]):
100
100
  return wrapper
101
101
 
102
102
  async def check(self, event: Update) -> bool:
103
- return False
103
+ return bool(self.handlers) or bool(self.middlewares)
104
104
 
105
- async def process(self, event: Update, api: ABCAPI) -> bool:
105
+ async def process(self, event: Update, api: API) -> bool:
106
106
  return await process_inner(
107
+ api,
107
108
  UpdateCute.from_update(event, bound_api=api),
108
109
  event,
109
110
  self.middlewares,
@@ -1,6 +1,6 @@
1
- from .machine import WaiterMachine, clear_wm_storage_worker
2
- from .middleware import WaiterMiddleware
3
- from .short_state import ShortState
1
+ from telegrinder.bot.dispatch.waiter_machine.machine import WaiterMachine, clear_wm_storage_worker
2
+ from telegrinder.bot.dispatch.waiter_machine.middleware import WaiterMiddleware
3
+ from telegrinder.bot.dispatch.waiter_machine.short_state import ShortState
4
4
 
5
5
  __all__ = (
6
6
  "ShortState",