telegrinder 0.1.dev171__py3-none-any.whl → 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of telegrinder might be problematic. Click here for more details.
- telegrinder/__init__.py +2 -2
- telegrinder/api/__init__.py +1 -2
- telegrinder/api/api.py +3 -3
- telegrinder/api/token.py +36 -0
- telegrinder/bot/__init__.py +12 -6
- telegrinder/bot/bot.py +12 -5
- telegrinder/bot/cute_types/__init__.py +7 -7
- telegrinder/bot/cute_types/base.py +7 -32
- telegrinder/bot/cute_types/callback_query.py +5 -6
- telegrinder/bot/cute_types/chat_join_request.py +4 -5
- telegrinder/bot/cute_types/chat_member_updated.py +3 -4
- telegrinder/bot/cute_types/inline_query.py +3 -4
- telegrinder/bot/cute_types/message.py +9 -10
- telegrinder/bot/cute_types/update.py +8 -9
- telegrinder/bot/cute_types/utils.py +1 -1
- telegrinder/bot/dispatch/__init__.py +9 -9
- telegrinder/bot/dispatch/abc.py +2 -2
- telegrinder/bot/dispatch/context.py +11 -2
- telegrinder/bot/dispatch/dispatch.py +18 -33
- telegrinder/bot/dispatch/handler/__init__.py +3 -3
- telegrinder/bot/dispatch/handler/abc.py +3 -3
- telegrinder/bot/dispatch/handler/func.py +17 -12
- telegrinder/bot/dispatch/handler/message_reply.py +6 -7
- telegrinder/bot/dispatch/middleware/__init__.py +1 -1
- telegrinder/bot/dispatch/process.py +30 -11
- telegrinder/bot/dispatch/return_manager/__init__.py +4 -4
- telegrinder/bot/dispatch/return_manager/callback_query.py +1 -2
- telegrinder/bot/dispatch/return_manager/inline_query.py +1 -2
- telegrinder/bot/dispatch/return_manager/message.py +1 -2
- telegrinder/bot/dispatch/view/__init__.py +8 -8
- telegrinder/bot/dispatch/view/abc.py +9 -4
- telegrinder/bot/dispatch/view/box.py +2 -2
- telegrinder/bot/dispatch/view/callback_query.py +1 -2
- telegrinder/bot/dispatch/view/chat_join_request.py +1 -2
- telegrinder/bot/dispatch/view/chat_member.py +16 -2
- telegrinder/bot/dispatch/view/inline_query.py +1 -2
- telegrinder/bot/dispatch/view/message.py +1 -2
- telegrinder/bot/dispatch/view/raw.py +8 -10
- telegrinder/bot/dispatch/waiter_machine/__init__.py +3 -3
- telegrinder/bot/dispatch/waiter_machine/machine.py +10 -6
- telegrinder/bot/dispatch/waiter_machine/short_state.py +2 -2
- telegrinder/bot/polling/abc.py +1 -1
- telegrinder/bot/polling/polling.py +3 -3
- telegrinder/bot/rules/__init__.py +20 -20
- telegrinder/bot/rules/abc.py +50 -40
- telegrinder/bot/rules/adapter/__init__.py +5 -5
- telegrinder/bot/rules/adapter/abc.py +6 -3
- telegrinder/bot/rules/adapter/errors.py +2 -1
- telegrinder/bot/rules/adapter/event.py +27 -15
- telegrinder/bot/rules/adapter/node.py +28 -22
- telegrinder/bot/rules/adapter/raw_update.py +13 -5
- telegrinder/bot/rules/callback_data.py +4 -4
- telegrinder/bot/rules/chat_join.py +4 -4
- telegrinder/bot/rules/func.py +1 -1
- telegrinder/bot/rules/inline.py +3 -3
- telegrinder/bot/rules/markup.py +3 -1
- telegrinder/bot/rules/message_entities.py +1 -1
- telegrinder/bot/rules/text.py +1 -2
- telegrinder/bot/rules/update.py +1 -2
- telegrinder/bot/scenario/abc.py +2 -2
- telegrinder/bot/scenario/checkbox.py +1 -2
- telegrinder/bot/scenario/choice.py +1 -2
- telegrinder/model.py +6 -1
- telegrinder/msgspec_utils.py +55 -55
- telegrinder/node/__init__.py +1 -3
- telegrinder/node/base.py +14 -86
- telegrinder/node/composer.py +71 -74
- telegrinder/node/container.py +3 -3
- telegrinder/node/event.py +40 -31
- telegrinder/node/polymorphic.py +12 -6
- telegrinder/node/rule.py +1 -9
- telegrinder/node/scope.py +9 -1
- telegrinder/node/source.py +11 -0
- telegrinder/node/update.py +6 -2
- telegrinder/rules.py +59 -0
- telegrinder/tools/error_handler/abc.py +2 -2
- telegrinder/tools/error_handler/error_handler.py +5 -5
- telegrinder/tools/global_context/global_context.py +1 -1
- telegrinder/tools/keyboard.py +1 -1
- telegrinder/tools/loop_wrapper/loop_wrapper.py +9 -9
- telegrinder/tools/magic.py +64 -19
- telegrinder/types/__init__.py +1 -0
- telegrinder/types/enums.py +1 -0
- telegrinder/types/methods.py +78 -11
- telegrinder/types/objects.py +46 -24
- telegrinder/verification_utils.py +1 -3
- {telegrinder-0.1.dev171.dist-info → telegrinder-0.2.0.dist-info}/METADATA +1 -1
- telegrinder-0.2.0.dist-info/RECORD +145 -0
- telegrinder/api/abc.py +0 -79
- telegrinder-0.1.dev171.dist-info/RECORD +0 -145
- {telegrinder-0.1.dev171.dist-info → telegrinder-0.2.0.dist-info}/LICENSE +0 -0
- {telegrinder-0.1.dev171.dist-info → telegrinder-0.2.0.dist-info}/WHEEL +0 -0
|
@@ -3,7 +3,7 @@ from functools import cached_property
|
|
|
3
3
|
|
|
4
4
|
import typing_extensions as typing
|
|
5
5
|
|
|
6
|
-
from telegrinder.api
|
|
6
|
+
from telegrinder.api import API
|
|
7
7
|
from telegrinder.bot.cute_types import BaseCute, UpdateCute
|
|
8
8
|
from telegrinder.bot.dispatch.context import Context
|
|
9
9
|
from telegrinder.bot.dispatch.process import check_rule
|
|
@@ -56,27 +56,27 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
|
|
|
56
56
|
def required_nodes(self) -> dict[str, type[Node]]:
|
|
57
57
|
return get_nodes(self.func)
|
|
58
58
|
|
|
59
|
-
async def check(self, api:
|
|
59
|
+
async def check(self, api: API, event: Update, ctx: Context | None = None) -> bool:
|
|
60
60
|
if self.update_type is not None and self.update_type != event.update_type:
|
|
61
61
|
return False
|
|
62
62
|
|
|
63
|
+
logger.debug("Checking handler {!r}...", self)
|
|
63
64
|
ctx = Context(raw_update=event) if ctx is None else ctx
|
|
64
65
|
temp_ctx = ctx.copy()
|
|
65
66
|
temp_ctx |= self.preset_context
|
|
66
67
|
|
|
67
68
|
nodes = self.required_nodes
|
|
68
69
|
node_col = None
|
|
70
|
+
update = event
|
|
69
71
|
|
|
70
72
|
if nodes:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
nodes,
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
if node_col is None:
|
|
73
|
+
result = await compose_nodes(nodes, ctx, data={Update: event, API: api})
|
|
74
|
+
if not result:
|
|
75
|
+
logger.debug(f"Cannot compose nodes for handler. {result.error}")
|
|
78
76
|
return False
|
|
79
|
-
|
|
77
|
+
|
|
78
|
+
node_col = result.value
|
|
79
|
+
temp_ctx |= node_col.values
|
|
80
80
|
|
|
81
81
|
if EVENT_NODE_KEY in ctx:
|
|
82
82
|
for name, node in nodes.items():
|
|
@@ -84,15 +84,18 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
|
|
|
84
84
|
ctx[EVENT_NODE_KEY] = temp_ctx.pop(name)
|
|
85
85
|
|
|
86
86
|
for rule in self.rules:
|
|
87
|
-
if not await check_rule(api, rule,
|
|
87
|
+
if not await check_rule(api, rule, update, temp_ctx):
|
|
88
88
|
logger.debug("Rule {!r} failed!", rule)
|
|
89
89
|
return False
|
|
90
90
|
|
|
91
|
+
logger.debug("All checks passed for handler.")
|
|
92
|
+
|
|
91
93
|
temp_ctx["node_col"] = node_col
|
|
92
94
|
ctx |= temp_ctx
|
|
93
95
|
return True
|
|
94
96
|
|
|
95
|
-
async def run(self, api:
|
|
97
|
+
async def run(self, api: API, event: Event, ctx: Context) -> typing.Any:
|
|
98
|
+
logger.debug(f"Running func handler {self.func}")
|
|
96
99
|
dataclass_type = typing.get_origin(self.dataclass) or self.dataclass
|
|
97
100
|
|
|
98
101
|
if dataclass_type is Update and (event_node := ctx.pop(EVENT_NODE_KEY, None)) is not None:
|
|
@@ -106,8 +109,10 @@ class FuncHandler(ABCHandler[Event], typing.Generic[Event, F, ErrorHandlerT]):
|
|
|
106
109
|
if issubclass(dataclass_type, BaseCute)
|
|
107
110
|
else self.dataclass(**update.to_dict()) # type: ignore
|
|
108
111
|
)
|
|
112
|
+
|
|
109
113
|
elif issubclass(dataclass_type, UpdateCute) and isinstance(event, Update):
|
|
110
114
|
event = self.dataclass.from_update(event, bound_api=api) # type: ignore
|
|
115
|
+
|
|
111
116
|
else:
|
|
112
117
|
event = self.dataclass(**event.to_dict()) # type: ignore
|
|
113
118
|
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
|
-
from telegrinder.api.
|
|
4
|
-
from telegrinder.bot.cute_types import MessageCute
|
|
3
|
+
from telegrinder.api.api import API
|
|
4
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
5
5
|
from telegrinder.bot.dispatch.context import Context
|
|
6
|
+
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
6
7
|
from telegrinder.bot.dispatch.process import check_rule
|
|
7
8
|
from telegrinder.bot.rules.abc import ABCRule
|
|
8
9
|
from telegrinder.modules import logger
|
|
9
10
|
from telegrinder.types.objects import ReplyParameters, Update
|
|
10
11
|
|
|
11
|
-
from .abc import ABCHandler
|
|
12
|
-
|
|
13
12
|
|
|
14
13
|
class MessageReplyHandler(ABCHandler[MessageCute]):
|
|
15
14
|
def __init__(
|
|
@@ -36,8 +35,8 @@ class MessageReplyHandler(ABCHandler[MessageCute]):
|
|
|
36
35
|
self.text,
|
|
37
36
|
)
|
|
38
37
|
|
|
39
|
-
async def check(self, api:
|
|
40
|
-
ctx = Context() if ctx is None else ctx
|
|
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
|
|
41
40
|
temp_ctx = ctx.copy()
|
|
42
41
|
temp_ctx |= self.preset_context
|
|
43
42
|
|
|
@@ -49,7 +48,7 @@ class MessageReplyHandler(ABCHandler[MessageCute]):
|
|
|
49
48
|
ctx |= temp_ctx
|
|
50
49
|
return True
|
|
51
50
|
|
|
52
|
-
async def run(self, _:
|
|
51
|
+
async def run(self, _: API, event: MessageCute, __: Context) -> typing.Any:
|
|
53
52
|
await event.answer(
|
|
54
53
|
text=self.text,
|
|
55
54
|
reply_parameters=ReplyParameters(event.message_id) if self.as_reply else None,
|
|
@@ -2,7 +2,7 @@ import typing
|
|
|
2
2
|
|
|
3
3
|
from fntypes.result import Error, Ok
|
|
4
4
|
|
|
5
|
-
from telegrinder.api.
|
|
5
|
+
from telegrinder.api.api import API
|
|
6
6
|
from telegrinder.bot.cute_types.update import UpdateCute
|
|
7
7
|
from telegrinder.bot.dispatch.context import Context
|
|
8
8
|
from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
|
|
@@ -18,11 +18,10 @@ if typing.TYPE_CHECKING:
|
|
|
18
18
|
from telegrinder.bot.rules.abc import ABCRule
|
|
19
19
|
|
|
20
20
|
Event = typing.TypeVar("Event", bound=Model)
|
|
21
|
-
_: typing.TypeAlias = typing.Any
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
async def process_inner(
|
|
25
|
-
api:
|
|
24
|
+
api: API,
|
|
26
25
|
event: Event,
|
|
27
26
|
raw_event: Update,
|
|
28
27
|
middlewares: list[ABCMiddleware[Event]],
|
|
@@ -31,10 +30,13 @@ async def process_inner(
|
|
|
31
30
|
) -> bool:
|
|
32
31
|
logger.debug("Processing {!r}...", event.__class__.__name__)
|
|
33
32
|
ctx = Context(raw_update=raw_event)
|
|
34
|
-
ctx[CONTEXT_STORE_NODES_KEY] = {} #
|
|
33
|
+
ctx[CONTEXT_STORE_NODES_KEY] = {} # For per-event shared nodes
|
|
35
34
|
|
|
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__.__name__, middleware_result)
|
|
39
|
+
if middleware_result is False:
|
|
38
40
|
return False
|
|
39
41
|
|
|
40
42
|
found = False
|
|
@@ -43,6 +45,7 @@ async def process_inner(
|
|
|
43
45
|
|
|
44
46
|
for handler in handlers:
|
|
45
47
|
if await handler.check(api, raw_event, ctx):
|
|
48
|
+
logger.debug("Handler {!r} matched, run...", handler)
|
|
46
49
|
found = True
|
|
47
50
|
response = await handler.run(api, event, ctx)
|
|
48
51
|
logger.debug("Handler {!r} returned: {!r}", handler, response)
|
|
@@ -54,17 +57,24 @@ async def process_inner(
|
|
|
54
57
|
|
|
55
58
|
ctx = ctx_copy
|
|
56
59
|
|
|
60
|
+
logger.debug("Run post middlewares...")
|
|
57
61
|
for middleware in middlewares:
|
|
62
|
+
logger.debug("Run post middleware {!r}", middleware.__class__.__name__)
|
|
58
63
|
await middleware.post(event, responses, ctx)
|
|
59
64
|
|
|
60
65
|
for session in ctx.get(CONTEXT_STORE_NODES_KEY, {}).values():
|
|
61
66
|
await session.close(scopes=(NodeScope.PER_EVENT,))
|
|
62
67
|
|
|
68
|
+
logger.debug(
|
|
69
|
+
"{} handlers, returns {!r}",
|
|
70
|
+
"No found" if not found else "Found",
|
|
71
|
+
found,
|
|
72
|
+
)
|
|
63
73
|
return found
|
|
64
74
|
|
|
65
75
|
|
|
66
76
|
async def check_rule(
|
|
67
|
-
api:
|
|
77
|
+
api: API,
|
|
68
78
|
rule: "ABCRule",
|
|
69
79
|
update: Update,
|
|
70
80
|
ctx: Context,
|
|
@@ -73,13 +83,21 @@ async def check_rule(
|
|
|
73
83
|
Returns check result."""
|
|
74
84
|
|
|
75
85
|
# Running adapter
|
|
76
|
-
match await rule.adapter.adapt(api, update):
|
|
86
|
+
match await rule.adapter.adapt(api, update, ctx):
|
|
77
87
|
case Ok(value):
|
|
78
88
|
adapted_value = value
|
|
79
89
|
case Error(err):
|
|
80
90
|
logger.debug("Adapter failed with error message: {!r}", str(err))
|
|
81
91
|
return False
|
|
82
92
|
|
|
93
|
+
# Preparing update
|
|
94
|
+
if isinstance(adapted_val := ctx.get(rule.adapter.ADAPTED_VALUE_KEY or ""), UpdateCute):
|
|
95
|
+
update = adapted_val
|
|
96
|
+
elif isinstance(adapted_value, UpdateCute):
|
|
97
|
+
update = adapted_value
|
|
98
|
+
else:
|
|
99
|
+
update = UpdateCute.from_update(update, bound_api=api)
|
|
100
|
+
|
|
83
101
|
# Running subrules to fetch requirements
|
|
84
102
|
ctx_copy = ctx.copy()
|
|
85
103
|
for requirement in rule.requires:
|
|
@@ -88,7 +106,7 @@ async def check_rule(
|
|
|
88
106
|
|
|
89
107
|
# Translating translatable rules
|
|
90
108
|
if I18nEnum.I18N in ctx:
|
|
91
|
-
rule = await rule.translate(ctx
|
|
109
|
+
rule = await rule.translate(ctx[I18nEnum.I18N])
|
|
92
110
|
|
|
93
111
|
ctx |= ctx_copy
|
|
94
112
|
|
|
@@ -96,12 +114,13 @@ async def check_rule(
|
|
|
96
114
|
nodes = rule.required_nodes
|
|
97
115
|
node_col = None
|
|
98
116
|
if nodes:
|
|
99
|
-
|
|
100
|
-
if
|
|
117
|
+
result = await compose_nodes(nodes, ctx, data={Update: update, API: api})
|
|
118
|
+
if not result:
|
|
101
119
|
return False
|
|
120
|
+
node_col = result.value
|
|
102
121
|
|
|
103
122
|
# Running check
|
|
104
|
-
result = await rule.bounding_check(adapted_value, ctx, node_col)
|
|
123
|
+
result = await rule.bounding_check(adapted_value, ctx, node_col=node_col)
|
|
105
124
|
|
|
106
125
|
# Closing node sessions if there are any
|
|
107
126
|
if node_col is not None:
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
from .abc import (
|
|
1
|
+
from telegrinder.bot.dispatch.return_manager.abc import (
|
|
2
2
|
ABCReturnManager,
|
|
3
3
|
BaseReturnManager,
|
|
4
4
|
Manager,
|
|
5
5
|
register_manager,
|
|
6
6
|
)
|
|
7
|
-
from .callback_query import CallbackQueryReturnManager
|
|
8
|
-
from .inline_query import InlineQueryReturnManager
|
|
9
|
-
from .message import MessageReturnManager
|
|
7
|
+
from telegrinder.bot.dispatch.return_manager.callback_query import CallbackQueryReturnManager
|
|
8
|
+
from telegrinder.bot.dispatch.return_manager.inline_query import InlineQueryReturnManager
|
|
9
|
+
from telegrinder.bot.dispatch.return_manager.message import MessageReturnManager
|
|
10
10
|
|
|
11
11
|
__all__ = (
|
|
12
12
|
"ABCReturnManager",
|
|
@@ -2,8 +2,7 @@ import typing
|
|
|
2
2
|
|
|
3
3
|
from telegrinder.bot.cute_types import CallbackQueryCute
|
|
4
4
|
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
|
|
6
|
-
from .abc import BaseReturnManager, register_manager
|
|
5
|
+
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
|
|
@@ -2,8 +2,7 @@ import typing
|
|
|
2
2
|
|
|
3
3
|
from telegrinder.bot.cute_types import InlineQueryCute
|
|
4
4
|
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
|
|
6
|
-
from .abc import BaseReturnManager, register_manager
|
|
5
|
+
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
|
|
@@ -2,10 +2,9 @@ import typing
|
|
|
2
2
|
|
|
3
3
|
from telegrinder.bot.cute_types import MessageCute
|
|
4
4
|
from telegrinder.bot.dispatch.context import Context
|
|
5
|
+
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
5
6
|
from telegrinder.tools.formatting import HTMLFormatter
|
|
6
7
|
|
|
7
|
-
from .abc import BaseReturnManager, register_manager
|
|
8
|
-
|
|
9
8
|
|
|
10
9
|
class MessageReturnManager(BaseReturnManager[MessageCute]):
|
|
11
10
|
@register_manager(str)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
from .abc import ABCStateView, ABCView, BaseStateView, BaseView
|
|
2
|
-
from .box import ViewBox
|
|
3
|
-
from .callback_query import CallbackQueryView
|
|
4
|
-
from .chat_join_request import ChatJoinRequestView
|
|
5
|
-
from .chat_member import ChatMemberView
|
|
6
|
-
from .inline_query import InlineQueryView
|
|
7
|
-
from .message import MessageView
|
|
8
|
-
from .raw import RawEventView
|
|
1
|
+
from telegrinder.bot.dispatch.view.abc import ABCStateView, ABCView, BaseStateView, BaseView
|
|
2
|
+
from telegrinder.bot.dispatch.view.box import ViewBox
|
|
3
|
+
from telegrinder.bot.dispatch.view.callback_query import CallbackQueryView
|
|
4
|
+
from telegrinder.bot.dispatch.view.chat_join_request import ChatJoinRequestView
|
|
5
|
+
from telegrinder.bot.dispatch.view.chat_member import ChatMemberView
|
|
6
|
+
from telegrinder.bot.dispatch.view.inline_query import InlineQueryView
|
|
7
|
+
from telegrinder.bot.dispatch.view.message import MessageView
|
|
8
|
+
from telegrinder.bot.dispatch.view.raw import RawEventView
|
|
9
9
|
|
|
10
10
|
__all__ = (
|
|
11
11
|
"ABCStateView",
|
|
@@ -4,7 +4,7 @@ from functools import cached_property
|
|
|
4
4
|
|
|
5
5
|
from fntypes.co import Nothing, Some
|
|
6
6
|
|
|
7
|
-
from telegrinder.api
|
|
7
|
+
from telegrinder.api import API
|
|
8
8
|
from telegrinder.bot.cute_types.base import BaseCute
|
|
9
9
|
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
10
10
|
from telegrinder.bot.dispatch.handler.func import FuncHandler
|
|
@@ -29,14 +29,14 @@ FuncType: typing.TypeAlias = typing.Callable[
|
|
|
29
29
|
|
|
30
30
|
class ABCView(ABC):
|
|
31
31
|
def __repr__(self) -> str:
|
|
32
|
-
return "<{
|
|
32
|
+
return "<{}>".format(self.__class__.__name__)
|
|
33
33
|
|
|
34
34
|
@abstractmethod
|
|
35
35
|
async def check(self, event: Update) -> bool:
|
|
36
36
|
pass
|
|
37
37
|
|
|
38
38
|
@abstractmethod
|
|
39
|
-
async def process(self, event: Update, api:
|
|
39
|
+
async def process(self, event: Update, api: API) -> bool:
|
|
40
40
|
pass
|
|
41
41
|
|
|
42
42
|
@abstractmethod
|
|
@@ -44,6 +44,10 @@ class ABCView(ABC):
|
|
|
44
44
|
pass
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
class ABCEventRawView(ABCView, ABC, typing.Generic[Event]):
|
|
48
|
+
handlers: list[ABCHandler[Event]]
|
|
49
|
+
|
|
50
|
+
|
|
47
51
|
class ABCStateView(ABCView, typing.Generic[Event]):
|
|
48
52
|
@abstractmethod
|
|
49
53
|
def get_state_key(self, event: Event) -> int | None:
|
|
@@ -184,7 +188,7 @@ class BaseView(ABCView, typing.Generic[Event]):
|
|
|
184
188
|
case _:
|
|
185
189
|
return False
|
|
186
190
|
|
|
187
|
-
async def process(self, event: Update, api:
|
|
191
|
+
async def process(self, event: Update, api: API) -> bool:
|
|
188
192
|
return await process_inner(
|
|
189
193
|
api,
|
|
190
194
|
self.get_event_type.unwrap().from_update(
|
|
@@ -211,6 +215,7 @@ class BaseStateView(ABCStateView[Event], BaseView[Event], ABC, typing.Generic[Ev
|
|
|
211
215
|
|
|
212
216
|
__all__ = (
|
|
213
217
|
"ABCStateView",
|
|
218
|
+
"ABCEventRawView",
|
|
214
219
|
"ABCView",
|
|
215
220
|
"BaseStateView",
|
|
216
221
|
"BaseView",
|
|
@@ -10,7 +10,7 @@ from telegrinder.bot.dispatch.view import (
|
|
|
10
10
|
message,
|
|
11
11
|
raw,
|
|
12
12
|
)
|
|
13
|
-
from telegrinder.bot.dispatch.view.abc import ABCView
|
|
13
|
+
from telegrinder.bot.dispatch.view.abc import ABCEventRawView, ABCView
|
|
14
14
|
from telegrinder.types.enums import UpdateType
|
|
15
15
|
|
|
16
16
|
CallbackQueryView = typing.TypeVar(
|
|
@@ -22,7 +22,7 @@ ChatJoinRequestView = typing.TypeVar(
|
|
|
22
22
|
ChatMemberView = typing.TypeVar("ChatMemberView", bound=ABCView, default=chat_member.ChatMemberView)
|
|
23
23
|
InlineQueryView = typing.TypeVar("InlineQueryView", bound=ABCView, default=inline_query.InlineQueryView)
|
|
24
24
|
MessageView = typing.TypeVar("MessageView", bound=ABCView, default=message.MessageView)
|
|
25
|
-
RawEventView = typing.TypeVar("RawEventView", bound=
|
|
25
|
+
RawEventView = typing.TypeVar("RawEventView", bound=ABCEventRawView, default=raw.RawEventView)
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
@dataclasses.dataclass(kw_only=True)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from telegrinder.bot.cute_types import CallbackQueryCute
|
|
2
2
|
from telegrinder.bot.dispatch.return_manager import CallbackQueryReturnManager
|
|
3
|
-
|
|
4
|
-
from .abc import BaseStateView
|
|
3
|
+
from telegrinder.bot.dispatch.view.abc import BaseStateView
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class CallbackQueryView(BaseStateView[CallbackQueryCute]):
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
3
|
from telegrinder.bot.cute_types import ChatMemberUpdatedCute
|
|
4
|
+
from telegrinder.bot.dispatch.view.abc import BaseStateView
|
|
4
5
|
from telegrinder.types.enums import UpdateType
|
|
5
|
-
|
|
6
|
-
from .abc import BaseStateView
|
|
6
|
+
from telegrinder.types.objects import Update
|
|
7
7
|
|
|
8
8
|
ChatMemberUpdateType: typing.TypeAlias = typing.Literal[
|
|
9
9
|
UpdateType.CHAT_MEMBER,
|
|
@@ -19,8 +19,22 @@ class ChatMemberView(BaseStateView[ChatMemberUpdatedCute]):
|
|
|
19
19
|
self.return_manager = None
|
|
20
20
|
self.update_type = update_type
|
|
21
21
|
|
|
22
|
+
def __repr__(self) -> str:
|
|
23
|
+
return "<{}: {!r}>".format(
|
|
24
|
+
self.__class__.__name__,
|
|
25
|
+
"chat_member_updated" if self.update_type is None else self.update_type.value,
|
|
26
|
+
)
|
|
27
|
+
|
|
22
28
|
def get_state_key(self, event: ChatMemberUpdatedCute) -> int | None:
|
|
23
29
|
return event.chat_id
|
|
24
30
|
|
|
25
31
|
|
|
32
|
+
async def check(self, event: Update) -> bool:
|
|
33
|
+
return not (
|
|
34
|
+
self.update_type is not None
|
|
35
|
+
and self.update_type != event.update_type
|
|
36
|
+
or not await super().check(event)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
26
40
|
__all__ = ("ChatMemberView",)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from telegrinder.bot.cute_types import InlineQueryCute
|
|
2
2
|
from telegrinder.bot.dispatch.return_manager import InlineQueryReturnManager
|
|
3
|
-
|
|
4
|
-
from .abc import BaseStateView
|
|
3
|
+
from telegrinder.bot.dispatch.view.abc import BaseStateView
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class InlineQueryView(BaseStateView[InlineQueryCute]):
|
|
@@ -2,10 +2,9 @@ import typing
|
|
|
2
2
|
|
|
3
3
|
from telegrinder.bot.cute_types import MessageCute
|
|
4
4
|
from telegrinder.bot.dispatch.return_manager import MessageReturnManager
|
|
5
|
+
from telegrinder.bot.dispatch.view.abc import BaseStateView
|
|
5
6
|
from telegrinder.types import Update, UpdateType
|
|
6
7
|
|
|
7
|
-
from .abc import BaseStateView
|
|
8
|
-
|
|
9
8
|
MessageUpdateType: typing.TypeAlias = typing.Literal[
|
|
10
9
|
UpdateType.MESSAGE,
|
|
11
10
|
UpdateType.BUSINESS_MESSAGE,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import typing
|
|
2
2
|
|
|
3
|
-
from telegrinder.api
|
|
3
|
+
from telegrinder.api import API
|
|
4
4
|
from telegrinder.bot.cute_types import UpdateCute
|
|
5
5
|
from telegrinder.bot.dispatch.handler.func import FuncHandler
|
|
6
6
|
from telegrinder.bot.dispatch.process import process_inner
|
|
7
|
+
from telegrinder.bot.dispatch.view.abc import ABCEventRawView, BaseView, ErrorHandlerT
|
|
7
8
|
from telegrinder.bot.rules.abc import ABCRule
|
|
8
9
|
from telegrinder.tools.error_handler.error_handler import ABCErrorHandler, ErrorHandler
|
|
9
|
-
from telegrinder.types import
|
|
10
|
-
|
|
11
|
-
from .abc import BaseView, ErrorHandlerT
|
|
10
|
+
from telegrinder.types.enums import UpdateType
|
|
11
|
+
from telegrinder.types.objects import Update
|
|
12
12
|
|
|
13
13
|
T = typing.TypeVar("T")
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ FuncType: typing.TypeAlias = typing.Callable[
|
|
|
18
18
|
]
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class RawEventView(BaseView[UpdateCute]):
|
|
21
|
+
class RawEventView(ABCEventRawView[UpdateCute], BaseView[UpdateCute]):
|
|
22
22
|
def __init__(self) -> None:
|
|
23
23
|
self.auto_rules = []
|
|
24
24
|
self.handlers = []
|
|
@@ -88,7 +88,7 @@ class RawEventView(BaseView[UpdateCute]):
|
|
|
88
88
|
def wrapper(func: FuncType[typing.Any]):
|
|
89
89
|
func_handler = FuncHandler(
|
|
90
90
|
func,
|
|
91
|
-
[*self.auto_rules, *rules],
|
|
91
|
+
rules=[*self.auto_rules, *rules],
|
|
92
92
|
is_blocking=is_blocking,
|
|
93
93
|
dataclass=dataclass,
|
|
94
94
|
error_handler=error_handler or ErrorHandler(),
|
|
@@ -100,11 +100,9 @@ class RawEventView(BaseView[UpdateCute]):
|
|
|
100
100
|
return wrapper
|
|
101
101
|
|
|
102
102
|
async def check(self, event: Update) -> bool:
|
|
103
|
-
return
|
|
103
|
+
return bool(self.handlers) or bool(self.middlewares)
|
|
104
104
|
|
|
105
|
-
async def process(self, event: Update, api:
|
|
106
|
-
if not self.handlers or not self.middlewares:
|
|
107
|
-
return False
|
|
105
|
+
async def process(self, event: Update, api: API) -> bool:
|
|
108
106
|
return await process_inner(
|
|
109
107
|
api,
|
|
110
108
|
UpdateCute.from_update(event, bound_api=api),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from .machine import WaiterMachine, clear_wm_storage_worker
|
|
2
|
-
from .middleware import WaiterMiddleware
|
|
3
|
-
from .short_state import ShortState
|
|
1
|
+
from telegrinder.bot.dispatch.waiter_machine.machine import WaiterMachine, clear_wm_storage_worker
|
|
2
|
+
from telegrinder.bot.dispatch.waiter_machine.middleware import WaiterMiddleware
|
|
3
|
+
from telegrinder.bot.dispatch.waiter_machine.short_state import ShortState
|
|
4
4
|
|
|
5
5
|
__all__ = (
|
|
6
6
|
"ShortState",
|
|
@@ -2,16 +2,20 @@ import asyncio
|
|
|
2
2
|
import datetime
|
|
3
3
|
import typing
|
|
4
4
|
|
|
5
|
-
from telegrinder.api
|
|
5
|
+
from telegrinder.api import API
|
|
6
6
|
from telegrinder.bot.dispatch.context import Context
|
|
7
7
|
from telegrinder.bot.dispatch.view.abc import ABCStateView, BaseStateView
|
|
8
|
+
from telegrinder.bot.dispatch.waiter_machine.middleware import WaiterMiddleware
|
|
9
|
+
from telegrinder.bot.dispatch.waiter_machine.short_state import (
|
|
10
|
+
Behaviour,
|
|
11
|
+
EventModel,
|
|
12
|
+
ShortState,
|
|
13
|
+
ShortStateContext,
|
|
14
|
+
)
|
|
8
15
|
from telegrinder.bot.rules.abc import ABCRule
|
|
9
16
|
from telegrinder.tools.limited_dict import LimitedDict
|
|
10
17
|
from telegrinder.types import Update
|
|
11
18
|
|
|
12
|
-
from .middleware import WaiterMiddleware
|
|
13
|
-
from .short_state import Behaviour, EventModel, ShortState, ShortStateContext
|
|
14
|
-
|
|
15
19
|
if typing.TYPE_CHECKING:
|
|
16
20
|
from telegrinder.bot.dispatch import Dispatch
|
|
17
21
|
|
|
@@ -67,7 +71,7 @@ class WaiterMachine:
|
|
|
67
71
|
async def wait(
|
|
68
72
|
self,
|
|
69
73
|
state_view: "BaseStateView[EventModel]",
|
|
70
|
-
linked: EventModel | tuple[
|
|
74
|
+
linked: EventModel | tuple[API, Identificator],
|
|
71
75
|
*rules: ABCRule,
|
|
72
76
|
default: Behaviour[EventModel] | None = None,
|
|
73
77
|
on_drop: Behaviour[EventModel] | None = None,
|
|
@@ -77,7 +81,7 @@ class WaiterMachine:
|
|
|
77
81
|
if isinstance(expiration, int | float):
|
|
78
82
|
expiration = datetime.timedelta(seconds=expiration)
|
|
79
83
|
|
|
80
|
-
api:
|
|
84
|
+
api: API
|
|
81
85
|
key: Identificator
|
|
82
86
|
api, key = linked if isinstance(linked, tuple) else (linked.ctx_api, state_view.get_state_key(linked)) # type: ignore
|
|
83
87
|
if not key:
|
|
@@ -3,7 +3,7 @@ import dataclasses
|
|
|
3
3
|
import datetime
|
|
4
4
|
import typing
|
|
5
5
|
|
|
6
|
-
from telegrinder.api import
|
|
6
|
+
from telegrinder.api import API
|
|
7
7
|
from telegrinder.bot.cute_types import BaseCute
|
|
8
8
|
from telegrinder.bot.dispatch.context import Context
|
|
9
9
|
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
@@ -27,7 +27,7 @@ class ShortStateContext(typing.Generic[EventModel], typing.NamedTuple):
|
|
|
27
27
|
@dataclasses.dataclass(slots=True)
|
|
28
28
|
class ShortState(typing.Generic[EventModel]):
|
|
29
29
|
key: "Identificator"
|
|
30
|
-
ctx_api:
|
|
30
|
+
ctx_api: API
|
|
31
31
|
event: asyncio.Event
|
|
32
32
|
rules: tuple[ABCRule, ...]
|
|
33
33
|
expiration: dataclasses.InitVar[datetime.timedelta | None] = dataclasses.field(
|
telegrinder/bot/polling/abc.py
CHANGED
|
@@ -5,18 +5,18 @@ import aiohttp
|
|
|
5
5
|
import msgspec
|
|
6
6
|
from fntypes.result import Error, Ok
|
|
7
7
|
|
|
8
|
-
from telegrinder.api
|
|
8
|
+
from telegrinder.api import API
|
|
9
9
|
from telegrinder.api.error import InvalidTokenError
|
|
10
10
|
from telegrinder.bot.polling.abc import ABCPolling
|
|
11
11
|
from telegrinder.modules import logger
|
|
12
12
|
from telegrinder.msgspec_utils import decoder
|
|
13
|
-
from telegrinder.types import Update, UpdateType
|
|
13
|
+
from telegrinder.types.objects import Update, UpdateType
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Polling(ABCPolling):
|
|
17
17
|
def __init__(
|
|
18
18
|
self,
|
|
19
|
-
api:
|
|
19
|
+
api: API,
|
|
20
20
|
*,
|
|
21
21
|
offset: int = 0,
|
|
22
22
|
reconnection_timeout: float = 5,
|