Pytdbot 0.9.5.dev0__tar.gz → 0.9.6__tar.gz
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.
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/PKG-INFO +2 -2
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/Pytdbot.egg-info/PKG-INFO +2 -2
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/Pytdbot.egg-info/SOURCES.txt +6 -7
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/README.md +1 -1
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/__init__.py +1 -1
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/client.py +179 -63
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/handlers/decorators.py +95 -15
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/handlers/handler.py +3 -1
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/handlers/td_updates.py +4072 -489
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/methods/methods.py +6 -1
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/methods/td_functions.py +444 -34
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/tdjson/tdjson.py +15 -2
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/types/__init__.py +115 -15
- {pytdbot-0.9.5.dev0/pytdbot/types/td_types → pytdbot-0.9.6/pytdbot/types}/bound_methods/__init__.py +4 -4
- {pytdbot-0.9.5.dev0/pytdbot/types/td_types → pytdbot-0.9.6/pytdbot/types}/bound_methods/callback_query.py +128 -110
- {pytdbot-0.9.5.dev0/pytdbot/types/td_types → pytdbot-0.9.6/pytdbot/types}/bound_methods/file.py +36 -36
- {pytdbot-0.9.5.dev0/pytdbot/types/td_types → pytdbot-0.9.6/pytdbot/types}/bound_methods/message.py +881 -881
- pytdbot-0.9.5.dev0/pytdbot/types/td_types/types.py → pytdbot-0.9.6/pytdbot/types/td_types.py +6113 -124
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/types/tdserver/schedule.py +19 -11
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/utils/__init__.py +13 -1
- pytdbot-0.9.6/pytdbot/utils/json_utils.py +83 -0
- pytdbot-0.9.5.dev0/pytdbot/types/td_types/__init__.py +0 -1
- pytdbot-0.9.5.dev0/pytdbot/utils/json_utils.py +0 -27
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/LICENSE +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/MANIFEST.in +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/Pytdbot.egg-info/dependency_links.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/Pytdbot.egg-info/requires.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/Pytdbot.egg-info/top_level.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/client_manager.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/exception/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/filters.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/handlers/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/methods/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/tdjson/__init__.py +0 -0
- {pytdbot-0.9.5.dev0/pytdbot/types/td_types → pytdbot-0.9.6/pytdbot/types}/bound_methods/chatActions.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/types/plugins/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/types/tdserver/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/types/tdserver/stats.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/utils/asyncio_utils.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/utils/escape.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/utils/obj_encoder.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/utils/strings.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/utils/text_format.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/pytdbot/utils/webapps.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/requirements.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/setup.cfg +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Pytdbot
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.6
|
|
4
4
|
Summary: Easy-to-use asynchronous TDLib wrapper for Python.
|
|
5
5
|
Home-page: https://github.com/pytdbot/client
|
|
6
6
|
Author: AYMEN Mohammed
|
|
@@ -30,7 +30,7 @@ Dynamic: requires-dist
|
|
|
30
30
|
Dynamic: requires-python
|
|
31
31
|
Dynamic: summary
|
|
32
32
|
|
|
33
|
-
# Pytdbot [](https://pypi.org/project/Pytdbot) [](https://pypi.org/project/Pytdbot) [](https://github.com/tdlib/td) [](https://pepy.tech/project/pytdbot) [](https://t.me/pytdbotchat)
|
|
34
34
|
|
|
35
35
|
Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
|
|
36
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Pytdbot
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.6
|
|
4
4
|
Summary: Easy-to-use asynchronous TDLib wrapper for Python.
|
|
5
5
|
Home-page: https://github.com/pytdbot/client
|
|
6
6
|
Author: AYMEN Mohammed
|
|
@@ -30,7 +30,7 @@ Dynamic: requires-dist
|
|
|
30
30
|
Dynamic: requires-python
|
|
31
31
|
Dynamic: summary
|
|
32
32
|
|
|
33
|
-
# Pytdbot [](https://pypi.org/project/Pytdbot) [](https://pypi.org/project/Pytdbot) [](https://github.com/tdlib/td) [](https://pepy.tech/project/pytdbot) [](https://t.me/pytdbotchat)
|
|
34
34
|
|
|
35
35
|
Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
|
|
36
36
|
|
|
@@ -23,14 +23,13 @@ pytdbot/methods/td_functions.py
|
|
|
23
23
|
pytdbot/tdjson/__init__.py
|
|
24
24
|
pytdbot/tdjson/tdjson.py
|
|
25
25
|
pytdbot/types/__init__.py
|
|
26
|
+
pytdbot/types/td_types.py
|
|
27
|
+
pytdbot/types/bound_methods/__init__.py
|
|
28
|
+
pytdbot/types/bound_methods/callback_query.py
|
|
29
|
+
pytdbot/types/bound_methods/chatActions.py
|
|
30
|
+
pytdbot/types/bound_methods/file.py
|
|
31
|
+
pytdbot/types/bound_methods/message.py
|
|
26
32
|
pytdbot/types/plugins/__init__.py
|
|
27
|
-
pytdbot/types/td_types/__init__.py
|
|
28
|
-
pytdbot/types/td_types/types.py
|
|
29
|
-
pytdbot/types/td_types/bound_methods/__init__.py
|
|
30
|
-
pytdbot/types/td_types/bound_methods/callback_query.py
|
|
31
|
-
pytdbot/types/td_types/bound_methods/chatActions.py
|
|
32
|
-
pytdbot/types/td_types/bound_methods/file.py
|
|
33
|
-
pytdbot/types/td_types/bound_methods/message.py
|
|
34
33
|
pytdbot/types/tdserver/__init__.py
|
|
35
34
|
pytdbot/types/tdserver/schedule.py
|
|
36
35
|
pytdbot/types/tdserver/stats.py
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Pytdbot [](https://pypi.org/project/Pytdbot) [](https://pypi.org/project/Pytdbot) [](https://github.com/tdlib/td) [](https://pepy.tech/project/pytdbot) [](https://t.me/pytdbotchat)
|
|
2
2
|
|
|
3
3
|
Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ from os.path import join as join_path
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from platform import python_implementation, python_version
|
|
9
9
|
from threading import current_thread, main_thread
|
|
10
|
-
from typing import Callable, Dict, Union
|
|
10
|
+
from typing import Callable, Dict, Type, Union
|
|
11
11
|
|
|
12
12
|
import aio_pika
|
|
13
13
|
from deepdiff import DeepDiff
|
|
@@ -94,6 +94,9 @@ class Client(Decorators, Methods):
|
|
|
94
94
|
workers (``int``, *optional*):
|
|
95
95
|
Number of workers to handle updates. Default is ``5``. If set to ``None``, updates will be immediately handled instead of being queued, which can impact performance.
|
|
96
96
|
|
|
97
|
+
default_handlers_timeout (``float``, *optional*):
|
|
98
|
+
Default timeout for handlers. If set, each handler will be awaited with this timeout (ignored if ``timeout`` is set when registering handler). Default is ``None`` (no timeout)
|
|
99
|
+
|
|
97
100
|
no_updates (``bool``, *optional*):
|
|
98
101
|
Whether the client should handle updates or not. Applicable only when using [TDLib Server](https://github.com/pytdbot/tdlib-server). Default is ``False``
|
|
99
102
|
|
|
@@ -128,10 +131,14 @@ class Client(Decorators, Methods):
|
|
|
128
131
|
loop: asyncio.AbstractEventLoop = None,
|
|
129
132
|
options: dict = None,
|
|
130
133
|
workers: int = 5,
|
|
134
|
+
queue_size: int = 1000,
|
|
135
|
+
default_handlers_timeout: float = None,
|
|
131
136
|
no_updates: bool = False,
|
|
137
|
+
load_messages_before_reply: bool = False,
|
|
132
138
|
td_verbosity: int = 2,
|
|
133
139
|
td_log: LogStream = None,
|
|
134
140
|
user_bot: bool = False,
|
|
141
|
+
server_ack: bool = True,
|
|
135
142
|
) -> None:
|
|
136
143
|
self.__api_id = api_id
|
|
137
144
|
self.__api_hash = api_hash
|
|
@@ -158,9 +165,13 @@ class Client(Decorators, Methods):
|
|
|
158
165
|
self.use_message_database = use_message_database
|
|
159
166
|
self.td_options = options
|
|
160
167
|
self.workers = workers
|
|
168
|
+
self.queue_size = queue_size
|
|
169
|
+
self.default_handlers_timeout = default_handlers_timeout
|
|
161
170
|
self.no_updates = no_updates
|
|
171
|
+
self.load_messages_before_reply = load_messages_before_reply
|
|
162
172
|
self.queue = asyncio.Queue()
|
|
163
173
|
self.user_bot = user_bot
|
|
174
|
+
self.server_ack = server_ack
|
|
164
175
|
self.my_id = (
|
|
165
176
|
get_bot_id_from_token(self.__token)
|
|
166
177
|
if isinstance(self.__token, str)
|
|
@@ -179,6 +190,12 @@ class Client(Decorators, Methods):
|
|
|
179
190
|
self.is_rabbitmq = True if rabbitmq_url else False
|
|
180
191
|
self.options = {}
|
|
181
192
|
self.allow_outgoing_message_types: tuple = (types.MessagePaymentRefunded,)
|
|
193
|
+
self.get_message_methods = {
|
|
194
|
+
"getmessage",
|
|
195
|
+
"getmessagelocally",
|
|
196
|
+
"getrepliedmessage",
|
|
197
|
+
"getcallbackquerymessage",
|
|
198
|
+
} # TODO: improve this
|
|
182
199
|
|
|
183
200
|
self._check_init_args()
|
|
184
201
|
|
|
@@ -240,13 +257,16 @@ class Client(Decorators, Methods):
|
|
|
240
257
|
return await self.invoke({"@type": "getServerStats"})
|
|
241
258
|
|
|
242
259
|
async def scheduleEvent(
|
|
243
|
-
self,
|
|
260
|
+
self, name: str, payload: str, send_at: int
|
|
244
261
|
) -> Union["pytdbot.types.ScheduledEvent", "pytdbot.types.Error"]:
|
|
245
262
|
"""Schedule an event
|
|
246
263
|
|
|
247
264
|
Parameters:
|
|
248
|
-
|
|
249
|
-
|
|
265
|
+
name (:class:`str`):
|
|
266
|
+
Event name
|
|
267
|
+
|
|
268
|
+
payload (:class:`str`):
|
|
269
|
+
The event payload to be scheduled
|
|
250
270
|
|
|
251
271
|
send_at (:class:`int`):
|
|
252
272
|
Unix timestamp when the event should be sent
|
|
@@ -254,13 +274,20 @@ class Client(Decorators, Methods):
|
|
|
254
274
|
|
|
255
275
|
self._check_rabbitmq()
|
|
256
276
|
|
|
257
|
-
if not isinstance(
|
|
258
|
-
raise ValueError("
|
|
277
|
+
if not isinstance(name, str):
|
|
278
|
+
raise ValueError("name must be str")
|
|
279
|
+
if not isinstance(payload, str):
|
|
280
|
+
raise ValueError("payload must be str")
|
|
259
281
|
if not isinstance(send_at, (int, float)):
|
|
260
282
|
raise ValueError("send_at must be int")
|
|
261
283
|
|
|
262
284
|
return await self.invoke(
|
|
263
|
-
{
|
|
285
|
+
{
|
|
286
|
+
"@type": "scheduleEvent",
|
|
287
|
+
"name": name,
|
|
288
|
+
"payload": payload,
|
|
289
|
+
"send_at": send_at,
|
|
290
|
+
}
|
|
264
291
|
)
|
|
265
292
|
|
|
266
293
|
async def cancelScheduledEvent(
|
|
@@ -326,17 +353,18 @@ class Client(Decorators, Methods):
|
|
|
326
353
|
|
|
327
354
|
def add_handler(
|
|
328
355
|
self,
|
|
329
|
-
update_type: str,
|
|
356
|
+
update_type: Union[Type["pytdbot.types.Update"], str],
|
|
330
357
|
func: Callable,
|
|
331
358
|
filters: pytdbot.filters.Filter = None,
|
|
332
359
|
position: int = None,
|
|
333
360
|
inner_object: bool = False,
|
|
361
|
+
timeout: float = None,
|
|
334
362
|
is_from_plugin: bool = False,
|
|
335
363
|
) -> None:
|
|
336
364
|
r"""Add an update handler
|
|
337
365
|
|
|
338
366
|
Parameters:
|
|
339
|
-
update_type (``str``):
|
|
367
|
+
update_type (``str`` || :class:`~pytdbot.types.Update`):
|
|
340
368
|
An update type
|
|
341
369
|
|
|
342
370
|
func (``Callable``):
|
|
@@ -351,6 +379,9 @@ class Client(Decorators, Methods):
|
|
|
351
379
|
inner_object (``bool``, *optional*):
|
|
352
380
|
Wether to pass an inner object of update or not; for example ``UpdateNewMessage.message``. Default is ``False``
|
|
353
381
|
|
|
382
|
+
timeout (``float``, *optional*):
|
|
383
|
+
Max execution time for the handler before it timeout. If ``None``, ``Client.default_handlers_timeout`` is preferred. Default is ``None``
|
|
384
|
+
|
|
354
385
|
is_from_plugin (``bool``, *optional*):
|
|
355
386
|
Wether this handler is from a loaded plugin (this can help reloading plugin during runtime; for development only). Default is ``False``
|
|
356
387
|
|
|
@@ -359,23 +390,34 @@ class Client(Decorators, Methods):
|
|
|
359
390
|
"""
|
|
360
391
|
|
|
361
392
|
if not isinstance(update_type, str):
|
|
362
|
-
|
|
363
|
-
|
|
393
|
+
if issubclass(update_type, types.Update):
|
|
394
|
+
update_type = update_type.getType()
|
|
395
|
+
else:
|
|
396
|
+
raise TypeError(
|
|
397
|
+
"update_type must be str or subclass of pytdbot.types.Update"
|
|
398
|
+
)
|
|
399
|
+
if not isinstance(func, Callable):
|
|
364
400
|
raise TypeError("func must be callable")
|
|
365
|
-
|
|
401
|
+
if filters is not None and not isinstance(filters, Filter):
|
|
366
402
|
raise TypeError("filters must be instance of pytdbot.filters.Filter")
|
|
367
|
-
else:
|
|
368
|
-
handler = Handler(
|
|
369
|
-
func, update_type, filters, position, inner_object, is_from_plugin
|
|
370
|
-
)
|
|
371
403
|
|
|
372
|
-
|
|
373
|
-
|
|
404
|
+
handler = Handler(
|
|
405
|
+
func=func,
|
|
406
|
+
update_type=update_type,
|
|
407
|
+
filter=filters,
|
|
408
|
+
position=position,
|
|
409
|
+
inner_object=inner_object,
|
|
410
|
+
timeout=timeout,
|
|
411
|
+
is_from_plugin=is_from_plugin,
|
|
412
|
+
)
|
|
374
413
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
414
|
+
if update_type not in self._handlers:
|
|
415
|
+
self._handlers[update_type] = []
|
|
416
|
+
|
|
417
|
+
if isinstance(position, int):
|
|
418
|
+
self._handlers[update_type].insert(position, handler)
|
|
419
|
+
else:
|
|
420
|
+
self._handlers[update_type].append(handler)
|
|
379
421
|
|
|
380
422
|
self._update_handlers()
|
|
381
423
|
|
|
@@ -451,56 +493,78 @@ class Client(Decorators, Methods):
|
|
|
451
493
|
"""
|
|
452
494
|
|
|
453
495
|
request = obj_to_dict(request)
|
|
454
|
-
|
|
455
496
|
request["@extra"] = {"id": create_extra_id()}
|
|
456
|
-
|
|
457
|
-
future = self._create_request_future(request)
|
|
497
|
+
request_method = request["@type"].lower()
|
|
458
498
|
|
|
459
499
|
if (
|
|
460
500
|
self.logger.root.level >= DEBUG or self.logger.level >= DEBUG
|
|
461
501
|
): # dumping all requests may create performance issues
|
|
462
502
|
self.logger.debug(f"Sending: {dumps(request, indent=4)}")
|
|
463
503
|
|
|
464
|
-
is_chat_attempted_load =
|
|
504
|
+
is_chat_attempted_load = request_method == "getchat"
|
|
505
|
+
is_message_attempted_load = request_method in self.get_message_methods
|
|
465
506
|
|
|
466
507
|
while True:
|
|
467
508
|
future = self._create_request_future(request)
|
|
468
509
|
await self.__send(request)
|
|
469
510
|
result = await future
|
|
470
511
|
|
|
471
|
-
if isinstance(result, types.Error):
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
raise ValueError(result.message)
|
|
512
|
+
if not isinstance(result, types.Error):
|
|
513
|
+
break
|
|
514
|
+
|
|
515
|
+
error_code = result.code
|
|
516
|
+
error_message = result.message
|
|
477
517
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
518
|
+
if error_message.startswith(
|
|
519
|
+
"Failed to parse JSON object as TDLib request:"
|
|
520
|
+
):
|
|
521
|
+
raise ValueError(error_message)
|
|
522
|
+
|
|
523
|
+
if error_code != 400:
|
|
524
|
+
break
|
|
525
|
+
|
|
526
|
+
chat_id = request.get("chat_id")
|
|
527
|
+
message_id = request.get("message_id")
|
|
528
|
+
|
|
529
|
+
if not is_message_attempted_load and (
|
|
530
|
+
error_message == "Message not found" and (chat_id and message_id)
|
|
531
|
+
):
|
|
532
|
+
is_message_attempted_load = True
|
|
482
533
|
|
|
483
|
-
|
|
534
|
+
self.logger.debug(f"Attempt to load message {message_id} in {chat_id}")
|
|
484
535
|
|
|
485
|
-
|
|
536
|
+
message = await self.getMessage(chat_id=chat_id, message_id=message_id)
|
|
537
|
+
if message:
|
|
538
|
+
self.logger.debug(f"Message {message_id} in {chat_id} is loaded")
|
|
539
|
+
continue
|
|
540
|
+
else:
|
|
541
|
+
self.logger.debug(
|
|
542
|
+
f"Failed to load message {message_id} in {chat_id}"
|
|
543
|
+
)
|
|
486
544
|
|
|
487
|
-
|
|
545
|
+
if not is_chat_attempted_load and (
|
|
546
|
+
error_message == "Chat not found" and chat_id
|
|
547
|
+
):
|
|
548
|
+
is_chat_attempted_load = True
|
|
488
549
|
|
|
489
|
-
|
|
490
|
-
self.logger.debug(f"Chat {chat_id} is loaded")
|
|
550
|
+
self.logger.debug(f"Attempt to load chat {chat_id}")
|
|
491
551
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
552
|
+
chat = await self.getChat(chat_id)
|
|
553
|
+
if not isinstance(chat, types.Error):
|
|
554
|
+
self.logger.debug(f"Chat {chat_id} is loaded")
|
|
495
555
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
await self.getMessage(chat_id, reply_to_message_id)
|
|
556
|
+
reply_to_message_id = (request.get("reply_to") or {}).get(
|
|
557
|
+
"message_id", 0
|
|
558
|
+
)
|
|
500
559
|
|
|
501
|
-
|
|
560
|
+
# if the request is a reply to another message
|
|
561
|
+
# load the replied message to avoid "Message not found"
|
|
562
|
+
if reply_to_message_id > 0:
|
|
563
|
+
await self.getMessage(chat_id, reply_to_message_id)
|
|
502
564
|
|
|
503
|
-
|
|
565
|
+
continue
|
|
566
|
+
else:
|
|
567
|
+
self.logger.error(f"Couldn't load chat {chat_id}")
|
|
504
568
|
|
|
505
569
|
break
|
|
506
570
|
|
|
@@ -701,12 +765,13 @@ class Client(Decorators, Methods):
|
|
|
701
765
|
for handler in handlers_to_load:
|
|
702
766
|
if asyncio.iscoroutinefunction(handler.func):
|
|
703
767
|
self.add_handler(
|
|
704
|
-
handler.update_type,
|
|
705
|
-
handler.func,
|
|
706
|
-
handler.filter,
|
|
707
|
-
handler.position,
|
|
708
|
-
handler.inner_object,
|
|
709
|
-
|
|
768
|
+
update_type=handler.update_type,
|
|
769
|
+
func=handler.func,
|
|
770
|
+
filters=handler.filter,
|
|
771
|
+
position=handler.position,
|
|
772
|
+
inner_object=handler.inner_object,
|
|
773
|
+
timeout=handler.timeout,
|
|
774
|
+
is_from_plugin=True,
|
|
710
775
|
)
|
|
711
776
|
handlers += 1
|
|
712
777
|
plugin_handlers_count += 1
|
|
@@ -785,7 +850,22 @@ class Client(Decorators, Methods):
|
|
|
785
850
|
elif not filter_function(self, handler_value):
|
|
786
851
|
continue
|
|
787
852
|
|
|
788
|
-
|
|
853
|
+
if (
|
|
854
|
+
self.default_handlers_timeout is None
|
|
855
|
+
and initializer.timeout is None
|
|
856
|
+
):
|
|
857
|
+
await initializer(self, handler_value)
|
|
858
|
+
else:
|
|
859
|
+
timeout = initializer.timeout or self.default_handlers_timeout
|
|
860
|
+
try:
|
|
861
|
+
await asyncio.wait_for(
|
|
862
|
+
initializer(self, handler_value),
|
|
863
|
+
timeout=timeout,
|
|
864
|
+
)
|
|
865
|
+
except asyncio.TimeoutError:
|
|
866
|
+
self.logger.warning(
|
|
867
|
+
f"Initializer {initializer} timed out after {timeout} seconds"
|
|
868
|
+
)
|
|
789
869
|
except StopHandlers as e:
|
|
790
870
|
raise e
|
|
791
871
|
except Exception:
|
|
@@ -806,7 +886,18 @@ class Client(Decorators, Methods):
|
|
|
806
886
|
elif not filter_function(self, handler_value):
|
|
807
887
|
continue
|
|
808
888
|
|
|
809
|
-
|
|
889
|
+
if self.default_handlers_timeout is None and handler.timeout is None:
|
|
890
|
+
await handler(self, handler_value)
|
|
891
|
+
else:
|
|
892
|
+
timeout = handler.timeout or self.default_handlers_timeout
|
|
893
|
+
try:
|
|
894
|
+
await asyncio.wait_for(
|
|
895
|
+
handler(self, handler_value), timeout=timeout
|
|
896
|
+
)
|
|
897
|
+
except asyncio.TimeoutError:
|
|
898
|
+
self.logger.warning(
|
|
899
|
+
f"Handler {handler} timed out after {timeout} seconds"
|
|
900
|
+
)
|
|
810
901
|
except StopHandlers as e:
|
|
811
902
|
raise e
|
|
812
903
|
except Exception:
|
|
@@ -828,7 +919,19 @@ class Client(Decorators, Methods):
|
|
|
828
919
|
elif not filter_function(self, handler_value):
|
|
829
920
|
continue
|
|
830
921
|
|
|
831
|
-
|
|
922
|
+
if self.default_handlers_timeout is None and finalizer.timeout is None:
|
|
923
|
+
await finalizer(self, handler_value)
|
|
924
|
+
else:
|
|
925
|
+
try:
|
|
926
|
+
timeout = finalizer.timeout or self.default_handlers_timeout
|
|
927
|
+
await asyncio.wait_for(
|
|
928
|
+
finalizer(self, handler_value),
|
|
929
|
+
timeout=timeout,
|
|
930
|
+
)
|
|
931
|
+
except asyncio.TimeoutError:
|
|
932
|
+
self.logger.warning(
|
|
933
|
+
f"Finalizer {finalizer} timed out after {timeout} seconds"
|
|
934
|
+
)
|
|
832
935
|
except StopHandlers as e:
|
|
833
936
|
raise e
|
|
834
937
|
except Exception:
|
|
@@ -869,6 +972,9 @@ class Client(Decorators, Methods):
|
|
|
869
972
|
`AuthorizationError`
|
|
870
973
|
"""
|
|
871
974
|
|
|
975
|
+
if self.is_rabbitmq:
|
|
976
|
+
return
|
|
977
|
+
|
|
872
978
|
if isinstance(self.__database_encryption_key, str):
|
|
873
979
|
self.__database_encryption_key = self.__database_encryption_key.encode(
|
|
874
980
|
"utf-8"
|
|
@@ -1060,13 +1166,22 @@ class Client(Decorators, Methods):
|
|
|
1060
1166
|
await self.__rqueues["notify"].consume(self.__on_update, no_ack=True)
|
|
1061
1167
|
|
|
1062
1168
|
async def __rabbitmq_iterator(self):
|
|
1063
|
-
async with self.__rqueues["updates"].iterator(
|
|
1169
|
+
async with self.__rqueues["updates"].iterator(
|
|
1170
|
+
no_ack=not self.server_ack
|
|
1171
|
+
) as iterator:
|
|
1064
1172
|
async for message in iterator:
|
|
1065
|
-
|
|
1173
|
+
if self.queue.qsize() > self.queue_size:
|
|
1174
|
+
await message.nack(requeue=True)
|
|
1175
|
+
continue
|
|
1176
|
+
|
|
1177
|
+
self.queue.put_nowait(message)
|
|
1066
1178
|
|
|
1067
1179
|
async def __rabbitmq_worker(self):
|
|
1068
1180
|
while self.is_running:
|
|
1069
|
-
|
|
1181
|
+
try:
|
|
1182
|
+
message: aio_pika.IncomingMessage = self.queue.get_nowait()
|
|
1183
|
+
except asyncio.QueueEmpty:
|
|
1184
|
+
message: aio_pika.IncomingMessage = await self.queue.get()
|
|
1070
1185
|
|
|
1071
1186
|
try:
|
|
1072
1187
|
update = json_loads(message.body)
|
|
@@ -1103,7 +1218,8 @@ class Client(Decorators, Methods):
|
|
|
1103
1218
|
|
|
1104
1219
|
async def __handle_authorization_state_wait_phone_number(self):
|
|
1105
1220
|
if (
|
|
1106
|
-
self.
|
|
1221
|
+
self.is_rabbitmq
|
|
1222
|
+
or self.authorization_state != "authorizationStateWaitPhoneNumber"
|
|
1107
1223
|
or not self.__token
|
|
1108
1224
|
):
|
|
1109
1225
|
return
|