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,216 +1,224 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import contextlib
|
|
3
|
-
import dataclasses
|
|
4
|
-
import datetime
|
|
5
|
-
import typing
|
|
6
|
-
|
|
7
|
-
from telegrinder.modules import logger
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
self.
|
|
93
|
-
self.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
self._loop
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
self.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
def
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
1
|
+
import asyncio
|
|
2
|
+
import contextlib
|
|
3
|
+
import dataclasses
|
|
4
|
+
import datetime
|
|
5
|
+
import typing
|
|
6
|
+
|
|
7
|
+
from telegrinder.modules import logger
|
|
8
|
+
from telegrinder.tools.loop_wrapper.abc import ABCLoopWrapper
|
|
9
|
+
|
|
10
|
+
T = typing.TypeVar("T")
|
|
11
|
+
P = typing.ParamSpec("P")
|
|
12
|
+
CoroFunc = typing.TypeVar("CoroFunc", bound="CoroutineFunc[..., typing.Any]")
|
|
13
|
+
|
|
14
|
+
CoroutineTask: typing.TypeAlias = typing.Coroutine[typing.Any, typing.Any, T]
|
|
15
|
+
CoroutineFunc: typing.TypeAlias = typing.Callable[P, CoroutineTask[T]]
|
|
16
|
+
Task: typing.TypeAlias = (
|
|
17
|
+
"CoroutineFunc[P, T] | CoroutineTask[T] | DelayedTask[typing.Callable[P, CoroutineTask[T]]]"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def run_tasks(
|
|
22
|
+
tasks: list[CoroutineTask[typing.Any]],
|
|
23
|
+
loop: asyncio.AbstractEventLoop,
|
|
24
|
+
) -> None:
|
|
25
|
+
while tasks:
|
|
26
|
+
loop.run_until_complete(tasks.pop(0))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def to_coroutine_task(task: Task) -> CoroutineTask[typing.Any]:
|
|
30
|
+
if asyncio.iscoroutinefunction(task) or isinstance(task, DelayedTask):
|
|
31
|
+
task = task()
|
|
32
|
+
elif not asyncio.iscoroutine(task):
|
|
33
|
+
raise TypeError("Task should be coroutine or coroutine function.")
|
|
34
|
+
return task
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclasses.dataclass(slots=True)
|
|
38
|
+
class DelayedTask(typing.Generic[CoroFunc]):
|
|
39
|
+
handler: CoroFunc
|
|
40
|
+
seconds: float
|
|
41
|
+
repeat: bool = dataclasses.field(default=False, kw_only=True)
|
|
42
|
+
_cancelled: bool = dataclasses.field(default=False, init=False, repr=False)
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def is_cancelled(self) -> bool:
|
|
46
|
+
return self._cancelled
|
|
47
|
+
|
|
48
|
+
async def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> None:
|
|
49
|
+
while not self.is_cancelled:
|
|
50
|
+
await asyncio.sleep(self.seconds)
|
|
51
|
+
if self.is_cancelled:
|
|
52
|
+
break
|
|
53
|
+
try:
|
|
54
|
+
await self.handler(*args, **kwargs)
|
|
55
|
+
finally:
|
|
56
|
+
if not self.repeat:
|
|
57
|
+
break
|
|
58
|
+
|
|
59
|
+
def cancel(self) -> None:
|
|
60
|
+
if not self._cancelled:
|
|
61
|
+
self._cancelled = True
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
|
|
65
|
+
class Lifespan:
|
|
66
|
+
startup_tasks: list[CoroutineTask[typing.Any]] = dataclasses.field(default_factory=lambda: [])
|
|
67
|
+
shutdown_tasks: list[CoroutineTask[typing.Any]] = dataclasses.field(default_factory=lambda: [])
|
|
68
|
+
|
|
69
|
+
def on_startup(self, task: Task, /) -> Task:
|
|
70
|
+
self.startup_tasks.append(to_coroutine_task(task))
|
|
71
|
+
return task
|
|
72
|
+
|
|
73
|
+
def on_shutdown(self, task: Task, /) -> Task:
|
|
74
|
+
self.shutdown_tasks.append(to_coroutine_task(task))
|
|
75
|
+
return task
|
|
76
|
+
|
|
77
|
+
def start(self, loop: asyncio.AbstractEventLoop, /) -> None:
|
|
78
|
+
run_tasks(self.startup_tasks, loop)
|
|
79
|
+
|
|
80
|
+
def shutdown(self, loop: asyncio.AbstractEventLoop, /) -> None:
|
|
81
|
+
run_tasks(self.shutdown_tasks, loop)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class LoopWrapper(ABCLoopWrapper):
|
|
85
|
+
def __init__(
|
|
86
|
+
self,
|
|
87
|
+
*,
|
|
88
|
+
tasks: list[CoroutineTask[typing.Any]] | None = None,
|
|
89
|
+
lifespan: Lifespan | None = None,
|
|
90
|
+
event_loop: asyncio.AbstractEventLoop | None = None,
|
|
91
|
+
) -> None:
|
|
92
|
+
self.tasks: list[CoroutineTask[typing.Any]] = tasks or []
|
|
93
|
+
self.lifespan = lifespan or Lifespan()
|
|
94
|
+
self._loop = event_loop
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def loop(self) -> asyncio.AbstractEventLoop:
|
|
98
|
+
assert self._loop is not None
|
|
99
|
+
return self._loop
|
|
100
|
+
|
|
101
|
+
def __repr__(self) -> str:
|
|
102
|
+
return "<{}: loop={!r} with tasks={!r}, lifespan={!r}>".format(
|
|
103
|
+
self.__class__.__name__,
|
|
104
|
+
self._loop,
|
|
105
|
+
self.tasks,
|
|
106
|
+
self.lifespan,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def run_event_loop(self) -> None:
|
|
110
|
+
if not self.tasks:
|
|
111
|
+
logger.warning("You run loop with 0 tasks!")
|
|
112
|
+
|
|
113
|
+
self._loop = asyncio.new_event_loop() if self._loop is None else self._loop
|
|
114
|
+
self.lifespan.start(self._loop)
|
|
115
|
+
|
|
116
|
+
while self.tasks:
|
|
117
|
+
self._loop.create_task(self.tasks.pop(0))
|
|
118
|
+
|
|
119
|
+
tasks = asyncio.all_tasks(self._loop)
|
|
120
|
+
try:
|
|
121
|
+
while tasks:
|
|
122
|
+
tasks_results, _ = self._loop.run_until_complete(
|
|
123
|
+
asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION),
|
|
124
|
+
)
|
|
125
|
+
for task_result in tasks_results:
|
|
126
|
+
try:
|
|
127
|
+
task_result.result()
|
|
128
|
+
except BaseException as ex:
|
|
129
|
+
logger.exception(ex)
|
|
130
|
+
tasks = asyncio.all_tasks(self._loop)
|
|
131
|
+
except KeyboardInterrupt:
|
|
132
|
+
print() # blank print for ^C
|
|
133
|
+
logger.info("Caught KeyboardInterrupt, cancellation...")
|
|
134
|
+
self.complete_tasks(tasks)
|
|
135
|
+
finally:
|
|
136
|
+
self.lifespan.shutdown(self._loop)
|
|
137
|
+
if self._loop.is_running():
|
|
138
|
+
self._loop.close()
|
|
139
|
+
|
|
140
|
+
def add_task(self, task: Task) -> None:
|
|
141
|
+
task = to_coroutine_task(task)
|
|
142
|
+
|
|
143
|
+
if self._loop is not None and self._loop.is_running():
|
|
144
|
+
self._loop.create_task(task)
|
|
145
|
+
else:
|
|
146
|
+
self.tasks.append(task)
|
|
147
|
+
|
|
148
|
+
def complete_tasks(self, tasks: set[asyncio.Task[typing.Any]]) -> None:
|
|
149
|
+
tasks = tasks | asyncio.all_tasks(self.loop)
|
|
150
|
+
task_to_cancel = asyncio.gather(*tasks, return_exceptions=True)
|
|
151
|
+
task_to_cancel.cancel()
|
|
152
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
153
|
+
self.loop.run_until_complete(task_to_cancel)
|
|
154
|
+
|
|
155
|
+
@typing.overload
|
|
156
|
+
def timer(self, *, seconds: datetime.timedelta) -> typing.Callable[..., typing.Any]: ...
|
|
157
|
+
|
|
158
|
+
@typing.overload
|
|
159
|
+
def timer(
|
|
160
|
+
self,
|
|
161
|
+
*,
|
|
162
|
+
days: int = 0,
|
|
163
|
+
hours: int = 0,
|
|
164
|
+
minutes: int = 0,
|
|
165
|
+
seconds: float = 0,
|
|
166
|
+
) -> typing.Callable[..., typing.Any]: ...
|
|
167
|
+
|
|
168
|
+
def timer(
|
|
169
|
+
self,
|
|
170
|
+
*,
|
|
171
|
+
days: int = 0,
|
|
172
|
+
hours: int = 0,
|
|
173
|
+
minutes: int = 0,
|
|
174
|
+
seconds: float | datetime.timedelta = 0,
|
|
175
|
+
) -> typing.Callable[..., typing.Any]:
|
|
176
|
+
if isinstance(seconds, datetime.timedelta):
|
|
177
|
+
seconds = seconds.total_seconds()
|
|
178
|
+
|
|
179
|
+
seconds += minutes * 60
|
|
180
|
+
seconds += hours * 60 * 60
|
|
181
|
+
seconds += days * 24 * 60 * 60
|
|
182
|
+
|
|
183
|
+
def decorator(func: CoroFunc) -> CoroFunc:
|
|
184
|
+
self.add_task(DelayedTask(func, seconds, repeat=False))
|
|
185
|
+
return func
|
|
186
|
+
|
|
187
|
+
return decorator
|
|
188
|
+
|
|
189
|
+
@typing.overload
|
|
190
|
+
def interval(self, *, seconds: datetime.timedelta) -> typing.Callable[..., typing.Any]: ...
|
|
191
|
+
|
|
192
|
+
@typing.overload
|
|
193
|
+
def interval(
|
|
194
|
+
self,
|
|
195
|
+
*,
|
|
196
|
+
days: int = 0,
|
|
197
|
+
hours: int = 0,
|
|
198
|
+
minutes: int = 0,
|
|
199
|
+
seconds: float = 0,
|
|
200
|
+
) -> typing.Callable[..., typing.Any]: ...
|
|
201
|
+
|
|
202
|
+
def interval(
|
|
203
|
+
self,
|
|
204
|
+
*,
|
|
205
|
+
days: int = 0,
|
|
206
|
+
hours: int = 0,
|
|
207
|
+
minutes: int = 0,
|
|
208
|
+
seconds: float | datetime.timedelta = 0,
|
|
209
|
+
) -> typing.Callable[..., typing.Any]:
|
|
210
|
+
if isinstance(seconds, datetime.timedelta):
|
|
211
|
+
seconds = seconds.total_seconds()
|
|
212
|
+
|
|
213
|
+
seconds += minutes * 60
|
|
214
|
+
seconds += hours * 60 * 60
|
|
215
|
+
seconds += days * 24 * 60 * 60
|
|
216
|
+
|
|
217
|
+
def decorator(func: CoroFunc) -> CoroFunc:
|
|
218
|
+
self.add_task(DelayedTask(func, seconds, repeat=True))
|
|
219
|
+
return func
|
|
220
|
+
|
|
221
|
+
return decorator
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
__all__ = ("DelayedTask", "Lifespan", "LoopWrapper", "to_coroutine_task")
|