mirror of
https://github.com/pyrogram/pyrogram
synced 2025-09-02 07:15:23 +00:00
Merge branch 'master' into new-api
# Conflicts: # pyrogram/client/client.py
This commit is contained in:
@@ -23,7 +23,7 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance
|
||||
"e" if sys.getfilesystemencoding() == "ascii" else "\xe8"
|
||||
)
|
||||
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
||||
__version__ = "0.6.2"
|
||||
__version__ = "0.6.4"
|
||||
|
||||
from .api.errors import Error
|
||||
from .client import ChatAction
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -81,7 +81,7 @@ class InputMedia:
|
||||
width: int = 0,
|
||||
height: int = 0,
|
||||
duration: int = 0,
|
||||
supports_streaming: bool = None):
|
||||
supports_streaming: bool = True):
|
||||
self.media = media
|
||||
self.caption = caption
|
||||
self.parse_mode = parse_mode
|
||||
|
@@ -36,7 +36,7 @@ class Markdown:
|
||||
CODE_DELIMITER = "`"
|
||||
PRE_DELIMITER = "```"
|
||||
|
||||
MARKDOWN_RE = re.compile(r"```([\w ]*)\n([\w\W]*)(?:\n|)```|\[([^[(]+)\]\(([^])]+)\)|({d})(.+?)\5".format(
|
||||
MARKDOWN_RE = re.compile(r"```([\w ]*)\n([\w\W]*)(?:\n|)```|\[(.+?)\]\((.+?)\)|({d})(.+?)\5".format(
|
||||
d="|".join(
|
||||
["".join(i) for i in [
|
||||
["\{}".format(j) for j in i]
|
||||
|
@@ -54,6 +54,7 @@ class Connection:
|
||||
|
||||
def close(self):
|
||||
self.connection.close()
|
||||
log.info("Disconnected")
|
||||
|
||||
def send(self, data: bytes):
|
||||
with self.lock:
|
||||
|
@@ -20,7 +20,15 @@ import logging
|
||||
import socket
|
||||
from collections import namedtuple
|
||||
|
||||
import socks
|
||||
try:
|
||||
import socks
|
||||
except ImportError as e:
|
||||
e.msg = (
|
||||
"PySocks is missing and Pyrogram can't run without. "
|
||||
"Please install it using \"pip3 install pysocks\"."
|
||||
)
|
||||
|
||||
raise e
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -16,52 +16,33 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import tgcrypto
|
||||
except ImportError:
|
||||
log.warning(
|
||||
"TgCrypto is missing! "
|
||||
"Pyrogram will work the same, but at a much slower speed. "
|
||||
except ImportError as e:
|
||||
e.msg = (
|
||||
"TgCrypto is missing and Pyrogram can't run without. "
|
||||
"Please install it using \"pip3 install tgcrypto\". "
|
||||
"More info: https://docs.pyrogram.ml/resources/TgCrypto"
|
||||
)
|
||||
is_fast = False
|
||||
import pyaes
|
||||
else:
|
||||
log.info("Using TgCrypto")
|
||||
is_fast = True
|
||||
|
||||
raise e
|
||||
|
||||
|
||||
# TODO: Ugly IFs
|
||||
class AES:
|
||||
@classmethod
|
||||
def ige_encrypt(cls, data: bytes, key: bytes, iv: bytes) -> bytes:
|
||||
if is_fast:
|
||||
return tgcrypto.ige_encrypt(data, key, iv)
|
||||
else:
|
||||
return cls.ige(data, key, iv, True)
|
||||
return tgcrypto.ige_encrypt(data, key, iv)
|
||||
|
||||
@classmethod
|
||||
def ige_decrypt(cls, data: bytes, key: bytes, iv: bytes) -> bytes:
|
||||
if is_fast:
|
||||
return tgcrypto.ige_decrypt(data, key, iv)
|
||||
else:
|
||||
return cls.ige(data, key, iv, False)
|
||||
return tgcrypto.ige_decrypt(data, key, iv)
|
||||
|
||||
@staticmethod
|
||||
def ctr_decrypt(data: bytes, key: bytes, iv: bytes, offset: int) -> bytes:
|
||||
replace = int.to_bytes(offset // 16, byteorder="big", length=4)
|
||||
replace = int.to_bytes(offset // 16, 4, "big")
|
||||
iv = iv[:-4] + replace
|
||||
|
||||
if is_fast:
|
||||
return tgcrypto.ctr_decrypt(data, key, iv)
|
||||
else:
|
||||
ctr = pyaes.AESModeOfOperationCTR(key)
|
||||
ctr._counter._counter = list(iv)
|
||||
return ctr.decrypt(data)
|
||||
return tgcrypto.ctr_decrypt(data, key, iv)
|
||||
|
||||
@staticmethod
|
||||
def xor(a: bytes, b: bytes) -> bytes:
|
||||
@@ -70,23 +51,3 @@ class AES:
|
||||
len(a),
|
||||
"big",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def ige(cls, data: bytes, key: bytes, iv: bytes, encrypt: bool) -> bytes:
|
||||
cipher = pyaes.AES(key)
|
||||
|
||||
iv_1 = iv[:16]
|
||||
iv_2 = iv[16:]
|
||||
|
||||
data = [data[i: i + 16] for i in range(0, len(data), 16)]
|
||||
|
||||
if encrypt:
|
||||
for i, chunk in enumerate(data):
|
||||
iv_1 = data[i] = cls.xor(cipher.encrypt(cls.xor(chunk, iv_1)), iv_2)
|
||||
iv_2 = chunk
|
||||
else:
|
||||
for i, chunk in enumerate(data):
|
||||
iv_2 = data[i] = cls.xor(cipher.decrypt(cls.xor(chunk, iv_2)), iv_1)
|
||||
iv_1 = chunk
|
||||
|
||||
return b"".join(data)
|
||||
|
@@ -61,7 +61,7 @@ class Session:
|
||||
|
||||
INITIAL_SALT = 0x616e67656c696361
|
||||
NET_WORKERS = 1
|
||||
WAIT_TIMEOUT = 10
|
||||
WAIT_TIMEOUT = 30
|
||||
MAX_RETRIES = 5
|
||||
ACKS_THRESHOLD = 8
|
||||
PING_INTERVAL = 5
|
||||
@@ -122,8 +122,6 @@ class Session:
|
||||
self.is_connected = Event()
|
||||
|
||||
def start(self):
|
||||
terms = None
|
||||
|
||||
while True:
|
||||
try:
|
||||
self.connection.connect()
|
||||
@@ -141,7 +139,7 @@ class Session:
|
||||
self.next_salt_thread.start()
|
||||
|
||||
if not self.is_cdn:
|
||||
terms = self._send(
|
||||
self._send(
|
||||
functions.InvokeWithLayer(
|
||||
layer,
|
||||
functions.InitConnection(
|
||||
@@ -150,10 +148,10 @@ class Session:
|
||||
self.SYSTEM_VERSION,
|
||||
self.APP_VERSION,
|
||||
"en", "", "en",
|
||||
functions.help.GetTermsOfService(),
|
||||
functions.help.GetConfig(),
|
||||
)
|
||||
)
|
||||
).text
|
||||
)
|
||||
|
||||
self.ping_thread = Thread(target=self.ping, name="PingThread")
|
||||
self.ping_thread.start()
|
||||
@@ -168,8 +166,6 @@ class Session:
|
||||
|
||||
log.debug("Session started")
|
||||
|
||||
return terms
|
||||
|
||||
def stop(self):
|
||||
self.is_connected.clear()
|
||||
|
||||
@@ -190,6 +186,9 @@ class Session:
|
||||
for i in range(self.NET_WORKERS):
|
||||
self.recv_queue.put(None)
|
||||
|
||||
for i in self.results.values():
|
||||
i.event.set()
|
||||
|
||||
log.debug("Session stopped")
|
||||
|
||||
def restart(self):
|
||||
@@ -401,7 +400,7 @@ class Session:
|
||||
try:
|
||||
return self._send(data)
|
||||
except (OSError, TimeoutError):
|
||||
log.warning("Retrying {}".format(type(data)))
|
||||
(log.warning if i > 0 else log.info)("{}: {} Retrying {}".format(i, datetime.now(), type(data)))
|
||||
continue
|
||||
else:
|
||||
return None
|
||||
|
Reference in New Issue
Block a user