telegrinder 0.1.dev171__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 (92) hide show
  1. telegrinder/__init__.py +2 -2
  2. telegrinder/api/__init__.py +1 -2
  3. telegrinder/api/api.py +3 -3
  4. telegrinder/api/token.py +36 -0
  5. telegrinder/bot/__init__.py +12 -6
  6. telegrinder/bot/bot.py +12 -5
  7. telegrinder/bot/cute_types/__init__.py +7 -7
  8. telegrinder/bot/cute_types/base.py +7 -32
  9. telegrinder/bot/cute_types/callback_query.py +5 -6
  10. telegrinder/bot/cute_types/chat_join_request.py +4 -5
  11. telegrinder/bot/cute_types/chat_member_updated.py +3 -4
  12. telegrinder/bot/cute_types/inline_query.py +3 -4
  13. telegrinder/bot/cute_types/message.py +9 -10
  14. telegrinder/bot/cute_types/update.py +8 -9
  15. telegrinder/bot/cute_types/utils.py +1 -1
  16. telegrinder/bot/dispatch/__init__.py +9 -9
  17. telegrinder/bot/dispatch/abc.py +2 -2
  18. telegrinder/bot/dispatch/context.py +11 -2
  19. telegrinder/bot/dispatch/dispatch.py +18 -33
  20. telegrinder/bot/dispatch/handler/__init__.py +3 -3
  21. telegrinder/bot/dispatch/handler/abc.py +3 -3
  22. telegrinder/bot/dispatch/handler/func.py +17 -12
  23. telegrinder/bot/dispatch/handler/message_reply.py +6 -7
  24. telegrinder/bot/dispatch/middleware/__init__.py +1 -1
  25. telegrinder/bot/dispatch/process.py +30 -11
  26. telegrinder/bot/dispatch/return_manager/__init__.py +4 -4
  27. telegrinder/bot/dispatch/return_manager/callback_query.py +1 -2
  28. telegrinder/bot/dispatch/return_manager/inline_query.py +1 -2
  29. telegrinder/bot/dispatch/return_manager/message.py +1 -2
  30. telegrinder/bot/dispatch/view/__init__.py +8 -8
  31. telegrinder/bot/dispatch/view/abc.py +9 -4
  32. telegrinder/bot/dispatch/view/box.py +2 -2
  33. telegrinder/bot/dispatch/view/callback_query.py +1 -2
  34. telegrinder/bot/dispatch/view/chat_join_request.py +1 -2
  35. telegrinder/bot/dispatch/view/chat_member.py +16 -2
  36. telegrinder/bot/dispatch/view/inline_query.py +1 -2
  37. telegrinder/bot/dispatch/view/message.py +1 -2
  38. telegrinder/bot/dispatch/view/raw.py +8 -10
  39. telegrinder/bot/dispatch/waiter_machine/__init__.py +3 -3
  40. telegrinder/bot/dispatch/waiter_machine/machine.py +10 -6
  41. telegrinder/bot/dispatch/waiter_machine/short_state.py +2 -2
  42. telegrinder/bot/polling/abc.py +1 -1
  43. telegrinder/bot/polling/polling.py +3 -3
  44. telegrinder/bot/rules/__init__.py +20 -20
  45. telegrinder/bot/rules/abc.py +50 -40
  46. telegrinder/bot/rules/adapter/__init__.py +5 -5
  47. telegrinder/bot/rules/adapter/abc.py +6 -3
  48. telegrinder/bot/rules/adapter/errors.py +2 -1
  49. telegrinder/bot/rules/adapter/event.py +27 -15
  50. telegrinder/bot/rules/adapter/node.py +28 -22
  51. telegrinder/bot/rules/adapter/raw_update.py +13 -5
  52. telegrinder/bot/rules/callback_data.py +4 -4
  53. telegrinder/bot/rules/chat_join.py +4 -4
  54. telegrinder/bot/rules/func.py +1 -1
  55. telegrinder/bot/rules/inline.py +3 -3
  56. telegrinder/bot/rules/markup.py +3 -1
  57. telegrinder/bot/rules/message_entities.py +1 -1
  58. telegrinder/bot/rules/text.py +1 -2
  59. telegrinder/bot/rules/update.py +1 -2
  60. telegrinder/bot/scenario/abc.py +2 -2
  61. telegrinder/bot/scenario/checkbox.py +1 -2
  62. telegrinder/bot/scenario/choice.py +1 -2
  63. telegrinder/model.py +6 -1
  64. telegrinder/msgspec_utils.py +55 -55
  65. telegrinder/node/__init__.py +1 -3
  66. telegrinder/node/base.py +14 -86
  67. telegrinder/node/composer.py +71 -74
  68. telegrinder/node/container.py +3 -3
  69. telegrinder/node/event.py +40 -31
  70. telegrinder/node/polymorphic.py +12 -6
  71. telegrinder/node/rule.py +1 -9
  72. telegrinder/node/scope.py +9 -1
  73. telegrinder/node/source.py +11 -0
  74. telegrinder/node/update.py +6 -2
  75. telegrinder/rules.py +59 -0
  76. telegrinder/tools/error_handler/abc.py +2 -2
  77. telegrinder/tools/error_handler/error_handler.py +5 -5
  78. telegrinder/tools/global_context/global_context.py +1 -1
  79. telegrinder/tools/keyboard.py +1 -1
  80. telegrinder/tools/loop_wrapper/loop_wrapper.py +9 -9
  81. telegrinder/tools/magic.py +64 -19
  82. telegrinder/types/__init__.py +1 -0
  83. telegrinder/types/enums.py +1 -0
  84. telegrinder/types/methods.py +78 -11
  85. telegrinder/types/objects.py +46 -24
  86. telegrinder/verification_utils.py +1 -3
  87. {telegrinder-0.1.dev171.dist-info → telegrinder-0.2.0.dist-info}/METADATA +1 -1
  88. telegrinder-0.2.0.dist-info/RECORD +145 -0
  89. telegrinder/api/abc.py +0 -79
  90. telegrinder-0.1.dev171.dist-info/RECORD +0 -145
  91. {telegrinder-0.1.dev171.dist-info → telegrinder-0.2.0.dist-info}/LICENSE +0 -0
  92. {telegrinder-0.1.dev171.dist-info → telegrinder-0.2.0.dist-info}/WHEEL +0 -0
