telegrinder 0.2.1__py3-none-any.whl → 0.3.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 (85) hide show
  1. telegrinder/__init__.py +45 -12
  2. telegrinder/bot/__init__.py +32 -4
  3. telegrinder/bot/cute_types/callback_query.py +60 -146
  4. telegrinder/bot/cute_types/chat_join_request.py +12 -16
  5. telegrinder/bot/cute_types/chat_member_updated.py +15 -105
  6. telegrinder/bot/cute_types/inline_query.py +5 -14
  7. telegrinder/bot/cute_types/message.py +623 -1238
  8. telegrinder/bot/dispatch/__init__.py +40 -3
  9. telegrinder/bot/dispatch/abc.py +8 -1
  10. telegrinder/bot/dispatch/context.py +2 -2
  11. telegrinder/bot/dispatch/dispatch.py +8 -1
  12. telegrinder/bot/dispatch/handler/__init__.py +17 -1
  13. telegrinder/bot/dispatch/handler/audio_reply.py +44 -0
  14. telegrinder/bot/dispatch/handler/base.py +57 -0
  15. telegrinder/bot/dispatch/handler/document_reply.py +44 -0
  16. telegrinder/bot/dispatch/handler/func.py +3 -3
  17. telegrinder/bot/dispatch/handler/media_group_reply.py +43 -0
  18. telegrinder/bot/dispatch/handler/message_reply.py +12 -35
  19. telegrinder/bot/dispatch/handler/photo_reply.py +44 -0
  20. telegrinder/bot/dispatch/handler/sticker_reply.py +37 -0
  21. telegrinder/bot/dispatch/handler/video_reply.py +44 -0
  22. telegrinder/bot/dispatch/process.py +2 -2
  23. telegrinder/bot/dispatch/return_manager/abc.py +11 -8
  24. telegrinder/bot/dispatch/return_manager/callback_query.py +2 -2
  25. telegrinder/bot/dispatch/return_manager/inline_query.py +2 -2
  26. telegrinder/bot/dispatch/return_manager/message.py +3 -3
  27. telegrinder/bot/dispatch/view/__init__.py +2 -1
  28. telegrinder/bot/dispatch/view/abc.py +2 -181
  29. telegrinder/bot/dispatch/view/base.py +200 -0
  30. telegrinder/bot/dispatch/view/callback_query.py +3 -3
  31. telegrinder/bot/dispatch/view/chat_join_request.py +2 -2
  32. telegrinder/bot/dispatch/view/chat_member.py +2 -3
  33. telegrinder/bot/dispatch/view/inline_query.py +2 -2
  34. telegrinder/bot/dispatch/view/message.py +5 -4
  35. telegrinder/bot/dispatch/view/raw.py +4 -3
  36. telegrinder/bot/dispatch/waiter_machine/__init__.py +18 -0
  37. telegrinder/bot/dispatch/waiter_machine/actions.py +10 -0
  38. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +15 -0
  39. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +60 -0
  40. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +49 -0
  41. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +54 -0
  42. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -0
  43. telegrinder/bot/dispatch/waiter_machine/machine.py +88 -101
  44. telegrinder/bot/dispatch/waiter_machine/middleware.py +23 -41
  45. telegrinder/bot/dispatch/waiter_machine/short_state.py +9 -9
  46. telegrinder/bot/polling/polling.py +5 -2
  47. telegrinder/bot/rules/__init__.py +3 -3
  48. telegrinder/bot/rules/abc.py +6 -5
  49. telegrinder/bot/rules/adapter/__init__.py +1 -1
  50. telegrinder/bot/rules/integer.py +1 -1
  51. telegrinder/bot/rules/is_from.py +19 -0
  52. telegrinder/bot/rules/state.py +9 -6
  53. telegrinder/bot/scenario/checkbox.py +5 -5
  54. telegrinder/bot/scenario/choice.py +2 -2
  55. telegrinder/client/aiohttp.py +5 -7
  56. telegrinder/model.py +6 -11
  57. telegrinder/modules.py +16 -25
  58. telegrinder/msgspec_json.py +1 -1
  59. telegrinder/msgspec_utils.py +56 -5
  60. telegrinder/node/base.py +2 -2
  61. telegrinder/node/composer.py +5 -9
  62. telegrinder/node/container.py +6 -1
  63. telegrinder/node/event.py +2 -0
  64. telegrinder/node/polymorphic.py +7 -7
  65. telegrinder/node/rule.py +6 -4
  66. telegrinder/node/scope.py +3 -3
  67. telegrinder/node/source.py +4 -2
  68. telegrinder/node/tools/generator.py +7 -6
  69. telegrinder/rules.py +2 -2
  70. telegrinder/tools/__init__.py +10 -10
  71. telegrinder/tools/functional.py +9 -0
  72. telegrinder/tools/keyboard.py +6 -1
  73. telegrinder/tools/loop_wrapper/loop_wrapper.py +4 -5
  74. telegrinder/tools/magic.py +17 -19
  75. telegrinder/tools/state_storage/__init__.py +3 -3
  76. telegrinder/tools/state_storage/abc.py +12 -10
  77. telegrinder/tools/state_storage/memory.py +9 -6
  78. telegrinder/types/__init__.py +1 -0
  79. telegrinder/types/methods.py +10 -2
  80. telegrinder/types/objects.py +47 -5
  81. {telegrinder-0.2.1.dist-info → telegrinder-0.3.0.dist-info}/METADATA +4 -5
  82. telegrinder-0.3.0.dist-info/RECORD +164 -0
  83. telegrinder-0.2.1.dist-info/RECORD +0 -149
  84. {telegrinder-0.2.1.dist-info → telegrinder-0.3.0.dist-info}/LICENSE +0 -0
  85. {telegrinder-0.2.1.dist-info → telegrinder-0.3.0.dist-info}/WHEEL +0 -0
