telegrinder 0.3.0.post2__py3-none-any.whl → 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of telegrinder might be problematic. Click here for more details.

Files changed (164) hide show
  1. telegrinder/__init__.py +144 -144
  2. telegrinder/api/__init__.py +8 -8
  3. telegrinder/api/api.py +93 -93
  4. telegrinder/api/error.py +16 -16
  5. telegrinder/api/response.py +20 -20
  6. telegrinder/api/token.py +36 -36
  7. telegrinder/bot/__init__.py +66 -66
  8. telegrinder/bot/bot.py +76 -76
  9. telegrinder/bot/cute_types/__init__.py +11 -11
  10. telegrinder/bot/cute_types/base.py +258 -234
  11. telegrinder/bot/cute_types/callback_query.py +382 -382
  12. telegrinder/bot/cute_types/chat_join_request.py +61 -61
  13. telegrinder/bot/cute_types/chat_member_updated.py +160 -160
  14. telegrinder/bot/cute_types/inline_query.py +53 -53
  15. telegrinder/bot/cute_types/message.py +2631 -2631
  16. telegrinder/bot/cute_types/update.py +75 -75
  17. telegrinder/bot/cute_types/utils.py +92 -92
  18. telegrinder/bot/dispatch/__init__.py +55 -55
  19. telegrinder/bot/dispatch/abc.py +77 -77
  20. telegrinder/bot/dispatch/context.py +92 -92
  21. telegrinder/bot/dispatch/dispatch.py +202 -201
  22. telegrinder/bot/dispatch/handler/__init__.py +13 -13
  23. telegrinder/bot/dispatch/handler/abc.py +24 -24
  24. telegrinder/bot/dispatch/handler/audio_reply.py +44 -44
  25. telegrinder/bot/dispatch/handler/base.py +57 -57
  26. telegrinder/bot/dispatch/handler/document_reply.py +44 -44
  27. telegrinder/bot/dispatch/handler/func.py +128 -123
  28. telegrinder/bot/dispatch/handler/media_group_reply.py +43 -43
  29. telegrinder/bot/dispatch/handler/message_reply.py +36 -36
  30. telegrinder/bot/dispatch/handler/photo_reply.py +44 -44
  31. telegrinder/bot/dispatch/handler/sticker_reply.py +37 -37
  32. telegrinder/bot/dispatch/handler/video_reply.py +44 -44
  33. telegrinder/bot/dispatch/middleware/__init__.py +3 -3
  34. telegrinder/bot/dispatch/middleware/abc.py +16 -16
  35. telegrinder/bot/dispatch/process.py +132 -132
  36. telegrinder/bot/dispatch/return_manager/__init__.py +13 -13
  37. telegrinder/bot/dispatch/return_manager/abc.py +108 -108
  38. telegrinder/bot/dispatch/return_manager/callback_query.py +20 -20
  39. telegrinder/bot/dispatch/return_manager/inline_query.py +15 -15
  40. telegrinder/bot/dispatch/return_manager/message.py +36 -36
  41. telegrinder/bot/dispatch/view/__init__.py +13 -13
  42. telegrinder/bot/dispatch/view/abc.py +41 -41
  43. telegrinder/bot/dispatch/view/base.py +200 -211
  44. telegrinder/bot/dispatch/view/box.py +129 -129
  45. telegrinder/bot/dispatch/view/callback_query.py +17 -17
  46. telegrinder/bot/dispatch/view/chat_join_request.py +16 -16
  47. telegrinder/bot/dispatch/view/chat_member.py +39 -39
  48. telegrinder/bot/dispatch/view/inline_query.py +17 -17
  49. telegrinder/bot/dispatch/view/message.py +44 -44
  50. telegrinder/bot/dispatch/view/raw.py +114 -118
  51. telegrinder/bot/dispatch/waiter_machine/__init__.py +17 -17
  52. telegrinder/bot/dispatch/waiter_machine/actions.py +13 -13
  53. telegrinder/bot/dispatch/waiter_machine/hasher/__init__.py +8 -8
  54. telegrinder/bot/dispatch/waiter_machine/hasher/callback.py +57 -57
  55. telegrinder/bot/dispatch/waiter_machine/hasher/hasher.py +57 -57
  56. telegrinder/bot/dispatch/waiter_machine/hasher/message.py +53 -53
  57. telegrinder/bot/dispatch/waiter_machine/hasher/state.py +19 -19
  58. telegrinder/bot/dispatch/waiter_machine/machine.py +168 -170
  59. telegrinder/bot/dispatch/waiter_machine/middleware.py +89 -89
  60. telegrinder/bot/dispatch/waiter_machine/short_state.py +65 -65
  61. telegrinder/bot/polling/__init__.py +4 -4
  62. telegrinder/bot/polling/abc.py +25 -25
  63. telegrinder/bot/polling/polling.py +131 -131
  64. telegrinder/bot/rules/__init__.py +62 -62
  65. telegrinder/bot/rules/abc.py +238 -233
  66. telegrinder/bot/rules/adapter/__init__.py +9 -9
  67. telegrinder/bot/rules/adapter/abc.py +29 -29
  68. telegrinder/bot/rules/adapter/errors.py +5 -5
  69. telegrinder/bot/rules/adapter/event.py +76 -76
  70. telegrinder/bot/rules/adapter/node.py +48 -48
  71. telegrinder/bot/rules/adapter/raw_update.py +30 -30
  72. telegrinder/bot/rules/callback_data.py +171 -171
  73. telegrinder/bot/rules/chat_join.py +48 -48
  74. telegrinder/bot/rules/command.py +126 -126
  75. telegrinder/bot/rules/enum_text.py +36 -33
  76. telegrinder/bot/rules/func.py +26 -26
  77. telegrinder/bot/rules/fuzzy.py +24 -24
  78. telegrinder/bot/rules/inline.py +60 -60
  79. telegrinder/bot/rules/integer.py +20 -20
  80. telegrinder/bot/rules/is_from.py +146 -146
  81. telegrinder/bot/rules/markup.py +43 -43
  82. telegrinder/bot/rules/mention.py +14 -14
  83. telegrinder/bot/rules/message.py +17 -17
  84. telegrinder/bot/rules/message_entities.py +35 -35
  85. telegrinder/bot/rules/node.py +27 -27
  86. telegrinder/bot/rules/regex.py +37 -37
  87. telegrinder/bot/rules/rule_enum.py +72 -72
  88. telegrinder/bot/rules/start.py +42 -42
  89. telegrinder/bot/rules/state.py +37 -37
  90. telegrinder/bot/rules/text.py +33 -33
  91. telegrinder/bot/rules/update.py +15 -15
  92. telegrinder/bot/scenario/__init__.py +5 -5
  93. telegrinder/bot/scenario/abc.py +19 -19
  94. telegrinder/bot/scenario/checkbox.py +167 -139
  95. telegrinder/bot/scenario/choice.py +46 -44
  96. telegrinder/client/__init__.py +4 -4
  97. telegrinder/client/abc.py +75 -75
  98. telegrinder/client/aiohttp.py +130 -130
  99. telegrinder/model.py +244 -244
  100. telegrinder/modules.py +237 -237
  101. telegrinder/msgspec_json.py +14 -14
  102. telegrinder/msgspec_utils.py +410 -410
  103. telegrinder/node/__init__.py +20 -20
  104. telegrinder/node/attachment.py +92 -92
  105. telegrinder/node/base.py +143 -144
  106. telegrinder/node/callback_query.py +14 -14
  107. telegrinder/node/command.py +33 -33
  108. telegrinder/node/composer.py +196 -184
  109. telegrinder/node/container.py +27 -27
  110. telegrinder/node/event.py +71 -73
  111. telegrinder/node/me.py +16 -16
  112. telegrinder/node/message.py +14 -14
  113. telegrinder/node/polymorphic.py +48 -52
  114. telegrinder/node/rule.py +76 -76
  115. telegrinder/node/scope.py +38 -38
  116. telegrinder/node/source.py +71 -71
  117. telegrinder/node/text.py +21 -21
  118. telegrinder/node/tools/__init__.py +3 -3
  119. telegrinder/node/tools/generator.py +40 -40
  120. telegrinder/node/update.py +15 -15
  121. telegrinder/rules.py +0 -0
  122. telegrinder/tools/__init__.py +74 -74
  123. telegrinder/tools/buttons.py +79 -79
  124. telegrinder/tools/error_handler/__init__.py +7 -7
  125. telegrinder/tools/error_handler/abc.py +33 -33
  126. telegrinder/tools/error_handler/error.py +9 -9
  127. telegrinder/tools/error_handler/error_handler.py +193 -193
  128. telegrinder/tools/formatting/__init__.py +46 -46
  129. telegrinder/tools/formatting/html.py +308 -308
  130. telegrinder/tools/formatting/links.py +33 -33
  131. telegrinder/tools/formatting/spec_html_formats.py +111 -111
  132. telegrinder/tools/functional.py +12 -12
  133. telegrinder/tools/global_context/__init__.py +7 -7
  134. telegrinder/tools/global_context/abc.py +63 -63
  135. telegrinder/tools/global_context/global_context.py +412 -412
  136. telegrinder/tools/global_context/telegrinder_ctx.py +27 -27
  137. telegrinder/tools/i18n/__init__.py +12 -12
  138. telegrinder/tools/i18n/abc.py +32 -32
  139. telegrinder/tools/i18n/middleware/__init__.py +3 -3
  140. telegrinder/tools/i18n/middleware/abc.py +25 -25
  141. telegrinder/tools/i18n/simple.py +43 -43
  142. telegrinder/tools/kb_set/__init__.py +4 -4
  143. telegrinder/tools/kb_set/base.py +15 -15
  144. telegrinder/tools/kb_set/yaml.py +63 -63
  145. telegrinder/tools/keyboard.py +128 -128
  146. telegrinder/tools/limited_dict.py +37 -37
  147. telegrinder/tools/loop_wrapper/__init__.py +4 -4
  148. telegrinder/tools/loop_wrapper/abc.py +15 -15
  149. telegrinder/tools/loop_wrapper/loop_wrapper.py +216 -216
  150. telegrinder/tools/magic.py +168 -164
  151. telegrinder/tools/parse_mode.py +6 -6
  152. telegrinder/tools/state_storage/__init__.py +4 -4
  153. telegrinder/tools/state_storage/abc.py +35 -35
  154. telegrinder/tools/state_storage/memory.py +25 -25
  155. telegrinder/types/__init__.py +6 -6
  156. telegrinder/types/enums.py +672 -672
  157. telegrinder/types/methods.py +4633 -4633
  158. telegrinder/types/objects.py +6317 -6317
  159. telegrinder/verification_utils.py +32 -32
  160. {telegrinder-0.3.0.post2.dist-info → telegrinder-0.3.2.dist-info}/LICENSE +22 -22
  161. {telegrinder-0.3.0.post2.dist-info → telegrinder-0.3.2.dist-info}/METADATA +1 -1
  162. telegrinder-0.3.2.dist-info/RECORD +164 -0
  163. telegrinder-0.3.0.post2.dist-info/RECORD +0 -164
  164. {telegrinder-0.3.0.post2.dist-info → telegrinder-0.3.2.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",)