telegrinder 0.1.dev165__py3-none-any.whl → 0.1.dev167__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 (101) hide show
  1. telegrinder/__init__.py +20 -0
  2. telegrinder/api/abc.py +1 -1
  3. telegrinder/api/api.py +8 -6
  4. telegrinder/api/error.py +2 -3
  5. telegrinder/bot/__init__.py +12 -0
  6. telegrinder/bot/bot.py +2 -2
  7. telegrinder/bot/cute_types/__init__.py +4 -0
  8. telegrinder/bot/cute_types/base.py +10 -10
  9. telegrinder/bot/cute_types/callback_query.py +1 -3
  10. telegrinder/bot/cute_types/chat_join_request.py +65 -0
  11. telegrinder/bot/cute_types/chat_member_updated.py +246 -0
  12. telegrinder/bot/cute_types/message.py +44 -38
  13. telegrinder/bot/cute_types/update.py +5 -4
  14. telegrinder/bot/cute_types/utils.py +40 -20
  15. telegrinder/bot/dispatch/__init__.py +8 -1
  16. telegrinder/bot/dispatch/composition.py +7 -7
  17. telegrinder/bot/dispatch/context.py +9 -10
  18. telegrinder/bot/dispatch/dispatch.py +30 -22
  19. telegrinder/bot/dispatch/handler/abc.py +1 -0
  20. telegrinder/bot/dispatch/handler/func.py +21 -5
  21. telegrinder/bot/dispatch/handler/message_reply.py +2 -3
  22. telegrinder/bot/dispatch/middleware/abc.py +2 -4
  23. telegrinder/bot/dispatch/process.py +4 -3
  24. telegrinder/bot/dispatch/return_manager/__init__.py +1 -1
  25. telegrinder/bot/dispatch/return_manager/abc.py +28 -20
  26. telegrinder/bot/dispatch/return_manager/callback_query.py +4 -2
  27. telegrinder/bot/dispatch/return_manager/inline_query.py +4 -2
  28. telegrinder/bot/dispatch/return_manager/message.py +8 -4
  29. telegrinder/bot/dispatch/view/__init__.py +8 -2
  30. telegrinder/bot/dispatch/view/abc.py +27 -23
  31. telegrinder/bot/dispatch/view/box.py +74 -11
  32. telegrinder/bot/dispatch/view/callback_query.py +1 -3
  33. telegrinder/bot/dispatch/view/chat_join_request.py +17 -0
  34. telegrinder/bot/dispatch/view/chat_member.py +26 -0
  35. telegrinder/bot/dispatch/view/message.py +23 -1
  36. telegrinder/bot/dispatch/view/raw.py +112 -0
  37. telegrinder/bot/dispatch/waiter_machine/machine.py +41 -26
  38. telegrinder/bot/dispatch/waiter_machine/middleware.py +14 -7
  39. telegrinder/bot/dispatch/waiter_machine/short_state.py +10 -7
  40. telegrinder/bot/polling/polling.py +2 -4
  41. telegrinder/bot/rules/__init__.py +20 -12
  42. telegrinder/bot/rules/abc.py +0 -9
  43. telegrinder/bot/rules/adapter/event.py +29 -22
  44. telegrinder/bot/rules/callback_data.py +15 -18
  45. telegrinder/bot/rules/chat_join.py +47 -0
  46. telegrinder/bot/rules/enum_text.py +7 -2
  47. telegrinder/bot/rules/fuzzy.py +1 -2
  48. telegrinder/bot/rules/inline.py +3 -3
  49. telegrinder/bot/rules/is_from.py +39 -51
  50. telegrinder/bot/rules/markup.py +1 -2
  51. telegrinder/bot/rules/mention.py +1 -4
  52. telegrinder/bot/rules/message.py +17 -0
  53. telegrinder/bot/rules/message_entities.py +1 -1
  54. telegrinder/bot/rules/regex.py +1 -2
  55. telegrinder/bot/rules/rule_enum.py +1 -3
  56. telegrinder/bot/rules/start.py +7 -7
  57. telegrinder/bot/rules/text.py +2 -1
  58. telegrinder/bot/rules/update.py +16 -0
  59. telegrinder/bot/scenario/checkbox.py +5 -7
  60. telegrinder/client/aiohttp.py +5 -7
  61. telegrinder/model.py +37 -22
  62. telegrinder/modules.py +15 -33
  63. telegrinder/msgspec_utils.py +34 -35
  64. telegrinder/node/__init__.py +12 -12
  65. telegrinder/node/attachment.py +21 -7
  66. telegrinder/node/base.py +14 -13
  67. telegrinder/node/composer.py +5 -5
  68. telegrinder/node/container.py +1 -1
  69. telegrinder/node/message.py +3 -1
  70. telegrinder/node/rule.py +4 -4
  71. telegrinder/node/source.py +6 -2
  72. telegrinder/node/text.py +3 -1
  73. telegrinder/node/tools/generator.py +1 -1
  74. telegrinder/tools/__init__.py +3 -1
  75. telegrinder/tools/buttons.py +4 -6
  76. telegrinder/tools/error_handler/abc.py +1 -2
  77. telegrinder/tools/error_handler/error.py +3 -6
  78. telegrinder/tools/error_handler/error_handler.py +34 -24
  79. telegrinder/tools/formatting/html.py +9 -5
  80. telegrinder/tools/formatting/links.py +1 -3
  81. telegrinder/tools/formatting/spec_html_formats.py +1 -1
  82. telegrinder/tools/global_context/abc.py +3 -1
  83. telegrinder/tools/global_context/global_context.py +13 -31
  84. telegrinder/tools/global_context/telegrinder_ctx.py +1 -1
  85. telegrinder/tools/i18n/base.py +4 -3
  86. telegrinder/tools/i18n/middleware/base.py +1 -3
  87. telegrinder/tools/i18n/simple.py +1 -3
  88. telegrinder/tools/keyboard.py +1 -1
  89. telegrinder/tools/limited_dict.py +27 -0
  90. telegrinder/tools/loop_wrapper/loop_wrapper.py +18 -14
  91. telegrinder/tools/magic.py +1 -1
  92. telegrinder/types/__init__.py +236 -0
  93. telegrinder/types/enums.py +34 -0
  94. telegrinder/types/methods.py +52 -47
  95. telegrinder/types/objects.py +533 -90
  96. telegrinder/verification_utils.py +4 -1
  97. {telegrinder-0.1.dev165.dist-info → telegrinder-0.1.dev167.dist-info}/METADATA +1 -1
  98. telegrinder-0.1.dev167.dist-info/RECORD +137 -0
  99. telegrinder-0.1.dev165.dist-info/RECORD +0 -128
  100. {telegrinder-0.1.dev165.dist-info → telegrinder-0.1.dev167.dist-info}/LICENSE +0 -0
  101. {telegrinder-0.1.dev165.dist-info → telegrinder-0.1.dev167.dist-info}/WHEEL +0 -0
