mirror of
https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git
synced 2025-08-14 00:25:46 +02:00
Все подряд
This commit is contained in:
26
.venv2/Lib/site-packages/telethon/tl/core/__init__.py
Normal file
26
.venv2/Lib/site-packages/telethon/tl/core/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
This module holds core "special" types, which are more convenient ways
|
||||
to do stuff in a `telethon.network.mtprotosender.MTProtoSender` instance.
|
||||
|
||||
Only special cases are gzip-packed data, the response message (not a
|
||||
client message), the message container which references these messages
|
||||
and would otherwise conflict with the rest, and finally the RpcResult:
|
||||
|
||||
rpc_result#f35c6d01 req_msg_id:long result:bytes = RpcResult;
|
||||
|
||||
Three things to note with this definition:
|
||||
1. The constructor ID is actually ``42d36c2c``.
|
||||
2. Those bytes are not read like the rest of bytes (length + payload).
|
||||
They are actually the raw bytes of another object, which can't be
|
||||
read directly because it depends on per-request information (since
|
||||
some can return ``Vector<int>`` and ``Vector<long>``).
|
||||
3. Those bytes may be gzipped data, which needs to be treated early.
|
||||
"""
|
||||
from .tlmessage import TLMessage
|
||||
from .gzippacked import GzipPacked
|
||||
from .messagecontainer import MessageContainer
|
||||
from .rpcresult import RpcResult
|
||||
|
||||
core_objects = {x.CONSTRUCTOR_ID: x for x in (
|
||||
GzipPacked, MessageContainer, RpcResult
|
||||
)}
|
45
.venv2/Lib/site-packages/telethon/tl/core/gzippacked.py
Normal file
45
.venv2/Lib/site-packages/telethon/tl/core/gzippacked.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import gzip
|
||||
import struct
|
||||
|
||||
from .. import TLObject
|
||||
|
||||
|
||||
class GzipPacked(TLObject):
|
||||
CONSTRUCTOR_ID = 0x3072cfa1
|
||||
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
@staticmethod
|
||||
def gzip_if_smaller(content_related, data):
|
||||
"""Calls bytes(request), and based on a certain threshold,
|
||||
optionally gzips the resulting data. If the gzipped data is
|
||||
smaller than the original byte array, this is returned instead.
|
||||
|
||||
Note that this only applies to content related requests.
|
||||
"""
|
||||
if content_related and len(data) > 512:
|
||||
gzipped = bytes(GzipPacked(data))
|
||||
return gzipped if len(gzipped) < len(data) else data
|
||||
else:
|
||||
return data
|
||||
|
||||
def __bytes__(self):
|
||||
return struct.pack('<I', GzipPacked.CONSTRUCTOR_ID) + \
|
||||
TLObject.serialize_bytes(gzip.compress(self.data))
|
||||
|
||||
@staticmethod
|
||||
def read(reader):
|
||||
constructor = reader.read_int(signed=False)
|
||||
assert constructor == GzipPacked.CONSTRUCTOR_ID
|
||||
return gzip.decompress(reader.tgread_bytes())
|
||||
|
||||
@classmethod
|
||||
def from_reader(cls, reader):
|
||||
return GzipPacked(gzip.decompress(reader.tgread_bytes()))
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'_': 'GzipPacked',
|
||||
'data': self.data
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
from .tlmessage import TLMessage
|
||||
from ..tlobject import TLObject
|
||||
|
||||
|
||||
class MessageContainer(TLObject):
|
||||
CONSTRUCTOR_ID = 0x73f1f8dc
|
||||
|
||||
# Maximum size in bytes for the inner payload of the container.
|
||||
# Telegram will close the connection if the payload is bigger.
|
||||
# The overhead of the container itself is subtracted.
|
||||
MAXIMUM_SIZE = 1044456 - 8
|
||||
|
||||
# Maximum amount of messages that can't be sent inside a single
|
||||
# container, inclusive. Beyond this limit Telegram will respond
|
||||
# with BAD_MESSAGE 64 (invalid container).
|
||||
#
|
||||
# This limit is not 100% accurate and may in some cases be higher.
|
||||
# However, sending up to 100 requests at once in a single container
|
||||
# is a reasonable conservative value, since it could also depend on
|
||||
# other factors like size per request, but we cannot know this.
|
||||
MAXIMUM_LENGTH = 100
|
||||
|
||||
def __init__(self, messages):
|
||||
self.messages = messages
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'_': 'MessageContainer',
|
||||
'messages':
|
||||
[] if self.messages is None else [
|
||||
None if x is None else x.to_dict() for x in self.messages
|
||||
],
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_reader(cls, reader):
|
||||
# This assumes that .read_* calls are done in the order they appear
|
||||
messages = []
|
||||
for _ in range(reader.read_int()):
|
||||
msg_id = reader.read_long()
|
||||
seq_no = reader.read_int()
|
||||
length = reader.read_int()
|
||||
before = reader.tell_position()
|
||||
obj = reader.tgread_object() # May over-read e.g. RpcResult
|
||||
reader.set_position(before + length)
|
||||
messages.append(TLMessage(msg_id, seq_no, obj))
|
||||
return MessageContainer(messages)
|
35
.venv2/Lib/site-packages/telethon/tl/core/rpcresult.py
Normal file
35
.venv2/Lib/site-packages/telethon/tl/core/rpcresult.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from .gzippacked import GzipPacked
|
||||
from .. import TLObject
|
||||
from ..types import RpcError
|
||||
|
||||
|
||||
class RpcResult(TLObject):
|
||||
CONSTRUCTOR_ID = 0xf35c6d01
|
||||
|
||||
def __init__(self, req_msg_id, body, error):
|
||||
self.req_msg_id = req_msg_id
|
||||
self.body = body
|
||||
self.error = error
|
||||
|
||||
@classmethod
|
||||
def from_reader(cls, reader):
|
||||
msg_id = reader.read_long()
|
||||
inner_code = reader.read_int(signed=False)
|
||||
if inner_code == RpcError.CONSTRUCTOR_ID:
|
||||
return RpcResult(msg_id, None, RpcError.from_reader(reader))
|
||||
if inner_code == GzipPacked.CONSTRUCTOR_ID:
|
||||
return RpcResult(msg_id, GzipPacked.from_reader(reader).data, None)
|
||||
|
||||
reader.seek(-4)
|
||||
# This reader.read() will read more than necessary, but it's okay.
|
||||
# We could make use of MessageContainer's length here, but since
|
||||
# it's not necessary we don't need to care about it.
|
||||
return RpcResult(msg_id, reader.read(), None)
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'_': 'RpcResult',
|
||||
'req_msg_id': self.req_msg_id,
|
||||
'body': self.body,
|
||||
'error': self.error
|
||||
}
|
34
.venv2/Lib/site-packages/telethon/tl/core/tlmessage.py
Normal file
34
.venv2/Lib/site-packages/telethon/tl/core/tlmessage.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from .. import TLObject
|
||||
|
||||
|
||||
class TLMessage(TLObject):
|
||||
"""
|
||||
https://core.telegram.org/mtproto/service_messages#simple-container.
|
||||
|
||||
Messages are what's ultimately sent to Telegram:
|
||||
message msg_id:long seqno:int bytes:int body:bytes = Message;
|
||||
|
||||
Each message has its own unique identifier, and the body is simply
|
||||
the serialized request that should be executed on the server, or
|
||||
the response object from Telegram. Since the body is always a valid
|
||||
object, it makes sense to store the object and not the bytes to
|
||||
ease working with them.
|
||||
|
||||
There is no need to add serializing logic here since that can be
|
||||
inlined and is unlikely to change. Thus these are only needed to
|
||||
encapsulate responses.
|
||||
"""
|
||||
SIZE_OVERHEAD = 12
|
||||
|
||||
def __init__(self, msg_id, seq_no, obj):
|
||||
self.msg_id = msg_id
|
||||
self.seq_no = seq_no
|
||||
self.obj = obj
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
'_': 'TLMessage',
|
||||
'msg_id': self.msg_id,
|
||||
'seq_no': self.seq_no,
|
||||
'obj': self.obj
|
||||
}
|
Reference in New Issue
Block a user