@@ -3,7 +3,7 @@ from functools import cached_property
3
3
 
4
4
  import typing_extensions as typing
5
5
 
6
- from telegrinder.api.abc import ABCAPI
6
+ from telegrinder.api import API
7
7
  from telegrinder.bot.cute_types import BaseCute, UpdateCute
8
8
  from telegrinder.bot.dispatch.context import Context
9
9
  from telegrinder.bot.dispatch.process import check_rule
@@ -56,27 +56,27 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
56
56
  def required_nodes(self) -> dict[str, type[Node]]:
57
57
  return get_nodes(self.func)
58
58
 
59
- async def check(self, api: ABCAPI, event: Update, ctx: Context | None = None) -> bool:
59
+ async def check(self, api: API, event: Update, ctx: Context | None = None) -> bool:
60
60
  if self.update_type is not None and self.update_type != event.update_type:
61
61
  return False
62
62
 
63
+ logger.debug("Checking handler {!r}...", self)
63
64
  ctx = Context(raw_update=event) if ctx is None else ctx
64
65
  temp_ctx = ctx.copy()
65
66
  temp_ctx |= self.preset_context
66
67
 
67
68
  nodes = self.required_nodes
68
69
  node_col = None
70
+ update = event
69
71
 
70
72
  if nodes:
71
- node_col = await compose_nodes(
72
- UpdateCute.from_update(event, api),
73
- ctx,
74
- nodes,
75
- )
76
-
77
- if node_col is None:
73
+ result = await compose_nodes(nodes, ctx, data={Update: event, API: api})
74
+ if not result:
75
+ logger.debug(f"Cannot compose nodes for handler. {result.error}")
78
76
  return False
