telegrinder 0.1.dev165__py3-none-any.whl → 0.1.dev166__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 (88) hide show
  1. telegrinder/__init__.py +22 -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 +14 -0
  6. telegrinder/bot/bot.py +5 -3
  7. telegrinder/bot/cute_types/__init__.py +4 -0
  8. telegrinder/bot/cute_types/base.py +22 -13
  9. telegrinder/bot/cute_types/chat_join_request.py +63 -0
  10. telegrinder/bot/cute_types/chat_member_updated.py +244 -0
  11. telegrinder/bot/cute_types/message.py +34 -7
  12. telegrinder/bot/cute_types/update.py +5 -4
  13. telegrinder/bot/cute_types/utils.py +39 -17
  14. telegrinder/bot/dispatch/__init__.py +9 -1
  15. telegrinder/bot/dispatch/composition.py +10 -8
  16. telegrinder/bot/dispatch/context.py +9 -10
  17. telegrinder/bot/dispatch/dispatch.py +29 -19
  18. telegrinder/bot/dispatch/handler/abc.py +1 -0
  19. telegrinder/bot/dispatch/handler/func.py +29 -6
  20. telegrinder/bot/dispatch/handler/message_reply.py +2 -3
  21. telegrinder/bot/dispatch/middleware/abc.py +2 -4
  22. telegrinder/bot/dispatch/process.py +4 -3
  23. telegrinder/bot/dispatch/return_manager/__init__.py +1 -1
  24. telegrinder/bot/dispatch/return_manager/abc.py +33 -21
  25. telegrinder/bot/dispatch/return_manager/callback_query.py +4 -2
  26. telegrinder/bot/dispatch/return_manager/inline_query.py +4 -2
  27. telegrinder/bot/dispatch/return_manager/message.py +12 -6
  28. telegrinder/bot/dispatch/view/__init__.py +8 -2
  29. telegrinder/bot/dispatch/view/abc.py +26 -20
  30. telegrinder/bot/dispatch/view/box.py +72 -1
  31. telegrinder/bot/dispatch/view/callback_query.py +1 -3
  32. telegrinder/bot/dispatch/view/chat_join_request.py +17 -0
  33. telegrinder/bot/dispatch/view/chat_member.py +26 -0
  34. telegrinder/bot/dispatch/view/message.py +23 -1
  35. telegrinder/bot/dispatch/view/raw.py +116 -0
  36. telegrinder/bot/dispatch/waiter_machine/__init__.py +2 -1
  37. telegrinder/bot/dispatch/waiter_machine/machine.py +73 -19
  38. telegrinder/bot/dispatch/waiter_machine/middleware.py +3 -3
  39. telegrinder/bot/dispatch/waiter_machine/short_state.py +6 -3
  40. telegrinder/bot/polling/polling.py +4 -2
  41. telegrinder/bot/rules/__init__.py +20 -12
  42. telegrinder/bot/rules/abc.py +0 -9
  43. telegrinder/bot/rules/adapter/event.py +31 -22
  44. telegrinder/bot/rules/callback_data.py +15 -20
  45. telegrinder/bot/rules/chat_join.py +47 -0
  46. telegrinder/bot/rules/enum_text.py +7 -2
  47. telegrinder/bot/rules/inline.py +3 -3
  48. telegrinder/bot/rules/is_from.py +36 -50
  49. telegrinder/bot/rules/message.py +17 -0
  50. telegrinder/bot/rules/message_entities.py +1 -1
  51. telegrinder/bot/rules/start.py +6 -4
  52. telegrinder/bot/rules/text.py +2 -1
  53. telegrinder/bot/rules/update.py +16 -0
  54. telegrinder/bot/scenario/checkbox.py +9 -7
  55. telegrinder/client/aiohttp.py +4 -4
  56. telegrinder/model.py +33 -19
  57. telegrinder/modules.py +16 -32
  58. telegrinder/msgspec_utils.py +37 -36
  59. telegrinder/node/__init__.py +12 -12
  60. telegrinder/node/attachment.py +15 -5
  61. telegrinder/node/base.py +24 -16
  62. telegrinder/node/composer.py +8 -6
  63. telegrinder/node/container.py +1 -1
  64. telegrinder/node/rule.py +4 -4
  65. telegrinder/node/source.py +4 -2
  66. telegrinder/node/tools/generator.py +1 -1
  67. telegrinder/tools/__init__.py +1 -1
  68. telegrinder/tools/error_handler/abc.py +4 -3
  69. telegrinder/tools/error_handler/error_handler.py +22 -16
  70. telegrinder/tools/formatting/html.py +15 -7
  71. telegrinder/tools/formatting/spec_html_formats.py +1 -1
  72. telegrinder/tools/global_context/abc.py +5 -1
  73. telegrinder/tools/global_context/telegrinder_ctx.py +1 -1
  74. telegrinder/tools/i18n/base.py +4 -3
  75. telegrinder/tools/i18n/simple.py +1 -3
  76. telegrinder/tools/keyboard.py +1 -1
  77. telegrinder/tools/loop_wrapper/loop_wrapper.py +24 -16
  78. telegrinder/tools/magic.py +1 -1
  79. telegrinder/types/__init__.py +206 -0
  80. telegrinder/types/enums.py +34 -0
  81. telegrinder/types/methods.py +52 -47
  82. telegrinder/types/objects.py +531 -88
  83. telegrinder/verification_utils.py +3 -1
  84. {telegrinder-0.1.dev165.dist-info → telegrinder-0.1.dev166.dist-info}/METADATA +1 -1
  85. telegrinder-0.1.dev166.dist-info/RECORD +136 -0
  86. telegrinder-0.1.dev165.dist-info/RECORD +0 -128
  87. {telegrinder-0.1.dev165.dist-info → telegrinder-0.1.dev166.dist-info}/LICENSE +0 -0
  88. {telegrinder-0.1.dev165.dist-info → telegrinder-0.1.dev166.dist-info}/WHEEL +0 -0
