telegrinder 0.2.1__py3-none-any.whl → 0.2.2__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 +22 -11
- telegrinder/bot/__init__.py +16 -4
- telegrinder/bot/cute_types/chat_member_updated.py +1 -1
- telegrinder/bot/cute_types/message.py +18 -11
- telegrinder/bot/dispatch/__init__.py +18 -2
- telegrinder/bot/dispatch/abc.py +1 -1
- telegrinder/bot/dispatch/context.py +2 -2
- telegrinder/bot/dispatch/dispatch.py +1 -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/machine.py +6 -7
- telegrinder/bot/dispatch/waiter_machine/middleware.py +0 -6
- telegrinder/bot/dispatch/waiter_machine/short_state.py +1 -1
- 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 +3 -3
- telegrinder/bot/scenario/choice.py +2 -2
- telegrinder/client/aiohttp.py +5 -7
- telegrinder/model.py +1 -8
- telegrinder/modules.py +16 -25
- telegrinder/msgspec_utils.py +5 -5
- telegrinder/node/base.py +2 -2
- telegrinder/node/composer.py +5 -9
- telegrinder/node/container.py +6 -1
- 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/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 +6 -3
- 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.2.2.dist-info}/METADATA +3 -4
- {telegrinder-0.2.1.dist-info → telegrinder-0.2.2.dist-info}/RECORD +71 -63
- {telegrinder-0.2.1.dist-info → telegrinder-0.2.2.dist-info}/LICENSE +0 -0
- {telegrinder-0.2.1.dist-info → telegrinder-0.2.2.dist-info}/WHEEL +0 -0
|
@@ -3,57 +3,34 @@ import typing
|
|
|
3
3
|
from telegrinder.api.api import API
|
|
4
4
|
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
5
|
from telegrinder.bot.dispatch.context import Context
|
|
6
|
-
from telegrinder.bot.dispatch.handler.
|
|
7
|
-
from telegrinder.bot.dispatch.process import check_rule
|
|
6
|
+
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
8
7
|
from telegrinder.bot.rules.abc import ABCRule
|
|
9
|
-
from telegrinder.modules import logger
|
|
10
|
-
from telegrinder.types.objects import ReplyParameters, Update
|
|
11
8
|
|
|
12
9
|
|
|
13
|
-
class MessageReplyHandler(
|
|
10
|
+
class MessageReplyHandler(BaseReplyHandler):
|
|
14
11
|
def __init__(
|
|
15
12
|
self,
|
|
16
13
|
text: str,
|
|
17
14
|
*rules: ABCRule,
|
|
15
|
+
parse_mode: str | None = None,
|
|
18
16
|
is_blocking: bool = True,
|
|
19
17
|
as_reply: bool = False,
|
|
20
18
|
preset_context: Context | None = None,
|
|
21
19
|
**default_params: typing.Any,
|
|
22
20
|
) -> None:
|
|
23
21
|
self.text = text
|
|
24
|
-
self.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return "<{}: with rules={!r}, {}: {!r}>".format(
|
|
32
|
-
("blocking " if self.is_blocking else "") + self.__class__.__name__,
|
|
33
|
-
self.rules,
|
|
34
|
-
"answer text as reply" if self.as_reply else "answer text",
|
|
35
|
-
self.text,
|
|
22
|
+
self.parse_mode = parse_mode
|
|
23
|
+
super().__init__(
|
|
24
|
+
*rules,
|
|
25
|
+
is_blocking=is_blocking,
|
|
26
|
+
as_reply=as_reply,
|
|
27
|
+
preset_context=preset_context,
|
|
28
|
+
**default_params,
|
|
36
29
|
)
|
|
37
30
|
|
|
38
|
-
async def check(self, api: API, event: Update, ctx: Context | None = None) -> bool:
|
|
39
|
-
ctx = Context(raw_update=event) if ctx is None else ctx
|
|
40
|
-
temp_ctx = ctx.copy()
|
|
41
|
-
temp_ctx |= self.preset_context
|
|
42
|
-
|
|
43
|
-
for rule in self.rules:
|
|
44
|
-
if not await check_rule(api, rule, event, ctx):
|
|
45
|
-
logger.debug("Rule {!r} failed!", rule)
|
|
46
|
-
return False
|
|
47
|
-
|
|
48
|
-
ctx |= temp_ctx
|
|
49
|
-
return True
|
|
50
|
-
|
|
51
31
|
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
reply_parameters=ReplyParameters(event.message_id) if self.as_reply else None,
|
|
55
|
-
**self.default_params,
|
|
56
|
-
)
|
|
32
|
+
method = event.answer if not self.as_reply else event.reply
|
|
33
|
+
await method(text=self.text, parse_mode=self.parse_mode, **self.default_params)
|
|
57
34
|
|
|
58
35
|
|
|
59
36
|
__all__ = ("MessageReplyHandler",)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
+
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
+
from telegrinder.types.objects import InputFile
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PhotoReplyHandler(BaseReplyHandler):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
photo: InputFile | str,
|
|
15
|
+
*rules: ABCRule,
|
|
16
|
+
caption: str | None = None,
|
|
17
|
+
parse_mode: str | None = None,
|
|
18
|
+
is_blocking: bool = True,
|
|
19
|
+
as_reply: bool = False,
|
|
20
|
+
preset_context: Context | None = None,
|
|
21
|
+
**default_params: typing.Any,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.photo = photo
|
|
24
|
+
self.parse_mode = parse_mode
|
|
25
|
+
self.caption = caption
|
|
26
|
+
super().__init__(
|
|
27
|
+
*rules,
|
|
28
|
+
is_blocking=is_blocking,
|
|
29
|
+
as_reply=as_reply,
|
|
30
|
+
preset_context=preset_context,
|
|
31
|
+
**default_params,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
35
|
+
method = event.answer_photo if not self.as_reply else event.reply_photo
|
|
36
|
+
await method(
|
|
37
|
+
photo=self.photo,
|
|
38
|
+
parse_mode=self.parse_mode,
|
|
39
|
+
caption=self.caption,
|
|
40
|
+
**self.default_params,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
__all__ = ("PhotoReplyHandler",)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
+
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
+
from telegrinder.types.objects import InputFile
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class StickerReplyHandler(BaseReplyHandler):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
sticker: InputFile | str,
|
|
15
|
+
*rules: ABCRule,
|
|
16
|
+
emoji: str | None = None,
|
|
17
|
+
is_blocking: bool = True,
|
|
18
|
+
as_reply: bool = False,
|
|
19
|
+
preset_context: Context | None = None,
|
|
20
|
+
**default_params: typing.Any,
|
|
21
|
+
) -> None:
|
|
22
|
+
self.sticker = sticker
|
|
23
|
+
self.emoji = emoji
|
|
24
|
+
super().__init__(
|
|
25
|
+
*rules,
|
|
26
|
+
is_blocking=is_blocking,
|
|
27
|
+
as_reply=as_reply,
|
|
28
|
+
preset_context=preset_context,
|
|
29
|
+
**default_params,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
33
|
+
method = event.answer_sticker if not self.as_reply else event.reply_sticker
|
|
34
|
+
await method(sticker=self.sticker, emoji=self.emoji, **self.default_params)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
__all__ = ("StickerReplyHandler",)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
|
+
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.handler.base import BaseReplyHandler
|
|
7
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
8
|
+
from telegrinder.types.objects import InputFile
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class VideoReplyHandler(BaseReplyHandler):
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
video: InputFile | str,
|
|
15
|
+
*rules: ABCRule,
|
|
16
|
+
caption: str | None = None,
|
|
17
|
+
parse_mode: str | None = None,
|
|
18
|
+
is_blocking: bool = True,
|
|
19
|
+
as_reply: bool = False,
|
|
20
|
+
preset_context: Context | None = None,
|
|
21
|
+
**default_params: typing.Any,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.video = video
|
|
24
|
+
self.parse_mode = parse_mode
|
|
25
|
+
self.caption = caption
|
|
26
|
+
super().__init__(
|
|
27
|
+
*rules,
|
|
28
|
+
is_blocking=is_blocking,
|
|
29
|
+
as_reply=as_reply,
|
|
30
|
+
preset_context=preset_context,
|
|
31
|
+
**default_params,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
35
|
+
method = event.answer_video if not self.as_reply else event.reply_video
|
|
36
|
+
await method(
|
|
37
|
+
video=self.video,
|
|
38
|
+
parse_mode=self.parse_mode,
|
|
39
|
+
caption=self.caption,
|
|
40
|
+
**self.default_params,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
__all__ = ("VideoReplyHandler",)
|
|
@@ -35,7 +35,7 @@ async def process_inner(
|
|
|
35
35
|
logger.debug("Run pre middlewares...")
|
|
36
36
|
for middleware in middlewares:
|
|
37
37
|
middleware_result = await middleware.pre(event, ctx)
|
|
38
|
-
logger.debug("Middleware {!r} returned {!r}", middleware.__class__.
|
|
38
|
+
logger.debug("Middleware {!r} returned: {!r}", middleware.__class__.__qualname__, middleware_result)
|
|
39
39
|
if middleware_result is False:
|
|
40
40
|
return False
|
|
41
41
|
|
|
@@ -59,7 +59,7 @@ async def process_inner(
|
|
|
59
59
|
|
|
60
60
|
logger.debug("Run post middlewares...")
|
|
61
61
|
for middleware in middlewares:
|
|
62
|
-
logger.debug("Run post middleware {!r}", middleware.__class__.
|
|
62
|
+
logger.debug("Run post middleware {!r}", middleware.__class__.__qualname__)
|
|
63
63
|
await middleware.post(event, responses, ctx)
|
|
64
64
|
|
|
65
65
|
for session in ctx.get(CONTEXT_STORE_NODES_KEY, {}).values():
|
|
@@ -27,13 +27,10 @@ def register_manager(return_type: type[typing.Any] | types.UnionType):
|
|
|
27
27
|
@dataclasses.dataclass(frozen=True, slots=True)
|
|
28
28
|
class Manager:
|
|
29
29
|
types: tuple[type, ...]
|
|
30
|
-
callback: typing.Callable[..., typing.Awaitable]
|
|
30
|
+
callback: typing.Callable[..., typing.Awaitable[typing.Any]]
|
|
31
31
|
|
|
32
32
|
async def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> None:
|
|
33
|
-
|
|
34
|
-
await self.callback(*args, **kwargs)
|
|
35
|
-
except BaseException as ex:
|
|
36
|
-
logger.exception(ex)
|
|
33
|
+
await self.callback(*args, **kwargs)
|
|
37
34
|
|
|
38
35
|
|
|
39
36
|
class ABCReturnManager(ABC, typing.Generic[Event]):
|
|
@@ -51,11 +48,16 @@ class BaseReturnManager(ABCReturnManager[Event]):
|
|
|
51
48
|
|
|
52
49
|
@property
|
|
53
50
|
def managers(self) -> list[Manager]:
|
|
54
|
-
|
|
51
|
+
managers = self.__dict__.get("managers")
|
|
52
|
+
if managers is not None:
|
|
53
|
+
return managers
|
|
54
|
+
managers_lst = [
|
|
55
55
|
manager
|
|
56
56
|
for manager in (vars(BaseReturnManager) | vars(self.__class__)).values()
|
|
57
57
|
if isinstance(manager, Manager)
|
|
58
58
|
]
|
|
59
|
+
self.__dict__["managers"] = managers_lst
|
|
60
|
+
return managers_lst
|
|
59
61
|
|
|
60
62
|
@register_manager(Context)
|
|
61
63
|
@staticmethod
|
|
@@ -73,7 +75,8 @@ class BaseReturnManager(ABCReturnManager[Event]):
|
|
|
73
75
|
|
|
74
76
|
@typing.overload
|
|
75
77
|
def register_manager(
|
|
76
|
-
self,
|
|
78
|
+
self,
|
|
79
|
+
return_type: type[T],
|
|
77
80
|
) -> typing.Callable[[typing.Callable[[T, Event, Context], typing.Awaitable[typing.Any]]], Manager]: ...
|
|
78
81
|
|
|
79
82
|
@typing.overload
|
|
@@ -94,7 +97,7 @@ class BaseReturnManager(ABCReturnManager[Event]):
|
|
|
94
97
|
]:
|
|
95
98
|
def wrapper(func: typing.Callable[[T, Event, Context], typing.Awaitable]) -> Manager:
|
|
96
99
|
manager = Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
|
|
97
|
-
|
|
100
|
+
self.managers.append(manager)
|
|
98
101
|
return manager
|
|
99
102
|
|
|
100
103
|
return wrapper
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
|
-
from telegrinder.bot.cute_types import CallbackQueryCute
|
|
3
|
+
from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
|
|
4
4
|
from telegrinder.bot.dispatch.context import Context
|
|
5
5
|
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
|
|
|
11
11
|
async def str_manager(value: str, event: CallbackQueryCute, ctx: Context) -> None:
|
|
12
12
|
await event.answer(value)
|
|
13
13
|
|
|
14
|
-
@register_manager(dict)
|
|
14
|
+
@register_manager(dict[str, typing.Any])
|
|
15
15
|
@staticmethod
|
|
16
16
|
async def dict_manager(value: dict[str, typing.Any], event: CallbackQueryCute, ctx: Context) -> None:
|
|
17
17
|
await event.answer(**value)
|
|
@@ -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
|
)
|