@@ -1,12 +1,12 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types import InlineQueryCute
3
+ from telegrinder.bot.cute_types.inline_query import InlineQueryCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
5
  from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
6
6
 
7
7
 
8
8
  class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
9
- @register_manager(dict)
9
+ @register_manager(dict[str, typing.Any])
10
10
  @staticmethod
11
11
  async def dict_manager(value: dict[str, typing.Any], event: InlineQueryCute, ctx: Context) -> None:
12
12
  await event.answer(**value)
@@ -1,6 +1,6 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types import MessageCute
3
+ from telegrinder.bot.cute_types.message import MessageCute
4
4
  from telegrinder.bot.dispatch.context import Context
5
5
  from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
6
6
  from telegrinder.tools.formatting import HTMLFormatter
@@ -12,7 +12,7 @@ class MessageReturnManager(BaseReturnManager[MessageCute]):
12
12
  async def str_manager(value: str, event: MessageCute, ctx: Context) -> None:
13
13
  await event.answer(value)
14
14
 
15
- @register_manager(list | tuple)
15
+ @register_manager(list[str] | tuple[str, ...])
16
16
  @staticmethod
17
17
  async def seq_manager(
18
18
  value: list[str] | tuple[str, ...],
@@ -22,7 +22,7 @@ class MessageReturnManager(BaseReturnManager[MessageCute]):
22
22
  for message in value:
23
23
  await event.answer(message)
24
24
 
25
- @register_manager(dict)
25
+ @register_manager(dict[str, typing.Any])
26
26
  @staticmethod
27
27
  async def dict_manager(value: dict[str, typing.Any], event: MessageCute, ctx: Context) -> None:
28
28
  await event.answer(**value)
@@ -1,4 +1,5 @@
1
- from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView, BaseStateView, BaseView
1
+ from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
2
+ from telegrinder.bot.dispatch.view.base import BaseStateView, BaseView
2
3
  from telegrinder.bot.dispatch.view.box import ViewBox
3
4
  from telegrinder.bot.dispatch.view.callback_query import CallbackQueryView
4
5
  from telegrinder.bot.dispatch.view.chat_join_request import ChatJoinRequestView
@@ -1,30 +1,12 @@
1
1
  import typing
2
2
  from abc import ABC, abstractmethod
3
- from functools import cached_property
4
3
 
5
- from fntypes.co import Nothing, Some
6
-
7
- from telegrinder.api import API
4
+ from telegrinder.api.api import API
8
5
  from telegrinder.bot.cute_types.base import BaseCute
9
6
  from telegrinder.bot.dispatch.handler.abc import ABCHandler
10
- from telegrinder.bot.dispatch.handler.func import FuncHandler
11
- from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
12
- from telegrinder.bot.dispatch.process import process_inner
13
- from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
14
- from telegrinder.bot.rules.abc import ABCRule
15
- from telegrinder.model import Model
16
- from telegrinder.msgspec_utils import Option
17
- from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
18
7
  from telegrinder.types.objects import Update
19
8
 
20
9
  Event = typing.TypeVar("Event", bound=BaseCute)
21
- ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler)
22
- MiddlewareT = typing.TypeVar("MiddlewareT", bound=ABCMiddleware)
23
-
24
- FuncType: typing.TypeAlias = typing.Callable[
25
- typing.Concatenate[Event, ...],
26
- typing.Coroutine[typing.Any, typing.Any, typing.Any],
27
- ]
28
10
 