@@ -8,11 +8,9 @@ T = typing.TypeVar("T", bound=BaseCute)
8
8
 
9
9
 
10
10
  class ABCMiddleware(ABC, typing.Generic[T]):
11
- async def pre(self, event: T, ctx: Context) -> bool:
12
- ...
11
+ async def pre(self, event: T, ctx: Context) -> bool: ...
13
12
 
14
- async def post(self, event: T, responses: list[typing.Any], ctx: Context) -> None:
15
- ...
13
+ async def post(self, event: T, responses: list[typing.Any], ctx: Context) -> None: ...
16
14
 
17
15
 
18
16
  __all__ = ("ABCMiddleware",)
@@ -25,7 +25,7 @@ async def process_inner(
25
25
  raw_event: Update,
26
26
  middlewares: list[ABCMiddleware[T]],
27
27
  handlers: list["ABCHandler[T]"],
28
- return_manager: ABCReturnManager[T],
28
+ return_manager: ABCReturnManager[T] | None = None,
29
29
  ) -> bool:
30
30
  logger.debug("Processing {!r}...", event.__class__.__name__)
31
31
  ctx = Context(raw_update=raw_event)
@@ -43,7 +43,8 @@ async def process_inner(
43
43
  found = True
44
44
  response = await handler.run(event, ctx)
45
45
  responses.append(response)
46
- await return_manager.run(response, event, ctx)
46
+ if return_manager is not None:
47
+ await return_manager.run(response, event, ctx)
47
48
  if handler.is_blocking:
48
49
  break
49
50
  ctx = ctx_copy
@@ -56,7 +57,7 @@ async def process_inner(
56
57
 
57
58
  async def check_rule(
58
59
  api: ABCAPI,
59
- rule: "ABCRule",
60
+ rule: "ABCRule[T]",
60
61
  update: Update,
61
62
  ctx: Context,
62
63
  ) -> bool:
@@ -16,4 +16,4 @@ __all__ = (
16
16
  "Manager",
17
17
  "MessageReturnManager",
18
18
  "register_manager",
19
- )
19
+ )
@@ -17,10 +17,10 @@ def get_union_types(t: types.UnionType) -> tuple[type, ...] | None:
17
17
  return None
18
18
 
19
19
 
20
- def register_manager(return_type: type | types.UnionType):
21
- def wrapper(func: typing.Callable[..., typing.Awaitable]):
20
+ def register_manager(return_type: type[typing.Any] | types.UnionType):
21
+ def wrapper(func: typing.Callable[..., typing.Awaitable[typing.Any]]):
22
22
  return Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
23
-
23
+
24
24
  return wrapper
25
25
 
26
26
 
@@ -61,34 +61,42 @@ class BaseReturnManager(ABCReturnManager[EventT]):
61
61
  @staticmethod
62
62
  async def ctx_manager(value: Context, event: EventT, ctx: Context) -> None:
63
63
  """Basic manager for returning context from handler."""
64
-
64
+
65
65
  ctx.update(value)
66
-
66
+
67
67
  async def run(self, response: typing.Any, event: EventT, ctx: Context) -> None:
68
68
  for manager in self.managers:
69
69
  if typing.Any in manager.types or any(type(response) is x for x in manager.types):
70
70
  await manager(response, event, ctx)
71
-
72
- @typing.overload
73
- def register_manager(self, return_type: type[T]) -> typing.Callable[
74
- [typing.Callable[[T, EventT, Context], typing.Awaitable]], Manager
75
- ]:
76
- ...
77
-
71
+
78
72
  @typing.overload
79
- def register_manager(self, return_type: tuple[type[T], ...]) -> typing.Callable[
80
- [typing.Callable[[tuple[T, ...], EventT, Context], typing.Awaitable]], Manager
81
- ]:
82
- ...
73
+ def register_manager(
74
+ self, return_type: type[T]
75
+ ) -> typing.Callable[
76
+ [typing.Callable[[T, EventT, Context], typing.Awaitable[typing.Any]]], Manager
77
+ ]: ...
83
78
 
84
- def register_manager(self, return_type: type[T] | tuple[type[T], ...]) -> typing.Callable[
85
- [typing.Callable[[T | tuple[T, ...], EventT, Context], typing.Awaitable]], Manager
79
+ @typing.overload
80
+ def register_manager(
81
+ self,
82
+ return_type: tuple[type[T], ...],
83
+ ) -> typing.Callable[
84
+ [typing.Callable[[tuple[T, ...], EventT, Context], typing.Awaitable[typing.Any]]],
85
+ Manager,
86
+ ]: ...
87
+
88
+ def register_manager(
89
+ self,
90
+ return_type: type[T] | tuple[type[T], ...],
91
+ ) -> typing.Callable[
92
+ [typing.Callable[[T | tuple[T, ...], EventT, Context], typing.Awaitable[typing.Any]]],
93
+ Manager,
86
94
  ]:
87
95
  def wrapper(func: typing.Callable[[T, EventT, Context], typing.Awaitable]) -> Manager:
88
96
  manager = Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
89
97
  setattr(self.__class__, func.__name__, manager)
90
98
  return manager
91
-
99
+
92
100
  return wrapper
93
101
 
94
102
 
@@ -96,6 +104,6 @@ __all__ = (
96
104
  "ABCReturnManager",
97
105
  "BaseReturnManager",
98
106
  "Manager",
99
- "register_manager",
100
107
  "get_union_types",
108
+ "register_manager",
101
109
  )
@@ -11,10 +11,12 @@ class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
11
11
  @staticmethod
12
12
  async def str_manager(value: str, event: CallbackQueryCute, ctx: Context) -> None:
13
13
  await event.answer(value)
14
-
14
+
15
15
  @register_manager(dict)
16
16
  @staticmethod
17
- async def dict_manager(value: dict[str, typing.Any], event: CallbackQueryCute, ctx: Context) -> None:
17
+ async def dict_manager(
18
+ value: dict[str, typing.Any], event: CallbackQueryCute, ctx: Context
19
+ ) -> None:
18
20
  await event.answer(**value)
19
21
 
20
22
 
@@ -6,10 +6,12 @@ from telegrinder.bot.dispatch.context import Context
6
6
  from .abc import BaseReturnManager, register_manager
7
7
 
8
8
 
9
- class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
9
+ class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
10
10
  @register_manager(dict)
11
11
  @staticmethod
12
- async def dict_manager(value: dict[str, typing.Any], event: InlineQueryCute, ctx: Context) -> None:
12
+ async def dict_manager(
13
+ value: dict[str, typing.Any], event: InlineQueryCute, ctx: Context
14
+ ) -> None:
13
15
  await event.answer(**value)
14
16
 
15
17
 
@@ -7,18 +7,22 @@ from telegrinder.tools.formatting import HTMLFormatter
7
7
  from .abc import BaseReturnManager, register_manager
8
8
 
9
9
 
10
- class MessageReturnManager(BaseReturnManager[MessageCute]):
10
+ class MessageReturnManager(BaseReturnManager[MessageCute]):
11
11
  @register_manager(str)
12
12
  @staticmethod
13
13
  async def str_manager(value: str, event: MessageCute, ctx: Context) -> None:
14
14
  await event.answer(value)
15
-
15
+
16
16
  @register_manager(list | tuple)
17
17
  @staticmethod
18
- async def seq_manager(value: list[str] | tuple[str, ...], event: MessageCute, ctx: Context) -> None:
18
+ async def seq_manager(
19
+ value: list[str] | tuple[str, ...],
20
+ event: MessageCute,
21
+ ctx: Context,
22
+ ) -> None:
19
23
  for message in value:
20
24
  await event.answer(message)
21
-
25
+
22
26
  @register_manager(dict)
23
27
  @staticmethod
24
28
  async def dict_manager(value: dict[str, typing.Any], event: MessageCute, ctx: Context) -> None:
@@ -1,16 +1,22 @@
1
1
  from .abc import ABCStateView, ABCView, BaseStateView, BaseView
2
2
  from .box import ViewBox
3
3
  from .callback_query import CallbackQueryView
4
+ from .chat_join_request import ChatJoinRequestView
5
+ from .chat_member import ChatMemberView
4
6
  from .inline_query import InlineQueryView
5
7
  from .message import MessageView
8
+ from .raw import RawEventView
6
9
 
7
10
  __all__ = (
8
- "ABCView",
9
11
  "ABCStateView",
10
- "BaseView",
12
+ "ABCView",
11
13
  "BaseStateView",
14
+ "BaseView",
12
15
  "CallbackQueryView",
16
+ "ChatJoinRequestView",
17
+ "ChatMemberView",
13
18
  "InlineQueryView",
14
19
  "MessageView",
20
+ "RawEventView",
15
21
  "ViewBox",
16
22
  )
@@ -27,12 +27,18 @@ FuncType: typing.TypeAlias = typing.Callable[
27
27
 
28
28
 
29
29
  class ABCView(ABC):
30
+ 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
+ )
35
+
30
36
  @abstractmethod
31
37
  async def check(self, event: Update) -> bool:
32
38
  pass
33
39
 
34
40
  @abstractmethod
35
- async def process(self, event: Update, api: ABCAPI):
41
+ async def process(self, event: Update, api: ABCAPI) -> None:
36
42
  pass
37
43
 
38
44
  @abstractmethod
@@ -45,27 +51,19 @@ class ABCStateView(ABCView, typing.Generic[EventType]):
45
51
  def get_state_key(self, event: EventType) -> int | None:
46
52
  pass
47
53
 
48
- def __repr__(self) -> str:
49
- return "<{!r}: {}>".format(
50
- self.__class__.__name__,
51
- ", ".join(f"{k}={v!r}" for k, v in self.__dict__.items()),
52
- )
53
-
54
54
 
55
55
  class BaseView(ABCView, typing.Generic[EventType]):
56
56
  auto_rules: list[ABCRule[EventType]]
57
57
  handlers: list[ABCHandler[EventType]]
58
58
  middlewares: list[ABCMiddleware[EventType]]
59
- return_manager: ABCReturnManager[EventType]
59
+ return_manager: ABCReturnManager[EventType] | None
60
60
 
61
61
  @classmethod
62
62
  def get_event_type(cls) -> Option[type[EventType]]:
63
63
  for base in cls.__dict__.get("__orig_bases__", ()):
64
64
  if issubclass(typing.get_origin(base) or base, ABCView):
65
65
  for generic_type in typing.get_args(base):
66
- if issubclass(
67
- typing.get_origin(generic_type) or generic_type, BaseCute
68
- ):
66
+ if issubclass(typing.get_origin(generic_type) or generic_type, BaseCute):
69
67
  return Some(generic_type)
70
68
  return Nothing()
71
69
 
@@ -76,22 +74,25 @@ class BaseView(ABCView, typing.Generic[EventType]):
76
74
  return getattr(update, update_type.value)
77
75
  case _:
78
76
  return Nothing()
79
-
77
+
80
78
  @typing.overload
81
79
  def __call__(
82
80
  self,
83
81
  *rules: ABCRule[EventType],
84
- ) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandler]]:
85
- ...
86
-
82
+ ) -> typing.Callable[
83
+ [FuncType[EventType]],
84
+ FuncHandler[EventType, FuncType[EventType], ErrorHandler[EventType]],
85
+ ]: ...
86
+
87
87
  @typing.overload
