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.
- telegrinder/__init__.py +45 -12
- telegrinder/bot/__init__.py +32 -4
- telegrinder/bot/cute_types/callback_query.py +60 -146
- telegrinder/bot/cute_types/chat_join_request.py +12 -16
- telegrinder/bot/cute_types/chat_member_updated.py +15 -105
- telegrinder/bot/cute_types/inline_query.py +5 -14
- telegrinder/bot/cute_types/message.py +623 -1238
- telegrinder/bot/dispatch/__init__.py +40 -3
- telegrinder/bot/dispatch/abc.py +8 -1
- telegrinder/bot/dispatch/context.py +2 -2
- telegrinder/bot/dispatch/dispatch.py +8 -1
- telegrinder/bot/dispatch/handler/__init__.py +17 -1
- telegrinder/bot/dispatch/handler/audio_reply.py +44 -0
- telegrinder/bot/dispatch/handler/base.py +57 -0
- telegrinder/bot/dispatch/handler/document_reply.py +44 -0
- telegrinder/bot/dispatch/handler/func.py +3 -3
- telegrinder/bot/dispatch/handler/media_group_reply.py +43 -0
- telegrinder/bot/dispatch/handler/message_reply.py +12 -35
- telegrinder/bot/dispatch/handler/photo_reply.py +44 -0
- telegrinder/bot/dispatch/handler/sticker_reply.py +37 -0
- telegrinder/bot/dispatch/handler/video_reply.py +44 -0
- telegrinder/bot/dispatch/process.py +2 -2
- telegrinder/bot/dispatch/return_manager/abc.py +11 -8
- telegrinder/bot/dispatch/return_manager/callback_query.py +2 -2
- telegrinder/bot/dispatch/return_manager/inline_query.py +2 -2
- telegrinder/bot/dispatch/return_manager/message.py +3 -3
- telegrinder/bot/dispatch/view/__init__.py +2 -1
- telegrinder/bot/dispatch/view/abc.py +2 -181
- telegrinder/bot/dispatch/view/base.py +200 -0
- telegrinder/bot/dispatch/view/callback_query.py +3 -3
- telegrinder/bot/dispatch/view/chat_join_request.py +2 -2
- telegrinder/bot/dispatch/view/chat_member.py +2 -3
- telegrinder/bot/dispatch/view/inline_query.py +2 -2
- telegrinder/bot/dispatch/view/message.py +5 -4
- telegrinder/bot/dispatch/view/raw.py +4 -3
- telegrinder/bot/dispatch/waiter_machine/__init__.py +18 -0
- telegrinder/bot/dispatch/waiter_machine/actions.py +10 -0
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +15 -0
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +60 -0
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +49 -0
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +54 -0
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -0
- telegrinder/bot/dispatch/waiter_machine/machine.py +88 -101
- telegrinder/bot/dispatch/waiter_machine/middleware.py +23 -41
- telegrinder/bot/dispatch/waiter_machine/short_state.py +9 -9
- telegrinder/bot/polling/polling.py +5 -2
- telegrinder/bot/rules/__init__.py +3 -3
- telegrinder/bot/rules/abc.py +6 -5
- telegrinder/bot/rules/adapter/__init__.py +1 -1
- telegrinder/bot/rules/integer.py +1 -1
- telegrinder/bot/rules/is_from.py +19 -0
- telegrinder/bot/rules/state.py +9 -6
- telegrinder/bot/scenario/checkbox.py +5 -5
- telegrinder/bot/scenario/choice.py +2 -2
- telegrinder/client/aiohttp.py +5 -7
- telegrinder/model.py +6 -11
- telegrinder/modules.py +16 -25
- telegrinder/msgspec_json.py +1 -1
- telegrinder/msgspec_utils.py +56 -5
- telegrinder/node/base.py +2 -2
- telegrinder/node/composer.py +5 -9
- telegrinder/node/container.py +6 -1
- telegrinder/node/event.py +2 -0
- telegrinder/node/polymorphic.py +7 -7
- telegrinder/node/rule.py +6 -4
- telegrinder/node/scope.py +3 -3
- telegrinder/node/source.py +4 -2
- telegrinder/node/tools/generator.py +7 -6
- telegrinder/rules.py +2 -2
- telegrinder/tools/__init__.py +10 -10
- telegrinder/tools/functional.py +9 -0
- telegrinder/tools/keyboard.py +6 -1
- telegrinder/tools/loop_wrapper/loop_wrapper.py +4 -5
- telegrinder/tools/magic.py +17 -19
- telegrinder/tools/state_storage/__init__.py +3 -3
- telegrinder/tools/state_storage/abc.py +12 -10
- telegrinder/tools/state_storage/memory.py +9 -6
- telegrinder/types/__init__.py +1 -0
- telegrinder/types/methods.py +10 -2
- telegrinder/types/objects.py +47 -5
- {telegrinder-0.2.1.dist-info → telegrinder-0.3.0.dist-info}/METADATA +4 -5
- telegrinder-0.3.0.dist-info/RECORD +164 -0
- telegrinder-0.2.1.dist-info/RECORD +0 -149
- {telegrinder-0.2.1.dist-info → telegrinder-0.3.0.dist-info}/LICENSE +0 -0
- {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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
6
|
-
from telegrinder.types import
|
|
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
|
|
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
|
+
)
|