29
11
 
30
12
  class ABCView(ABC):
@@ -54,169 +36,8 @@ class ABCStateView(ABCView, typing.Generic[Event]):
54
36
  pass
55
37
 
56
38
 
57
- class BaseView(ABCView, typing.Generic[Event]):
58
- auto_rules: list[ABCRule]
59
- handlers: list[ABCHandler[Event]]
60
- middlewares: list[ABCMiddleware[Event]]
61
- return_manager: ABCReturnManager[Event] | None = None
62
-
63
- @staticmethod
64
- def get_raw_event(update: Update) -> Option[Model]:
65
- return getattr(update, update.update_type.value)
66
-
67
- @cached_property
68
- def get_event_type(self) -> Option[type[Event]]:
69
- for base in self.__class__.__dict__.get("__orig_bases__", ()):
70
- if issubclass(typing.get_origin(base) or base, ABCView):
71
- for generic_type in typing.get_args(base):
72
- if issubclass(typing.get_origin(generic_type) or generic_type, BaseCute):
73
- return Some(generic_type)
74
- return Nothing()
75
-
76
- @typing.overload
77
- @classmethod
78
- def to_handler(
79
- cls,
80
- *rules: ABCRule,
81
- ) -> typing.Callable[
82
- [FuncType[Event]],
83
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
84
- ]: ...
85
-
86
- @typing.overload
87
- @classmethod
88
- def to_handler(
89
- cls,
90
- *rules: ABCRule,
91
- error_handler: ErrorHandlerT,
92
- is_blocking: bool = True,
93
- ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
94
-
95
- @typing.overload
96
- @classmethod
97
- def to_handler(
98
- cls,
99
- *rules: ABCRule,
100
- error_handler: typing.Literal[None] = None,
101
- is_blocking: bool = True,
102
- ) -> typing.Callable[
103
- [FuncType[Event]],
104
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
105
- ]: ...
106
-
107
- @classmethod
108
- def to_handler( # type: ignore
109
- cls,
110
- *rules: ABCRule,
111
- error_handler: ABCErrorHandler | None = None,
112
- is_blocking: bool = True,
113
- ):
114
- def wrapper(func: FuncType[Event]):
115
- return FuncHandler(
116
- func,
117
- list(rules),
118
- is_blocking=is_blocking,
119
- dataclass=None,
120
- error_handler=error_handler or ErrorHandler(),
121
- )
122
-
123
- return wrapper
124
-
125
- @typing.overload
126
- def __call__(
127
- self,
128
- *rules: ABCRule,
129
- ) -> typing.Callable[
130
- [FuncType[Event]],
131
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
132
- ]: ...
133
-
134
- @typing.overload
135
- def __call__( # type: ignore
136
- self,
137
- *rules: ABCRule,
138
- error_handler: ErrorHandlerT,
139
- is_blocking: bool = True,
140
- ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
141
-
142
- @typing.overload
143
- def __call__(
144
- self,
145
- *rules: ABCRule,
146
- error_handler: typing.Literal[None] = None,
147
- is_blocking: bool = True,
148
- ) -> typing.Callable[
149
- [FuncType[Event]],
150
- FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
151
- ]: ...
152
-
153
- def __call__( # type: ignore
154
- self,
155
- *rules: ABCRule,
156
- error_handler: ABCErrorHandler | None = None,
157
- is_blocking: bool = True,
158
- ):
159
- def wrapper(func: FuncType[Event]):
160
- func_handler = FuncHandler(
161
- func,
162
- [*self.auto_rules, *rules],
163
- is_blocking=is_blocking,
164
- dataclass=None,
165
- error_handler=error_handler or ErrorHandler(),
166
- )
167
- self.handlers.append(func_handler)
168
- return func_handler
169
-
170
- return wrapper
171
-
172
- def register_middleware(self, *args: typing.Any, **kwargs: typing.Any):
173
- def wrapper(cls: type[MiddlewareT]) -> type[MiddlewareT]:
174
- self.middlewares.append(cls(*args, **kwargs))
175
- return cls
176
-
177
- return wrapper
178
-
179
- async def check(self, event: Update) -> bool:
180
- match self.get_raw_event(event):
181
- case Some(e) if issubclass(
182
- self.get_event_type.expect(
183
- "{!r} has no event type in generic.".format(self.__class__.__name__),
184
- ),
185
- e.__class__,
186
- ) and (self.handlers or self.middlewares):
187
- return True
188
- case _:
189
- return False
190
-
191
- async def process(self, event: Update, api: API) -> bool:
192
- return await process_inner(
193
- api,
194
- self.get_event_type.unwrap().from_update(
195
- update=self.get_raw_event(event).unwrap(),
196
- bound_api=api,
197
- ),
198
- event,
199
- self.middlewares,
200
- self.handlers,
201
- self.return_manager,
202
- )
203
-
204
- def load(self, external: typing.Self) -> None:
205
- self.auto_rules.extend(external.auto_rules)
206
- self.handlers.extend(external.handlers)
207
- self.middlewares.extend(external.middlewares)
208
-
209
-
210
- class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Event]):
211
- @abstractmethod
212
- def get_state_key(self, event: Event) -> int | None:
213
- pass
214
-
215
-
216
39
  __all__ = (
217
- "ABCStateView",
218
40
  "ABCEventRawView",
41
+ "ABCStateView",
219
42
  "ABCView",
220
- "BaseStateView",
221
- "BaseView",
222
43
  )