@@ -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,46 @@ 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
- if typing.Any in manager.types or any(type(response) is x for x in manager.types):
69
+ if typing.Any in manager.types or any(
70
+ type(response) is x for x in manager.types
71
+ ):
70
72
  await manager(response, event, ctx)
71
-
73
+
72
74
  @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
-
75
+ def register_manager(
76
+ self, return_type: type[T]
77
+ ) -> typing.Callable[
78
+ [typing.Callable[[T, EventT, Context], typing.Awaitable[typing.Any]]], Manager
79
+ ]: ...
80
+
78
81
  @typing.overload
79
82
  def register_manager(self, return_type: tuple[type[T], ...]) -> typing.Callable[
80
- [typing.Callable[[tuple[T, ...], EventT, Context], typing.Awaitable]], Manager
83
+ [typing.Callable[[tuple[T, ...], EventT, Context], typing.Awaitable[typing.Any]]],
84
+ Manager,
85
+ ]: ...
86
+
87
+ def register_manager(
88
+ self, return_type: type[T] | tuple[type[T], ...]
89
+ ) -> typing.Callable[
90
+ [
91
+ typing.Callable[
92
+ [T | tuple[T, ...], EventT, Context], typing.Awaitable[typing.Any]
93
+ ]
94
+ ],
95
+ Manager,
81
96
  ]:
82
- ...
83
-
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
86
- ]:
87
- def wrapper(func: typing.Callable[[T, EventT, Context], typing.Awaitable]) -> Manager:
97
+ def wrapper(
98
+ func: typing.Callable[[T, EventT, Context], typing.Awaitable]
99
+ ) -> Manager:
88
100
  manager = Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
89
101
  setattr(self.__class__, func.__name__, manager)
90
102
  return manager
91
-
103
+
92
104
  return wrapper
93
105
 
94
106
 
@@ -96,6 +108,6 @@ __all__ = (
96
108
  "ABCReturnManager",
97
109
  "BaseReturnManager",
98
110
  "Manager",
99
- "register_manager",
100
111
  "get_union_types",
112
+ "register_manager",
101
113
  )