79
- temp_ctx |= node_col.values()
77
+
78
+ node_col = result.value
79
+ temp_ctx |= node_col.values
80
80
 
81
81
  if EVENT_NODE_KEY in ctx:
82
82
  for name, node in nodes.items():
@@ -84,15 +84,18 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
84
84
  ctx[EVENT_NODE_KEY] = temp_ctx.pop(name)
85
85
 
86
86
  for rule in self.rules:
87
- if not await check_rule(api, rule, event, temp_ctx):
87
+ if not await check_rule(api, rule, update, temp_ctx):
88
88
  logger.debug("Rule {!r} failed!", rule)
89
89
  return False
90
90
 
91
+ logger.debug("All checks passed for handler.")
92
+
91
93
  temp_ctx["node_col"] = node_col
92
94
  ctx |= temp_ctx
93
95
  return True
94
96
 
95
- async def run(self, api: ABCAPI, event: Event, ctx: Context) -> typing.Any:
97
+ async def run(self, api: API, event: Event, ctx: Context) -> typing.Any:
98
+ logger.debug(f"Running func handler {self.func}")
96
99
  dataclass_type = typing.get_origin(self.dataclass) or self.dataclass
97
100
 
98
101
  if dataclass_type is Update and (event_node := ctx.pop(EVENT_NODE_KEY, None)) is not None:
@@ -106,8 +109,10 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
106
109
  if issubclass(dataclass_type, BaseCute)
107
110
  else self.dataclass(**update.to_dict()) # type: ignore
108
111
  )
112
+
109
113
  elif issubclass(dataclass_type, UpdateCute) and isinstance(event, Update):
110
114
  event = self.dataclass.from_update(event, bound_api=api) # type: ignore
115
+
111
116
  else:
112
117
  event = self.dataclass(**event.to_dict()) # type: ignore
113
118
 
@@ -1,15 +1,14 @@
1
1
  import typing
2
2
 
3
- from telegrinder.api.abc import ABCAPI
4
- from telegrinder.bot.cute_types import MessageCute
3
+ from telegrinder.api.api import API
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
6
7
  from telegrinder.bot.dispatch.process import check_rule
7
8
  from telegrinder.bot.rules.abc import ABCRule
8
9
  from telegrinder.modules import logger
9
10
  from telegrinder.types.objects import ReplyParameters, Update
10
11
 
11
- from .abc import ABCHandler
12
-
13
12
 
14
13
  class MessageReplyHandler(ABCHandler[MessageCute]):
15
14
  def __init__(
@@ -36,8 +35,8 @@ class MessageReplyHandler(ABCHandler[MessageCute]):
36
35
  self.text,
37
36
  )
38
37
 
39
- async def check(self, api: ABCAPI, event: Update, ctx: Context | None = None) -> bool:
40
- ctx = Context() if ctx is None else ctx
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
41
40
  temp_ctx = ctx.copy()
42
41
  temp_ctx |= self.preset_context
43
42
 
@@ -49,7 +48,7 @@ class MessageReplyHandler(ABCHandler[MessageCute]):
49
48
  ctx |= temp_ctx
50
49
  return True
51
50
 
