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