telegrinder 0.1.dev163__py3-none-any.whl → 0.1.dev164__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/bot/dispatch/abc.py +1 -1
- telegrinder/bot/dispatch/composition.py +15 -1
- telegrinder/bot/dispatch/context.py +8 -0
- telegrinder/bot/dispatch/dispatch.py +65 -28
- telegrinder/bot/dispatch/handler/abc.py +2 -4
- telegrinder/bot/dispatch/handler/func.py +31 -25
- telegrinder/bot/dispatch/handler/message_reply.py +21 -9
- telegrinder/bot/dispatch/middleware/abc.py +1 -1
- telegrinder/bot/dispatch/process.py +5 -3
- telegrinder/bot/dispatch/return_manager/callback_query.py +3 -1
- telegrinder/bot/dispatch/return_manager/inline_query.py +3 -1
- telegrinder/bot/dispatch/return_manager/message.py +9 -1
- telegrinder/bot/dispatch/view/abc.py +31 -5
- telegrinder/bot/dispatch/view/box.py +2 -1
- telegrinder/bot/dispatch/view/inline_query.py +1 -1
- telegrinder/bot/dispatch/view/message.py +1 -1
- telegrinder/bot/dispatch/waiter_machine/machine.py +14 -8
- telegrinder/bot/dispatch/waiter_machine/middleware.py +9 -7
- telegrinder/bot/dispatch/waiter_machine/short_state.py +17 -18
- telegrinder/bot/rules/text.py +1 -1
- telegrinder/bot/scenario/checkbox.py +16 -0
- telegrinder/node/base.py +1 -1
- telegrinder/node/composer.py +1 -1
- telegrinder/tools/error_handler/abc.py +3 -3
- telegrinder/tools/error_handler/error_handler.py +21 -21
- {telegrinder-0.1.dev163.dist-info → telegrinder-0.1.dev164.dist-info}/METADATA +1 -1
- {telegrinder-0.1.dev163.dist-info → telegrinder-0.1.dev164.dist-info}/RECORD +29 -29
- {telegrinder-0.1.dev163.dist-info → telegrinder-0.1.dev164.dist-info}/WHEEL +1 -1
- {telegrinder-0.1.dev163.dist-info → telegrinder-0.1.dev164.dist-info}/LICENSE +0 -0
telegrinder/bot/dispatch/abc.py
CHANGED
|
@@ -27,12 +27,20 @@ class Composition:
|
|
|
27
27
|
}
|
|
28
28
|
self.is_blocking = is_blocking
|
|
29
29
|
|
|
30
|
+
def __repr__(self) -> str:
|
|
31
|
+
return "<{}: for function={!r} with nodes={}>".format(
|
|
32
|
+
("blocking " if self.is_blocking else "")
|
|
33
|
+
+ self.__class__.__name__,
|
|
34
|
+
self.func.__name__,
|
|
35
|
+
self.nodes,
|
|
36
|
+
)
|
|
37
|
+
|
|
30
38
|
async def compose_nodes(self, update: UpdateCute) -> NodeCollection | None:
|
|
31
39
|
nodes: dict[str, NodeSession] = {}
|
|
32
40
|
for name, node_t in self.nodes.items():
|
|
33
41
|
try:
|
|
34
42
|
nodes[name] = await compose_node(node_t, update)
|
|
35
|
-
except ComposeError
|
|
43
|
+
except ComposeError:
|
|
36
44
|
await NodeCollection(nodes).close_all()
|
|
37
45
|
return None
|
|
38
46
|
return NodeCollection(nodes)
|
|
@@ -45,6 +53,12 @@ class CompositionDispatch(ABCDispatch):
|
|
|
45
53
|
def __init__(self) -> None:
|
|
46
54
|
self.compositions: list[Composition] = []
|
|
47
55
|
|
|
56
|
+
def __repr__(self) -> str:
|
|
57
|
+
return "<{}: with compositions={!r}>".format(
|
|
58
|
+
self.__class__.__name__,
|
|
59
|
+
self.compositions,
|
|
60
|
+
)
|
|
61
|
+
|
|
48
62
|
async def feed(self, event: Update, api: ABCAPI) -> bool:
|
|
49
63
|
update = UpdateCute(**event.to_dict(), api=api)
|
|
50
64
|
is_found = False
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import enum
|
|
2
2
|
import typing
|
|
3
|
+
from reprlib import recursive_repr
|
|
3
4
|
|
|
4
5
|
from telegrinder.types import Update
|
|
5
6
|
|
|
@@ -33,6 +34,13 @@ class Context(dict[str, AnyValue]):
|
|
|
33
34
|
delattr(self.__class__, k)
|
|
34
35
|
dict.__init__(self, **defaults | kwargs)
|
|
35
36
|
|
|
37
|
+
@recursive_repr()
|
|
38
|
+
def __repr__(self) -> str:
|
|
39
|
+
return "{}({})".format(
|
|
40
|
+
self.__class__.__name__,
|
|
41
|
+
", ".join(f"{k}={v!r}" for k, v in self.items())
|
|
42
|
+
)
|
|
43
|
+
|
|
36
44
|
def __setitem__(self, __key: Key, __value: AnyValue) -> None:
|
|
37
45
|
dict.__setitem__(self, self.key_to_str(__key), __value)
|
|
38
46
|
|
|
@@ -6,8 +6,10 @@ from vbml.patcher import Patcher
|
|
|
6
6
|
|
|
7
7
|
from telegrinder.api.abc import ABCAPI
|
|
8
8
|
from telegrinder.bot.cute_types.base import BaseCute
|
|
9
|
+
from telegrinder.bot.dispatch.context import Context
|
|
9
10
|
from telegrinder.bot.rules import ABCRule
|
|
10
11
|
from telegrinder.modules import logger
|
|
12
|
+
from telegrinder.tools.error_handler.error_handler import ErrorHandler
|
|
11
13
|
from telegrinder.tools.global_context import TelegrinderCtx
|
|
12
14
|
from telegrinder.types import Update
|
|
13
15
|
|
|
@@ -19,6 +21,7 @@ from .view.box import CallbackQueryViewT, InlineQueryViewT, MessageViewT, ViewBo
|
|
|
19
21
|
T = typing.TypeVar("T")
|
|
20
22
|
R = typing.TypeVar("R")
|
|
21
23
|
P = typing.ParamSpec("P")
|
|
24
|
+
Handler = typing.Callable[typing.Concatenate[T, ...], typing.Coroutine[typing.Any, typing.Any, typing.Any]]
|
|
22
25
|
Event = typing.TypeVar("Event", bound=BaseCute)
|
|
23
26
|
|
|
24
27
|
DEFAULT_DATACLASS: typing.Final[type[Update]] = Update
|
|
@@ -47,17 +50,74 @@ class Dispatch(
|
|
|
47
50
|
def patcher(self) -> Patcher:
|
|
48
51
|
"""Alias `patcher` to get `vbml.Patcher` from the global context"""
|
|
49
52
|
return self.global_context.vbml_patcher
|
|
53
|
+
|
|
54
|
+
@typing.overload
|
|
55
|
+
def handle(
|
|
56
|
+
self,
|
|
57
|
+
*rules: ABCRule[Event],
|
|
58
|
+
) -> typing.Callable[[Handler[T]], FuncHandler[Event, Handler[T], ErrorHandler]]:
|
|
59
|
+
...
|
|
50
60
|
|
|
61
|
+
@typing.overload
|
|
51
62
|
def handle(
|
|
52
63
|
self,
|
|
53
|
-
*rules: ABCRule,
|
|
64
|
+
*rules: ABCRule[Event],
|
|
65
|
+
is_blocking: bool = True,
|
|
66
|
+
) -> typing.Callable[[Handler[T]], FuncHandler[Event, Handler[T], ErrorHandler]]:
|
|
67
|
+
...
|
|
68
|
+
|
|
69
|
+
@typing.overload
|
|
70
|
+
def handle(
|
|
71
|
+
self,
|
|
72
|
+
*rules: ABCRule[Event],
|
|
73
|
+
dataclass: type[T],
|
|
74
|
+
is_blocking: bool = True,
|
|
75
|
+
) -> typing.Callable[[Handler[T]], FuncHandler[Event, Handler[T], ErrorHandler]]:
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
@typing.overload
|
|
79
|
+
def handle( # type: ignore
|
|
80
|
+
self,
|
|
81
|
+
*rules: ABCRule[Event],
|
|
82
|
+
error_handler: ErrorHandlerT,
|
|
83
|
+
is_blocking: bool = True,
|
|
84
|
+
) -> typing.Callable[[Handler[T]], FuncHandler[Event, Handler[T], ErrorHandlerT]]:
|
|
85
|
+
...
|
|
86
|
+
|
|
87
|
+
@typing.overload
|
|
88
|
+
def handle(
|
|
89
|
+
self,
|
|
90
|
+
*rules: ABCRule[Event],
|
|
91
|
+
dataclass: type[T],
|
|
92
|
+
error_handler: ErrorHandlerT,
|
|
93
|
+
is_blocking: bool = True,
|
|
94
|
+
) -> typing.Callable[[Handler[T]], FuncHandler[Event, Handler[T], ErrorHandlerT]]:
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
@typing.overload
|
|
98
|
+
def handle(
|
|
99
|
+
self,
|
|
100
|
+
*rules: ABCRule[Event],
|
|
101
|
+
dataclass: type[T] = DEFAULT_DATACLASS,
|
|
102
|
+
error_handler: typing.Literal[None] = None,
|
|
54
103
|
is_blocking: bool = True,
|
|
104
|
+
) -> typing.Callable[[Handler[T]], FuncHandler[Event, Handler[T], ErrorHandler]]:
|
|
105
|
+
...
|
|
106
|
+
|
|
107
|
+
def handle( # type: ignore
|
|
108
|
+
self,
|
|
109
|
+
*rules: ABCRule,
|
|
55
110
|
dataclass: type[typing.Any] = DEFAULT_DATACLASS,
|
|
56
111
|
error_handler: ErrorHandlerT | None = None,
|
|
112
|
+
is_blocking: bool = True,
|
|
57
113
|
):
|
|
58
114
|
def wrapper(func: typing.Callable):
|
|
59
115
|
handler = FuncHandler(
|
|
60
|
-
func,
|
|
116
|
+
func,
|
|
117
|
+
list(rules),
|
|
118
|
+
is_blocking=is_blocking,
|
|
119
|
+
dataclass=dataclass,
|
|
120
|
+
error_handler=error_handler or ErrorHandler(),
|
|
61
121
|
)
|
|
62
122
|
self.default_handlers.append(handler)
|
|
63
123
|
return handler
|
|
@@ -77,11 +137,12 @@ class Dispatch(
|
|
|
77
137
|
return True
|
|
78
138
|
|
|
79
139
|
loop = asyncio.get_running_loop()
|
|
140
|
+
ctx = Context()
|
|
80
141
|
found = False
|
|
81
142
|
for handler in self.default_handlers:
|
|
82
|
-
if await handler.check(api, event):
|
|
143
|
+
if await handler.check(api, event, ctx):
|
|
83
144
|
found = True
|
|
84
|
-
loop.create_task(handler.run(event))
|
|
145
|
+
loop.create_task(handler.run(event, ctx))
|
|
85
146
|
if handler.is_blocking:
|
|
86
147
|
break
|
|
87
148
|
return found
|
|
@@ -94,30 +155,6 @@ class Dispatch(
|
|
|
94
155
|
), f"View {name!r} is undefined in external dispatch."
|
|
95
156
|
view.load(view_external[name])
|
|
96
157
|
setattr(external, name, view)
|
|
97
|
-
|
|
98
|
-
@classmethod
|
|
99
|
-
def to_handler(
|
|
100
|
-
cls,
|
|
101
|
-
*rules: ABCRule[BaseCute],
|
|
102
|
-
is_blocking: bool = True,
|
|
103
|
-
error_handler: ErrorHandlerT | None = None,
|
|
104
|
-
):
|
|
105
|
-
def wrapper(
|
|
106
|
-
func: typing.Callable[typing.Concatenate[T, P], typing.Awaitable[R]]
|
|
107
|
-
) -> FuncHandler[
|
|
108
|
-
BaseCute,
|
|
109
|
-
typing.Callable[typing.Concatenate[T, P], typing.Awaitable[R]],
|
|
110
|
-
ErrorHandlerT,
|
|
111
|
-
]:
|
|
112
|
-
return FuncHandler(
|
|
113
|
-
func,
|
|
114
|
-
list(rules),
|
|
115
|
-
is_blocking=is_blocking,
|
|
116
|
-
dataclass=None,
|
|
117
|
-
error_handler=error_handler,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
return wrapper
|
|
121
158
|
|
|
122
159
|
|
|
123
160
|
__all__ = ("Dispatch",)
|
|
@@ -11,15 +11,13 @@ T = typing.TypeVar("T", bound=Model)
|
|
|
11
11
|
|
|
12
12
|
class ABCHandler(ABC, typing.Generic[T]):
|
|
13
13
|
is_blocking: bool
|
|
14
|
-
ctx: Context
|
|
15
14
|
|
|
16
15
|
@abstractmethod
|
|
17
|
-
async def
|
|
16
|
+
async def check(self, api: ABCAPI, event: Update, ctx: Context | None = None) -> bool:
|
|
18
17
|
pass
|
|
19
18
|
|
|
20
19
|
@abstractmethod
|
|
21
|
-
async def
|
|
20
|
+
async def run(self, event: T, ctx: Context) -> typing.Any:
|
|
22
21
|
pass
|
|
23
22
|
|
|
24
|
-
|
|
25
23
|
__all__ = ("ABCHandler",)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
|
|
1
3
|
import typing_extensions as typing
|
|
2
4
|
|
|
3
5
|
from telegrinder.api.abc import ABCAPI
|
|
@@ -13,46 +15,50 @@ from .abc import ABCHandler
|
|
|
13
15
|
if typing.TYPE_CHECKING:
|
|
14
16
|
from telegrinder.bot.rules import ABCRule
|
|
15
17
|
|
|
16
|
-
F = typing.TypeVar("F", bound=typing.Callable[typing.Concatenate[typing.Any, ...], typing.Awaitable])
|
|
18
|
+
F = typing.TypeVar("F", bound=typing.Callable[typing.Concatenate[typing.Any, ...], typing.Awaitable[typing.Any]])
|
|
17
19
|
EventT = typing.TypeVar("EventT", bound=BaseCute)
|
|
18
20
|
ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler, default=ErrorHandler)
|
|
19
21
|
|
|
20
22
|
|
|
23
|
+
@dataclasses.dataclass(repr=False)
|
|
21
24
|
class FuncHandler(ABCHandler[EventT], typing.Generic[EventT, F, ErrorHandlerT]):
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
func: F
|
|
26
|
+
rules: list["ABCRule[EventT]"]
|
|
27
|
+
_: dataclasses.KW_ONLY
|
|
28
|
+
is_blocking: bool = dataclasses.field(default=True)
|
|
29
|
+
dataclass: type[typing.Any] | None = dataclasses.field(default=dict)
|
|
30
|
+
error_handler: ErrorHandlerT = dataclasses.field(
|
|
31
|
+
default_factory=lambda: typing.cast(ErrorHandlerT, ErrorHandler()),
|
|
32
|
+
)
|
|
33
|
+
preset_context: Context = dataclasses.field(default_factory=lambda: Context())
|
|
34
|
+
|
|
35
|
+
def __repr__(self) -> str:
|
|
36
|
+
return "<{}: {}={!r} with rules={!r}, dataclass={!r}, error_handler={!r}>".format(
|
|
37
|
+
self.__class__.__name__,
|
|
38
|
+
"blocking function" if self.is_blocking else "function",
|
|
39
|
+
self.func.__name__,
|
|
40
|
+
self.rules,
|
|
41
|
+
self.dataclass,
|
|
42
|
+
self.error_handler,
|
|
43
|
+
)
|
|
40
44
|
|
|
41
45
|
async def check(self, api: ABCAPI, event: Update, ctx: Context | None = None) -> bool:
|
|
42
46
|
ctx = ctx or Context()
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
temp_ctx = ctx.copy()
|
|
48
|
+
temp_ctx |= self.preset_context
|
|
49
|
+
|
|
45
50
|
for rule in self.rules:
|
|
46
|
-
if not await check_rule(api, rule, event,
|
|
51
|
+
if not await check_rule(api, rule, event, temp_ctx):
|
|
47
52
|
logger.debug("Rule {!r} failed!", rule)
|
|
48
|
-
self.ctx = preset_ctx
|
|
49
53
|
return False
|
|
54
|
+
|
|
55
|
+
ctx |= temp_ctx
|
|
50
56
|
return True
|
|
51
57
|
|
|
52
|
-
async def run(self, event: EventT) -> typing.Any:
|
|
58
|
+
async def run(self, event: EventT, ctx: Context) -> typing.Any:
|
|
53
59
|
if self.dataclass is not None:
|
|
54
60
|
event = self.dataclass(**event.to_dict())
|
|
55
|
-
return (await self.error_handler.run(self.func, event, event.api,
|
|
61
|
+
return (await self.error_handler.run(self.func, event, event.api, ctx)).unwrap()
|
|
56
62
|
|
|
57
63
|
|
|
58
64
|
__all__ = ("FuncHandler",)
|
|
@@ -7,7 +7,7 @@ from telegrinder.bot.dispatch.process import check_rule
|
|
|
7
7
|
from telegrinder.bot.rules.abc import ABCRule
|
|
8
8
|
from telegrinder.modules import logger
|
|
9
9
|
from telegrinder.msgspec_utils import Nothing
|
|
10
|
-
from telegrinder.types.objects import Update
|
|
10
|
+
from telegrinder.types.objects import ReplyParameters, Update
|
|
11
11
|
|
|
12
12
|
from .abc import ABCHandler
|
|
13
13
|
|
|
@@ -17,29 +17,41 @@ class MessageReplyHandler(ABCHandler[MessageCute]):
|
|
|
17
17
|
self,
|
|
18
18
|
text: str,
|
|
19
19
|
*rules: ABCRule[MessageCute],
|
|
20
|
-
as_reply: bool = False,
|
|
21
20
|
is_blocking: bool = True,
|
|
22
|
-
|
|
21
|
+
as_reply: bool = False,
|
|
22
|
+
) -> None:
|
|
23
23
|
self.text = text
|
|
24
24
|
self.rules = list(rules)
|
|
25
25
|
self.as_reply = as_reply
|
|
26
26
|
self.is_blocking = is_blocking
|
|
27
|
-
self.
|
|
28
|
-
|
|
27
|
+
self.preset_context = Context()
|
|
28
|
+
|
|
29
|
+
def __repr__(self) -> str:
|
|
30
|
+
return "<{}: with rules={!r}, {}: {!r}>".format(
|
|
31
|
+
("blocking " if self.is_blocking else "")
|
|
32
|
+
+ self.__class__.__name__,
|
|
33
|
+
self.rules,
|
|
34
|
+
"answer text as reply" if self.as_reply else "answer text",
|
|
35
|
+
self.text,
|
|
36
|
+
)
|
|
29
37
|
|
|
30
38
|
async def check(self, api: ABCAPI, event: Update, ctx: Context | None = None) -> bool:
|
|
31
39
|
ctx = ctx or Context()
|
|
32
|
-
|
|
40
|
+
temp_ctx = ctx.copy()
|
|
41
|
+
temp_ctx |= self.preset_context
|
|
42
|
+
|
|
33
43
|
for rule in self.rules:
|
|
34
|
-
if not await check_rule(api, rule, event,
|
|
44
|
+
if not await check_rule(api, rule, event, ctx):
|
|
35
45
|
logger.debug("Rule {!r} failed!", rule)
|
|
36
46
|
return False
|
|
47
|
+
|
|
48
|
+
ctx |= temp_ctx
|
|
37
49
|
return True
|
|
38
50
|
|
|
39
|
-
async def run(self, event: MessageCute) -> typing.Any:
|
|
51
|
+
async def run(self, event: MessageCute, _: Context) -> typing.Any:
|
|
40
52
|
await event.answer(
|
|
41
53
|
text=self.text,
|
|
42
|
-
|
|
54
|
+
reply_parameters=ReplyParameters(event.message_id) if self.as_reply else None,
|
|
43
55
|
)
|
|
44
56
|
|
|
45
57
|
|
|
@@ -11,7 +11,7 @@ class ABCMiddleware(ABC, typing.Generic[T]):
|
|
|
11
11
|
async def pre(self, event: T, ctx: Context) -> bool:
|
|
12
12
|
...
|
|
13
13
|
|
|
14
|
-
async def post(self, event: T, responses: list[typing.Any], ctx: Context):
|
|
14
|
+
async def post(self, event: T, responses: list[typing.Any], ctx: Context) -> None:
|
|
15
15
|
...
|
|
16
16
|
|
|
17
17
|
|
|
@@ -17,7 +17,7 @@ if typing.TYPE_CHECKING:
|
|
|
17
17
|
from telegrinder.bot.rules.abc import ABCRule
|
|
18
18
|
|
|
19
19
|
T = typing.TypeVar("T", bound=BaseCute)
|
|
20
|
-
_ = typing.Any
|
|
20
|
+
_: typing.TypeAlias = typing.Any
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
async def process_inner(
|
|
@@ -36,15 +36,17 @@ async def process_inner(
|
|
|
36
36
|
|
|
37
37
|
found = False
|
|
38
38
|
responses = []
|
|
39
|
+
ctx_copy = ctx.copy()
|
|
40
|
+
|
|
39
41
|
for handler in handlers:
|
|
40
42
|
if await handler.check(event.api, raw_event, ctx):
|
|
41
43
|
found = True
|
|
42
|
-
handler.
|
|
43
|
-
response = await handler.run(event)
|
|
44
|
+
response = await handler.run(event, ctx)
|
|
44
45
|
responses.append(response)
|
|
45
46
|
await return_manager.run(response, event, ctx)
|
|
46
47
|
if handler.is_blocking:
|
|
47
48
|
break
|
|
49
|
+
ctx = ctx_copy
|
|
48
50
|
|
|
49
51
|
for middleware in middlewares:
|
|
50
52
|
await middleware.post(event, responses, ctx)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
1
3
|
from telegrinder.bot.cute_types import CallbackQueryCute
|
|
2
4
|
from telegrinder.bot.dispatch.context import Context
|
|
3
5
|
|
|
@@ -12,7 +14,7 @@ class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
|
|
|
12
14
|
|
|
13
15
|
@register_manager(dict)
|
|
14
16
|
@staticmethod
|
|
15
|
-
async def dict_manager(value: dict, event: CallbackQueryCute, ctx: Context) -> None:
|
|
17
|
+
async def dict_manager(value: dict[str, typing.Any], event: CallbackQueryCute, ctx: Context) -> None:
|
|
16
18
|
await event.answer(**value)
|
|
17
19
|
|
|
18
20
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
1
3
|
from telegrinder.bot.cute_types import InlineQueryCute
|
|
2
4
|
from telegrinder.bot.dispatch.context import Context
|
|
3
5
|
|
|
@@ -7,7 +9,7 @@ from .abc import BaseReturnManager, register_manager
|
|
|
7
9
|
class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
|
|
8
10
|
@register_manager(dict)
|
|
9
11
|
@staticmethod
|
|
10
|
-
async def dict_manager(value: dict, event: InlineQueryCute, ctx: Context) -> None:
|
|
12
|
+
async def dict_manager(value: dict[str, typing.Any], event: InlineQueryCute, ctx: Context) -> None:
|
|
11
13
|
await event.answer(**value)
|
|
12
14
|
|
|
13
15
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
1
3
|
from telegrinder.bot.cute_types import MessageCute
|
|
2
4
|
from telegrinder.bot.dispatch.context import Context
|
|
5
|
+
from telegrinder.tools.formatting import HTMLFormatter
|
|
3
6
|
|
|
4
7
|
from .abc import BaseReturnManager, register_manager
|
|
5
8
|
|
|
@@ -18,8 +21,13 @@ class MessageReturnManager(BaseReturnManager[MessageCute]):
|
|
|
18
21
|
|
|
19
22
|
@register_manager(dict)
|
|
20
23
|
@staticmethod
|
|
21
|
-
async def dict_manager(value: dict, event: MessageCute, ctx: Context) -> None:
|
|
24
|
+
async def dict_manager(value: dict[str, typing.Any], event: MessageCute, ctx: Context) -> None:
|
|
22
25
|
await event.answer(**value)
|
|
23
26
|
|
|
27
|
+
@register_manager(HTMLFormatter)
|
|
28
|
+
@staticmethod
|
|
29
|
+
async def htmlformatter_manager(value: HTMLFormatter, event: MessageCute, ctx: Context) -> None:
|
|
30
|
+
await event.answer(value, parse_mode=HTMLFormatter.PARSE_MODE)
|
|
31
|
+
|
|
24
32
|
|
|
25
33
|
__all__ = ("MessageReturnManager",)
|
|
@@ -6,16 +6,18 @@ from fntypes.co import Nothing, Some
|
|
|
6
6
|
from telegrinder.api.abc import ABCAPI
|
|
7
7
|
from telegrinder.bot.cute_types.base import BaseCute
|
|
8
8
|
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
9
|
-
from telegrinder.bot.dispatch.handler.func import
|
|
9
|
+
from telegrinder.bot.dispatch.handler.func import FuncHandler
|
|
10
10
|
from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
|
|
11
11
|
from telegrinder.bot.dispatch.process import process_inner
|
|
12
12
|
from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
|
|
13
13
|
from telegrinder.bot.rules.abc import ABCRule
|
|
14
14
|
from telegrinder.model import Model
|
|
15
15
|
from telegrinder.msgspec_utils import Option
|
|
16
|
+
from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
|
|
16
17
|
from telegrinder.types.objects import Update
|
|
17
18
|
|
|
18
19
|
EventType = typing.TypeVar("EventType", bound=BaseCute)
|
|
20
|
+
ErrorHandlerT = typing.TypeVar("ErrorHandlerT", bound=ABCErrorHandler)
|
|
19
21
|
MiddlewareT = typing.TypeVar("MiddlewareT", bound=ABCMiddleware)
|
|
20
22
|
|
|
21
23
|
FuncType: typing.TypeAlias = typing.Callable[
|
|
@@ -74,20 +76,44 @@ class BaseView(ABCView, typing.Generic[EventType]):
|
|
|
74
76
|
return getattr(update, update_type.value)
|
|
75
77
|
case _:
|
|
76
78
|
return Nothing()
|
|
79
|
+
|
|
80
|
+
@typing.overload
|
|
81
|
+
def __call__(
|
|
82
|
+
self,
|
|
83
|
+
*rules: ABCRule[EventType],
|
|
84
|
+
) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandler]]:
|
|
85
|
+
...
|
|
86
|
+
|
|
87
|
+
@typing.overload
|
|
88
|
+
def __call__(
|
|
89
|
+
self,
|
|
90
|
+
*rules: ABCRule[EventType],
|
|
91
|
+
error_handler: ErrorHandlerT,
|
|
92
|
+
is_blocking: bool = True,
|
|
93
|
+
) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandlerT]]:
|
|
94
|
+
...
|
|
77
95
|
|
|
96
|
+
@typing.overload
|
|
78
97
|
def __call__(
|
|
79
98
|
self,
|
|
80
99
|
*rules: ABCRule[EventType],
|
|
100
|
+
error_handler: typing.Literal[None] = None,
|
|
101
|
+
is_blocking: bool = True,
|
|
102
|
+
) -> typing.Callable[[FuncType[EventType]], FuncHandler[EventType, FuncType[EventType], ErrorHandler]]:
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
def __call__( # type: ignore
|
|
106
|
+
self,
|
|
107
|
+
*rules: ABCRule[EventType],
|
|
108
|
+
error_handler: ABCErrorHandler | None = None,
|
|
81
109
|
is_blocking: bool = True,
|
|
82
|
-
error_handler: ErrorHandlerT | None = None,
|
|
83
110
|
):
|
|
84
111
|
def wrapper(func: FuncType[EventType]):
|
|
85
|
-
func_handler = FuncHandler
|
|
112
|
+
func_handler = FuncHandler(
|
|
86
113
|
func,
|
|
87
114
|
[*self.auto_rules, *rules],
|
|
88
|
-
is_blocking,
|
|
115
|
+
is_blocking=is_blocking,
|
|
89
116
|
dataclass=None,
|
|
90
|
-
error_handler=error_handler,
|
|
91
117
|
)
|
|
92
118
|
self.handlers.append(func_handler)
|
|
93
119
|
return func_handler
|
|
@@ -30,7 +30,8 @@ class ViewBox(typing.Generic[CallbackQueryViewT, InlineQueryViewT, MessageViewT]
|
|
|
30
30
|
|
|
31
31
|
def get_views(self) -> dict[str, ABCView]:
|
|
32
32
|
return {
|
|
33
|
-
name: view
|
|
33
|
+
name: view
|
|
34
|
+
for name, view in self.__dict__.items()
|
|
34
35
|
if isinstance(view, ABCView)
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -12,7 +12,7 @@ class InlineQueryView(BaseStateView[InlineQueryCute]):
|
|
|
12
12
|
self.return_manager = InlineQueryReturnManager()
|
|
13
13
|
|
|
14
14
|
def get_state_key(self, event: InlineQueryCute) -> int | None:
|
|
15
|
-
return event.
|
|
15
|
+
return event.from_user.id
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
__all__ = ("InlineQueryView",)
|
|
@@ -19,12 +19,18 @@ if typing.TYPE_CHECKING:
|
|
|
19
19
|
class WaiterMachine:
|
|
20
20
|
def __init__(self) -> None:
|
|
21
21
|
self.storage: Storage = {}
|
|
22
|
+
|
|
23
|
+
def __repr__(self) -> str:
|
|
24
|
+
return "<{}: storage={!r}>".format(
|
|
25
|
+
self.__class__.__name__,
|
|
26
|
+
self.storage,
|
|
27
|
+
)
|
|
22
28
|
|
|
23
29
|
async def drop(
|
|
24
30
|
self,
|
|
25
31
|
state_view: "ABCStateView[EventModel]",
|
|
26
32
|
id: Identificator,
|
|
27
|
-
**context,
|
|
33
|
+
**context: typing.Any,
|
|
28
34
|
) -> None:
|
|
29
35
|
view_name = state_view.__class__.__name__
|
|
30
36
|
if view_name not in self.storage:
|
|
@@ -60,9 +66,9 @@ class WaiterMachine:
|
|
|
60
66
|
*rules: ABCRule[EventModel],
|
|
61
67
|
default: Behaviour = None,
|
|
62
68
|
on_drop: Behaviour = None,
|
|
63
|
-
expiration: datetime.timedelta | int | None = None,
|
|
69
|
+
expiration: datetime.timedelta | int | float | None = None,
|
|
64
70
|
) -> tuple[EventModel, Context]:
|
|
65
|
-
if isinstance(expiration, int):
|
|
71
|
+
if isinstance(expiration, int | float):
|
|
66
72
|
expiration = datetime.timedelta(seconds=expiration)
|
|
67
73
|
|
|
68
74
|
api: ABCAPI
|
|
@@ -77,9 +83,9 @@ class WaiterMachine:
|
|
|
77
83
|
|
|
78
84
|
short_state = ShortState(
|
|
79
85
|
key,
|
|
80
|
-
|
|
81
|
-
event
|
|
82
|
-
rules
|
|
86
|
+
api,
|
|
87
|
+
event,
|
|
88
|
+
rules,
|
|
83
89
|
expiration=expiration,
|
|
84
90
|
default_behaviour=default,
|
|
85
91
|
on_drop_behaviour=on_drop,
|
|
@@ -104,13 +110,13 @@ class WaiterMachine:
|
|
|
104
110
|
view: "ABCStateView[EventModel]",
|
|
105
111
|
behaviour: Behaviour,
|
|
106
112
|
event: asyncio.Event | EventModel,
|
|
107
|
-
**context,
|
|
113
|
+
**context: typing.Any,
|
|
108
114
|
) -> None:
|
|
109
115
|
if behaviour is None:
|
|
110
116
|
return
|
|
111
117
|
# TODO: add behaviour check
|
|
112
118
|
# TODO: support view as a behaviour
|
|
113
|
-
await behaviour.run(event)
|
|
119
|
+
await behaviour.run(event, context) # type: ignore
|
|
114
120
|
|
|
115
121
|
|
|
116
122
|
__all__ = ("WaiterMachine",)
|
|
@@ -38,32 +38,34 @@ class WaiterMiddleware(ABCMiddleware[EventType]):
|
|
|
38
38
|
if key is None:
|
|
39
39
|
raise RuntimeError("Unable to get state key.")
|
|
40
40
|
|
|
41
|
-
short_state: typing.Optional["ShortState"] = self.machine.storage[view_name].get(key)
|
|
41
|
+
short_state: typing.Optional["ShortState[EventType]"] = self.machine.storage[view_name].get(key)
|
|
42
42
|
if not short_state:
|
|
43
43
|
return True
|
|
44
44
|
|
|
45
45
|
if (
|
|
46
|
-
short_state.
|
|
47
|
-
and datetime.datetime.now() >= short_state.
|
|
46
|
+
short_state.expiration_date is not None
|
|
47
|
+
and datetime.datetime.now() >= short_state.expiration_date
|
|
48
48
|
):
|
|
49
49
|
await self.machine.drop(self.view, short_state.key)
|
|
50
50
|
return True
|
|
51
51
|
|
|
52
52
|
handler = FuncHandler(
|
|
53
|
-
self.pass_runtime,
|
|
53
|
+
self.pass_runtime,
|
|
54
|
+
list(short_state.rules),
|
|
55
|
+
dataclass=None,
|
|
54
56
|
)
|
|
55
|
-
handler.
|
|
57
|
+
handler.preset_context.set("short_state", short_state)
|
|
56
58
|
result = await handler.check(event.ctx_api, ctx.raw_update, ctx)
|
|
57
59
|
|
|
58
60
|
if result is True:
|
|
59
|
-
await handler.run(event)
|
|
61
|
+
await handler.run(event, ctx)
|
|
60
62
|
|
|
61
63
|
elif short_state.default_behaviour is not None:
|
|
62
64
|
await self.machine.call_behaviour(
|
|
63
65
|
self.view,
|
|
64
66
|
short_state.default_behaviour,
|
|
65
67
|
event,
|
|
66
|
-
**handler.
|
|
68
|
+
**handler.preset_context,
|
|
67
69
|
)
|
|
68
70
|
|
|
69
71
|
return False
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import dataclasses
|
|
2
3
|
import datetime
|
|
3
4
|
import typing
|
|
4
5
|
|
|
5
|
-
from telegrinder.api
|
|
6
|
+
from telegrinder.api import ABCAPI
|
|
6
7
|
from telegrinder.bot.cute_types import BaseCute
|
|
7
8
|
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
8
9
|
from telegrinder.bot.rules.abc import ABCRule
|
|
@@ -14,24 +15,22 @@ EventModel = typing.TypeVar("EventModel", bound=BaseCute)
|
|
|
14
15
|
Behaviour: typing.TypeAlias = ABCHandler | None
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
@dataclasses.dataclass
|
|
17
19
|
class ShortState(typing.Generic[EventModel]):
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
self.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
self.default_behaviour = default_behaviour
|
|
33
|
-
self.expiration = (datetime.datetime.now() + expiration) if expiration else None
|
|
34
|
-
self.on_drop_behaviour = on_drop_behaviour
|
|
20
|
+
key: "Identificator"
|
|
21
|
+
ctx_api: ABCAPI
|
|
22
|
+
event: asyncio.Event
|
|
23
|
+
rules: tuple[ABCRule[EventModel], ...]
|
|
24
|
+
_: dataclasses.KW_ONLY
|
|
25
|
+
expiration: dataclasses.InitVar[datetime.timedelta | None] = dataclasses.field(default=None)
|
|
26
|
+
default_behaviour: Behaviour | None = dataclasses.field(default=None)
|
|
27
|
+
on_drop_behaviour: Behaviour | None = dataclasses.field(default=None)
|
|
28
|
+
expiration_date: datetime.datetime | None = dataclasses.field(init=False)
|
|
29
|
+
|
|
30
|
+
def __post_init__(self, expiration: datetime.timedelta | None = None) -> None:
|
|
31
|
+
self.expiration_date = (
|
|
32
|
+
datetime.datetime.now() - expiration
|
|
33
|
+
) if expiration is not None else None
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
__all__ = ("ShortState",)
|
telegrinder/bot/rules/text.py
CHANGED
|
@@ -14,7 +14,7 @@ class TextMessageRule(MessageRule, ABC, requires=[HasText()]):
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Text(TextMessageRule):
|
|
17
|
-
def __init__(self, texts: str | list[str], ignore_case: bool = False):
|
|
17
|
+
def __init__(self, texts: str | list[str], *, ignore_case: bool = False) -> None:
|
|
18
18
|
if not isinstance(texts, list):
|
|
19
19
|
texts = [texts]
|
|
20
20
|
self.texts = texts if not ignore_case else list(map(str.lower, texts))
|
|
@@ -45,6 +45,21 @@ class Checkbox(ABCScenario[CallbackQueryCute]):
|
|
|
45
45
|
self.max_in_row = max_in_row
|
|
46
46
|
self.random_code = secrets.token_hex(8)
|
|
47
47
|
self.waiter_machine = waiter_machine
|
|
48
|
+
|
|
49
|
+
def __repr__(self) -> str:
|
|
50
|
+
return (
|
|
51
|
+
"<{}@{!r}: (choices={!r}, max_in_row={}) with waiter_machine={!r}, ready_text={!r} "
|
|
52
|
+
"for chat_id={} with message={!r}>"
|
|
53
|
+
).format(
|
|
54
|
+
self.__class__.__name__,
|
|
55
|
+
self.random_code,
|
|
56
|
+
self.choices,
|
|
57
|
+
self.max_in_row,
|
|
58
|
+
self.waiter_machine,
|
|
59
|
+
self.ready,
|
|
60
|
+
self.chat_id,
|
|
61
|
+
self.msg,
|
|
62
|
+
)
|
|
48
63
|
|
|
49
64
|
def get_markup(self) -> InlineKeyboardMarkup:
|
|
50
65
|
kb = InlineKeyboard()
|
|
@@ -70,6 +85,7 @@ class Checkbox(ABCScenario[CallbackQueryCute]):
|
|
|
70
85
|
name: str,
|
|
71
86
|
default_text: str,
|
|
72
87
|
picked_text: str,
|
|
88
|
+
*,
|
|
73
89
|
is_picked: bool = False,
|
|
74
90
|
) -> typing.Self:
|
|
75
91
|
self.choices.append(
|
telegrinder/node/base.py
CHANGED
telegrinder/node/composer.py
CHANGED
|
@@ -27,7 +27,7 @@ class NodeSession:
|
|
|
27
27
|
self.generator = None
|
|
28
28
|
|
|
29
29
|
def __repr__(self) -> str:
|
|
30
|
-
return f"<NodeSession {self.value}" + ("ACTIVE>" if self.generator else ">")
|
|
30
|
+
return f"<NodeSession: {self.value}" + ("ACTIVE>" if self.generator else ">")
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class NodeCollection:
|
|
@@ -13,12 +13,12 @@ Handler = typing.Callable[typing.Concatenate[EventT, ...], typing.Awaitable[typi
|
|
|
13
13
|
|
|
14
14
|
class ABCErrorHandler(ABC, typing.Generic[EventT]):
|
|
15
15
|
@abstractmethod
|
|
16
|
-
def
|
|
16
|
+
def __call__(
|
|
17
17
|
self,
|
|
18
18
|
*args: typing.Any,
|
|
19
19
|
**kwargs: typing.Any,
|
|
20
20
|
) -> typing.Callable[[typing.Callable[..., typing.Any]], typing.Callable[..., typing.Any]]:
|
|
21
|
-
|
|
21
|
+
"""Decorator for registering callback as an error handler."""
|
|
22
22
|
|
|
23
23
|
@abstractmethod
|
|
24
24
|
async def run(
|
|
@@ -28,7 +28,7 @@ class ABCErrorHandler(ABC, typing.Generic[EventT]):
|
|
|
28
28
|
api: ABCAPI,
|
|
29
29
|
ctx: Context,
|
|
30
30
|
) -> Result[typing.Any, typing.Any]:
|
|
31
|
-
|
|
31
|
+
"""Run error handler."""
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
__all__ = ("ABCErrorHandler",)
|
|
@@ -97,27 +97,8 @@ class ErrorHandler(ABCErrorHandler[EventT]):
|
|
|
97
97
|
if self.catcher is not None
|
|
98
98
|
else "<ErrorHandler: No catcher>"
|
|
99
99
|
)
|
|
100
|
-
|
|
101
|
-
async def __call__(
|
|
102
|
-
self,
|
|
103
|
-
handler: Handler[EventT],
|
|
104
|
-
event: EventT,
|
|
105
|
-
api: ABCAPI,
|
|
106
|
-
ctx: Context,
|
|
107
|
-
) -> Result[typing.Any, BaseException]:
|
|
108
|
-
assert self.catcher is not None
|
|
109
100
|
|
|
110
|
-
|
|
111
|
-
return await self.catcher(handler, event, api, ctx)
|
|
112
|
-
except BaseException as exc:
|
|
113
|
-
return Error(CatcherError(
|
|
114
|
-
exc,
|
|
115
|
-
"Exception {!r} was occurred during the running catcher {!r}.".format(
|
|
116
|
-
repr(exc), self.catcher.func.__name__
|
|
117
|
-
)
|
|
118
|
-
))
|
|
119
|
-
|
|
120
|
-
def register_catcher(
|
|
101
|
+
def __call__(
|
|
121
102
|
self,
|
|
122
103
|
*exceptions: type[BaseException] | BaseException,
|
|
123
104
|
logging: bool = False,
|
|
@@ -142,6 +123,25 @@ class ErrorHandler(ABCErrorHandler[EventT]):
|
|
|
142
123
|
return func
|
|
143
124
|
return decorator
|
|
144
125
|
|
|
126
|
+
async def process(
|
|
127
|
+
self,
|
|
128
|
+
handler: Handler[EventT],
|
|
129
|
+
event: EventT,
|
|
130
|
+
api: ABCAPI,
|
|
131
|
+
ctx: Context,
|
|
132
|
+
) -> Result[typing.Any, BaseException]:
|
|
133
|
+
assert self.catcher is not None
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
return await self.catcher(handler, event, api, ctx)
|
|
137
|
+
except BaseException as exc:
|
|
138
|
+
return Error(CatcherError(
|
|
139
|
+
exc,
|
|
140
|
+
"Exception {!r} was occurred during the running catcher {!r}.".format(
|
|
141
|
+
repr(exc), self.catcher.func.__name__
|
|
142
|
+
)
|
|
143
|
+
))
|
|
144
|
+
|
|
145
145
|
def process_catcher_error(self, error: CatcherError) -> Result[None, str]:
|
|
146
146
|
assert self.catcher is not None
|
|
147
147
|
|
|
@@ -164,7 +164,7 @@ class ErrorHandler(ABCErrorHandler[EventT]):
|
|
|
164
164
|
if not self.catcher:
|
|
165
165
|
return Ok(await handler(event, **magic_bundle(handler, ctx))) # type: ignore
|
|
166
166
|
|
|
167
|
-
match await self(handler, event, api, ctx):
|
|
167
|
+
match await self.process(handler, event, api, ctx):
|
|
168
168
|
case Ok(_) as ok:
|
|
169
169
|
return ok
|
|
170
170
|
case Error(exc) as err:
|
|
@@ -14,32 +14,32 @@ telegrinder/bot/cute_types/message.py,sha256=xYlbHfKP1kbVpUXOLed8yCuxW8v1cD7lV6N
|
|
|
14
14
|
telegrinder/bot/cute_types/update.py,sha256=VakZ2FwapOJvpEBIyzuiT8eftHHzBS-uPXrAUROQxOg,752
|
|
15
15
|
telegrinder/bot/cute_types/utils.py,sha256=Gp7zHUn5gEfxFItIYbzkaj6wxWoPNe7hM9abHkn3Jug,16349
|
|
16
16
|
telegrinder/bot/dispatch/__init__.py,sha256=o10t98PY1BuIGaJcloxfbgUYp0bf5ZqAaBQScIaV3VQ,1322
|
|
17
|
-
telegrinder/bot/dispatch/abc.py,sha256=
|
|
18
|
-
telegrinder/bot/dispatch/composition.py,sha256=
|
|
19
|
-
telegrinder/bot/dispatch/context.py,sha256=
|
|
20
|
-
telegrinder/bot/dispatch/dispatch.py,sha256=
|
|
17
|
+
telegrinder/bot/dispatch/abc.py,sha256=YX184RfqSTMtxrt6qyNRu9uhlPHJLEJY3RKsLfBV7nw,462
|
|
18
|
+
telegrinder/bot/dispatch/composition.py,sha256=EcIgiFJm1v7y8uaumrvBl-43vl8pABbjYLdgVNp4M-s,2973
|
|
19
|
+
telegrinder/bot/dispatch/context.py,sha256=ozsL1oy5BGjXADzVT-qhe8YohMxc-ORQKfUaKNbYm-Q,2322
|
|
20
|
+
telegrinder/bot/dispatch/dispatch.py,sha256=NSPLNAUu2q2-73JXLPAatF5cej1ySZykeiHaQD4XFhE,5048
|
|
21
21
|
telegrinder/bot/dispatch/handler/__init__.py,sha256=mzchbArrm0eoTEeVKHYrtJX4WSfW5t6T4xDU3-mtYaA,169
|
|
22
|
-
telegrinder/bot/dispatch/handler/abc.py,sha256=
|
|
23
|
-
telegrinder/bot/dispatch/handler/func.py,sha256=
|
|
24
|
-
telegrinder/bot/dispatch/handler/message_reply.py,sha256=
|
|
22
|
+
telegrinder/bot/dispatch/handler/abc.py,sha256=Qi7MDVlUdvMZYqYis3HuSoSW6KF23q3nqfvQ8FM5sEw,569
|
|
23
|
+
telegrinder/bot/dispatch/handler/func.py,sha256=IvDWA3ybQUcxXBOeEwteKeIVKp9-Lj9EEfKf2IIVQ40,2369
|
|
24
|
+
telegrinder/bot/dispatch/handler/message_reply.py,sha256=rpBRDHuJ4PdCUKq0CtFWgs7jCS4PlcgYoPFr6QOYpgw,1827
|
|
25
25
|
telegrinder/bot/dispatch/middleware/__init__.py,sha256=qDuTt2ZZKX9UMjPdw5xaaNZdMI-i3P4Px2T8qbYCMJw,61
|
|
26
|
-
telegrinder/bot/dispatch/middleware/abc.py,sha256=
|
|
27
|
-
telegrinder/bot/dispatch/process.py,sha256=
|
|
26
|
+
telegrinder/bot/dispatch/middleware/abc.py,sha256=mF_G22pes-qJg6wqK9Tf71sduODXSyPjWyPT1hAiDo0,429
|
|
27
|
+
telegrinder/bot/dispatch/process.py,sha256=J9MYuP-soXXa0eFjJ-5wE_bNEFmr4SukJzdajDSTfAw,2313
|
|
28
28
|
telegrinder/bot/dispatch/return_manager/__init__.py,sha256=-4h9nU-vdyPgv7bqKi1fAlfzNOKTO9m9FtdTZOhrmuc,447
|
|
29
29
|
telegrinder/bot/dispatch/return_manager/abc.py,sha256=dGPwsIUJW_6SRsNxSiWS69xOOwSOATzMP2a7FoD90sA,3150
|
|
30
|
-
telegrinder/bot/dispatch/return_manager/callback_query.py,sha256=
|
|
31
|
-
telegrinder/bot/dispatch/return_manager/inline_query.py,sha256
|
|
32
|
-
telegrinder/bot/dispatch/return_manager/message.py,sha256=
|
|
30
|
+
telegrinder/bot/dispatch/return_manager/callback_query.py,sha256=LIkXTGGyEnAHY-L_F82sbtzQtjvOHBi2GeL2eiWsEFc,656
|
|
31
|
+
telegrinder/bot/dispatch/return_manager/inline_query.py,sha256=-GRnPcdnNamtKL0IbbxCynyO3Dimk9Uz-_-wegfr1h4,484
|
|
32
|
+
telegrinder/bot/dispatch/return_manager/message.py,sha256=MNML9jGAAkmza1bwUOQVn9l2FmFqGHP4npub6TM_vqs,1139
|
|
33
33
|
telegrinder/bot/dispatch/view/__init__.py,sha256=iMReW_At2YzenjUGOgrVnOcHLVJAIQAfI9DdQElZdcM,379
|
|
34
|
-
telegrinder/bot/dispatch/view/abc.py,sha256=
|
|
35
|
-
telegrinder/bot/dispatch/view/box.py,sha256=
|
|
34
|
+
telegrinder/bot/dispatch/view/abc.py,sha256=E6fB_WRsX3y1i84_DwTYNhFyLUyOc0ougihvoxQSuFE,5564
|
|
35
|
+
telegrinder/bot/dispatch/view/box.py,sha256=rek4a2cxO6VTPRVXoz9KJsb0kU_rAYX2SlN-7LCZvsM,1252
|
|
36
36
|
telegrinder/bot/dispatch/view/callback_query.py,sha256=iL6DbB8ucXGvlv0w8eyMeZ94S1xz181pIn2yvYK1N_8,636
|
|
37
|
-
telegrinder/bot/dispatch/view/inline_query.py,sha256=
|
|
38
|
-
telegrinder/bot/dispatch/view/message.py,sha256=
|
|
37
|
+
telegrinder/bot/dispatch/view/inline_query.py,sha256=hRwrgfhgS5YF0E6eUrR8FuWVHUMlnA758kG7V049lkE,531
|
|
38
|
+
telegrinder/bot/dispatch/view/message.py,sha256=XX-_UmVf3_12-8I4TuH7utMRKxRcVKpWknXKhnGEx44,498
|
|
39
39
|
telegrinder/bot/dispatch/waiter_machine/__init__.py,sha256=RUuq-J1qZMeREL8omM8kxEfgAz3-7h3B9NhzSjLTMqA,190
|
|
40
|
-
telegrinder/bot/dispatch/waiter_machine/machine.py,sha256=
|
|
41
|
-
telegrinder/bot/dispatch/waiter_machine/middleware.py,sha256=
|
|
42
|
-
telegrinder/bot/dispatch/waiter_machine/short_state.py,sha256=
|
|
40
|
+
telegrinder/bot/dispatch/waiter_machine/machine.py,sha256=RHq0x6XOl7xcT3nZICIpkaDgVibiLLIEak_mYt5jnTw,3610
|
|
41
|
+
telegrinder/bot/dispatch/waiter_machine/middleware.py,sha256=6i_E2VPX71wYFnjESsUoCq1PaL4T6uaSXIWTgsTu874,2556
|
|
42
|
+
telegrinder/bot/dispatch/waiter_machine/short_state.py,sha256=2jYjr5RM2DknakcdbTc_xvH8FCrKKvDI8tsUwG0I5Hg,1200
|
|
43
43
|
telegrinder/bot/polling/__init__.py,sha256=OqfIFPS_V6UrCg-vCv9pkMFzTKdNbDP2faBfATs_TGg,94
|
|
44
44
|
telegrinder/bot/polling/abc.py,sha256=-5BpX55SJfDlEJWt15yOXWCizQRrgeY5oiA5eHkm1Nw,434
|
|
45
45
|
telegrinder/bot/polling/polling.py,sha256=GPXXlAhI81PZVUMGXsPd4j67GO19zozMRJaVNAgsBMg,4280
|
|
@@ -64,10 +64,10 @@ telegrinder/bot/rules/message_entities.py,sha256=_lWHCNymbV1Sv-f2Q8Ca3SOxqIPSHVy
|
|
|
64
64
|
telegrinder/bot/rules/regex.py,sha256=wqGEEiFqe5t_RwX9KjVCtg0wRZfwqo1ktGvNBo9JaKE,1191
|
|
65
65
|
telegrinder/bot/rules/rule_enum.py,sha256=BUd78f7fEa0hfu1Paa384_Q-r0lB-ZWWukqkrFXdn58,2083
|
|
66
66
|
telegrinder/bot/rules/start.py,sha256=5ok581Ww56g27rE4QkrykbBZ-ER-SnATQNzMGut2PHA,1183
|
|
67
|
-
telegrinder/bot/rules/text.py,sha256=
|
|
67
|
+
telegrinder/bot/rules/text.py,sha256=FUynYklF7VCFwOXj-cFCXWOA2N5Ul9BV9Wolbi5X72c,1158
|
|
68
68
|
telegrinder/bot/scenario/__init__.py,sha256=Ehe2uH-eQ-vRBPxIzdmE23B-FBOAa9YQyndmb6K8C5E,166
|
|
69
69
|
telegrinder/bot/scenario/abc.py,sha256=3AZYRjZlkbDtyFbsKdZ6BefzWYlJ0DOrGwh8jI3nzv4,474
|
|
70
|
-
telegrinder/bot/scenario/checkbox.py,sha256=
|
|
70
|
+
telegrinder/bot/scenario/checkbox.py,sha256=IIpC6F1JTtnH3D49R9xrXXrBd7A6klWzpDRCeBHwGg8,4202
|
|
71
71
|
telegrinder/bot/scenario/choice.py,sha256=-NYyzgfGI0njVuT-EY0j3jS4tPlsKOEkZaUagtns7dE,1442
|
|
72
72
|
telegrinder/client/__init__.py,sha256=ZiS1Wb_l_kv3FHzEEi1oXtFLwlA_HXmWOzeN0xA3E7Y,104
|
|
73
73
|
telegrinder/client/abc.py,sha256=OxsTX_PLYBEeFT9zpidFUzAbQL9BM7rQqru7zdn5DiQ,1611
|
|
@@ -78,8 +78,8 @@ telegrinder/msgspec_json.py,sha256=phfyhUvYYZUGEcI6RAyRx9lnARPK_Fqtw3Q0MEJnuUk,2
|
|
|
78
78
|
telegrinder/msgspec_utils.py,sha256=ZA_qj36FabalE65J82j_Hp34umHhUFbNIOt8CBYbqvA,7987
|
|
79
79
|
telegrinder/node/__init__.py,sha256=01XTe8GPUBp5LXayDshihTxre7ejf99NYte20d08JLM,706
|
|
80
80
|
telegrinder/node/attachment.py,sha256=vMnD2tWQQQ6PFuXEIq2ZdL91xcBxiwlAkMkqJqseLlk,2587
|
|
81
|
-
telegrinder/node/base.py,sha256=
|
|
82
|
-
telegrinder/node/composer.py,sha256=
|
|
81
|
+
telegrinder/node/base.py,sha256=rEYPjLQ5EqahyIvH9ktlk_iOiym2NGK2wzh9akVIs6I,2220
|
|
82
|
+
telegrinder/node/composer.py,sha256=OQj3WpY5EJ2UyFa5BWw70-AvXBny9jcuOVMRbrgOQWg,2226
|
|
83
83
|
telegrinder/node/container.py,sha256=sECP3TyC6AaNcJqKOfrL1T7-N8fkZzP2vB84kku6Jxg,636
|
|
84
84
|
telegrinder/node/message.py,sha256=2IW6DjF0KqH2_TZbZ-MXNsDioQRVPg9TUt86aQos0Kk,415
|
|
85
85
|
telegrinder/node/rule.py,sha256=VGmS4lJAFCoR0hCZSLn56fonMt0FhOGyZ1BQn_1vgeg,1724
|
|
@@ -92,9 +92,9 @@ telegrinder/rules.py,sha256=BFB8RFwKKxqs9HFfo_p0RfulQNonPZAX8cHpmnG7qCU,39
|
|
|
92
92
|
telegrinder/tools/__init__.py,sha256=EssNbs2XHkoL-tRMB_nk5pQsgdDLg2zb0nSUY8liXIM,2878
|
|
93
93
|
telegrinder/tools/buttons.py,sha256=qMvtpawzkjdqopqE7o9C0k-no1dGJVy5gjFX4SiOE6A,2430
|
|
94
94
|
telegrinder/tools/error_handler/__init__.py,sha256=WmYWZCNhhSk32j4lIOltEwzoYUx086TGTbOF5h3Ps7s,207
|
|
95
|
-
telegrinder/tools/error_handler/abc.py,sha256=
|
|
95
|
+
telegrinder/tools/error_handler/abc.py,sha256=ymQGDXgnIkfjMMBsLeNcpekQ-p7lj9kSSTLFWqpZ8Ok,952
|
|
96
96
|
telegrinder/tools/error_handler/error.py,sha256=jVp3J4pMkkL20QHvDtlid9hKtAc66jZIcpsecB3-f98,188
|
|
97
|
-
telegrinder/tools/error_handler/error_handler.py,sha256=
|
|
97
|
+
telegrinder/tools/error_handler/error_handler.py,sha256=GpGNkEHZAv_4awk96tpJwcnm_YdI3MAfWVILS49jNQ4,5992
|
|
98
98
|
telegrinder/tools/formatting/__init__.py,sha256=_oxb-4y_vyIgALlO2rfaa-azqicySpHHIcaYBrVPdSg,1609
|
|
99
99
|
telegrinder/tools/formatting/html.py,sha256=-tvN1zJK_Q7evil3-XgRdvsdYsOgaG9eX2KsIQkt0m8,8718
|
|
100
100
|
telegrinder/tools/formatting/links.py,sha256=ABglEz8EA6XitSM5xJt2FU78ffUdXVNbziJUjoUjKnI,1074
|
|
@@ -121,7 +121,7 @@ telegrinder/types/__init__.py,sha256=pvPKWDXq9PBiIOCW8dFcJMqgr1kAqodPhwT-u8I4kug
|
|
|
121
121
|
telegrinder/types/enums.py,sha256=9ZYiz_KRP1o7jB5If6730YLDfLt_-wKVK8UFs5a6CVI,18330
|
|
122
122
|
telegrinder/types/methods.py,sha256=CbeuZgtH5IIH1cKZlMWVkTnNAFqQLOYLw-_DeWHKKhk,186385
|
|
123
123
|
telegrinder/types/objects.py,sha256=znpGLbPrFu5GCUf4j6p_XA7iCVaxYqUZN1UqBEpr5FY,214803
|
|
124
|
-
telegrinder-0.1.
|
|
125
|
-
telegrinder-0.1.
|
|
126
|
-
telegrinder-0.1.
|
|
127
|
-
telegrinder-0.1.
|
|
124
|
+
telegrinder-0.1.dev164.dist-info/LICENSE,sha256=J9ngGsqHCNNjpm3xYPT7EnlzsnjhfqNXej5mJFjM6lw,1094
|
|
125
|
+
telegrinder-0.1.dev164.dist-info/METADATA,sha256=iaWGLP29CV1O042MEqTS25vDC7FsqUSB9Zh5cE62gGc,2892
|
|
126
|
+
telegrinder-0.1.dev164.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
127
|
+
telegrinder-0.1.dev164.dist-info/RECORD,,
|
|
File without changes
|