52
- async def run(self, _: ABCAPI, event: MessageCute, __: Context) -> typing.Any:
51
+ async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
53
52
  await event.answer(
54
53
  text=self.text,
55
54
  reply_parameters=ReplyParameters(event.message_id) if self.as_reply else None,
@@ -1,3 +1,3 @@
1
- from .abc import ABCMiddleware
1
+ from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
2
2
 
3
3
  __all__ = ("ABCMiddleware",)
@@ -2,7 +2,7 @@ import typing
2
2
 
3
3
  from fntypes.result import Error, Ok
4
4
 
5
- from telegrinder.api.abc import ABCAPI
5
+ from telegrinder.api.api import API
6
6
  from telegrinder.bot.cute_types.update import UpdateCute
7
7
  from telegrinder.bot.dispatch.context import Context
8
8
  from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
@@ -18,11 +18,10 @@ if typing.TYPE_CHECKING:
18
18
  from telegrinder.bot.rules.abc import ABCRule
19
19
 
20
20
  Event = typing.TypeVar("Event", bound=Model)
21
- _: typing.TypeAlias = typing.Any
22
21
 
23
22
 
24
23
  async def process_inner(
25
- api: ABCAPI,
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
@@ -43,6 +45,7 @@ async def process_inner(
43
45
 
44
46
  for handler in handlers:
45
47
  if await handler.check(api, raw_event, ctx):
48
+ logger.debug("Handler {!r} matched, run...", handler)
46
49
  found = True
47
50
  response = await handler.run(api, event, ctx)
48
51
  logger.debug("Handler {!r} returned: {!r}", handler, response)
@@ -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,7 +106,7 @@ 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
 
@@ -96,12 +114,13 @@ async def check_rule(
96
114
  nodes = rule.required_nodes
97
115
  node_col = None
98
116
  if nodes:
99
- node_col = await compose_nodes(UpdateCute.from_update(update, api), ctx, nodes)
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",
@@ -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",
@@ -4,7 +4,7 @@ from functools import cached_property
4
4
 
5
5
  from fntypes.co import Nothing, Some
6
6
 
7
- from telegrinder.api.abc import ABCAPI
7
+ from telegrinder.api import API
8
8
  from telegrinder.bot.cute_types.base import BaseCute
9
9
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
10
10
  from telegrinder.bot.dispatch.handler.func import FuncHandler
@@ -29,14 +29,14 @@ FuncType: typing.TypeAlias = typing.Callable[
29
29
 
30
30
  class ABCView(ABC):
31
31
  def __repr__(self) -> str:
32
- return "<{!r}>".format(self.__class__.__name__)
32
+ return "<{}>".format(self.__class__.__name__)
33
33
 
34
34
  @abstractmethod
35
35
  async def check(self, event: Update) -> bool:
36
36
  pass
37
37
 
38
38
  @abstractmethod
39
- async def process(self, event: Update, api: ABCAPI) -> bool:
39
+ async def process(self, event: Update, api: API) -> bool:
40
40
  pass
41
41
 
42
42
  @abstractmethod
@@ -44,6 +44,10 @@ class ABCView(ABC):
44
44
  pass
45
45
 
46
46
 
47
+ class ABCEventRawView(ABCView, ABC, typing.Generic[Event]):
48
+ handlers: list[ABCHandler[Event]]
49
+
50
+
47
51
  class ABCStateView(ABCView, typing.Generic[Event]):
48
52
  @abstractmethod
49
53
  def get_state_key(self, event: Event) -> int | None:
@@ -184,7 +188,7 @@ class BaseView(ABCView, typing.Generic[Event]):
184
188
  case _:
185
189
  return False
186
190
 
187
- async def process(self, event: Update, api: ABCAPI) -> bool:
191
+ async def process(self, event: Update, api: API) -> bool:
188
192
  return await process_inner(
189
193
  api,
190
194
  self.get_event_type.unwrap().from_update(
@@ -211,6 +215,7 @@ class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Ev
211
215
 
212
216
  __all__ = (
213
217
  "ABCStateView",
218
+ "ABCEventRawView",
214
219
  "ABCView",
215
220
  "BaseStateView",
216
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)
@@ -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,
@@ -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,11 +100,9 @@ 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:
106
- if not self.handlers or not self.middlewares:
107
- return False
105
+ async def process(self, event: Update, api: API) -> bool:
108
106
  return await process_inner(
109
107
  api,
110
108
  UpdateCute.from_update(event, bound_api=api),
@@ -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",
@@ -2,16 +2,20 @@ import asyncio
2
2
  import datetime
3
3
  import typing
4
4
 
5
- from telegrinder.api.abc import ABCAPI
5
+ from telegrinder.api import API
6
6
  from telegrinder.bot.dispatch.context import Context
7
7
  from telegrinder.bot.dispatch.view.abc import ABCStateView, BaseStateView
8
+ from telegrinder.bot.dispatch.waiter_machine.middleware import WaiterMiddleware
9
+ from telegrinder.bot.dispatch.waiter_machine.short_state import (
10
+ Behaviour,
11
+ EventModel,
12
+ ShortState,
13
+ ShortStateContext,
14
+ )
8
15
  from telegrinder.bot.rules.abc import ABCRule
9
16
  from telegrinder.tools.limited_dict import LimitedDict
10
17
  from telegrinder.types import Update
11
18
 
12
- from .middleware import WaiterMiddleware
13
- from .short_state import Behaviour, EventModel, ShortState, ShortStateContext
14
-
15
19
  if typing.TYPE_CHECKING:
16
20
  from telegrinder.bot.dispatch import Dispatch
17
21
 
@@ -67,7 +71,7 @@ class WaiterMachine:
67
71
  async def wait(
68
72
  self,
69
73
  state_view: "BaseStateView[EventModel]",
70
- linked: EventModel | tuple[ABCAPI, Identificator],
74
+ linked: EventModel | tuple[API, Identificator],
71
75
  *rules: ABCRule,
72
76
  default: Behaviour[EventModel] | None = None,
73
77
  on_drop: Behaviour[EventModel] | None = None,
@@ -77,7 +81,7 @@ class WaiterMachine:
77
81
  if isinstance(expiration, int | float):
78
82
  expiration = datetime.timedelta(seconds=expiration)
79
83
 
80
- api: ABCAPI
84
+ api: API
81
85
  key: Identificator
82
86
  api, key = linked if isinstance(linked, tuple) else (linked.ctx_api, state_view.get_state_key(linked)) # type: ignore
83
87
  if not key:
@@ -3,7 +3,7 @@ import dataclasses
3
3
  import datetime
4
4
  import typing
5
5
 
6
- from telegrinder.api import ABCAPI
6
+ from telegrinder.api import API
7
7
  from telegrinder.bot.cute_types import BaseCute
8
8
  from telegrinder.bot.dispatch.context import Context
9
9
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
@@ -27,7 +27,7 @@ class ShortStateContext(typing.Generic[EventModel], typing.NamedTuple):
27
27
  @dataclasses.dataclass(slots=True)
28
28
  class ShortState(typing.Generic[EventModel]):
29
29
  key: "Identificator"
30
- ctx_api: ABCAPI
30
+ ctx_api: API
31
31
  event: asyncio.Event
32
32
  rules: tuple[ABCRule, ...]
33
33
  expiration: dataclasses.InitVar[datetime.timedelta | None] = dataclasses.field(
@@ -3,7 +3,7 @@ from abc import ABC, abstractmethod
3
3
 
4
4
  import msgspec
5
5
 
6
- from telegrinder.types import Update
6
+ from telegrinder.types.objects import Update
7
7
 
8
8
 
9
9
  class ABCPolling(ABC):
@@ -5,18 +5,18 @@ import aiohttp
5
5
  import msgspec
6
6
  from fntypes.result import Error, Ok
7
7
 
8
- from telegrinder.api.abc import ABCAPI
8
+ from telegrinder.api import API
9
9
  from telegrinder.api.error import InvalidTokenError
10
10
  from telegrinder.bot.polling.abc import ABCPolling
11
11
  from telegrinder.modules import logger
12
12
  from telegrinder.msgspec_utils import decoder
13
- from telegrinder.types import Update, UpdateType
13
+ from telegrinder.types.objects import Update, UpdateType
14
14
 
15
15
 
16
16
  class Polling(ABCPolling):
17
17
  def __init__(
18
18
  self,
19
- api: ABCAPI,
19
+ api: API,
20
20
  *,
21
21
  offset: int = 0,
22
22
  reconnection_timeout: float = 5,