88
88
  def __call__(
89
89
  self,
90
90
  *rules: ABCRule[EventType],
91
91
  error_handler: ErrorHandlerT,
92
92
  is_blocking: bool = True,
93
- ) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandlerT]]:
94
- ...
93
+ ) -> typing.Callable[
94
+ [FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandlerT]
95
+ ]: ...
95
96
 
96
97
  @typing.overload
97
98
  def __call__(
@@ -99,8 +100,10 @@ class BaseView(ABCView, typing.Generic[EventType]):
99
100
  *rules: ABCRule[EventType],
100
101
  error_handler: typing.Literal[None] = None,
101
102
  is_blocking: bool = True,
102
- ) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandler]]:
103
- ...
103
+ ) -> typing.Callable[
104
+ [FuncType[EventType]],
105
+ FuncHandler[EventType, FuncType[EventType], ErrorHandler[EventType]],
106
+ ]: ...
104
107
 
105
108
  def __call__( # type: ignore
106
109
  self,
@@ -114,6 +117,7 @@ class BaseView(ABCView, typing.Generic[EventType]):
114
117
  [*self.auto_rules, *rules],
115
118
  is_blocking=is_blocking,
116
119
  dataclass=None,
120
+ error_handler=error_handler or ErrorHandler(),
117
121
  )
