telegrinder 0.3.1__py3-none-any.whl → 0.3.3__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 +144 -144
- telegrinder/api/__init__.py +8 -8
- telegrinder/api/api.py +93 -93
- telegrinder/api/error.py +16 -16
- telegrinder/api/response.py +20 -20
- telegrinder/api/token.py +36 -36
- telegrinder/bot/__init__.py +66 -66
- telegrinder/bot/bot.py +76 -76
- telegrinder/bot/cute_types/__init__.py +17 -17
- telegrinder/bot/cute_types/base.py +258 -234
- telegrinder/bot/cute_types/callback_query.py +385 -382
- telegrinder/bot/cute_types/chat_join_request.py +61 -61
- telegrinder/bot/cute_types/chat_member_updated.py +160 -160
- telegrinder/bot/cute_types/inline_query.py +43 -53
- telegrinder/bot/cute_types/message.py +2637 -2631
- telegrinder/bot/cute_types/update.py +109 -75
- telegrinder/bot/cute_types/utils.py +95 -95
- telegrinder/bot/dispatch/__init__.py +55 -55
- telegrinder/bot/dispatch/abc.py +77 -77
- telegrinder/bot/dispatch/context.py +98 -92
- telegrinder/bot/dispatch/dispatch.py +202 -201
- telegrinder/bot/dispatch/handler/__init__.py +13 -13
- telegrinder/bot/dispatch/handler/abc.py +24 -24
- telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
- telegrinder/bot/dispatch/handler/base.py +57 -57
- telegrinder/bot/dispatch/handler/document_reply.py +44 -44
- telegrinder/bot/dispatch/handler/func.py +135 -123
- telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
- telegrinder/bot/dispatch/handler/message_reply.py +36 -36
- telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
- telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
- telegrinder/bot/dispatch/handler/video_reply.py +44 -44
- telegrinder/bot/dispatch/middleware/__init__.py +3 -3
- telegrinder/bot/dispatch/middleware/abc.py +16 -16
- telegrinder/bot/dispatch/process.py +132 -132
- telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
- telegrinder/bot/dispatch/return_manager/abc.py +108 -108
- telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
- telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
- telegrinder/bot/dispatch/return_manager/message.py +36 -36
- telegrinder/bot/dispatch/view/__init__.py +13 -13
- telegrinder/bot/dispatch/view/abc.py +41 -41
- telegrinder/bot/dispatch/view/base.py +200 -211
- telegrinder/bot/dispatch/view/box.py +129 -129
- telegrinder/bot/dispatch/view/callback_query.py +17 -17
- telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
- telegrinder/bot/dispatch/view/chat_member.py +39 -39
- telegrinder/bot/dispatch/view/inline_query.py +17 -17
- telegrinder/bot/dispatch/view/message.py +44 -44
- telegrinder/bot/dispatch/view/raw.py +114 -118
- telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
- telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
- telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
- telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +55 -55
- telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
- telegrinder/bot/dispatch/waiter_machine/hasher/message.py +51 -51
- telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
- telegrinder/bot/dispatch/waiter_machine/machine.py +167 -170
- telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
- telegrinder/bot/dispatch/waiter_machine/short_state.py +68 -65
- telegrinder/bot/polling/__init__.py +4 -4
- telegrinder/bot/polling/abc.py +25 -25
- telegrinder/bot/polling/polling.py +131 -131
- telegrinder/bot/rules/__init__.py +62 -62
- telegrinder/bot/rules/abc.py +213 -238
- telegrinder/bot/rules/adapter/__init__.py +9 -9
- telegrinder/bot/rules/adapter/abc.py +29 -29
- telegrinder/bot/rules/adapter/errors.py +5 -5
- telegrinder/bot/rules/adapter/event.py +67 -76
- telegrinder/bot/rules/adapter/node.py +48 -48
- telegrinder/bot/rules/adapter/raw_update.py +30 -30
- telegrinder/bot/rules/callback_data.py +170 -171
- telegrinder/bot/rules/chat_join.py +46 -48
- telegrinder/bot/rules/command.py +126 -126
- telegrinder/bot/rules/enum_text.py +36 -36
- telegrinder/bot/rules/func.py +26 -26
- telegrinder/bot/rules/fuzzy.py +24 -24
- telegrinder/bot/rules/inline.py +60 -60
- telegrinder/bot/rules/integer.py +20 -20
- telegrinder/bot/rules/is_from.py +127 -127
- telegrinder/bot/rules/markup.py +43 -43
- telegrinder/bot/rules/mention.py +14 -14
- telegrinder/bot/rules/message.py +17 -17
- telegrinder/bot/rules/message_entities.py +35 -35
- telegrinder/bot/rules/node.py +27 -27
- telegrinder/bot/rules/regex.py +37 -37
- telegrinder/bot/rules/rule_enum.py +72 -72
- telegrinder/bot/rules/start.py +42 -42
- telegrinder/bot/rules/state.py +37 -37
- telegrinder/bot/rules/text.py +33 -33
- telegrinder/bot/rules/update.py +15 -15
- telegrinder/bot/scenario/__init__.py +5 -5
- telegrinder/bot/scenario/abc.py +19 -19
- telegrinder/bot/scenario/checkbox.py +167 -147
- telegrinder/bot/scenario/choice.py +46 -44
- telegrinder/client/__init__.py +4 -4
- telegrinder/client/abc.py +75 -75
- telegrinder/client/aiohttp.py +130 -130
- telegrinder/model.py +295 -244
- telegrinder/modules.py +237 -237
- telegrinder/msgspec_json.py +14 -14
- telegrinder/msgspec_utils.py +410 -410
- telegrinder/node/__init__.py +7 -3
- telegrinder/node/attachment.py +87 -87
- telegrinder/node/base.py +166 -144
- telegrinder/node/callback_query.py +53 -14
- telegrinder/node/command.py +33 -33
- telegrinder/node/composer.py +198 -184
- telegrinder/node/container.py +27 -27
- telegrinder/node/event.py +65 -73
- telegrinder/node/me.py +16 -16
- telegrinder/node/message.py +14 -14
- telegrinder/node/polymorphic.py +48 -52
- telegrinder/node/rule.py +76 -76
- telegrinder/node/scope.py +38 -38
- telegrinder/node/source.py +71 -71
- telegrinder/node/text.py +41 -21
- telegrinder/node/tools/__init__.py +3 -3
- telegrinder/node/tools/generator.py +40 -40
- telegrinder/node/update.py +15 -15
- telegrinder/rules.py +0 -0
- telegrinder/tools/__init__.py +74 -74
- telegrinder/tools/buttons.py +79 -79
- telegrinder/tools/error_handler/__init__.py +7 -7
- telegrinder/tools/error_handler/abc.py +33 -33
- telegrinder/tools/error_handler/error.py +9 -9
- telegrinder/tools/error_handler/error_handler.py +193 -193
- telegrinder/tools/formatting/__init__.py +46 -46
- telegrinder/tools/formatting/html.py +283 -283
- telegrinder/tools/formatting/links.py +33 -33
- telegrinder/tools/formatting/spec_html_formats.py +111 -111
- telegrinder/tools/functional.py +12 -12
- telegrinder/tools/global_context/__init__.py +7 -7
- telegrinder/tools/global_context/abc.py +63 -63
- telegrinder/tools/global_context/global_context.py +412 -412
- telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
- telegrinder/tools/i18n/__init__.py +7 -7
- telegrinder/tools/i18n/abc.py +30 -30
- telegrinder/tools/i18n/middleware/__init__.py +3 -3
- telegrinder/tools/i18n/middleware/abc.py +25 -25
- telegrinder/tools/i18n/simple.py +43 -43
- telegrinder/tools/kb_set/__init__.py +4 -4
- telegrinder/tools/kb_set/base.py +15 -15
- telegrinder/tools/kb_set/yaml.py +63 -63
- telegrinder/tools/keyboard.py +132 -132
- telegrinder/tools/limited_dict.py +37 -37
- telegrinder/tools/loop_wrapper/__init__.py +4 -4
- telegrinder/tools/loop_wrapper/abc.py +15 -15
- telegrinder/tools/loop_wrapper/loop_wrapper.py +224 -216
- telegrinder/tools/magic.py +157 -157
- telegrinder/tools/parse_mode.py +6 -6
- telegrinder/tools/state_storage/__init__.py +4 -4
- telegrinder/tools/state_storage/abc.py +35 -35
- telegrinder/tools/state_storage/memory.py +25 -25
- telegrinder/types/__init__.py +260 -260
- telegrinder/types/enums.py +701 -701
- telegrinder/types/methods.py +4633 -4633
- telegrinder/types/objects.py +8561 -6541
- telegrinder/verification_utils.py +32 -32
- {telegrinder-0.3.1.dist-info → telegrinder-0.3.3.dist-info}/LICENSE +22 -22
- {telegrinder-0.3.1.dist-info → telegrinder-0.3.3.dist-info}/METADATA +1 -1
- telegrinder-0.3.3.dist-info/RECORD +164 -0
- telegrinder-0.3.1.dist-info/RECORD +0 -164
- {telegrinder-0.3.1.dist-info → telegrinder-0.3.3.dist-info}/WHEEL +0 -0
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from fntypes.result import Error, Ok
|
|
4
|
-
|
|
5
|
-
from telegrinder.api.api import API
|
|
6
|
-
from telegrinder.bot.cute_types.update import UpdateCute
|
|
7
|
-
from telegrinder.bot.dispatch.context import Context
|
|
8
|
-
from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
|
|
9
|
-
from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
|
|
10
|
-
from telegrinder.model import Model
|
|
11
|
-
from telegrinder.modules import logger
|
|
12
|
-
from telegrinder.node.composer import CONTEXT_STORE_NODES_KEY, NodeScope, compose_nodes
|
|
13
|
-
from telegrinder.tools.i18n.abc import I18nEnum
|
|
14
|
-
from telegrinder.types.objects import Update
|
|
15
|
-
|
|
16
|
-
if typing.TYPE_CHECKING:
|
|
17
|
-
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
18
|
-
from telegrinder.bot.rules.abc import ABCRule
|
|
19
|
-
|
|
20
|
-
Event = typing.TypeVar("Event", bound=Model)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
async def process_inner(
|
|
24
|
-
api: API,
|
|
25
|
-
event: Event,
|
|
26
|
-
raw_event: Update,
|
|
27
|
-
middlewares: list[ABCMiddleware[Event]],
|
|
28
|
-
handlers: list["ABCHandler[Event]"],
|
|
29
|
-
return_manager: ABCReturnManager[Event] | None = None,
|
|
30
|
-
) -> bool:
|
|
31
|
-
logger.debug("Processing {!r}...", event.__class__.__name__)
|
|
32
|
-
ctx = Context(raw_update=raw_event)
|
|
33
|
-
ctx[CONTEXT_STORE_NODES_KEY] = {} # For per-event shared nodes
|
|
34
|
-
|
|
35
|
-
logger.debug("Run pre middlewares...")
|
|
36
|
-
for middleware in middlewares:
|
|
37
|
-
middleware_result = await middleware.pre(event, ctx)
|
|
38
|
-
logger.debug("Middleware {!r} returned: {!r}", middleware.__class__.__qualname__, middleware_result)
|
|
39
|
-
if middleware_result is False:
|
|
40
|
-
return False
|
|
41
|
-
|
|
42
|
-
found = False
|
|
43
|
-
responses = []
|
|
44
|
-
ctx_copy = ctx.copy()
|
|
45
|
-
|
|
46
|
-
for handler in handlers:
|
|
47
|
-
if await handler.check(api, raw_event, ctx):
|
|
48
|
-
logger.debug("Handler {!r} matched, run...", handler)
|
|
49
|
-
found = True
|
|
50
|
-
response = await handler.run(api, event, ctx)
|
|
51
|
-
logger.debug("Handler {!r} returned: {!r}", handler, response)
|
|
52
|
-
responses.append(response)
|
|
53
|
-
if return_manager is not None:
|
|
54
|
-
await return_manager.run(response, event, ctx)
|
|
55
|
-
if handler.is_blocking:
|
|
56
|
-
break
|
|
57
|
-
|
|
58
|
-
ctx = ctx_copy
|
|
59
|
-
|
|
60
|
-
logger.debug("Run post middlewares...")
|
|
61
|
-
for middleware in middlewares:
|
|
62
|
-
logger.debug("Run post middleware {!r}", middleware.__class__.__qualname__)
|
|
63
|
-
await middleware.post(event, responses, ctx)
|
|
64
|
-
|
|
65
|
-
for session in ctx.get(CONTEXT_STORE_NODES_KEY, {}).values():
|
|
66
|
-
await session.close(scopes=(NodeScope.PER_EVENT,))
|
|
67
|
-
|
|
68
|
-
logger.debug(
|
|
69
|
-
"{} handlers, returns {!r}",
|
|
70
|
-
"No found" if not found else "Found",
|
|
71
|
-
found,
|
|
72
|
-
)
|
|
73
|
-
return found
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
async def check_rule(
|
|
77
|
-
api: API,
|
|
78
|
-
rule: "ABCRule",
|
|
79
|
-
update: Update,
|
|
80
|
-
ctx: Context,
|
|
81
|
-
) -> bool:
|
|
82
|
-
"""Checks requirements, adapts update.
|
|
83
|
-
Returns check result."""
|
|
84
|
-
|
|
85
|
-
# Running adapter
|
|
86
|
-
match await rule.adapter.adapt(api, update, ctx):
|
|
87
|
-
case Ok(value):
|
|
88
|
-
adapted_value = value
|
|
89
|
-
case Error(err):
|
|
90
|
-
logger.debug("Adapter failed with error message: {!r}", str(err))
|
|
91
|
-
return False
|
|
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
|
-
|
|
101
|
-
# Running subrules to fetch requirements
|
|
102
|
-
ctx_copy = ctx.copy()
|
|
103
|
-
for requirement in rule.requires:
|
|
104
|
-
if not await check_rule(api, requirement, update, ctx_copy):
|
|
105
|
-
return False
|
|
106
|
-
|
|
107
|
-
# Translating translatable rules
|
|
108
|
-
if I18nEnum.I18N in ctx:
|
|
109
|
-
rule = await rule.translate(ctx[I18nEnum.I18N])
|
|
110
|
-
|
|
111
|
-
ctx |= ctx_copy
|
|
112
|
-
|
|
113
|
-
# Composing required nodes
|
|
114
|
-
nodes = rule.required_nodes
|
|
115
|
-
node_col = None
|
|
116
|
-
if nodes:
|
|
117
|
-
result = await compose_nodes(nodes, ctx, data={Update: update, API: api})
|
|
118
|
-
if not result:
|
|
119
|
-
return False
|
|
120
|
-
node_col = result.value
|
|
121
|
-
|
|
122
|
-
# Running check
|
|
123
|
-
result = await rule.bounding_check(adapted_value, ctx, node_col=node_col)
|
|
124
|
-
|
|
125
|
-
# Closing node sessions if there are any
|
|
126
|
-
if node_col is not None:
|
|
127
|
-
await node_col.close_all()
|
|
128
|
-
|
|
129
|
-
return result
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
__all__ = ("check_rule", "process_inner")
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from fntypes.result import Error, Ok
|
|
4
|
+
|
|
5
|
+
from telegrinder.api.api import API
|
|
6
|
+
from telegrinder.bot.cute_types.update import UpdateCute
|
|
7
|
+
from telegrinder.bot.dispatch.context import Context
|
|
8
|
+
from telegrinder.bot.dispatch.middleware.abc import ABCMiddleware
|
|
9
|
+
from telegrinder.bot.dispatch.return_manager.abc import ABCReturnManager
|
|
10
|
+
from telegrinder.model import Model
|
|
11
|
+
from telegrinder.modules import logger
|
|
12
|
+
from telegrinder.node.composer import CONTEXT_STORE_NODES_KEY, NodeScope, compose_nodes
|
|
13
|
+
from telegrinder.tools.i18n.abc import I18nEnum
|
|
14
|
+
from telegrinder.types.objects import Update
|
|
15
|
+
|
|
16
|
+
if typing.TYPE_CHECKING:
|
|
17
|
+
from telegrinder.bot.dispatch.handler.abc import ABCHandler
|
|
18
|
+
from telegrinder.bot.rules.abc import ABCRule
|
|
19
|
+
|
|
20
|
+
Event = typing.TypeVar("Event", bound=Model)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def process_inner(
|
|
24
|
+
api: API,
|
|
25
|
+
event: Event,
|
|
26
|
+
raw_event: Update,
|
|
27
|
+
middlewares: list[ABCMiddleware[Event]],
|
|
28
|
+
handlers: list["ABCHandler[Event]"],
|
|
29
|
+
return_manager: ABCReturnManager[Event] | None = None,
|
|
30
|
+
) -> bool:
|
|
31
|
+
logger.debug("Processing {!r}...", event.__class__.__name__)
|
|
32
|
+
ctx = Context(raw_update=raw_event)
|
|
33
|
+
ctx[CONTEXT_STORE_NODES_KEY] = {} # For per-event shared nodes
|
|
34
|
+
|
|
35
|
+
logger.debug("Run pre middlewares...")
|
|
36
|
+
for middleware in middlewares:
|
|
37
|
+
middleware_result = await middleware.pre(event, ctx)
|
|
38
|
+
logger.debug("Middleware {!r} returned: {!r}", middleware.__class__.__qualname__, middleware_result)
|
|
39
|
+
if middleware_result is False:
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
found = False
|
|
43
|
+
responses = []
|
|
44
|
+
ctx_copy = ctx.copy()
|
|
45
|
+
|
|
46
|
+
for handler in handlers:
|
|
47
|
+
if await handler.check(api, raw_event, ctx):
|
|
48
|
+
logger.debug("Handler {!r} matched, run...", handler)
|
|
49
|
+
found = True
|
|
50
|
+
response = await handler.run(api, event, ctx)
|
|
51
|
+
logger.debug("Handler {!r} returned: {!r}", handler, response)
|
|
52
|
+
responses.append(response)
|
|
53
|
+
if return_manager is not None:
|
|
54
|
+
await return_manager.run(response, event, ctx)
|
|
55
|
+
if handler.is_blocking:
|
|
56
|
+
break
|
|
57
|
+
|
|
58
|
+
ctx = ctx_copy
|
|
59
|
+
|
|
60
|
+
logger.debug("Run post middlewares...")
|
|
61
|
+
for middleware in middlewares:
|
|
62
|
+
logger.debug("Run post middleware {!r}", middleware.__class__.__qualname__)
|
|
63
|
+
await middleware.post(event, responses, ctx)
|
|
64
|
+
|
|
65
|
+
for session in ctx.get(CONTEXT_STORE_NODES_KEY, {}).values():
|
|
66
|
+
await session.close(scopes=(NodeScope.PER_EVENT,))
|
|
67
|
+
|
|
68
|
+
logger.debug(
|
|
69
|
+
"{} handlers, returns {!r}",
|
|
70
|
+
"No found" if not found else "Found",
|
|
71
|
+
found,
|
|
72
|
+
)
|
|
73
|
+
return found
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
async def check_rule(
|
|
77
|
+
api: API,
|
|
78
|
+
rule: "ABCRule",
|
|
79
|
+
update: Update,
|
|
80
|
+
ctx: Context,
|
|
81
|
+
) -> bool:
|
|
82
|
+
"""Checks requirements, adapts update.
|
|
83
|
+
Returns check result."""
|
|
84
|
+
|
|
85
|
+
# Running adapter
|
|
86
|
+
match await rule.adapter.adapt(api, update, ctx):
|
|
87
|
+
case Ok(value):
|
|
88
|
+
adapted_value = value
|
|
89
|
+
case Error(err):
|
|
90
|
+
logger.debug("Adapter failed with error message: {!r}", str(err))
|
|
91
|
+
return False
|
|
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
|
+
|
|
101
|
+
# Running subrules to fetch requirements
|
|
102
|
+
ctx_copy = ctx.copy()
|
|
103
|
+
for requirement in rule.requires:
|
|
104
|
+
if not await check_rule(api, requirement, update, ctx_copy):
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
# Translating translatable rules
|
|
108
|
+
if I18nEnum.I18N in ctx:
|
|
109
|
+
rule = await rule.translate(ctx[I18nEnum.I18N])
|
|
110
|
+
|
|
111
|
+
ctx |= ctx_copy
|
|
112
|
+
|
|
113
|
+
# Composing required nodes
|
|
114
|
+
nodes = rule.required_nodes
|
|
115
|
+
node_col = None
|
|
116
|
+
if nodes:
|
|
117
|
+
result = await compose_nodes(nodes, ctx, data={Update: update, API: api})
|
|
118
|
+
if not result:
|
|
119
|
+
return False
|
|
120
|
+
node_col = result.value
|
|
121
|
+
|
|
122
|
+
# Running check
|
|
123
|
+
result = await rule.bounding_check(adapted_value, ctx, node_col=node_col)
|
|
124
|
+
|
|
125
|
+
# Closing node sessions if there are any
|
|
126
|
+
if node_col is not None:
|
|
127
|
+
await node_col.close_all()
|
|
128
|
+
|
|
129
|
+
return result
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
__all__ = ("check_rule", "process_inner")
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
from telegrinder.bot.dispatch.return_manager.abc import (
|
|
2
|
-
ABCReturnManager,
|
|
3
|
-
BaseReturnManager,
|
|
4
|
-
Manager,
|
|
5
|
-
register_manager,
|
|
6
|
-
)
|
|
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
|
-
|
|
11
|
-
__all__ = (
|
|
1
|
+
from telegrinder.bot.dispatch.return_manager.abc import (
|
|
2
|
+
ABCReturnManager,
|
|
3
|
+
BaseReturnManager,
|
|
4
|
+
Manager,
|
|
5
|
+
register_manager,
|
|
6
|
+
)
|
|
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
|
+
|
|
11
|
+
__all__ = (
|
|
12
12
|
"ABCReturnManager",
|
|
13
13
|
"BaseReturnManager",
|
|
14
14
|
"CallbackQueryReturnManager",
|
|
15
15
|
"InlineQueryReturnManager",
|
|
16
16
|
"Manager",
|
|
17
17
|
"MessageReturnManager",
|
|
18
|
-
"register_manager",
|
|
19
|
-
)
|
|
18
|
+
"register_manager",
|
|
19
|
+
)
|
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
import dataclasses
|
|
2
|
-
import types
|
|
3
|
-
import typing
|
|
4
|
-
from abc import ABC, abstractmethod
|
|
5
|
-
|
|
6
|
-
from telegrinder.bot.dispatch.context import Context
|
|
7
|
-
from telegrinder.model import Model
|
|
8
|
-
from telegrinder.modules import logger
|
|
9
|
-
|
|
10
|
-
T = typing.TypeVar("T")
|
|
11
|
-
Event = typing.TypeVar("Event", bound=Model, contravariant=True)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def get_union_types(t: types.UnionType) -> tuple[type, ...] | None:
|
|
15
|
-
if type(t) in (types.UnionType, typing._UnionGenericAlias): # type: ignore
|
|
16
|
-
return tuple(typing.get_origin(x) or x for x in typing.get_args(t))
|
|
17
|
-
return None
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def register_manager(return_type: type[typing.Any] | types.UnionType):
|
|
21
|
-
def wrapper(func: typing.Callable[..., typing.Awaitable[typing.Any]]):
|
|
22
|
-
return Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
|
|
23
|
-
|
|
24
|
-
return wrapper
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclasses.dataclass(frozen=True, slots=True)
|
|
28
|
-
class Manager:
|
|
29
|
-
types: tuple[type, ...]
|
|
30
|
-
callback: typing.Callable[..., typing.Awaitable[typing.Any]]
|
|
31
|
-
|
|
32
|
-
async def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> None:
|
|
33
|
-
await self.callback(*args, **kwargs)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class ABCReturnManager(ABC, typing.Generic[Event]):
|
|
37
|
-
@abstractmethod
|
|
38
|
-
async def run(self, response: typing.Any, event: Event, ctx: Context) -> None:
|
|
39
|
-
pass
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class BaseReturnManager(ABCReturnManager[Event]):
|
|
43
|
-
def __repr__(self) -> str:
|
|
44
|
-
return "<{}: {}>".format(
|
|
45
|
-
self.__class__.__name__,
|
|
46
|
-
", ".join(x.callback.__name__ + "=" + repr(x) for x in self.managers),
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def managers(self) -> list[Manager]:
|
|
51
|
-
managers = self.__dict__.get("managers")
|
|
52
|
-
if managers is not None:
|
|
53
|
-
return managers
|
|
54
|
-
managers_lst = [
|
|
55
|
-
manager
|
|
56
|
-
for manager in (vars(BaseReturnManager) | vars(self.__class__)).values()
|
|
57
|
-
if isinstance(manager, Manager)
|
|
58
|
-
]
|
|
59
|
-
self.__dict__["managers"] = managers_lst
|
|
60
|
-
return managers_lst
|
|
61
|
-
|
|
62
|
-
@register_manager(Context)
|
|
63
|
-
@staticmethod
|
|
64
|
-
async def ctx_manager(value: Context, event: Event, ctx: Context) -> None:
|
|
65
|
-
"""Basic manager for returning context from handler."""
|
|
66
|
-
|
|
67
|
-
ctx.update(value)
|
|
68
|
-
|
|
69
|
-
async def run(self, response: typing.Any, event: Event, ctx: Context) -> None:
|
|
70
|
-
logger.debug("Run return manager for response: {!r}", response)
|
|
71
|
-
for manager in self.managers:
|
|
72
|
-
if typing.Any in manager.types or any(type(response) is x for x in manager.types):
|
|
73
|
-
logger.debug("Run manager {!r}...", manager.callback.__name__)
|
|
74
|
-
await manager(response, event, ctx)
|
|
75
|
-
|
|
76
|
-
@typing.overload
|
|
77
|
-
def register_manager(
|
|
78
|
-
self,
|
|
79
|
-
return_type: type[T],
|
|
80
|
-
) -> typing.Callable[[typing.Callable[[T, Event, Context], typing.Awaitable[typing.Any]]], Manager]: ...
|
|
81
|
-
|
|
82
|
-
@typing.overload
|
|
83
|
-
def register_manager(
|
|
84
|
-
self,
|
|
85
|
-
return_type: tuple[type[T], ...],
|
|
86
|
-
) -> typing.Callable[
|
|
87
|
-
[typing.Callable[[tuple[T, ...], Event, Context], typing.Awaitable[typing.Any]]],
|
|
88
|
-
Manager,
|
|
89
|
-
]: ...
|
|
90
|
-
|
|
91
|
-
def register_manager(
|
|
92
|
-
self,
|
|
93
|
-
return_type: type[T] | tuple[type[T], ...],
|
|
94
|
-
) -> typing.Callable[
|
|
95
|
-
[typing.Callable[[T | tuple[T, ...], Event, Context], typing.Awaitable[typing.Any]]],
|
|
96
|
-
Manager,
|
|
97
|
-
]:
|
|
98
|
-
def wrapper(func: typing.Callable[[T, Event, Context], typing.Awaitable]) -> Manager:
|
|
99
|
-
manager = Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
|
|
100
|
-
self.managers.append(manager)
|
|
101
|
-
return manager
|
|
102
|
-
|
|
103
|
-
return wrapper
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
__all__ = (
|
|
1
|
+
import dataclasses
|
|
2
|
+
import types
|
|
3
|
+
import typing
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
|
|
6
|
+
from telegrinder.bot.dispatch.context import Context
|
|
7
|
+
from telegrinder.model import Model
|
|
8
|
+
from telegrinder.modules import logger
|
|
9
|
+
|
|
10
|
+
T = typing.TypeVar("T")
|
|
11
|
+
Event = typing.TypeVar("Event", bound=Model, contravariant=True)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_union_types(t: types.UnionType) -> tuple[type, ...] | None:
|
|
15
|
+
if type(t) in (types.UnionType, typing._UnionGenericAlias): # type: ignore
|
|
16
|
+
return tuple(typing.get_origin(x) or x for x in typing.get_args(t))
|
|
17
|
+
return None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def register_manager(return_type: type[typing.Any] | types.UnionType):
|
|
21
|
+
def wrapper(func: typing.Callable[..., typing.Awaitable[typing.Any]]):
|
|
22
|
+
return Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
|
|
23
|
+
|
|
24
|
+
return wrapper
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclasses.dataclass(frozen=True, slots=True)
|
|
28
|
+
class Manager:
|
|
29
|
+
types: tuple[type, ...]
|
|
30
|
+
callback: typing.Callable[..., typing.Awaitable[typing.Any]]
|
|
31
|
+
|
|
32
|
+
async def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> None:
|
|
33
|
+
await self.callback(*args, **kwargs)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ABCReturnManager(ABC, typing.Generic[Event]):
|
|
37
|
+
@abstractmethod
|
|
38
|
+
async def run(self, response: typing.Any, event: Event, ctx: Context) -> None:
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class BaseReturnManager(ABCReturnManager[Event]):
|
|
43
|
+
def __repr__(self) -> str:
|
|
44
|
+
return "<{}: {}>".format(
|
|
45
|
+
self.__class__.__name__,
|
|
46
|
+
", ".join(x.callback.__name__ + "=" + repr(x) for x in self.managers),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def managers(self) -> list[Manager]:
|
|
51
|
+
managers = self.__dict__.get("managers")
|
|
52
|
+
if managers is not None:
|
|
53
|
+
return managers
|
|
54
|
+
managers_lst = [
|
|
55
|
+
manager
|
|
56
|
+
for manager in (vars(BaseReturnManager) | vars(self.__class__)).values()
|
|
57
|
+
if isinstance(manager, Manager)
|
|
58
|
+
]
|
|
59
|
+
self.__dict__["managers"] = managers_lst
|
|
60
|
+
return managers_lst
|
|
61
|
+
|
|
62
|
+
@register_manager(Context)
|
|
63
|
+
@staticmethod
|
|
64
|
+
async def ctx_manager(value: Context, event: Event, ctx: Context) -> None:
|
|
65
|
+
"""Basic manager for returning context from handler."""
|
|
66
|
+
|
|
67
|
+
ctx.update(value)
|
|
68
|
+
|
|
69
|
+
async def run(self, response: typing.Any, event: Event, ctx: Context) -> None:
|
|
70
|
+
logger.debug("Run return manager for response: {!r}", response)
|
|
71
|
+
for manager in self.managers:
|
|
72
|
+
if typing.Any in manager.types or any(type(response) is x for x in manager.types):
|
|
73
|
+
logger.debug("Run manager {!r}...", manager.callback.__name__)
|
|
74
|
+
await manager(response, event, ctx)
|
|
75
|
+
|
|
76
|
+
@typing.overload
|
|
77
|
+
def register_manager(
|
|
78
|
+
self,
|
|
79
|
+
return_type: type[T],
|
|
80
|
+
) -> typing.Callable[[typing.Callable[[T, Event, Context], typing.Awaitable[typing.Any]]], Manager]: ...
|
|
81
|
+
|
|
82
|
+
@typing.overload
|
|
83
|
+
def register_manager(
|
|
84
|
+
self,
|
|
85
|
+
return_type: tuple[type[T], ...],
|
|
86
|
+
) -> typing.Callable[
|
|
87
|
+
[typing.Callable[[tuple[T, ...], Event, Context], typing.Awaitable[typing.Any]]],
|
|
88
|
+
Manager,
|
|
89
|
+
]: ...
|
|
90
|
+
|
|
91
|
+
def register_manager(
|
|
92
|
+
self,
|
|
93
|
+
return_type: type[T] | tuple[type[T], ...],
|
|
94
|
+
) -> typing.Callable[
|
|
95
|
+
[typing.Callable[[T | tuple[T, ...], Event, Context], typing.Awaitable[typing.Any]]],
|
|
96
|
+
Manager,
|
|
97
|
+
]:
|
|
98
|
+
def wrapper(func: typing.Callable[[T, Event, Context], typing.Awaitable]) -> Manager:
|
|
99
|
+
manager = Manager(get_union_types(return_type) or (return_type,), func) # type: ignore
|
|
100
|
+
self.managers.append(manager)
|
|
101
|
+
return manager
|
|
102
|
+
|
|
103
|
+
return wrapper
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
__all__ = (
|
|
107
107
|
"ABCReturnManager",
|
|
108
108
|
"BaseReturnManager",
|
|
109
109
|
"Manager",
|
|
110
110
|
"get_union_types",
|
|
111
|
-
"register_manager",
|
|
112
|
-
)
|
|
111
|
+
"register_manager",
|
|
112
|
+
)
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
|
|
4
|
-
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
|
|
9
|
-
@register_manager(str)
|
|
10
|
-
@staticmethod
|
|
11
|
-
async def str_manager(value: str, event: CallbackQueryCute, ctx: Context) -> None:
|
|
12
|
-
await event.answer(value)
|
|
13
|
-
|
|
14
|
-
@register_manager(dict[str, typing.Any])
|
|
15
|
-
@staticmethod
|
|
16
|
-
async def dict_manager(value: dict[str, typing.Any], event: CallbackQueryCute, ctx: Context) -> None:
|
|
17
|
-
await event.answer(**value)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
__all__ = ("CallbackQueryReturnManager",)
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.bot.cute_types.callback_query import CallbackQueryCute
|
|
4
|
+
from telegrinder.bot.dispatch.context import Context
|
|
5
|
+
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CallbackQueryReturnManager(BaseReturnManager[CallbackQueryCute]):
|
|
9
|
+
@register_manager(str)
|
|
10
|
+
@staticmethod
|
|
11
|
+
async def str_manager(value: str, event: CallbackQueryCute, ctx: Context) -> None:
|
|
12
|
+
await event.answer(value)
|
|
13
|
+
|
|
14
|
+
@register_manager(dict[str, typing.Any])
|
|
15
|
+
@staticmethod
|
|
16
|
+
async def dict_manager(value: dict[str, typing.Any], event: CallbackQueryCute, ctx: Context) -> None:
|
|
17
|
+
await event.answer(**value)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = ("CallbackQueryReturnManager",)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from telegrinder.bot.cute_types.inline_query import InlineQueryCute
|
|
4
|
-
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
|
|
9
|
-
@register_manager(dict[str, typing.Any])
|
|
10
|
-
@staticmethod
|
|
11
|
-
async def dict_manager(value: dict[str, typing.Any], event: InlineQueryCute, ctx: Context) -> None:
|
|
12
|
-
await event.answer(**value)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
__all__ = ("InlineQueryReturnManager",)
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.bot.cute_types.inline_query import InlineQueryCute
|
|
4
|
+
from telegrinder.bot.dispatch.context import Context
|
|
5
|
+
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class InlineQueryReturnManager(BaseReturnManager[InlineQueryCute]):
|
|
9
|
+
@register_manager(dict[str, typing.Any])
|
|
10
|
+
@staticmethod
|
|
11
|
+
async def dict_manager(value: dict[str, typing.Any], event: InlineQueryCute, ctx: Context) -> None:
|
|
12
|
+
await event.answer(**value)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
__all__ = ("InlineQueryReturnManager",)
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
|
-
from telegrinder.bot.cute_types.message import MessageCute
|
|
4
|
-
from telegrinder.bot.dispatch.context import Context
|
|
5
|
-
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
6
|
-
from telegrinder.tools.formatting import HTMLFormatter
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class MessageReturnManager(BaseReturnManager[MessageCute]):
|
|
10
|
-
@register_manager(str)
|
|
11
|
-
@staticmethod
|
|
12
|
-
async def str_manager(value: str, event: MessageCute, ctx: Context) -> None:
|
|
13
|
-
await event.answer(value)
|
|
14
|
-
|
|
15
|
-
@register_manager(list[str] | tuple[str, ...])
|
|
16
|
-
@staticmethod
|
|
17
|
-
async def seq_manager(
|
|
18
|
-
value: list[str] | tuple[str, ...],
|
|
19
|
-
event: MessageCute,
|
|
20
|
-
ctx: Context,
|
|
21
|
-
) -> None:
|
|
22
|
-
for message in value:
|
|
23
|
-
await event.answer(message)
|
|
24
|
-
|
|
25
|
-
@register_manager(dict[str, typing.Any])
|
|
26
|
-
@staticmethod
|
|
27
|
-
async def dict_manager(value: dict[str, typing.Any], event: MessageCute, ctx: Context) -> None:
|
|
28
|
-
await event.answer(**value)
|
|
29
|
-
|
|
30
|
-
@register_manager(HTMLFormatter)
|
|
31
|
-
@staticmethod
|
|
32
|
-
async def htmlformatter_manager(value: HTMLFormatter, event: MessageCute, ctx: Context) -> None:
|
|
33
|
-
await event.answer(value, parse_mode=HTMLFormatter.PARSE_MODE)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
__all__ = ("MessageReturnManager",)
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from telegrinder.bot.cute_types.message import MessageCute
|
|
4
|
+
from telegrinder.bot.dispatch.context import Context
|
|
5
|
+
from telegrinder.bot.dispatch.return_manager.abc import BaseReturnManager, register_manager
|
|
6
|
+
from telegrinder.tools.formatting import HTMLFormatter
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class MessageReturnManager(BaseReturnManager[MessageCute]):
|
|
10
|
+
@register_manager(str)
|
|
11
|
+
@staticmethod
|
|
12
|
+
async def str_manager(value: str, event: MessageCute, ctx: Context) -> None:
|
|
13
|
+
await event.answer(value)
|
|
14
|
+
|
|
15
|
+
@register_manager(list[str] | tuple[str, ...])
|
|
16
|
+
@staticmethod
|
|
17
|
+
async def seq_manager(
|
|
18
|
+
value: list[str] | tuple[str, ...],
|
|
19
|
+
event: MessageCute,
|
|
20
|
+
ctx: Context,
|
|
21
|
+
) -> None:
|
|
22
|
+
for message in value:
|
|
23
|
+
await event.answer(message)
|
|
24
|
+
|
|
25
|
+
@register_manager(dict[str, typing.Any])
|
|
26
|
+
@staticmethod
|
|
27
|
+
async def dict_manager(value: dict[str, typing.Any], event: MessageCute, ctx: Context) -> None:
|
|
28
|
+
await event.answer(**value)
|
|
29
|
+
|
|
30
|
+
@register_manager(HTMLFormatter)
|
|
31
|
+
@staticmethod
|
|
32
|
+
async def htmlformatter_manager(value: HTMLFormatter, event: MessageCute, ctx: Context) -> None:
|
|
33
|
+
await event.answer(value, parse_mode=HTMLFormatter.PARSE_MODE)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
__all__ = ("MessageReturnManager",)
|