Pytdbot 0.8.4.dev2__tar.gz → 0.8.4.dev3__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.8.4.dev2 → Pytdbot-0.8.4.dev3}/PKG-INFO +3 -2
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/Pytdbot.egg-info/PKG-INFO +3 -2
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/README.md +2 -1
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/__init__.py +1 -1
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/client.py +76 -68
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/LICENSE +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/MANIFEST.in +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/Pytdbot.egg-info/SOURCES.txt +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/Pytdbot.egg-info/dependency_links.txt +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/Pytdbot.egg-info/requires.txt +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/Pytdbot.egg-info/top_level.txt +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/exception/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/filters.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/generate_files.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/generate_json.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/handlers/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/handlers/decorators.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/handlers/handler.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/handlers/updates.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/methods/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/methods/methods.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/methods/tdlibfunctions.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/td_api.json +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/td_api.tl +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/tdjson/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/tdjson/tdjson.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/buttons/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/buttons/base.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/buttons/force_reply.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/buttons/inline_keyboard.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/buttons/remove_keyboard.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/buttons/show_keyboard.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/inputfile/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/inputfile/base.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/inputfile/input_file_generated.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/inputfile/input_file_id.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/inputfile/input_file_local.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/inputfile/input_file_remote.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/inputfile/input_thumbnail.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/logstream/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/logstream/base.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/logstream/log_stream_default.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/logstream/log_stream_empty.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/logstream/log_stream_file.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/plugins/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/plugins/plugins.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/result/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/result/result.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/update/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/update/chatActions.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/types/update/update.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/utils/__init__.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/utils/escape.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/pytdbot/utils/text_format.py +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/requirements.txt +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/setup.cfg +0 -0
- {Pytdbot-0.8.4.dev2 → Pytdbot-0.8.4.dev3}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Pytdbot
|
|
3
|
-
Version: 0.8.4.
|
|
3
|
+
Version: 0.8.4.dev3
|
|
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
|
|
@@ -36,10 +36,11 @@ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/t
|
|
|
36
36
|
### Installation
|
|
37
37
|
> For better performance, it's recommended to install [orjson](https://github.com/ijl/orjson#install) or [ujson](https://github.com/ultrajson/ultrajson#ultrajson).
|
|
38
38
|
|
|
39
|
+
You can install Pytdbot using pip:
|
|
39
40
|
```bash
|
|
40
41
|
pip install pytdbot
|
|
41
42
|
```
|
|
42
|
-
|
|
43
|
+
To install the development version from Github, use the following command:
|
|
43
44
|
```bash
|
|
44
45
|
pip install git+https://github.com/pytdbot/client.git
|
|
45
46
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Pytdbot
|
|
3
|
-
Version: 0.8.4.
|
|
3
|
+
Version: 0.8.4.dev3
|
|
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
|
|
@@ -36,10 +36,11 @@ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/t
|
|
|
36
36
|
### Installation
|
|
37
37
|
> For better performance, it's recommended to install [orjson](https://github.com/ijl/orjson#install) or [ujson](https://github.com/ultrajson/ultrajson#ultrajson).
|
|
38
38
|
|
|
39
|
+
You can install Pytdbot using pip:
|
|
39
40
|
```bash
|
|
40
41
|
pip install pytdbot
|
|
41
42
|
```
|
|
42
|
-
|
|
43
|
+
To install the development version from Github, use the following command:
|
|
43
44
|
```bash
|
|
44
45
|
pip install git+https://github.com/pytdbot/client.git
|
|
45
46
|
```
|
|
@@ -20,10 +20,11 @@ Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/t
|
|
|
20
20
|
### Installation
|
|
21
21
|
> For better performance, it's recommended to install [orjson](https://github.com/ijl/orjson#install) or [ujson](https://github.com/ultrajson/ultrajson#ultrajson).
|
|
22
22
|
|
|
23
|
+
You can install Pytdbot using pip:
|
|
23
24
|
```bash
|
|
24
25
|
pip install pytdbot
|
|
25
26
|
```
|
|
26
|
-
|
|
27
|
+
To install the development version from Github, use the following command:
|
|
27
28
|
```bash
|
|
28
29
|
pip install git+https://github.com/pytdbot/client.git
|
|
29
30
|
```
|
|
@@ -2,7 +2,7 @@ from . import types, utils, filters, exception
|
|
|
2
2
|
from .tdjson import TdJson
|
|
3
3
|
from .client import Client
|
|
4
4
|
|
|
5
|
-
__version__ = "0.8.
|
|
5
|
+
__version__ = "0.8.4dev3"
|
|
6
6
|
__copyright__ = "Copyright (c) 2022-2023 AYMEN Mohammed ~ https://github.com/AYMENJD"
|
|
7
7
|
__license__ = "MIT License"
|
|
8
8
|
|
|
@@ -12,8 +12,7 @@ from typing import Callable, Union
|
|
|
12
12
|
from logging import getLogger, DEBUG
|
|
13
13
|
from base64 import b64encode
|
|
14
14
|
from deepdiff import DeepDiff
|
|
15
|
-
from
|
|
16
|
-
from threading import current_thread, main_thread
|
|
15
|
+
from threading import current_thread, main_thread, Thread
|
|
17
16
|
from json import dumps
|
|
18
17
|
|
|
19
18
|
from .tdjson import TdJson
|
|
@@ -94,7 +93,7 @@ class Client(Decorators, Methods):
|
|
|
94
93
|
If any request is rate limited (flood waited) the client will repeat the request after sleeping the required amount of seconds returned by the error. If the ``retry after`` value is higher than ``sleep_threshold`` the error is returned. Defaults to ``None`` (Disabled)
|
|
95
94
|
|
|
96
95
|
workers (``int``, *optional*):
|
|
97
|
-
Number of workers
|
|
96
|
+
Number of workers to handle updates. Defaults to ``5``. If set to ``None``, updates will be immediately handled instead of being queued, which can impact performance.
|
|
98
97
|
|
|
99
98
|
td_verbosity (``int``, *optional*):
|
|
100
99
|
Verbosity level of TDLib. Defaults to ``2``
|
|
@@ -140,7 +139,7 @@ class Client(Decorators, Methods):
|
|
|
140
139
|
self.default_parse_mode = (
|
|
141
140
|
default_parse_mode
|
|
142
141
|
if isinstance(default_parse_mode, str)
|
|
143
|
-
and default_parse_mode in
|
|
142
|
+
and default_parse_mode in ("markdown", "markdownv2", "html")
|
|
144
143
|
else None
|
|
145
144
|
)
|
|
146
145
|
self.system_language_code = system_language_code
|
|
@@ -169,9 +168,9 @@ class Client(Decorators, Methods):
|
|
|
169
168
|
self._handlers = {"initializer": [], "finalizer": []}
|
|
170
169
|
self._results = {}
|
|
171
170
|
self._tdjson = TdJson(lib_path, td_verbosity)
|
|
172
|
-
self._executor = ThreadPoolExecutor(5, "Pytdbot")
|
|
173
|
-
self._workers_tasks = None
|
|
174
171
|
self._retry_after_prefex = "Too Many Requests: retry after "
|
|
172
|
+
self._workers_tasks = None
|
|
173
|
+
self.__listen_loop_thread = Thread(target=self.__listen_loop, daemon=True)
|
|
175
174
|
self.__authorization_state = None
|
|
176
175
|
self.__authorization = None
|
|
177
176
|
self.__cache = {"is_coro_filter": {}}
|
|
@@ -218,14 +217,19 @@ class Client(Decorators, Methods):
|
|
|
218
217
|
if not self.is_running:
|
|
219
218
|
logger.info("Starting pytdbot client...")
|
|
220
219
|
|
|
221
|
-
self.
|
|
222
|
-
self.
|
|
223
|
-
|
|
224
|
-
|
|
220
|
+
if isinstance(self.workers, int):
|
|
221
|
+
self._workers_tasks = [
|
|
222
|
+
self.loop.create_task(self._queue_update_worker())
|
|
223
|
+
for x in range(self.workers)
|
|
224
|
+
]
|
|
225
|
+
self.__is_queue_worker = True
|
|
225
226
|
|
|
226
|
-
|
|
227
|
+
logger.info("Started with %s workers", self.workers)
|
|
228
|
+
else:
|
|
229
|
+
self.__is_queue_worker = False
|
|
230
|
+
logger.info("Started with unlimited updates processes")
|
|
227
231
|
|
|
228
|
-
self.
|
|
232
|
+
self.__listen_loop_thread.start()
|
|
229
233
|
|
|
230
234
|
if login:
|
|
231
235
|
await self.login()
|
|
@@ -238,7 +242,7 @@ class Client(Decorators, Methods):
|
|
|
238
242
|
|
|
239
243
|
self.__login = True
|
|
240
244
|
|
|
241
|
-
await self.getOption("version") # Ping TDLib to start authorization
|
|
245
|
+
await self.getOption("version") # Ping TDLib to start authorization process
|
|
242
246
|
|
|
243
247
|
while self.authorization_state != "authorizationStateReady":
|
|
244
248
|
await asyncio.sleep(0.1)
|
|
@@ -503,12 +507,7 @@ class Client(Decorators, Methods):
|
|
|
503
507
|
def __send(self, request: dict) -> None:
|
|
504
508
|
return self._tdjson.send(
|
|
505
509
|
request
|
|
506
|
-
) # tdjson.send is
|
|
507
|
-
|
|
508
|
-
async def __receive(self, timeout: float = 2.0) -> dict:
|
|
509
|
-
return await self.loop.run_in_executor(
|
|
510
|
-
self._executor, self._tdjson.receive, timeout
|
|
511
|
-
)
|
|
510
|
+
) # tdjson.send is non-blocking method, So we don't need run_in_executor. This improves performance
|
|
512
511
|
|
|
513
512
|
def _check_init_args(self):
|
|
514
513
|
if not isinstance(self.__api_id, int):
|
|
@@ -523,14 +522,12 @@ class Client(Decorators, Methods):
|
|
|
523
522
|
raise TypeError("files_directory must be str")
|
|
524
523
|
elif not isinstance(self.td_verbosity, int):
|
|
525
524
|
raise TypeError("td_verbosity must be int")
|
|
526
|
-
elif not isinstance(self.workers, int):
|
|
527
|
-
raise TypeError("workers must be int")
|
|
528
525
|
elif type(Update) is not type(self.update_class):
|
|
529
526
|
raise TypeError(
|
|
530
527
|
"update_class must be instance of class pytdbot.types.Update"
|
|
531
528
|
)
|
|
532
529
|
|
|
533
|
-
if self.workers < 1:
|
|
530
|
+
if isinstance(self.workers, int) and self.workers < 1:
|
|
534
531
|
raise ValueError("workers must be greater than 0")
|
|
535
532
|
|
|
536
533
|
def get_retry_after_time(self, error_message: str) -> int:
|
|
@@ -589,13 +586,13 @@ class Client(Decorators, Methods):
|
|
|
589
586
|
self.__cache["is_coro_filter"][func] = is_coro
|
|
590
587
|
return is_coro
|
|
591
588
|
|
|
592
|
-
|
|
589
|
+
def __listen_loop(self):
|
|
593
590
|
try:
|
|
594
591
|
self.is_running = True
|
|
595
592
|
logger.info("Listening to updates...")
|
|
596
593
|
|
|
597
594
|
while self.is_running:
|
|
598
|
-
update =
|
|
595
|
+
update = self._tdjson.receive(100000.0) # seconds
|
|
599
596
|
if update is None:
|
|
600
597
|
continue
|
|
601
598
|
self._process_update(update)
|
|
@@ -624,19 +621,36 @@ class Client(Decorators, Methods):
|
|
|
624
621
|
logger.error(f"{update['@extra']['option']}: {update['message']}")
|
|
625
622
|
else:
|
|
626
623
|
if update["@type"] == "updateAuthorizationState":
|
|
627
|
-
|
|
624
|
+
asyncio.run_coroutine_threadsafe(
|
|
625
|
+
self.__handle_authorization_state(update), loop=self.loop
|
|
626
|
+
)
|
|
628
627
|
elif update["@type"] == "updateMessageSendSucceeded":
|
|
629
|
-
|
|
628
|
+
asyncio.run_coroutine_threadsafe(
|
|
629
|
+
self.__handle_update_message_succeeded(update), loop=self.loop
|
|
630
|
+
)
|
|
630
631
|
elif update["@type"] == "updateMessageSendFailed":
|
|
631
|
-
|
|
632
|
+
asyncio.run_coroutine_threadsafe(
|
|
633
|
+
self.__handle_update_message_failed(update), loop=self.loop
|
|
634
|
+
)
|
|
632
635
|
elif update["@type"] == "updateConnectionState":
|
|
633
|
-
|
|
636
|
+
asyncio.run_coroutine_threadsafe(
|
|
637
|
+
self.__handle_connection_state(update), loop=self.loop
|
|
638
|
+
)
|
|
634
639
|
elif update["@type"] == "updateOption":
|
|
635
|
-
|
|
640
|
+
asyncio.run_coroutine_threadsafe(
|
|
641
|
+
self.__handle_update_option(update), loop=self.loop
|
|
642
|
+
)
|
|
636
643
|
elif update["@type"] == "updateUser":
|
|
637
|
-
|
|
644
|
+
asyncio.run_coroutine_threadsafe(
|
|
645
|
+
self.__handle_update_user(update), loop=self.loop
|
|
646
|
+
)
|
|
638
647
|
|
|
639
|
-
self.
|
|
648
|
+
if self.__is_queue_worker:
|
|
649
|
+
self.queue.put_nowait(update)
|
|
650
|
+
else:
|
|
651
|
+
asyncio.run_coroutine_threadsafe(
|
|
652
|
+
self._handle_update(update), loop=self.loop
|
|
653
|
+
)
|
|
640
654
|
|
|
641
655
|
async def __run_initializers(self, update):
|
|
642
656
|
for initializer in self._handlers["initializer"]:
|
|
@@ -692,39 +706,35 @@ class Client(Decorators, Methods):
|
|
|
692
706
|
except Exception:
|
|
693
707
|
logger.exception(f"Finalizer {finalizer} failed")
|
|
694
708
|
|
|
695
|
-
async def
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
709
|
+
async def _handle_update(self, update):
|
|
710
|
+
if (
|
|
711
|
+
logger.root.level >= DEBUG
|
|
712
|
+
): # dumping all updates can create performance issues
|
|
713
|
+
logger.debug(
|
|
714
|
+
f"Received: {dumps(update, indent=4)}",
|
|
715
|
+
)
|
|
702
716
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
717
|
+
if update["@type"] in self._handlers:
|
|
718
|
+
update = self.update_class(self, update)
|
|
719
|
+
if (
|
|
720
|
+
update["@type"] == "updateNewMessage"
|
|
721
|
+
and update["message"]["is_outgoing"]
|
|
722
|
+
and "sending_state" in update["message"]
|
|
723
|
+
):
|
|
724
|
+
return
|
|
709
725
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
continue
|
|
726
|
+
try:
|
|
727
|
+
await self.__run_initializers(update)
|
|
728
|
+
await self.__run_handlers(update)
|
|
729
|
+
except StopHandlers:
|
|
730
|
+
pass
|
|
731
|
+
finally:
|
|
732
|
+
await self.__run_finalizers(update)
|
|
718
733
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
pass
|
|
724
|
-
finally:
|
|
725
|
-
await self.__run_finalizers(update)
|
|
726
|
-
except Exception:
|
|
727
|
-
logger.exception("Exception in _update_worker")
|
|
734
|
+
async def _queue_update_worker(self):
|
|
735
|
+
self.is_running = True
|
|
736
|
+
while self.is_running:
|
|
737
|
+
await self._handle_update(await self.queue.get())
|
|
728
738
|
|
|
729
739
|
async def set_td_paramaters(self):
|
|
730
740
|
"""Make a call to :meth:`~pytdbot.Client.setTdlibParameters` with the current client init parameters
|
|
@@ -1014,8 +1024,7 @@ class Client(Decorators, Methods):
|
|
|
1014
1024
|
print(f"Your 2FA password hint is: {self.__authorization['password_hint']}")
|
|
1015
1025
|
|
|
1016
1026
|
while self.is_running:
|
|
1017
|
-
password = await
|
|
1018
|
-
self._executor,
|
|
1027
|
+
password = await asyncio.to_thread(
|
|
1019
1028
|
getpass,
|
|
1020
1029
|
"Enter your 2FA password {}: ".format(
|
|
1021
1030
|
"(empty to recover)"
|
|
@@ -1074,10 +1083,9 @@ class Client(Decorators, Methods):
|
|
|
1074
1083
|
self.is_authenticated = False
|
|
1075
1084
|
self.is_running = False
|
|
1076
1085
|
|
|
1077
|
-
|
|
1078
|
-
worker_task.
|
|
1079
|
-
|
|
1080
|
-
self._executor.shutdown(wait=False, cancel_futures=True)
|
|
1086
|
+
if self.__is_queue_worker:
|
|
1087
|
+
for worker_task in self._workers_tasks:
|
|
1088
|
+
worker_task.cancel()
|
|
1081
1089
|
|
|
1082
1090
|
def _register_signal_handlers(self):
|
|
1083
1091
|
def _handle_signal():
|
|
@@ -1103,7 +1111,7 @@ class Client(Decorators, Methods):
|
|
|
1103
1111
|
pass
|
|
1104
1112
|
|
|
1105
1113
|
def __ainput(self, prompt: str):
|
|
1106
|
-
return
|
|
1114
|
+
return asyncio.to_thread(input, prompt)
|
|
1107
1115
|
|
|
1108
1116
|
def _print_welcome(self):
|
|
1109
1117
|
print(f"Welcome to Pytdbot (v{pytdbot.__version__}). {pytdbot.__copyright__}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|