@@ -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,26 +7,32 @@ 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, ...], event: MessageCute, ctx: Context
20
+ ) -> None:
19
21
  for message in value:
20
22
  await event.answer(message)
21
-
23
+
22
24
  @register_manager(dict)
23
25
  @staticmethod
24
- async def dict_manager(value: dict[str, typing.Any], event: MessageCute, ctx: Context) -> None:
26
+ async def dict_manager(
27
+ value: dict[str, typing.Any], event: MessageCute, ctx: Context
28
+ ) -> None:
25
29
  await event.answer(**value)
26
30
 
27
31
  @register_manager(HTMLFormatter)
28
32
  @staticmethod
29
- async def htmlformatter_manager(value: HTMLFormatter, event: MessageCute, ctx: Context) -> None:
33
+ async def htmlformatter_manager(
34
+ value: HTMLFormatter, event: MessageCute, ctx: Context
35
+ ) -> None:
30
36
  await event.answer(value, parse_mode=HTMLFormatter.PARSE_MODE)
31
37
 
32
38
 
@@ -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,18 +51,12 @@ 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]]:
@@ -76,22 +76,25 @@ class BaseView(ABCView, typing.Generic[EventType]):
76
76
  return getattr(update, update_type.value)
77
77
  case _:
78
78
  return Nothing()
79
-
79
+
80
80
  @typing.overload
81
81
  def __call__(
82
82
  self,
83
83
  *rules: ABCRule[EventType],
84
- ) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandler]]:
85
- ...
86
-
84
+ ) -> typing.Callable[
85
+ [FuncType[EventType]],
86
+ FuncHandler[EventType, FuncType[EventType], ErrorHandler[EventType]],
87
+ ]: ...
88
+
87
89
  @typing.overload
88
90
  def __call__(
89
91
  self,
90
92
  *rules: ABCRule[EventType],
91
93
  error_handler: ErrorHandlerT,
92
94
  is_blocking: bool = True,
93
- ) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandlerT]]:
94
- ...
95
+ ) -> typing.Callable[
96
+ [FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandlerT]
97
+ ]: ...
95
98
 
96
99
  @typing.overload
97
100
  def __call__(
@@ -99,8 +102,10 @@ class BaseView(ABCView, typing.Generic[EventType]):
99
102
  *rules: ABCRule[EventType],
100
103
  error_handler: typing.Literal[None] = None,
101
104
  is_blocking: bool = True,
102
- ) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandler]]:
103
- ...
105
+ ) -> typing.Callable[
106
+ [FuncType[EventType]],
107
+ FuncHandler[EventType, FuncType[EventType], ErrorHandler[EventType]],
108
+ ]: ...
104
109
 
105
110
  def __call__( # type: ignore
106
111
  self,
@@ -114,6 +119,7 @@ class BaseView(ABCView, typing.Generic[EventType]):
114
119
  [*self.auto_rules, *rules],
115
120
  is_blocking=is_blocking,
116
121
  dataclass=None,
122
+ error_handler=error_handler or ErrorHandler(),
117
123
  )
118
124
  self.handlers.append(func_handler)
119
125
  return func_handler
@@ -139,8 +145,8 @@ class BaseView(ABCView, typing.Generic[EventType]):
139
145
  case _:
140
146
  return False
141
147
 