@@ -0,0 +1,200 @@
1
+ import typing
2
+ from abc import ABC, abstractmethod
3
+ from functools import cached_property
4
+
5
+ from fntypes.option import Nothing, Some
6
+
7
+ from telegrinder.api.api import API
8
+ from telegrinder.bot.cute_types.base import BaseCute
9
+ from telegrinder.bot.dispatch.handler.abc import ABCHandler
10
+ from telegrinder.bot.dispatch.handler.func import FuncHandler
11
+ from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
12
+ from telegrinder.bot.dispatch.process import process_inner
13
+ from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
14
+ from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView
15
+ from telegrinder.bot.rules.abc import ABCRule
16
+ from telegrinder.model import Model
17
+ from telegrinder.msgspec_utils import Option
18
+ from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
19
+ from telegrinder.types.objects import Update
20
+
21
+ Event = typing.TypeVar("Event", bound=BaseCute)
22
+ ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler)
23
+ MiddlewareT = typing.TypeVar("MiddlewareT", bound=ABCMiddleware)
24
+
25
+ FuncType: typing.TypeAlias = typing.Callable[
26
+ typing.Concatenate[Event, ...],
27
+ typing.Coroutine[typing.Any, typing.Any, typing.Any],
28
+ ]
29
+
30
+
31
+ def get_event_model_class(view: "BaseView[Event]") -> Option[type[Event]]:
32
+ for base in view.__class__.__bases__ + (view.__class__,):
33
+ if "__orig_bases__" not in base.__dict__:
34
+ continue
35
+
36
+ for orig_base in base.__dict__["__orig_bases__"]:
37
+ origin_base = typing.get_origin(orig_base) or orig_base
38
+ if not isinstance(origin_base, type) and not issubclass(origin_base, object):
39
+ continue
40
+
41
+ for generic_type in typing.get_args(orig_base):
42
+ orig_generic_type = typing.get_origin(generic_type) or generic_type
43
+ if isinstance(orig_generic_type, type) and issubclass(orig_generic_type, BaseCute):
44
+ return Some(generic_type)
45
+
46
+ return Nothing()
47
+
48
+
49
+ class BaseView(ABCView, typing.Generic[Event]):
50
+ auto_rules: list[ABCRule]
51
+ handlers: list[ABCHandler[Event]]
52
+ middlewares: list[ABCMiddleware[Event]]
53
+ return_manager: ABCReturnManager[Event] | None = None
54
+
55
+ @staticmethod
56
+ def get_raw_event(update: Update) -> Option[Model]:
57
+ return getattr(update, update.update_type.value)
58
+
59
+ @cached_property
60
+ def event_model_class(self) -> Option[type[Event]]:
61
+ return get_event_model_class(self)
62
+
63
+ @typing.overload
64
+ @classmethod
65
+ def to_handler(
66
+ cls,
67
+ *rules: ABCRule,
68
+ ) -> typing.Callable[
69
+ [FuncType[Event]],
70
+ FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
71
+ ]: ...
72
+
73
+ @typing.overload
74
+ @classmethod
75
+ def to_handler(
76
+ cls,
77
+ *rules: ABCRule,
78
+ error_handler: ErrorHandlerT,
79
+ is_blocking: bool = True,
80
+ ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
81
+
82
+ @typing.overload
83
+ @classmethod
84
+ def to_handler(
85
+ cls,
86
+ *rules: ABCRule,
87
+ error_handler: typing.Literal[None] = None,
88
+ is_blocking: bool = True,
89
+ ) -> typing.Callable[
90
+ [FuncType[Event]],
91
+ FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
92
+ ]: ...
93
+
94
+ @classmethod
95
+ def to_handler( # type: ignore
96
+ cls,
97
+ *rules: ABCRule,
98
+ error_handler: ABCErrorHandler | None = None,
99
+ is_blocking: bool = True,
100
+ ):
101
+ def wrapper(func: FuncType[Event]):
102
+ return FuncHandler(
103
+ func,
104
+ list(rules),
105
+ is_blocking=is_blocking,
106
+ dataclass=None,
107
+ error_handler=error_handler or ErrorHandler(),
108
+ )
109
+
110
+ return wrapper
111
+
112
+ @typing.overload
113
+ def __call__(
114
+ self,
115
+ *rules: ABCRule,
116
+ ) -> typing.Callable[
117
+ [FuncType[Event]],
118
+ FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
119
+ ]: ...
120
+
121
+ @typing.overload
122
+ def __call__( # type: ignore
123
+ self,
124
+ *rules: ABCRule,
125
+ error_handler: ErrorHandlerT,
126
+ is_blocking: bool = True,
127
+ ) -> typing.Callable[[FuncType[Event]], FuncHandler[Event, FuncType[Event], ErrorHandlerT]]: ...
128
+
129
+ @typing.overload
130
+ def __call__(
131
+ self,
132
+ *rules: ABCRule,
133
+ error_handler: typing.Literal[None] = None,
134
+ is_blocking: bool = True,
135
+ ) -> typing.Callable[
136
+ [FuncType[Event]],
137
+ FuncHandler[Event, FuncType[Event], ErrorHandler[Event]],
138
+ ]: ...
139
+
140
+ def __call__( # type: ignore
141
+ self,
142
+ *rules: ABCRule,
143
+ error_handler: ABCErrorHandler | None = None,
144
+ is_blocking: bool = True,
145
+ ):
146
+ def wrapper(func: FuncType[Event]):
147
+ func_handler = FuncHandler(
148
+ func,
149
+ [*self.auto_rules, *rules],
150
+ is_blocking=is_blocking,
151
+ dataclass=None,
152
+ error_handler=error_handler or ErrorHandler(),
153
+ )
154
+ self.handlers.append(func_handler)
155
+ return func_handler
156
+
157
+ return wrapper
158
+
159
+ def register_middleware(self, *args: typing.Any, **kwargs: typing.Any):
160
+ def wrapper(cls: type[MiddlewareT]) -> type[MiddlewareT]:
161
+ self.middlewares.append(cls(*args, **kwargs))
162
+ return cls
163
+
164
+ return wrapper
165
+
166
+ async def check(self, event: Update) -> bool:
167
+ match self.get_raw_event(event):
168
+ case Some(e) if issubclass(
169
+ self.event_model_class.expect(
170
+ "{!r} has no event model class in generic.".format(self.__class__.__qualname__),
171
+ ),
172
+ e.__class__,
173
+ ) and (self.handlers or self.middlewares):
174
+ return True
175
+ case _:
176
+ return False
177
+
178
+ async def process(self, event: Update, api: API) -> bool:
179
+ return await process_inner(
180
+ api,
181
+ self.event_model_class.unwrap().from_update(
182
+ update=self.get_raw_event(event).unwrap(),
183
+ bound_api=api,
184
+ ),
185
+ event,
186
+ self.middlewares,
187
+ self.handlers,
188
+ self.return_manager,
189
+ )
190
+
191
+ def load(self, external: typing.Self) -> None:
192
+ self.auto_rules.extend(external.auto_rules)
193
+ self.handlers.extend(external.handlers)
194
+ self.middlewares.extend(external.middlewares)
195
+
196
+
197
+ class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Event]):
198
+ @abstractmethod
199
+ def get_state_key(self, event: Event) -> int | None:
200
+ pass
@@ -1,6 +1,6 @@
1
- from telegrinder.bot.cute_types import CallbackQueryCute
2
- from telegrinder.bot.dispatch.return_manager import CallbackQueryReturnManager
3
- from telegrinder.bot.dispatch.view.abc import BaseStateView
1
+ from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
2
+ from telegrinder.bot.dispatch.return_manager.callback_query import CallbackQueryReturnManager
3
+ from telegrinder.bot.dispatch.view.base import BaseStateView
4
4
 
