Pytdbot 0.9.5__tar.gz → 0.9.6.dev0__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 → pytdbot-0.9.6.dev0}/PKG-INFO +1 -1
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/Pytdbot.egg-info/PKG-INFO +1 -1
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/__init__.py +1 -1
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/client.py +85 -50
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/methods/methods.py +6 -1
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/td_types/types.py +3585 -3
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/tdserver/schedule.py +11 -11
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/LICENSE +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/MANIFEST.in +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/Pytdbot.egg-info/SOURCES.txt +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/Pytdbot.egg-info/dependency_links.txt +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/Pytdbot.egg-info/requires.txt +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/Pytdbot.egg-info/top_level.txt +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/README.md +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/client_manager.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/exception/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/filters.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/handlers/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/handlers/decorators.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/handlers/handler.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/handlers/td_updates.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/methods/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/methods/td_functions.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/tdjson/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/tdjson/tdjson.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/plugins/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/td_types/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/td_types/bound_methods/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/td_types/bound_methods/callback_query.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/td_types/bound_methods/chatActions.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/td_types/bound_methods/file.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/td_types/bound_methods/message.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/tdserver/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/types/tdserver/stats.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/__init__.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/asyncio_utils.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/escape.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/json_utils.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/obj_encoder.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/strings.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/text_format.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/pytdbot/utils/webapps.py +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/requirements.txt +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/setup.cfg +0 -0
- {pytdbot-0.9.5 → pytdbot-0.9.6.dev0}/setup.py +0 -0
|
@@ -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
|
|
@@ -129,6 +129,7 @@ class Client(Decorators, Methods):
|
|
|
129
129
|
options: dict = None,
|
|
130
130
|
workers: int = 5,
|
|
131
131
|
no_updates: bool = False,
|
|
132
|
+
load_messages_before_reply: bool = False,
|
|
132
133
|
td_verbosity: int = 2,
|
|
133
134
|
td_log: LogStream = None,
|
|
134
135
|
user_bot: bool = False,
|
|
@@ -159,6 +160,7 @@ class Client(Decorators, Methods):
|
|
|
159
160
|
self.td_options = options
|
|
160
161
|
self.workers = workers
|
|
161
162
|
self.no_updates = no_updates
|
|
163
|
+
self.load_messages_before_reply = load_messages_before_reply
|
|
162
164
|
self.queue = asyncio.Queue()
|
|
163
165
|
self.user_bot = user_bot
|
|
164
166
|
self.my_id = (
|
|
@@ -179,6 +181,12 @@ class Client(Decorators, Methods):
|
|
|
179
181
|
self.is_rabbitmq = True if rabbitmq_url else False
|
|
180
182
|
self.options = {}
|
|
181
183
|
self.allow_outgoing_message_types: tuple = (types.MessagePaymentRefunded,)
|
|
184
|
+
self.get_message_methods = {
|
|
185
|
+
"getmessage",
|
|
186
|
+
"getmessagelocally",
|
|
187
|
+
"getrepliedmessage",
|
|
188
|
+
"getcallbackquerymessage",
|
|
189
|
+
} # TODO: improve this
|
|
182
190
|
|
|
183
191
|
self._check_init_args()
|
|
184
192
|
|
|
@@ -240,13 +248,13 @@ class Client(Decorators, Methods):
|
|
|
240
248
|
return await self.invoke({"@type": "getServerStats"})
|
|
241
249
|
|
|
242
250
|
async def scheduleEvent(
|
|
243
|
-
self,
|
|
251
|
+
self, payload: str, send_at: int
|
|
244
252
|
) -> Union["pytdbot.types.ScheduledEvent", "pytdbot.types.Error"]:
|
|
245
253
|
"""Schedule an event
|
|
246
254
|
|
|
247
255
|
Parameters:
|
|
248
|
-
|
|
249
|
-
The event
|
|
256
|
+
payload (:class:`str`):
|
|
257
|
+
The event payload to be scheduled
|
|
250
258
|
|
|
251
259
|
send_at (:class:`int`):
|
|
252
260
|
Unix timestamp when the event should be sent
|
|
@@ -254,13 +262,13 @@ class Client(Decorators, Methods):
|
|
|
254
262
|
|
|
255
263
|
self._check_rabbitmq()
|
|
256
264
|
|
|
257
|
-
if not isinstance(
|
|
258
|
-
raise ValueError("
|
|
265
|
+
if not isinstance(payload, str):
|
|
266
|
+
raise ValueError("payload must be str")
|
|
259
267
|
if not isinstance(send_at, (int, float)):
|
|
260
268
|
raise ValueError("send_at must be int")
|
|
261
269
|
|
|
262
270
|
return await self.invoke(
|
|
263
|
-
{"@type": "scheduleEvent", "
|
|
271
|
+
{"@type": "scheduleEvent", "payload": payload, "send_at": send_at}
|
|
264
272
|
)
|
|
265
273
|
|
|
266
274
|
async def cancelScheduledEvent(
|
|
@@ -326,7 +334,7 @@ class Client(Decorators, Methods):
|
|
|
326
334
|
|
|
327
335
|
def add_handler(
|
|
328
336
|
self,
|
|
329
|
-
update_type: str,
|
|
337
|
+
update_type: Union[Type["pytdbot.types.Update"], str],
|
|
330
338
|
func: Callable,
|
|
331
339
|
filters: pytdbot.filters.Filter = None,
|
|
332
340
|
position: int = None,
|
|
@@ -336,7 +344,7 @@ class Client(Decorators, Methods):
|
|
|
336
344
|
r"""Add an update handler
|
|
337
345
|
|
|
338
346
|
Parameters:
|
|
339
|
-
update_type (``str``):
|
|
347
|
+
update_type (``str`` || :class:`~pytdbot.types.Update`):
|
|
340
348
|
An update type
|
|
341
349
|
|
|
342
350
|
func (``Callable``):
|
|
@@ -359,23 +367,28 @@ class Client(Decorators, Methods):
|
|
|
359
367
|
"""
|
|
360
368
|
|
|
361
369
|
if not isinstance(update_type, str):
|
|
362
|
-
|
|
363
|
-
|
|
370
|
+
if issubclass(update_type, types.Update):
|
|
371
|
+
update_type = update_type.getType()
|
|
372
|
+
else:
|
|
373
|
+
raise TypeError(
|
|
374
|
+
"update_type must be str or subclass of pytdbot.types.Update"
|
|
375
|
+
)
|
|
376
|
+
if not isinstance(func, Callable):
|
|
364
377
|
raise TypeError("func must be callable")
|
|
365
|
-
|
|
378
|
+
if filters is not None and not isinstance(filters, Filter):
|
|
366
379
|
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
380
|
|
|
372
|
-
|
|
373
|
-
|
|
381
|
+
handler = Handler(
|
|
382
|
+
func, update_type, filters, position, inner_object, is_from_plugin
|
|
383
|
+
)
|
|
374
384
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
385
|
+
if update_type not in self._handlers:
|
|
386
|
+
self._handlers[update_type] = []
|
|
387
|
+
|
|
388
|
+
if isinstance(position, int):
|
|
389
|
+
self._handlers[update_type].insert(position, handler)
|
|
390
|
+
else:
|
|
391
|
+
self._handlers[update_type].append(handler)
|
|
379
392
|
|
|
380
393
|
self._update_handlers()
|
|
381
394
|
|
|
@@ -451,56 +464,78 @@ class Client(Decorators, Methods):
|
|
|
451
464
|
"""
|
|
452
465
|
|
|
453
466
|
request = obj_to_dict(request)
|
|
454
|
-
|
|
455
467
|
request["@extra"] = {"id": create_extra_id()}
|
|
456
|
-
|
|
457
|
-
future = self._create_request_future(request)
|
|
468
|
+
request_method = request["@type"].lower()
|
|
458
469
|
|
|
459
470
|
if (
|
|
460
471
|
self.logger.root.level >= DEBUG or self.logger.level >= DEBUG
|
|
461
472
|
): # dumping all requests may create performance issues
|
|
462
473
|
self.logger.debug(f"Sending: {dumps(request, indent=4)}")
|
|
463
474
|
|
|
464
|
-
is_chat_attempted_load =
|
|
475
|
+
is_chat_attempted_load = request_method == "getchat"
|
|
476
|
+
is_message_attempted_load = request_method in self.get_message_methods
|
|
465
477
|
|
|
466
478
|
while True:
|
|
467
479
|
future = self._create_request_future(request)
|
|
468
480
|
await self.__send(request)
|
|
469
481
|
result = await future
|
|
470
482
|
|
|
471
|
-
if isinstance(result, types.Error):
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
483
|
+
if not isinstance(result, types.Error):
|
|
484
|
+
break
|
|
485
|
+
|
|
486
|
+
error_code = result.code
|
|
487
|
+
error_message = result.message
|
|
488
|
+
|
|
489
|
+
if error_message.startswith(
|
|
490
|
+
"Failed to parse JSON object as TDLib request:"
|
|
491
|
+
):
|
|
492
|
+
raise ValueError(error_message)
|
|
477
493
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
):
|
|
481
|
-
is_chat_attempted_load = True
|
|
494
|
+
if error_code != 400:
|
|
495
|
+
break
|
|
482
496
|
|
|
483
|
-
|
|
497
|
+
chat_id = request.get("chat_id")
|
|
498
|
+
message_id = request.get("message_id")
|
|
484
499
|
|
|
485
|
-
|
|
500
|
+
if not is_message_attempted_load and (
|
|
501
|
+
error_message == "Message not found" and (chat_id and message_id)
|
|
502
|
+
):
|
|
503
|
+
is_message_attempted_load = True
|
|
486
504
|
|
|
487
|
-
|
|
505
|
+
self.logger.debug(f"Attempt to load message {message_id} in {chat_id}")
|
|
488
506
|
|
|
489
|
-
|
|
490
|
-
|
|
507
|
+
message = await self.getMessage(chat_id=chat_id, message_id=message_id)
|
|
508
|
+
if message:
|
|
509
|
+
self.logger.debug(f"Message {message_id} in {chat_id} is loaded")
|
|
510
|
+
continue
|
|
511
|
+
else:
|
|
512
|
+
self.logger.debug(
|
|
513
|
+
f"Failed to load message {message_id} in {chat_id}"
|
|
514
|
+
)
|
|
491
515
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
516
|
+
if not is_chat_attempted_load and (
|
|
517
|
+
error_message == "Chat not found" and chat_id
|
|
518
|
+
):
|
|
519
|
+
is_chat_attempted_load = True
|
|
495
520
|
|
|
496
|
-
|
|
497
|
-
# load the replied message to avoid "Message not found"
|
|
498
|
-
if reply_to_message_id > 0:
|
|
499
|
-
await self.getMessage(chat_id, reply_to_message_id)
|
|
521
|
+
self.logger.debug(f"Attempt to load chat {chat_id}")
|
|
500
522
|
|
|
501
|
-
|
|
523
|
+
chat = await self.getChat(chat_id)
|
|
524
|
+
if not isinstance(chat, types.Error):
|
|
525
|
+
self.logger.debug(f"Chat {chat_id} is loaded")
|
|
526
|
+
|
|
527
|
+
reply_to_message_id = (request.get("reply_to") or {}).get(
|
|
528
|
+
"message_id", 0
|
|
529
|
+
)
|
|
502
530
|
|
|
503
|
-
|
|
531
|
+
# if the request is a reply to another message
|
|
532
|
+
# load the replied message to avoid "Message not found"
|
|
533
|
+
if reply_to_message_id > 0:
|
|
534
|
+
await self.getMessage(chat_id, reply_to_message_id)
|
|
535
|
+
|
|
536
|
+
continue
|
|
537
|
+
else:
|
|
538
|
+
self.logger.error(f"Couldn't load chat {chat_id}")
|
|
504
539
|
|
|
505
540
|
break
|
|
506
541
|
|
|
@@ -1027,7 +1027,7 @@ class Methods(TDLibFunctions):
|
|
|
1027
1027
|
return await self.sendMessageWithContent(
|
|
1028
1028
|
chat_id=chat_id,
|
|
1029
1029
|
content=InputMessageVoiceNote(
|
|
1030
|
-
|
|
1030
|
+
voice_note=voice,
|
|
1031
1031
|
waveform=waveform,
|
|
1032
1032
|
duration=duration,
|
|
1033
1033
|
caption=caption,
|
|
@@ -1389,6 +1389,11 @@ class Methods(TDLibFunctions):
|
|
|
1389
1389
|
message_id=reply_to_message_id, quote=quote
|
|
1390
1390
|
)
|
|
1391
1391
|
|
|
1392
|
+
if self.load_messages_before_reply and isinstance(
|
|
1393
|
+
reply_to, InputMessageReplyToMessage
|
|
1394
|
+
):
|
|
1395
|
+
await self.getMessage(chat_id=chat_id, message_id=reply_to.message_id)
|
|
1396
|
+
|
|
1392
1397
|
res = await self.sendMessage(
|
|
1393
1398
|
chat_id=chat_id,
|
|
1394
1399
|
message_thread_id=message_thread_id,
|