142
- async def process(self, event: Update, api: ABCAPI) -> bool:
143
- return await process_inner(
148
+ async def process(self, event: Update, api: ABCAPI) -> None:
149
+ await process_inner(
144
150
  self.get_event_type()
145
151
  .unwrap()
146
152
  .from_update(
@@ -166,8 +172,8 @@ class BaseStateView(ABCStateView[EventType], BaseView[EventType], ABC, typing.Ge
166
172
 
167
173
 
168
174
  __all__ = (
169
- "ABCView",
170
175
  "ABCStateView",
171
- "BaseView",
176
+ "ABCView",
172
177
  "BaseStateView",
178
+ "BaseView",
173
179
  )
@@ -2,33 +2,104 @@ 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
15
  CallbackQueryViewT = typing.TypeVar(
11
16
  "CallbackQueryViewT", bound=ABCView, default=CallbackQueryView
12
17
  )
18
+ ChatJoinRequestViewT = typing.TypeVar(
19
+ "ChatJoinRequestViewT", bound=ABCView, default=ChatJoinRequestView
20
+ )
21
+ ChatMemberViewT = typing.TypeVar("ChatMemberViewT", bound=ABCView, default=ChatMemberView)
13
22
  InlineQueryViewT = typing.TypeVar(
14
23
  "InlineQueryViewT", bound=ABCView, default=InlineQueryView
15
24
  )
16
25
  MessageViewT = typing.TypeVar("MessageViewT", bound=ABCView, default=MessageView)
26
+ RawEventViewT = typing.TypeVar("RawEventViewT", bound=ABCView, default=RawEventView)
17
27
 
18
28
 
19
29
  @dataclasses.dataclass(kw_only=True)
20
- class ViewBox(typing.Generic[CallbackQueryViewT, InlineQueryViewT, MessageViewT]):
30
+ class ViewBox(
31
+ typing.Generic[
32
+ CallbackQueryViewT,
33
+ ChatJoinRequestViewT,
34
+ ChatMemberViewT,
35
+ InlineQueryViewT,
36
+ MessageViewT,
37
+ RawEventViewT,
38
+ ],
39
+ ):
21
40
  callback_query: CallbackQueryViewT = dataclasses.field(
22
41
  default_factory=lambda: typing.cast(CallbackQueryViewT, CallbackQueryView()),
23
42
  )
43
+ chat_join_request: ChatJoinRequestViewT = dataclasses.field(
44
+ default_factory=lambda: typing.cast(ChatJoinRequestViewT, ChatJoinRequestView()),
45
+ )
46
+ chat_member: ChatMemberViewT = dataclasses.field(
47
+ default_factory=lambda: typing.cast(
48
+ ChatMemberViewT, ChatMemberView(update_type=UpdateType.CHAT_MEMBER)
49
+ ),
50
+ )
51
+ my_chat_member: ChatMemberViewT = dataclasses.field(
52
+ default_factory=lambda: typing.cast(
53
+ ChatMemberViewT, ChatMemberView(update_type=UpdateType.MY_CHAT_MEMBER)
54
+ ),
55
+ )
24
56
  inline_query: InlineQueryViewT = dataclasses.field(
25
57
  default_factory=lambda: typing.cast(InlineQueryViewT, InlineQueryView()),
26
58
  )
27
59
  message: MessageViewT = dataclasses.field(
60
+ default_factory=lambda: typing.cast(
61
+ MessageViewT, MessageView(update_type=UpdateType.MESSAGE)
62
+ ),
63
+ )
64
+ business_message: MessageViewT = dataclasses.field(
65
+ default_factory=lambda: typing.cast(
66
+ MessageViewT, MessageView(update_type=UpdateType.BUSINESS_MESSAGE)
67
+ ),
68
+ )
69
+ channel_post: MessageViewT = dataclasses.field(
70
+ default_factory=lambda: typing.cast(
71
+ MessageViewT, MessageView(update_type=UpdateType.CHANNEL_POST)
72
+ ),
73
+ )
74
+ edited_message: MessageViewT = dataclasses.field(
75
+ default_factory=lambda: typing.cast(
76
+ MessageViewT, MessageView(update_type=UpdateType.EDITED_MESSAGE)
77
+ ),
78
+ )
79
+ edited_business_message: MessageViewT = dataclasses.field(
80
+ default_factory=lambda: typing.cast(
81
+ MessageViewT,
82
+ MessageView(update_type=UpdateType.EDITED_BUSINESS_MESSAGE),
83
+ ),
84
+ )
85
+ edited_channel_post: MessageViewT = dataclasses.field(
86
+ default_factory=lambda: typing.cast(
87
+ MessageViewT, MessageView(update_type=UpdateType.EDITED_CHANNEL_POST)
88
+ ),
89
+ )
90
+ any_message: MessageViewT = dataclasses.field(
28
91
  default_factory=lambda: typing.cast(MessageViewT, MessageView()),
29
92
  )
93
+ chat_member_updated: ChatMemberViewT = dataclasses.field(
94
+ default_factory=lambda: typing.cast(ChatMemberViewT, ChatMemberView()),
95
+ )
96
+ raw_event: RawEventViewT = dataclasses.field(
97
+ default_factory=lambda: typing.cast(RawEventViewT, RawEventView()),
98
+ )
30
99
 
31
100
  def get_views(self) -> dict[str, ABCView]:
101
+ """Get all views."""
102
+
32
103
  return {
33
104
  name: view
34
105
  for name, view in self.__dict__.items()
@@ -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,116 @@
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[
45
+ [FuncType[T]], FuncHandler[UpdateCute, FuncType[T], ErrorHandler[T]]
46
+ ]: ...
47
+
48
+ @typing.overload
49
+ def __call__(
50
+ self,
51
+ update_type: UpdateType,
52
+ *rules: ABCRule[UpdateCute],
53
+ error_handler: ErrorHandlerT,
54
+ ) -> typing.Callable[
55
+ [FuncType[UpdateCute]],
56
+ FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandlerT],
57
+ ]: ...
58
+
59
+ @typing.overload
60
+ def __call__(
61
+ self,
62
+ update_type: UpdateType,
63
+ *rules: ABCRule[UpdateCute],
64
+ dataclass: type[T],
65
+ error_handler: ErrorHandlerT,
66
+ is_blocking: bool = True,
67
+ ) -> typing.Callable[
68
+ [FuncType[T]], FuncHandler[UpdateCute, FuncType[T], ErrorHandlerT]
69
+ ]: ...
70
+
71
+ @typing.overload
72
+ def __call__(
73
+ self,
74
+ update_type: UpdateType,
75
+ *rules: ABCRule[UpdateCute],
76
+ dataclass: typing.Literal[None] = None,
77
+ error_handler: typing.Literal[None] = None,
78
+ is_blocking: bool = True,
79
+ ) -> typing.Callable[
80
+ [FuncType[UpdateCute]],
81
+ FuncHandler[UpdateCute, FuncType[UpdateCute], ErrorHandler[UpdateCute]],
82
+ ]: ...
83
+
84
+ def __call__( # type: ignore
85
+ self,
86
+ update_type: UpdateType,
87
+ *rules: ABCRule[typing.Any],
88
+ dataclass: type[typing.Any] | None = None,
89
+ error_handler: ABCErrorHandler | None = None,
90
+ is_blocking: bool = True,
91
+ ):
92
+ def wrapper(func: FuncType[typing.Any]):
93
+ func_handler = FuncHandler(
94
+ func,
95
+ [*self.auto_rules, *rules],
96
+ is_blocking=is_blocking,
97
+ dataclass=dataclass,
98
+ error_handler=error_handler or ErrorHandler(),
99
+ update_type=update_type,
100
+ )
101
+ self.handlers.append(func_handler)
102
+ return func_handler
103
+
104
+ return wrapper
105
+
106
+ async def check(self, event: Update) -> bool:
107
+ return False
108
+
109
+ async def process(self, event: Update, api: ABCAPI) -> bool:
110
+ return await process_inner(
111
+ UpdateCute.from_update(event, bound_api=api),
112
+ event,
113
+ self.middlewares,
114
+ self.handlers,
115
+ self.return_manager,
116
+ )
@@ -1,9 +1,10 @@
1
- from .machine import WaiterMachine
1
+ from .machine import ShortStateStorage, WaiterMachine
2
2
  from .middleware import WaiterMiddleware
3
3
  from .short_state import ShortState
4
4
 
5
5
  __all__ = (
6
6
  "ShortState",
7
+ "ShortStateStorage",
7
8
  "WaiterMachine",
8
9
  "WaiterMiddleware",
9
10
  )