5
5
 
6
6
  class CallbackQueryView(BaseStateView[CallbackQueryCute]):
@@ -1,5 +1,5 @@
1
- from telegrinder.bot.cute_types import ChatJoinRequestCute
2
- from telegrinder.bot.dispatch.view.abc import BaseStateView
1
+ from telegrinder.bot.cute_types.chat_join_request import ChatJoinRequestCute
2
+ from telegrinder.bot.dispatch.view.base import BaseStateView
3
3
 
4
4
 
5
5
  class ChatJoinRequestView(BaseStateView[ChatJoinRequestCute]):
@@ -1,7 +1,7 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types import ChatMemberUpdatedCute
4
- from telegrinder.bot.dispatch.view.abc import BaseStateView
3
+ from telegrinder.bot.cute_types.chat_member_updated import ChatMemberUpdatedCute
4
+ from telegrinder.bot.dispatch.view.base import BaseStateView
5
5
  from telegrinder.types.enums import UpdateType
6
6
  from telegrinder.types.objects import Update
7
7
 
@@ -28,7 +28,6 @@ class ChatMemberView(BaseStateView[ChatMemberUpdatedCute]):
28
28
  def get_state_key(self, event: ChatMemberUpdatedCute) -> int | None:
29
29
  return event.chat_id