118
122
  self.handlers.append(func_handler)
119
123
  return func_handler
@@ -139,8 +143,8 @@ class BaseView(ABCView, typing.Generic[EventType]):
139
143
  case _:
140
144
  return False
141
145
 
142
- async def process(self, event: Update, api: ABCAPI) -> bool:
143
- return await process_inner(
146
+ async def process(self, event: Update, api: ABCAPI) -> None:
147
+ await process_inner(
144
148
  self.get_event_type()
145
149
  .unwrap()
146
150
  .from_update(
@@ -166,8 +170,8 @@ class BaseStateView(ABCStateView[EventType], BaseView[EventType], ABC, typing.Ge
166
170
 
167
171
 
168
172
  __all__ = (
169
- "ABCView",
170
173
  "ABCStateView",
171
- "BaseView",
174
+ "ABCView",
172
175
  "BaseStateView",
176
+ "BaseView",
173
177
  )
@@ -2,38 +2,101 @@ import dataclasses
2
2
 
3
3
  import typing_extensions as typing
4
4
 
5
+ from telegrinder.types.enums import UpdateType
6
+
5
7
  from .abc import ABCView
6
8
  from .callback_query import CallbackQueryView
9
+ from .chat_join_request import ChatJoinRequestView
10
+ from .chat_member import ChatMemberView
7
11
  from .inline_query import InlineQueryView
8
12
  from .message import MessageView
13
+ from .raw import RawEventView
9
14
 
10
- CallbackQueryViewT = typing.TypeVar(
11
- "CallbackQueryViewT", bound=ABCView, default=CallbackQueryView
12
- )
13
- InlineQueryViewT = typing.TypeVar(
14
- "InlineQueryViewT", bound=ABCView, default=InlineQueryView
15
+ CallbackQueryViewT = typing.TypeVar("CallbackQueryViewT", bound=ABCView, default=CallbackQueryView)
16
+ ChatJoinRequestViewT = typing.TypeVar(
17
+ "ChatJoinRequestViewT", bound=ABCView, default=ChatJoinRequestView
15
18
  )
19
+ ChatMemberViewT = typing.TypeVar("ChatMemberViewT", bound=ABCView, default=ChatMemberView)
20
+ InlineQueryViewT = typing.TypeVar("InlineQueryViewT", bound=ABCView, default=InlineQueryView)
16
21
  MessageViewT = typing.TypeVar("MessageViewT", bound=ABCView, default=MessageView)
22
+ RawEventViewT = typing.TypeVar("RawEventViewT", bound=ABCView, default=RawEventView)
17
23
 
18
24
 
19
25
  @dataclasses.dataclass(kw_only=True)
20
- class ViewBox(typing.Generic[CallbackQueryViewT, InlineQueryViewT, MessageViewT]):
26
+ class ViewBox(
27
+ typing.Generic[
28
+ CallbackQueryViewT,
29
+ ChatJoinRequestViewT,
30
+ ChatMemberViewT,
31
+ InlineQueryViewT,
32
+ MessageViewT,
33
+ RawEventViewT,
34
+ ],
35
+ ):
21
36
  callback_query: CallbackQueryViewT = dataclasses.field(
22
37
  default_factory=lambda: typing.cast(CallbackQueryViewT, CallbackQueryView()),
23
38
  )
39
+ chat_join_request: ChatJoinRequestViewT = dataclasses.field(
40
+ default_factory=lambda: typing.cast(ChatJoinRequestViewT, ChatJoinRequestView()),
41
+ )
42
+ chat_member: ChatMemberViewT = dataclasses.field(
43
+ default_factory=lambda: typing.cast(
44
+ ChatMemberViewT, ChatMemberView(update_type=UpdateType.CHAT_MEMBER)
45
+ ),
46
+ )
47
+ my_chat_member: ChatMemberViewT = dataclasses.field(
48
+ default_factory=lambda: typing.cast(
49
+ ChatMemberViewT, ChatMemberView(update_type=UpdateType.MY_CHAT_MEMBER)
50
+ ),
51
+ )
24
52
  inline_query: InlineQueryViewT = dataclasses.field(
25
53
  default_factory=lambda: typing.cast(InlineQueryViewT, InlineQueryView()),
26
54
  )
27
55
  message: MessageViewT = dataclasses.field(
56
+ default_factory=lambda: typing.cast(
57
+ MessageViewT, MessageView(update_type=UpdateType.MESSAGE)
58
+ ),
59
+ )
60
+ business_message: MessageViewT = dataclasses.field(
61
+ default_factory=lambda: typing.cast(
62
+ MessageViewT, MessageView(update_type=UpdateType.BUSINESS_MESSAGE)
63
+ ),
64
+ )
65
+ channel_post: MessageViewT = dataclasses.field(
66
+ default_factory=lambda: typing.cast(
67
+ MessageViewT, MessageView(update_type=UpdateType.CHANNEL_POST)
68
+ ),
69
+ )
70
+ edited_message: MessageViewT = dataclasses.field(
71
+ default_factory=lambda: typing.cast(
72
+ MessageViewT, MessageView(update_type=UpdateType.EDITED_MESSAGE)
73
+ ),
74
+ )
75
+ edited_business_message: MessageViewT = dataclasses.field(
76
+ default_factory=lambda: typing.cast(
77
+ MessageViewT,
78
+ MessageView(update_type=UpdateType.EDITED_BUSINESS_MESSAGE),
79
+ ),
80
+ )
81
+ edited_channel_post: MessageViewT = dataclasses.field(
82
+ default_factory=lambda: typing.cast(
83
+ MessageViewT, MessageView(update_type=UpdateType.EDITED_CHANNEL_POST)
84
+ ),
85
+ )
86
+ any_message: MessageViewT = dataclasses.field(
28
87
  default_factory=lambda: typing.cast(MessageViewT, MessageView()),
29
88
  )
89
+ chat_member_updated: ChatMemberViewT = dataclasses.field(
90
+ default_factory=lambda: typing.cast(ChatMemberViewT, ChatMemberView()),
91
+ )
92
+ raw_event: RawEventViewT = dataclasses.field(
93
+ default_factory=lambda: typing.cast(RawEventViewT, RawEventView()),
94
+ )
30
95
 
31
96
  def get_views(self) -> dict[str, ABCView]:
32
- return {
33
- name: view
34
- for name, view in self.__dict__.items()
35
- if isinstance(view, ABCView)
36
- }
97
+ """Get all views."""
98
+
99
+ return {name: view for name, view in self.__dict__.items() if isinstance(view, ABCView)}
37
100
 
38
101
 
39
102
  __all__ = ("ViewBox",)
@@ -1,5 +1,3 @@
1
- from fntypes.option import Some
2
-
3
1
  from telegrinder.bot.cute_types import CallbackQueryCute
4
2
  from telegrinder.bot.dispatch.return_manager import CallbackQueryReturnManager
5
3
 
@@ -14,7 +12,7 @@ class CallbackQueryView(BaseStateView[CallbackQueryCute]):
14
12
  self.return_manager = CallbackQueryReturnManager()
15
13
 
16
14
  def get_state_key(self, event: CallbackQueryCute) -> int | None:
17
- return event.message.map(lambda variative: variative.v.message_id).unwrap_or_none()
15
+ return event.message_id.unwrap_or_none()
18
16
 
19
17
 
20
18
  __all__ = ("CallbackQueryView",)
@@ -0,0 +1,17 @@
1
+ from telegrinder.bot.cute_types import ChatJoinRequestCute
2
+
3
+ from .abc import BaseStateView
4
+
5
+
6
+ class ChatJoinRequestView(BaseStateView[ChatJoinRequestCute]):
7
+ def __init__(self) -> None:
8
+ self.auto_rules = []
9
+ self.handlers = []
10
+ self.middlewares = []
11
+ self.return_manager = None
12
+
13
+ def get_state_key(self, event: ChatJoinRequestCute) -> int | None:
14
+ return event.chat_id
15
+
16
+
17
+ __all__ = ("ChatJoinRequestView",)
@@ -0,0 +1,26 @@
1
+ import typing
2
+
3
+ from telegrinder.bot.cute_types import ChatMemberUpdatedCute
4
+ from telegrinder.types.enums import UpdateType
5
+
6
+ from .abc import BaseStateView
7
+
8
+ ChatMemberUpdateType: typing.TypeAlias = typing.Literal[
9
+ UpdateType.CHAT_MEMBER,
10
+ UpdateType.MY_CHAT_MEMBER,
11
+ ]
12
+
13
+
14
+ class ChatMemberView(BaseStateView[ChatMemberUpdatedCute]):
15
+ def __init__(self, *, update_type: ChatMemberUpdateType | None = None) -> None:
16
+ self.auto_rules = []
17
+ self.handlers = []
18
+ self.middlewares = []
19
+ self.return_manager = None
20
+ self.update_type = update_type
21
+
22
+ def get_state_key(self, event: ChatMemberUpdatedCute) -> int | None:
23
+ return event.chat_id
24
+
25
+
26
+ __all__ = ("ChatMemberView",)
@@ -1,18 +1,40 @@
1
+ import typing
2
+
1
3
  from telegrinder.bot.cute_types import MessageCute
2
4
  from telegrinder.bot.dispatch.return_manager import MessageReturnManager
5
+ from telegrinder.types import Update, UpdateType
3
6
 
4
7
  from .abc import BaseStateView
5
8
 
9
+ MessageUpdateType: typing.TypeAlias = typing.Literal[
10
+ UpdateType.MESSAGE,
11
+ UpdateType.BUSINESS_MESSAGE,
12
+ UpdateType.CHANNEL_POST,
13
+ UpdateType.EDITED_BUSINESS_MESSAGE,
14
+ UpdateType.EDITED_CHANNEL_POST,
15
+ UpdateType.EDITED_MESSAGE,
16
+ ]
17
+
6
18
 
7
19
  class MessageView(BaseStateView[MessageCute]):
8
- def __init__(self) -> None:
20
+ def __init__(self, *, update_type: MessageUpdateType | None = None) -> None:
9
21
  self.auto_rules = []
10
22
  self.handlers = []
23
+ self.update_type = update_type
11
24
  self.middlewares = []
12
25
  self.return_manager = MessageReturnManager()
13
26
 
14
27
  def get_state_key(self, event: MessageCute) -> int | None:
15
28
  return event.chat_id
16
29
 
30
+ async def check(self, event: Update) -> bool:
31
+ if not await super().check(event):
32
+ return False
33
+ return (
34
+ True
35
+ if self.update_type is None
36
+ else self.update_type == event.update_type.unwrap_or_none()
37
+ )
38
+
17
39
 
18
40
  __all__ = ("MessageView",)
@@ -0,0 +1,112 @@
1
+ import typing
2
+
3
+ from telegrinder.api.abc import ABCAPI
4
+ from telegrinder.bot.cute_types import UpdateCute
5
+ from telegrinder.bot.dispatch.handler.func import FuncHandler
6
+ from telegrinder.bot.dispatch.process import process_inner
7
+ from telegrinder.bot.rules.abc import ABCRule
8
+ from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
9
+ from telegrinder.types import Update, UpdateType
10
+
11
+ from .abc import BaseView, ErrorHandlerT
12
+
13
+ T = typing.TypeVar("T")
14
+
15
+ FuncType: typing.TypeAlias = typing.Callable[
16
+ typing.Concatenate[T, ...],
17
+ typing.Coroutine[typing.Any, typing.Any, typing.Any],
18
+ ]
19
+
20
+
21
+ class RawEventView(BaseView[UpdateCute]):
22
+ def __init__(self) -> None:
23
+ self.auto_rules = []
24
+ self.handlers = []
25
+ self.middlewares = []
26
+ self.return_manager = None
27
+
28
+ @typing.overload
29
+ def __call__(
30
+ self,
31
+ update_type: UpdateType,
32
+ *rules: ABCRule[UpdateCute],
33
+ ) -> typing.Callable[
34
+ [FuncType[UpdateCute]],
35
+ FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandler[UpdateCute]],
36
+ ]: ...
37
+
38
+ @typing.overload
39
+ def __call__(
40
+ self,
41
+ update_type: UpdateType,
42
+ *rules: ABCRule[UpdateCute],
43
+ dataclass: type[T],
44
+ ) -> typing.Callable[[FuncType[T]], FuncHandler[UpdateCute, FuncType[T], ErrorHandler[T]]]: ...
45
+
46
+ @typing.overload
47
+ def __call__(
48
+ self,
49
+ update_type: UpdateType,
50
+ *rules: ABCRule[UpdateCute],
51
+ error_handler: ErrorHandlerT,
52
+ ) -> typing.Callable[
53
+ [FuncType[UpdateCute]],
54
+ FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandlerT],
55
+ ]: ...
56
+
57
+ @typing.overload
58
+ def __call__(
59
+ self,
60
+ update_type: UpdateType,
61
+ *rules: ABCRule[UpdateCute],
62
+ dataclass: type[T],
63
+ error_handler: ErrorHandlerT,
64
+ is_blocking: bool = True,
65
+ ) -> typing.Callable[[FuncType[T]], FuncHandler[UpdateCute, FuncType[T], ErrorHandlerT]]: ...
66
+
67
+ @typing.overload
68
+ def __call__(
69
+ self,
70
+ update_type: UpdateType,
71
+ *rules: ABCRule[UpdateCute],
72
+ dataclass: typing.Literal[None] = None,
73
+ error_handler: typing.Literal[None] = None,
74
+ is_blocking: bool = True,
75
+ ) -> typing.Callable[
76
+ [FuncType[UpdateCute]],
77
+ FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandler[UpdateCute]],
78
+ ]: ...
79
+
80
+ def __call__( # type: ignore
81
+ self,
82
+ update_type: UpdateType,
83
+ *rules: ABCRule[typing.Any],
84
+ dataclass: type[typing.Any] | None = None,
85
+ error_handler: ABCErrorHandler | None = None,
86
+ is_blocking: bool = True,
87
+ ):
88
+ def wrapper(func: FuncType[typing.Any]):
89
+ func_handler = FuncHandler(
90
+ func,
91
+ [*self.auto_rules, *rules],
92
+ is_blocking=is_blocking,
93
+ dataclass=dataclass,
94
+ error_handler=error_handler or ErrorHandler(),
95
+ update_type=update_type,
96
+ )
97
+ self.handlers.append(func_handler)
98
+ return func_handler
99
+
100
+ return wrapper
101
+
102
+ async def check(self, event: Update) -> bool:
103
+ return False
104
+
105
+ async def process(self, event: Update, api: ABCAPI) -> bool:
106
+ return await process_inner(
107
+ UpdateCute.from_update(event, bound_api=api),
108
+ event,
109
+ self.middlewares,
110
+ self.handlers,
111
+ self.return_manager,
112
+ )