30
30
 
31
-
32
31
  async def check(self, event: Update) -> bool:
33
32
  return not (
34
33
  self.update_type is not None
@@ -1,6 +1,6 @@
1
- from telegrinder.bot.cute_types import InlineQueryCute
1
+ from telegrinder.bot.cute_types.inline_query import InlineQueryCute
2
2
  from telegrinder.bot.dispatch.return_manager import InlineQueryReturnManager
3
- from telegrinder.bot.dispatch.view.abc import BaseStateView
3
+ from telegrinder.bot.dispatch.view.base import BaseStateView
4
4
 
5
5
 
6
6
  class InlineQueryView(BaseStateView[InlineQueryCute]):
@@ -1,9 +1,10 @@
1
1
  import typing
2
2
 
3
- from telegrinder.bot.cute_types import MessageCute
4
- from telegrinder.bot.dispatch.return_manager import MessageReturnManager
5
- from telegrinder.bot.dispatch.view.abc import BaseStateView
6
- from telegrinder.types import Update, UpdateType
3
+ from telegrinder.bot.cute_types.message import MessageCute
4
+ from telegrinder.bot.dispatch.return_manager.message import MessageReturnManager
5
+ from telegrinder.bot.dispatch.view.base import BaseStateView
6
+ from telegrinder.types.enums import UpdateType
7
+ from telegrinder.types.objects import Update
7
8
 
8
9
  MessageUpdateType: typing.TypeAlias = typing.Literal[
9
10
  UpdateType.MESSAGE,
@@ -1,10 +1,11 @@
1
1
  import typing
2
2
 
3
- from telegrinder.api import API
4
- from telegrinder.bot.cute_types import UpdateCute
3
+ from telegrinder.api.api import API
4
+ from telegrinder.bot.cute_types.update 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
+ from telegrinder.bot.dispatch.view.abc import ABCEventRawView
8
+ from telegrinder.bot.dispatch.view.base import BaseView, ErrorHandlerT
8
9
  from telegrinder.bot.rules.abc import ABCRule
9
10
  from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
10
11
  from telegrinder.types.enums import UpdateType
@@ -1,9 +1,27 @@
1
+ from telegrinder.bot.dispatch.waiter_machine.hasher import (
2
+ CALLBACK_QUERY_FOR_MESSAGE,
3
+ CALLBACK_QUERY_FROM_CHAT,
4
+ CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE,
5
+ MESSAGE_FROM_USER,
6
+ MESSAGE_FROM_USER_IN_CHAT,
7
+ MESSAGE_IN_CHAT,
8
+ Hasher,
9
+ StateViewHasher,
10
+ )
1
11
  from telegrinder.bot.dispatch.waiter_machine.machine import WaiterMachine, clear_wm_storage_worker
2
12
  from telegrinder.bot.dispatch.waiter_machine.middleware import WaiterMiddleware
3
13
  from telegrinder.bot.dispatch.waiter_machine.short_state import ShortState
4
14
 
5
15
  __all__ = (
16
+ "CALLBACK_QUERY_FOR_MESSAGE",
17
+ "CALLBACK_QUERY_FROM_CHAT",
18
+ "CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE",
19
+ "Hasher",
20
+ "MESSAGE_FROM_USER",
21
+ "MESSAGE_FROM_USER_IN_CHAT",
22
+ "MESSAGE_IN_CHAT",
6
23
  "ShortState",
24
+ "StateViewHasher",
7
25
  "WaiterMachine",
8
26
  "WaiterMiddleware",
9
27
  "clear_wm_storage_worker",
@@ -0,0 +1,10 @@
1
+ import typing
2
+
3
+ from telegrinder.bot.dispatch.handler.abc import ABCHandler
4
+
5
+ from .short_state import EventModel, ShortState
6
+
7
+
8
+ class WaiterActions(typing.TypedDict, typing.Generic[EventModel]):
9
+ on_miss: typing.NotRequired[ABCHandler[EventModel]]
10
+ on_drop: typing.NotRequired[typing.Callable[[ShortState[EventModel]], None]]
@@ -0,0 +1,15 @@
1
+ from .callback import CALLBACK_QUERY_FOR_MESSAGE, CALLBACK_QUERY_FROM_CHAT, CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE
2
+ from .hasher import Hasher
3
+ from .message import MESSAGE_FROM_USER, MESSAGE_FROM_USER_IN_CHAT, MESSAGE_IN_CHAT
4
+ from .state import StateViewHasher
5
+
6
+ __all__ = (
7
+ "CALLBACK_QUERY_FOR_MESSAGE",
8
+ "CALLBACK_QUERY_FROM_CHAT",
9
+ "CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE",
10
+ "Hasher",
11
+ "MESSAGE_FROM_USER",
12
+ "MESSAGE_FROM_USER_IN_CHAT",
13
+ "MESSAGE_IN_CHAT",
14
+ "StateViewHasher",
15
+ )
@@ -0,0 +1,60 @@
1
+ from fntypes import Some
2
+
3
+ from telegrinder.bot.cute_types import CallbackQueryCute as CallbackQuery
4
+ from telegrinder.bot.dispatch.view import CallbackQueryView
5
+
6
+ from .hasher import Hasher
7
+
8
+
9
+ def from_chat_hash(chat_id: int) -> int:
10
+ return chat_id
11
+
12
+
13
+ def get_chat_from_event(event: CallbackQuery) -> int | None:
14
+ return event.chat.and_then(lambda chat: Some(chat.id)).unwrap_or_none()
15
+
16
+
17
+ CALLBACK_QUERY_FROM_CHAT = Hasher(
18
+ view=CallbackQueryView,
19
+ get_hash_from_data=from_chat_hash,
20
+ get_data_from_event=get_chat_from_event,
21
+ )
22
+
23
+
24
+ def for_message_hash(message_id: int) -> int:
25
+ return message_id
26
+
27
+
28
+ def get_message_for_event(event: CallbackQuery) -> int | None:
29
+ return event.message_id.unwrap_or_none()
30
+
31
+
32
+ CALLBACK_QUERY_FOR_MESSAGE = Hasher(
33
+ view=CallbackQueryView,
34
+ get_hash_from_data=for_message_hash,
35
+ get_data_from_event=get_message_for_event,
36
+ )
37
+
38
+
39
+ def for_message_in_chat(chat_and_message: tuple[int, int]) -> str:
40
+ return f"{chat_and_message[0]}_{chat_and_message[1]}"
41
+
42
+
43
+ def get_chat_and_message_for_event(event: CallbackQuery) -> tuple[int, int] | None:
44
+ if not event.message_id or not event.chat:
45
+ return None
46
+ return event.chat.unwrap().id, event.message_id.unwrap()
47
+
48
+
49
+ CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE = Hasher(
50
+ view=CallbackQueryView,
51
+ get_hash_from_data=for_message_in_chat,
52
+ get_data_from_event=get_chat_and_message_for_event,
53
+ )
54
+
55
+
56
+ __all__ = (
57
+ "CALLBACK_QUERY_FOR_MESSAGE",
58
+ "CALLBACK_QUERY_FROM_CHAT",
59
+ "CALLBACK_QUERY_IN_CHAT_FOR_MESSAGE",
60
+ )