mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-29 04:43:45 +03:00
Replace most raw API usage with new location
This commit is contained in:
parent
a901d43a6d
commit
d48649602b
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,6 +1,6 @@
|
|||
# Generated code
|
||||
/telethon/_tl/functions/
|
||||
/telethon/_tl/types/
|
||||
/telethon/_tl/fn/
|
||||
/telethon/_tl/*.py
|
||||
/telethon/_tl/alltlobjects.py
|
||||
/telethon/errors/rpcerrorlist.py
|
||||
|
||||
|
|
2
setup.py
2
setup.py
|
@ -55,7 +55,7 @@ METHODS_IN = GENERATOR_DIR / 'data/methods.csv'
|
|||
FRIENDLY_IN = GENERATOR_DIR / 'data/friendly.csv'
|
||||
|
||||
TLOBJECT_IN_TLS = [Path(x) for x in GENERATOR_DIR.glob('data/*.tl')]
|
||||
TLOBJECT_OUT = LIBRARY_DIR / 'tl'
|
||||
TLOBJECT_OUT = LIBRARY_DIR / '_tl'
|
||||
IMPORT_DEPTH = 2
|
||||
|
||||
DOCS_IN_RES = GENERATOR_DIR / 'data/html'
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
from ._client.telegramclient import TelegramClient
|
||||
from .network import connection
|
||||
from .tl import types, functions, custom
|
||||
from .tl.custom import Button
|
||||
from .tl import patched as _ # import for its side-effects
|
||||
from ._tl import custom
|
||||
from ._tl.custom import Button
|
||||
from . import version, events, utils, errors
|
||||
|
||||
__version__ = version.__version__
|
||||
|
|
|
@ -3,8 +3,7 @@ import inspect
|
|||
import typing
|
||||
|
||||
from .users import _NOT_A_REQUEST
|
||||
from .. import helpers, utils
|
||||
from ..tl import functions, TLRequest
|
||||
from .. import helpers, utils, _tl
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .telegramclient import TelegramClient
|
||||
|
@ -50,7 +49,7 @@ class _TakeoutClient:
|
|||
self.__success = exc_type is None
|
||||
|
||||
if self.__success is not None:
|
||||
result = await self(functions.account.FinishTakeoutSessionRequest(
|
||||
result = await self(_tl.fn.account.FinishTakeoutSession(
|
||||
self.__success))
|
||||
if not result:
|
||||
raise ValueError("Failed to finish the takeout.")
|
||||
|
@ -66,10 +65,10 @@ class _TakeoutClient:
|
|||
requests = ((request,) if single else request)
|
||||
wrapped = []
|
||||
for r in requests:
|
||||
if not isinstance(r, TLRequest):
|
||||
if not isinstance(r, _tl.TLRequest):
|
||||
raise _NOT_A_REQUEST()
|
||||
await r.resolve(self, utils)
|
||||
wrapped.append(functions.InvokeWithTakeoutRequest(takeout_id, r))
|
||||
wrapped.append(_tl.fn.InvokeWithTakeout(takeout_id, r))
|
||||
|
||||
return await self.__client(
|
||||
wrapped[0] if single else wrapped, ordered=ordered)
|
||||
|
@ -127,7 +126,7 @@ def takeout(
|
|||
arg_specified = (arg is not None for arg in request_kwargs.values())
|
||||
|
||||
if self.session.takeout_id is None or any(arg_specified):
|
||||
request = functions.account.InitTakeoutSessionRequest(
|
||||
request = _tl.fn.account.InitTakeoutSession(
|
||||
**request_kwargs)
|
||||
else:
|
||||
request = None
|
||||
|
|
|
@ -5,8 +5,7 @@ import sys
|
|||
import typing
|
||||
import warnings
|
||||
|
||||
from .. import utils, helpers, errors, password as pwd_mod
|
||||
from ..tl import types, functions, custom
|
||||
from .. import utils, helpers, errors, password as pwd_mod, _tl
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .telegramclient import TelegramClient
|
||||
|
@ -201,7 +200,7 @@ async def sign_in(
|
|||
*,
|
||||
password: str = None,
|
||||
bot_token: str = None,
|
||||
phone_code_hash: str = None) -> 'typing.Union[types.User, types.auth.SentCode]':
|
||||
phone_code_hash: str = None) -> 'typing.Union[_tl.User, _tl.auth.SentCode]':
|
||||
me = await self.get_me()
|
||||
if me:
|
||||
return me
|
||||
|
@ -214,16 +213,16 @@ async def sign_in(
|
|||
|
||||
# May raise PhoneCodeEmptyError, PhoneCodeExpiredError,
|
||||
# PhoneCodeHashEmptyError or PhoneCodeInvalidError.
|
||||
request = functions.auth.SignInRequest(
|
||||
request = _tl.fn.auth.SignIn(
|
||||
phone, phone_code_hash, str(code)
|
||||
)
|
||||
elif password:
|
||||
pwd = await self(functions.account.GetPasswordRequest())
|
||||
request = functions.auth.CheckPasswordRequest(
|
||||
pwd = await self(_tl.fn.account.GetPassword())
|
||||
request = _tl.fn.auth.CheckPassword(
|
||||
pwd_mod.compute_check(pwd, password)
|
||||
)
|
||||
elif bot_token:
|
||||
request = functions.auth.ImportBotAuthorizationRequest(
|
||||
request = _tl.fn.auth.ImportBotAuthorization(
|
||||
flags=0, bot_auth_token=bot_token,
|
||||
api_id=self.api_id, api_hash=self.api_hash
|
||||
)
|
||||
|
@ -234,7 +233,7 @@ async def sign_in(
|
|||
)
|
||||
|
||||
result = await self(request)
|
||||
if isinstance(result, types.auth.AuthorizationSignUpRequired):
|
||||
if isinstance(result, _tl.auth.AuthorizationSignUpRequired):
|
||||
# Emulate pre-layer 104 behaviour
|
||||
self._tos = result.terms_of_service
|
||||
raise errors.PhoneNumberUnoccupiedError(request=request)
|
||||
|
@ -248,7 +247,7 @@ async def sign_up(
|
|||
last_name: str = '',
|
||||
*,
|
||||
phone: str = None,
|
||||
phone_code_hash: str = None) -> 'types.User':
|
||||
phone_code_hash: str = None) -> '_tl.User':
|
||||
me = await self.get_me()
|
||||
if me:
|
||||
return me
|
||||
|
@ -281,7 +280,7 @@ async def sign_up(
|
|||
phone, phone_code_hash = \
|
||||
self._parse_phone_and_hash(phone, phone_code_hash)
|
||||
|
||||
result = await self(functions.auth.SignUpRequest(
|
||||
result = await self(_tl.fn.auth.SignUp(
|
||||
phone_number=phone,
|
||||
phone_code_hash=phone_code_hash,
|
||||
first_name=first_name,
|
||||
|
@ -290,7 +289,7 @@ async def sign_up(
|
|||
|
||||
if self._tos:
|
||||
await self(
|
||||
functions.help.AcceptTermsOfServiceRequest(self._tos.id))
|
||||
_tl.fn.help.AcceptTermsOfService(self._tos.id))
|
||||
|
||||
return self._on_login(result.user)
|
||||
|
||||
|
@ -309,20 +308,20 @@ async def send_code_request(
|
|||
self: 'TelegramClient',
|
||||
phone: str,
|
||||
*,
|
||||
force_sms: bool = False) -> 'types.auth.SentCode':
|
||||
force_sms: bool = False) -> '_tl.auth.SentCode':
|
||||
result = None
|
||||
phone = utils.parse_phone(phone) or self._phone
|
||||
phone_hash = self._phone_code_hash.get(phone)
|
||||
|
||||
if not phone_hash:
|
||||
try:
|
||||
result = await self(functions.auth.SendCodeRequest(
|
||||
phone, self.api_id, self.api_hash, types.CodeSettings()))
|
||||
result = await self(_tl.fn.auth.SendCode(
|
||||
phone, self.api_id, self.api_hash, _tl.CodeSettings()))
|
||||
except errors.AuthRestartError:
|
||||
return await self.send_code_request(phone, force_sms=force_sms)
|
||||
|
||||
# If we already sent a SMS, do not resend the code (hash may be empty)
|
||||
if isinstance(result.type, types.auth.SentCodeTypeSms):
|
||||
if isinstance(result.type, _tl.auth.SentCodeTypeSms):
|
||||
force_sms = False
|
||||
|
||||
# phone_code_hash may be empty, if it is, do not save it (#1283)
|
||||
|
@ -335,7 +334,7 @@ async def send_code_request(
|
|||
|
||||
if force_sms:
|
||||
result = await self(
|
||||
functions.auth.ResendCodeRequest(phone, phone_hash))
|
||||
_tl.fn.auth.ResendCode(phone, phone_hash))
|
||||
|
||||
self._phone_code_hash[phone] = result.phone_code_hash
|
||||
|
||||
|
@ -348,7 +347,7 @@ async def qr_login(self: 'TelegramClient', ignored_ids: typing.List[int] = None)
|
|||
|
||||
async def log_out(self: 'TelegramClient') -> bool:
|
||||
try:
|
||||
await self(functions.auth.LogOutRequest())
|
||||
await self(_tl.fn.auth.LogOut())
|
||||
except errors.RPCError:
|
||||
return False
|
||||
|
||||
|
@ -375,16 +374,16 @@ async def edit_2fa(
|
|||
if email and not callable(email_code_callback):
|
||||
raise ValueError('email present without email_code_callback')
|
||||
|
||||
pwd = await self(functions.account.GetPasswordRequest())
|
||||
pwd = await self(_tl.fn.account.GetPassword())
|
||||
pwd.new_algo.salt1 += os.urandom(32)
|
||||
assert isinstance(pwd, types.account.Password)
|
||||
assert isinstance(pwd, _tl.account.Password)
|
||||
if not pwd.has_password and current_password:
|
||||
current_password = None
|
||||
|
||||
if current_password:
|
||||
password = pwd_mod.compute_check(pwd, current_password)
|
||||
else:
|
||||
password = types.InputCheckPasswordEmpty()
|
||||
password = _tl.InputCheckPasswordEmpty()
|
||||
|
||||
if new_password:
|
||||
new_password_hash = pwd_mod.compute_digest(
|
||||
|
@ -393,9 +392,9 @@ async def edit_2fa(
|
|||
new_password_hash = b''
|
||||
|
||||
try:
|
||||
await self(functions.account.UpdatePasswordSettingsRequest(
|
||||
await self(_tl.fn.account.UpdatePasswordSettings(
|
||||
password=password,
|
||||
new_settings=types.account.PasswordInputSettings(
|
||||
new_settings=_tl.account.PasswordInputSettings(
|
||||
new_algo=pwd.new_algo,
|
||||
new_password_hash=new_password_hash,
|
||||
hint=hint,
|
||||
|
@ -409,6 +408,6 @@ async def edit_2fa(
|
|||
code = await code
|
||||
|
||||
code = str(code)
|
||||
await self(functions.account.ConfirmPasswordEmailRequest(code))
|
||||
await self(_tl.fn.account.ConfirmPasswordEmail(code))
|
||||
|
||||
return True
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import typing
|
||||
|
||||
from .. import hints
|
||||
from ..tl import types, functions, custom
|
||||
from .. import hints, _tl
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .telegramclient import TelegramClient
|
||||
|
@ -14,14 +13,14 @@ async def inline_query(
|
|||
*,
|
||||
entity: 'hints.EntityLike' = None,
|
||||
offset: str = None,
|
||||
geo_point: 'types.GeoPoint' = None) -> custom.InlineResults:
|
||||
geo_point: '_tl.GeoPoint' = None) -> _tl.custom.InlineResults:
|
||||
bot = await self.get_input_entity(bot)
|
||||
if entity:
|
||||
peer = await self.get_input_entity(entity)
|
||||
else:
|
||||
peer = types.InputPeerEmpty()
|
||||
peer = _tl.InputPeerEmpty()
|
||||
|
||||
result = await self(functions.messages.GetInlineBotResultsRequest(
|
||||
result = await self(_tl.fn.messages.GetInlineBotResults(
|
||||
bot=bot,
|
||||
peer=peer,
|
||||
query=query,
|
||||
|
@ -29,4 +28,4 @@ async def inline_query(
|
|||
geo_point=geo_point
|
||||
))
|
||||
|
||||
return custom.InlineResults(self, result, entity=peer if entity else None)
|
||||
return _tl.custom.InlineResults(self, result, entity=peer if entity else None)
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import typing
|
||||
|
||||
from .. import utils, hints
|
||||
from ..tl import types, custom
|
||||
from .. import utils, hints, _tl
|
||||
|
||||
|
||||
def build_reply_markup(
|
||||
buttons: 'typing.Optional[hints.MarkupLike]',
|
||||
inline_only: bool = False) -> 'typing.Optional[types.TypeReplyMarkup]':
|
||||
inline_only: bool = False) -> 'typing.Optional[_tl.TypeReplyMarkup]':
|
||||
if buttons is None:
|
||||
return None
|
||||
|
||||
|
@ -31,7 +30,7 @@ def build_reply_markup(
|
|||
for row in buttons:
|
||||
current = []
|
||||
for button in row:
|
||||
if isinstance(button, custom.Button):
|
||||
if isinstance(button, _tl.custom.Button):
|
||||
if button.resize is not None:
|
||||
resize = button.resize
|
||||
if button.single_use is not None:
|
||||
|
@ -40,10 +39,10 @@ def build_reply_markup(
|
|||
selective = button.selective
|
||||
|
||||
button = button.button
|
||||
elif isinstance(button, custom.MessageButton):
|
||||
elif isinstance(button, _tl.custom.MessageButton):
|
||||
button = button.button
|
||||
|
||||
inline = custom.Button._is_inline(button)
|
||||
inline = _tl.custom.Button._is_inline(button)
|
||||
is_inline |= inline
|
||||
is_normal |= not inline
|
||||
|
||||
|
@ -52,14 +51,14 @@ def build_reply_markup(
|
|||
current.append(button)
|
||||
|
||||
if current:
|
||||
rows.append(types.KeyboardButtonRow(current))
|
||||
rows.append(_tl.KeyboardButtonRow(current))
|
||||
|
||||
if inline_only and is_normal:
|
||||
raise ValueError('You cannot use non-inline buttons here')
|
||||
elif is_inline == is_normal and is_normal:
|
||||
raise ValueError('You cannot mix inline with normal buttons')
|
||||
elif is_inline:
|
||||
return types.ReplyInlineMarkup(rows)
|
||||
return _tl.ReplyInlineMarkup(rows)
|
||||
# elif is_normal:
|
||||
return types.ReplyKeyboardMarkup(
|
||||
return _tl.ReplyKeyboardMarkup(
|
||||
rows, resize=resize, single_use=single_use, selective=selective)
|
||||
|
|
|
@ -4,9 +4,8 @@ import itertools
|
|||
import string
|
||||
import typing
|
||||
|
||||
from .. import helpers, utils, hints, errors
|
||||
from .. import helpers, utils, hints, errors, _tl
|
||||
from ..requestiter import RequestIter
|
||||
from ..tl import types, functions, custom
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .telegramclient import TelegramClient
|
||||
|
@ -18,28 +17,28 @@ _MAX_PROFILE_PHOTO_CHUNK_SIZE = 100
|
|||
|
||||
class _ChatAction:
|
||||
_str_mapping = {
|
||||
'typing': types.SendMessageTypingAction(),
|
||||
'contact': types.SendMessageChooseContactAction(),
|
||||
'game': types.SendMessageGamePlayAction(),
|
||||
'location': types.SendMessageGeoLocationAction(),
|
||||
'sticker': types.SendMessageChooseStickerAction(),
|
||||
'typing': _tl.SendMessageTypingAction(),
|
||||
'contact': _tl.SendMessageChooseContactAction(),
|
||||
'game': _tl.SendMessageGamePlayAction(),
|
||||
'location': _tl.SendMessageGeoLocationAction(),
|
||||
'sticker': _tl.SendMessageChooseStickerAction(),
|
||||
|
||||
'record-audio': types.SendMessageRecordAudioAction(),
|
||||
'record-voice': types.SendMessageRecordAudioAction(), # alias
|
||||
'record-round': types.SendMessageRecordRoundAction(),
|
||||
'record-video': types.SendMessageRecordVideoAction(),
|
||||
'record-audio': _tl.SendMessageRecordAudioAction(),
|
||||
'record-voice': _tl.SendMessageRecordAudioAction(), # alias
|
||||
'record-round': _tl.SendMessageRecordRoundAction(),
|
||||
'record-video': _tl.SendMessageRecordVideoAction(),
|
||||
|
||||
'audio': types.SendMessageUploadAudioAction(1),
|
||||
'voice': types.SendMessageUploadAudioAction(1), # alias
|
||||
'song': types.SendMessageUploadAudioAction(1), # alias
|
||||
'round': types.SendMessageUploadRoundAction(1),
|
||||
'video': types.SendMessageUploadVideoAction(1),
|
||||
'audio': _tl.SendMessageUploadAudioAction(1),
|
||||
'voice': _tl.SendMessageUploadAudioAction(1), # alias
|
||||
'song': _tl.SendMessageUploadAudioAction(1), # alias
|
||||
'round': _tl.SendMessageUploadRoundAction(1),
|
||||
'video': _tl.SendMessageUploadVideoAction(1),
|
||||
|
||||
'photo': types.SendMessageUploadPhotoAction(1),
|
||||
'document': types.SendMessageUploadDocumentAction(1),
|
||||
'file': types.SendMessageUploadDocumentAction(1), # alias
|
||||
'photo': _tl.SendMessageUploadPhotoAction(1),
|
||||
'document': _tl.SendMessageUploadDocumentAction(1),
|
||||
'file': _tl.SendMessageUploadDocumentAction(1), # alias
|
||||
|
||||
'cancel': types.SendMessageCancelAction()
|
||||
'cancel': _tl.SendMessageCancelAction()
|
||||
}
|
||||
|
||||
def __init__(self, client, chat, action, *, delay, auto_cancel):
|
||||
|
@ -58,7 +57,7 @@ class _ChatAction:
|
|||
# Since `self._action` is passed by reference we can avoid
|
||||
# recreating the request all the time and still modify
|
||||
# `self._action.progress` directly in `progress`.
|
||||
self._request = functions.messages.SetTypingRequest(
|
||||
self._request = _tl.fn.messages.SetTyping(
|
||||
self._chat, self._action)
|
||||
|
||||
self._running = True
|
||||
|
@ -85,8 +84,8 @@ class _ChatAction:
|
|||
pass
|
||||
except asyncio.CancelledError:
|
||||
if self._auto_cancel:
|
||||
await self._client(functions.messages.SetTypingRequest(
|
||||
self._chat, types.SendMessageCancelAction()))
|
||||
await self._client(_tl.fn.messages.SetTyping(
|
||||
self._chat, _tl.SendMessageCancelAction()))
|
||||
|
||||
def progress(self, current, total):
|
||||
if hasattr(self._action, 'progress'):
|
||||
|
@ -96,10 +95,10 @@ class _ChatAction:
|
|||
class _ParticipantsIter(RequestIter):
|
||||
async def _init(self, entity, filter, search, aggressive):
|
||||
if isinstance(filter, type):
|
||||
if filter in (types.ChannelParticipantsBanned,
|
||||
types.ChannelParticipantsKicked,
|
||||
types.ChannelParticipantsSearch,
|
||||
types.ChannelParticipantsContacts):
|
||||
if filter in (_tl.ChannelParticipantsBanned,
|
||||
_tl.ChannelParticipantsKicked,
|
||||
_tl.ChannelParticipantsSearch,
|
||||
_tl.ChannelParticipantsContacts):
|
||||
# These require a `q` parameter (support types for convenience)
|
||||
filter = filter('')
|
||||
else:
|
||||
|
@ -125,23 +124,23 @@ class _ParticipantsIter(RequestIter):
|
|||
if self.limit <= 0:
|
||||
# May not have access to the channel, but getFull can get the .total.
|
||||
self.total = (await self.client(
|
||||
functions.channels.GetFullChannelRequest(entity)
|
||||
_tl.fn.channels.GetFullChannel(entity)
|
||||
)).full_chat.participants_count
|
||||
raise StopAsyncIteration
|
||||
|
||||
self.seen = set()
|
||||
if aggressive and not filter:
|
||||
self.requests.extend(functions.channels.GetParticipantsRequest(
|
||||
self.requests.extend(_tl.fn.channels.GetParticipants(
|
||||
channel=entity,
|
||||
filter=types.ChannelParticipantsSearch(x),
|
||||
filter=_tl.ChannelParticipantsSearch(x),
|
||||
offset=0,
|
||||
limit=_MAX_PARTICIPANTS_CHUNK_SIZE,
|
||||
hash=0
|
||||
) for x in (search or string.ascii_lowercase))
|
||||
else:
|
||||
self.requests.append(functions.channels.GetParticipantsRequest(
|
||||
self.requests.append(_tl.fn.channels.GetParticipants(
|
||||
channel=entity,
|
||||
filter=filter or types.ChannelParticipantsSearch(search),
|
||||
filter=filter or _tl.ChannelParticipantsSearch(search),
|
||||
offset=0,
|
||||
limit=_MAX_PARTICIPANTS_CHUNK_SIZE,
|
||||
hash=0
|
||||
|
@ -149,9 +148,9 @@ class _ParticipantsIter(RequestIter):
|
|||
|
||||
elif ty == helpers._EntityType.CHAT:
|
||||
full = await self.client(
|
||||
functions.messages.GetFullChatRequest(entity.chat_id))
|
||||
_tl.fn.messages.GetFullChat(entity.chat_id))
|
||||
if not isinstance(
|
||||
full.full_chat.participants, types.ChatParticipants):
|
||||
full.full_chat.participants, _tl.ChatParticipants):
|
||||
# ChatParticipantsForbidden won't have ``.participants``
|
||||
self.total = 0
|
||||
raise StopAsyncIteration
|
||||
|
@ -160,7 +159,7 @@ class _ParticipantsIter(RequestIter):
|
|||
|
||||
users = {user.id: user for user in full.users}
|
||||
for participant in full.full_chat.participants.participants:
|
||||
if isinstance(participant, types.ChannelParticipantBanned):
|
||||
if isinstance(participant, _tl.ChannelParticipantBanned):
|
||||
user_id = participant.peer.user_id
|
||||
else:
|
||||
user_id = participant.user_id
|
||||
|
@ -202,15 +201,15 @@ class _ParticipantsIter(RequestIter):
|
|||
if self.total is None:
|
||||
f = self.requests[0].filter
|
||||
if len(self.requests) > 1 or (
|
||||
not isinstance(f, types.ChannelParticipantsRecent)
|
||||
and (not isinstance(f, types.ChannelParticipantsSearch) or f.q)
|
||||
not isinstance(f, _tl.ChannelParticipantsRecent)
|
||||
and (not isinstance(f, _tl.ChannelParticipantsSearch) or f.q)
|
||||
):
|
||||
# Only do an additional getParticipants here to get the total
|
||||
# if there's a filter which would reduce the real total number.
|
||||
# getParticipants is cheaper than getFull.
|
||||
self.total = (await self.client(functions.channels.GetParticipantsRequest(
|
||||
self.total = (await self.client(_tl.fn.channels.GetParticipants(
|
||||
channel=self.requests[0].channel,
|
||||
filter=types.ChannelParticipantsRecent(),
|
||||
filter=_tl.ChannelParticipantsRecent(),
|
||||
offset=0,
|
||||
limit=1,
|
||||
hash=0
|
||||
|
@ -230,8 +229,8 @@ class _ParticipantsIter(RequestIter):
|
|||
users = {user.id: user for user in participants.users}
|
||||
for participant in participants.participants:
|
||||
|
||||
if isinstance(participant, types.ChannelParticipantBanned):
|
||||
if not isinstance(participant.peer, types.PeerUser):
|
||||
if isinstance(participant, _tl.ChannelParticipantBanned):
|
||||
if not isinstance(participant.peer, _tl.PeerUser):
|
||||
# May have the entire channel banned. See #3105.
|
||||
continue
|
||||
user_id = participant.peer.user_id
|
||||
|
@ -257,7 +256,7 @@ class _AdminLogIter(RequestIter):
|
|||
if any((join, leave, invite, restrict, unrestrict, ban, unban,
|
||||
promote, demote, info, settings, pinned, edit, delete,
|
||||
group_call)):
|
||||
events_filter = types.ChannelAdminLogEventsFilter(
|
||||
events_filter = _tl.ChannelAdminLogEventsFilter(
|
||||
join=join, leave=leave, invite=invite, ban=restrict,
|
||||
unban=unrestrict, kick=ban, unkick=unban, promote=promote,
|
||||
demote=demote, info=info, settings=settings, pinned=pinned,
|
||||
|
@ -276,7 +275,7 @@ class _AdminLogIter(RequestIter):
|
|||
for admin in admins:
|
||||
admin_list.append(await self.client.get_input_entity(admin))
|
||||
|
||||
self.request = functions.channels.GetAdminLogRequest(
|
||||
self.request = _tl.fn.channels.GetAdminLog(
|
||||
self.entity, q=search or '', min_id=min_id, max_id=max_id,
|
||||
limit=0, events_filter=events_filter, admins=admin_list or None
|
||||
)
|
||||
|
@ -290,7 +289,7 @@ class _AdminLogIter(RequestIter):
|
|||
self.request.max_id = min((e.id for e in r.events), default=0)
|
||||
for ev in r.events:
|
||||
if isinstance(ev.action,
|
||||
types.ChannelAdminLogEventActionEditMessage):
|
||||
_tl.ChannelAdminLogEventActionEditMessage):
|
||||
ev.action.prev_message._finish_init(
|
||||
self.client, entities, self.entity)
|
||||
|
||||
|
@ -298,11 +297,11 @@ class _AdminLogIter(RequestIter):
|
|||
self.client, entities, self.entity)
|
||||
|
||||
elif isinstance(ev.action,
|
||||
types.ChannelAdminLogEventActionDeleteMessage):
|
||||
_tl.ChannelAdminLogEventActionDeleteMessage):
|
||||
ev.action.message._finish_init(
|
||||
self.client, entities, self.entity)
|
||||
|
||||
self.buffer.append(custom.AdminLogEvent(ev, entities))
|
||||
self.buffer.append(_tl.custom.AdminLogEvent(ev, entities))
|
||||
|
||||
if len(r.events) < self.request.limit:
|
||||
return True
|
||||
|
@ -315,17 +314,17 @@ class _ProfilePhotoIter(RequestIter):
|
|||
entity = await self.client.get_input_entity(entity)
|
||||
ty = helpers._entity_type(entity)
|
||||
if ty == helpers._EntityType.USER:
|
||||
self.request = functions.photos.GetUserPhotosRequest(
|
||||
self.request = _tl.fn.photos.GetUserPhotos(
|
||||
entity,
|
||||
offset=offset,
|
||||
max_id=max_id,
|
||||
limit=1
|
||||
)
|
||||
else:
|
||||
self.request = functions.messages.SearchRequest(
|
||||
self.request = _tl.fn.messages.Search(
|
||||
peer=entity,
|
||||
q='',
|
||||
filter=types.InputMessagesFilterChatPhotos(),
|
||||
filter=_tl.InputMessagesFilterChatPhotos(),
|
||||
min_date=None,
|
||||
max_date=None,
|
||||
offset_id=0,
|
||||
|
@ -339,9 +338,9 @@ class _ProfilePhotoIter(RequestIter):
|
|||
if self.limit == 0:
|
||||
self.request.limit = 1
|
||||
result = await self.client(self.request)
|
||||
if isinstance(result, types.photos.Photos):
|
||||
if isinstance(result, _tl.photos.Photos):
|
||||
self.total = len(result.photos)
|
||||
elif isinstance(result, types.messages.Messages):
|
||||
elif isinstance(result, _tl.messages.Messages):
|
||||
self.total = len(result.messages)
|
||||
else:
|
||||
# Luckily both photosSlice and messages have a count for total
|
||||
|
@ -351,17 +350,17 @@ class _ProfilePhotoIter(RequestIter):
|
|||
self.request.limit = min(self.left, _MAX_PROFILE_PHOTO_CHUNK_SIZE)
|
||||
result = await self.client(self.request)
|
||||
|
||||
if isinstance(result, types.photos.Photos):
|
||||
if isinstance(result, _tl.photos.Photos):
|
||||
self.buffer = result.photos
|
||||
self.left = len(self.buffer)
|
||||
self.total = len(self.buffer)
|
||||
elif isinstance(result, types.messages.Messages):
|
||||
elif isinstance(result, _tl.messages.Messages):
|
||||
self.buffer = [x.action.photo for x in result.messages
|
||||
if isinstance(x.action, types.MessageActionChatEditPhoto)]
|
||||
if isinstance(x.action, _tl.MessageActionChatEditPhoto)]
|
||||
|
||||
self.left = len(self.buffer)
|
||||
self.total = len(self.buffer)
|
||||
elif isinstance(result, types.photos.PhotosSlice):
|
||||
elif isinstance(result, _tl.photos.PhotosSlice):
|
||||
self.buffer = result.photos
|
||||
self.total = result.count
|
||||
if len(self.buffer) < self.request.limit:
|
||||
|
@ -381,16 +380,16 @@ class _ProfilePhotoIter(RequestIter):
|
|||
# Unconditionally fetch the full channel to obtain this photo and
|
||||
# yield it with the rest (unless it's a duplicate).
|
||||
seen_id = None
|
||||
if isinstance(result, types.messages.ChannelMessages):
|
||||
channel = await self.client(functions.channels.GetFullChannelRequest(self.request.peer))
|
||||
if isinstance(result, _tl.messages.ChannelMessages):
|
||||
channel = await self.client(_tl.fn.channels.GetFullChannel(self.request.peer))
|
||||
photo = channel.full_chat.chat_photo
|
||||
if isinstance(photo, types.Photo):
|
||||
if isinstance(photo, _tl.Photo):
|
||||
self.buffer.append(photo)
|
||||
seen_id = photo.id
|
||||
|
||||
self.buffer.extend(
|
||||
x.action.photo for x in result.messages
|
||||
if isinstance(x.action, types.MessageActionChatEditPhoto)
|
||||
if isinstance(x.action, _tl.MessageActionChatEditPhoto)
|
||||
and x.action.photo.id != seen_id
|
||||
)
|
||||
|
||||
|
@ -407,7 +406,7 @@ def iter_participants(
|
|||
limit: float = None,
|
||||
*,
|
||||
search: str = '',
|
||||
filter: 'types.TypeChannelParticipantsFilter' = None,
|
||||
filter: '_tl.TypeChannelParticipantsFilter' = None,
|
||||
aggressive: bool = False) -> _ParticipantsIter:
|
||||
return _ParticipantsIter(
|
||||
self,
|
||||
|
@ -506,7 +505,7 @@ async def get_profile_photos(
|
|||
def action(
|
||||
self: 'TelegramClient',
|
||||
entity: 'hints.EntityLike',
|
||||
action: 'typing.Union[str, types.TypeSendMessageAction]',
|
||||
action: 'typing.Union[str, _tl.TypeSendMessageAction]',
|
||||
*,
|
||||
delay: float = 4,
|
||||
auto_cancel: bool = True) -> 'typing.Union[_ChatAction, typing.Coroutine]':
|
||||
|
@ -516,17 +515,17 @@ def action(
|
|||
except KeyError:
|
||||
raise ValueError(
|
||||
'No such action "{}"'.format(action)) from None
|
||||
elif not isinstance(action, types.TLObject) or action.SUBCLASS_OF_ID != 0x20b2cc21:
|
||||
elif not isinstance(action, _tl.TLObject) or action.SUBCLASS_OF_ID != 0x20b2cc21:
|
||||
# 0x20b2cc21 = crc32(b'SendMessageAction')
|
||||
if isinstance(action, type):
|
||||
raise ValueError('You must pass an instance, not the class')
|
||||
else:
|
||||
raise ValueError('Cannot use {} as action'.format(action))
|
||||
|
||||
if isinstance(action, types.SendMessageCancelAction):
|
||||
if isinstance(action, _tl.SendMessageCancelAction):
|
||||
# ``SetTypingRequest.resolve`` will get input peer of ``entity``.
|
||||
return self(functions.messages.SetTypingRequest(
|
||||
entity, types.SendMessageCancelAction()))
|
||||
return self(_tl.fn.messages.SetTyping(
|
||||
entity, _tl.SendMessageCancelAction()))
|
||||
|
||||
return _ChatAction(
|
||||
self, entity, action, delay=delay, auto_cancel=auto_cancel)
|
||||
|
@ -547,7 +546,7 @@ async def edit_admin(
|
|||
manage_call: bool = None,
|
||||
anonymous: bool = None,
|
||||
is_admin: bool = None,
|
||||
title: str = None) -> types.Updates:
|
||||
title: str = None) -> _tl.Updates:
|
||||
entity = await self.get_input_entity(entity)
|
||||
user = await self.get_input_entity(user)
|
||||
ty = helpers._entity_type(user)
|
||||
|
@ -576,7 +575,7 @@ async def edit_admin(
|
|||
edit_messages = None
|
||||
|
||||
perms = locals()
|
||||
return await self(functions.channels.EditAdminRequest(entity, user, types.ChatAdminRights(**{
|
||||
return await self(_tl.fn.channels.EditAdmin(entity, user, _tl.ChatAdminRights(**{
|
||||
# A permission is its explicit (not-None) value or `is_admin`.
|
||||
# This essentially makes `is_admin` be the default value.
|
||||
name: perms[name] if perms[name] is not None else is_admin
|
||||
|
@ -589,7 +588,7 @@ async def edit_admin(
|
|||
if is_admin is None:
|
||||
is_admin = any(locals()[x] for x in perm_names)
|
||||
|
||||
return await self(functions.messages.EditChatAdminRequest(
|
||||
return await self(_tl.fn.messages.EditChatAdmin(
|
||||
entity, user, is_admin=is_admin))
|
||||
|
||||
else:
|
||||
|
@ -613,13 +612,13 @@ async def edit_permissions(
|
|||
send_polls: bool = True,
|
||||
change_info: bool = True,
|
||||
invite_users: bool = True,
|
||||
pin_messages: bool = True) -> types.Updates:
|
||||
pin_messages: bool = True) -> _tl.Updates:
|
||||
entity = await self.get_input_entity(entity)
|
||||
ty = helpers._entity_type(entity)
|
||||
if ty != helpers._EntityType.CHANNEL:
|
||||
raise ValueError('You must pass either a channel or a supergroup')
|
||||
|
||||
rights = types.ChatBannedRights(
|
||||
rights = _tl.ChatBannedRights(
|
||||
until_date=until_date,
|
||||
view_messages=not view_messages,
|
||||
send_messages=not send_messages,
|
||||
|
@ -636,7 +635,7 @@ async def edit_permissions(
|
|||
)
|
||||
|
||||
if user is None:
|
||||
return await self(functions.messages.EditChatDefaultBannedRightsRequest(
|
||||
return await self(_tl.fn.messages.EditChatDefaultBannedRights(
|
||||
peer=entity,
|
||||
banned_rights=rights
|
||||
))
|
||||
|
@ -646,10 +645,10 @@ async def edit_permissions(
|
|||
if ty != helpers._EntityType.USER:
|
||||
raise ValueError('You must pass a user entity')
|
||||
|
||||
if isinstance(user, types.InputPeerSelf):
|
||||
if isinstance(user, _tl.InputPeerSelf):
|
||||
raise ValueError('You cannot restrict yourself')
|
||||
|
||||
return await self(functions.channels.EditBannedRequest(
|
||||
return await self(_tl.fn.channels.EditBanned(
|
||||
channel=entity,
|
||||
participant=user,
|
||||
banned_rights=rights
|
||||
|
@ -667,24 +666,24 @@ async def kick_participant(
|
|||
|
||||
ty = helpers._entity_type(entity)
|
||||
if ty == helpers._EntityType.CHAT:
|
||||
resp = await self(functions.messages.DeleteChatUserRequest(entity.chat_id, user))
|
||||
resp = await self(_tl.fn.messages.DeleteChatUser(entity.chat_id, user))
|
||||
elif ty == helpers._EntityType.CHANNEL:
|
||||
if isinstance(user, types.InputPeerSelf):
|
||||
if isinstance(user, _tl.InputPeerSelf):
|
||||
# Despite no longer being in the channel, the account still
|
||||
# seems to get the service message.
|
||||
resp = await self(functions.channels.LeaveChannelRequest(entity))
|
||||
resp = await self(_tl.fn.channels.LeaveChannel(entity))
|
||||
else:
|
||||
resp = await self(functions.channels.EditBannedRequest(
|
||||
resp = await self(_tl.fn.channels.EditBanned(
|
||||
channel=entity,
|
||||
participant=user,
|
||||
banned_rights=types.ChatBannedRights(
|
||||
banned_rights=_tl.ChatBannedRights(
|
||||
until_date=None, view_messages=True)
|
||||
))
|
||||
await asyncio.sleep(0.5)
|
||||
await self(functions.channels.EditBannedRequest(
|
||||
await self(_tl.fn.channels.EditBanned(
|
||||
channel=entity,
|
||||
participant=user,
|
||||
banned_rights=types.ChatBannedRights(until_date=None)
|
||||
banned_rights=_tl.ChatBannedRights(until_date=None)
|
||||
))
|
||||
else:
|
||||
raise ValueError('You must pass either a channel or a chat')
|
||||
|
@ -695,14 +694,14 @@ async def get_permissions(
|
|||
self: 'TelegramClient',
|
||||
entity: 'hints.EntityLike',
|
||||
user: 'hints.EntityLike' = None
|
||||
) -> 'typing.Optional[custom.ParticipantPermissions]':
|
||||
) -> 'typing.Optional[_tl.custom.ParticipantPermissions]':
|
||||
entity = await self.get_entity(entity)
|
||||
|
||||
if not user:
|
||||
if isinstance(entity, types.Channel):
|
||||
FullChat = await self(functions.channels.GetFullChannelRequest(entity))
|
||||
elif isinstance(entity, types.Chat):
|
||||
FullChat = await self(functions.messages.GetFullChatRequest(entity))
|
||||
if isinstance(entity, _tl.Channel):
|
||||
FullChat = await self(_tl.fn.channels.GetFullChannel(entity))
|
||||
elif isinstance(entity, _tl.Chat):
|
||||
FullChat = await self(_tl.fn.messages.GetFullChat(entity))
|
||||
else:
|
||||
return
|
||||
return FullChat.chats[0].default_banned_rights
|
||||
|
@ -712,20 +711,20 @@ async def get_permissions(
|
|||
if helpers._entity_type(user) != helpers._EntityType.USER:
|
||||
raise ValueError('You must pass a user entity')
|
||||
if helpers._entity_type(entity) == helpers._EntityType.CHANNEL:
|
||||
participant = await self(functions.channels.GetParticipantRequest(
|
||||
participant = await self(_tl.fn.channels.GetParticipant(
|
||||
entity,
|
||||
user
|
||||
))
|
||||
return custom.ParticipantPermissions(participant.participant, False)
|
||||
return _tl.custom.ParticipantPermissions(participant.participant, False)
|
||||
elif helpers._entity_type(entity) == helpers._EntityType.CHAT:
|
||||
chat = await self(functions.messages.GetFullChatRequest(
|
||||
chat = await self(_tl.fn.messages.GetFullChat(
|
||||
entity
|
||||
))
|
||||
if isinstance(user, types.InputPeerSelf):
|
||||
if isinstance(user, _tl.InputPeerSelf):
|
||||
user = await self.get_me(input_peer=True)
|
||||
for participant in chat.full_chat.participants.participants:
|
||||
if participant.user_id == user.user_id:
|
||||
return custom.ParticipantPermissions(participant, True)
|
||||
return _tl.custom.ParticipantPermissions(participant, True)
|
||||
raise errors.UserNotParticipantError(None)
|
||||
|
||||
raise ValueError('You must pass either a channel or a chat')
|
||||
|
@ -733,7 +732,7 @@ async def get_permissions(
|
|||
async def get_stats(
|
||||
self: 'TelegramClient',
|
||||
entity: 'hints.EntityLike',
|
||||
message: 'typing.Union[int, types.Message]' = None,
|
||||
message: 'typing.Union[int, _tl.Message]' = None,
|
||||
):
|
||||
entity = await self.get_input_entity(entity)
|
||||
if helpers._entity_type(entity) != helpers._EntityType.CHANNEL:
|
||||
|
@ -742,7 +741,7 @@ async def get_stats(
|
|||
message = utils.get_message_id(message)
|
||||
if message is not None:
|
||||
try:
|
||||
req = functions.stats.GetMessageStatsRequest(entity, message)
|
||||
req = _tl.fn.stats.GetMessageStats(entity, message)
|
||||
return await self(req)
|
||||
except errors.StatsMigrateError as e:
|
||||
dc = e.dc
|
||||
|
@ -751,12 +750,12 @@ async def get_stats(
|
|||
# try to guess and if it fails we know it's the other one (best case
|
||||
# no extra request, worst just one).
|
||||
try:
|
||||
req = functions.stats.GetBroadcastStatsRequest(entity)
|
||||
req = _tl.fn.stats.GetBroadcastStats(entity)
|
||||
return await self(req)
|
||||
except errors.StatsMigrateError as e:
|
||||
dc = e.dc
|
||||
except errors.BroadcastRequiredError:
|
||||
req = functions.stats.GetMegagroupStatsRequest(entity)
|
||||
req = _tl.fn.stats.GetMegagroupStats(entity)
|
||||
try:
|
||||
return await self(req)
|
||||
except errors.StatsMigrateError as e:
|
||||
|
|
|
@ -3,9 +3,8 @@ import inspect
|
|||
import itertools
|
||||
import typing
|
||||
|
||||
from .. import helpers, utils, hints, errors
|
||||
from .. import helpers, utils, hints, errors, _tl
|
||||
from ..requestiter import RequestIter
|
||||
from ..tl import types, functions, custom
|
||||
|
||||
_MAX_CHUNK_SIZE = 100
|
||||
|
||||
|
@ -21,14 +20,14 @@ def _dialog_message_key(peer, message_id):
|
|||
and the peer ID is required to distinguish between them. But it is not
|
||||
necessary in small group chats and private chats.
|
||||
"""
|
||||
return (peer.channel_id if isinstance(peer, types.PeerChannel) else None), message_id
|
||||
return (peer.channel_id if isinstance(peer, _tl.PeerChannel) else None), message_id
|
||||
|
||||
|
||||
class _DialogsIter(RequestIter):
|
||||
async def _init(
|
||||
self, offset_date, offset_id, offset_peer, ignore_pinned, ignore_migrated, folder
|
||||
):
|
||||
self.request = functions.messages.GetDialogsRequest(
|
||||
self.request = _tl.fn.messages.GetDialogs(
|
||||
offset_date=offset_date,
|
||||
offset_id=offset_id,
|
||||
offset_peer=offset_peer,
|
||||
|
@ -56,7 +55,7 @@ class _DialogsIter(RequestIter):
|
|||
|
||||
entities = {utils.get_peer_id(x): x
|
||||
for x in itertools.chain(r.users, r.chats)
|
||||
if not isinstance(x, (types.UserEmpty, types.ChatEmpty))}
|
||||
if not isinstance(x, (_tl.UserEmpty, _tl.ChatEmpty))}
|
||||
|
||||
messages = {}
|
||||
for m in r.messages:
|
||||
|
@ -80,7 +79,7 @@ class _DialogsIter(RequestIter):
|
|||
# Real world example: https://t.me/TelethonChat/271471
|
||||
continue
|
||||
|
||||
cd = custom.Dialog(self.client, d, entities, message)
|
||||
cd = _tl.custom.Dialog(self.client, d, entities, message)
|
||||
if cd.dialog.pts:
|
||||
self.client._channel_pts[cd.id] = cd.dialog.pts
|
||||
|
||||
|
@ -89,7 +88,7 @@ class _DialogsIter(RequestIter):
|
|||
self.buffer.append(cd)
|
||||
|
||||
if len(r.dialogs) < self.request.limit\
|
||||
or not isinstance(r, types.messages.DialogsSlice):
|
||||
or not isinstance(r, _tl.messages.DialogsSlice):
|
||||
# Less than we requested means we reached the end, or
|
||||
# we didn't get a DialogsSlice which means we got all.
|
||||
return True
|
||||
|
@ -112,15 +111,15 @@ class _DialogsIter(RequestIter):
|
|||
class _DraftsIter(RequestIter):
|
||||
async def _init(self, entities, **kwargs):
|
||||
if not entities:
|
||||
r = await self.client(functions.messages.GetAllDraftsRequest())
|
||||
r = await self.client(_tl.fn.messages.GetAllDrafts())
|
||||
items = r.updates
|
||||
else:
|
||||
peers = []
|
||||
for entity in entities:
|
||||
peers.append(types.InputDialogPeer(
|
||||
peers.append(_tl.InputDialogPeer(
|
||||
await self.client.get_input_entity(entity)))
|
||||
|
||||
r = await self.client(functions.messages.GetPeerDialogsRequest(peers))
|
||||
r = await self.client(_tl.fn.messages.GetPeerDialogs(peers))
|
||||
items = r.dialogs
|
||||
|
||||
# TODO Maybe there should be a helper method for this?
|
||||
|
@ -128,7 +127,7 @@ class _DraftsIter(RequestIter):
|
|||
for x in itertools.chain(r.users, r.chats)}
|
||||
|
||||
self.buffer.extend(
|
||||
custom.Draft(self.client, entities[utils.get_peer_id(d.peer)], d.draft)
|
||||
_tl.custom.Draft(self.client, entities[utils.get_peer_id(d.peer)], d.draft)
|
||||
for d in items
|
||||
)
|
||||
|
||||
|
@ -142,7 +141,7 @@ def iter_dialogs(
|
|||
*,
|
||||
offset_date: 'hints.DateLike' = None,
|
||||
offset_id: int = 0,
|
||||
offset_peer: 'hints.EntityLike' = types.InputPeerEmpty(),
|
||||
offset_peer: 'hints.EntityLike' = _tl.InputPeerEmpty(),
|
||||
ignore_pinned: bool = False,
|
||||
ignore_migrated: bool = False,
|
||||
folder: int = None,
|
||||
|
@ -192,12 +191,12 @@ async def edit_folder(
|
|||
folder: typing.Union[int, typing.Sequence[int]] = None,
|
||||
*,
|
||||
unpack=None
|
||||
) -> types.Updates:
|
||||
) -> _tl.Updates:
|
||||
if (entity is None) == (unpack is None):
|
||||
raise ValueError('You can only set either entities or unpack, not both')
|
||||
|
||||
if unpack is not None:
|
||||
return await self(functions.folders.DeleteFolderRequest(
|
||||
return await self(_tl.fn.folders.DeleteFolder(
|
||||
folder_id=unpack
|
||||
))
|
||||
|
||||
|
@ -214,8 +213,8 @@ async def edit_folder(
|
|||
elif len(entities) != len(folder):
|
||||
raise ValueError('Number of folders does not match number of entities')
|
||||
|
||||
return await self(functions.folders.EditPeerFoldersRequest([
|
||||
types.InputFolderPeer(x, folder_id=y)
|
||||
return await self(_tl.fn.folders.EditPeerFolders([
|
||||
_tl.InputFolderPeer(x, folder_id=y)
|
||||
for x, y in zip(entities, folder)
|
||||
]))
|
||||
|
||||
|
@ -227,7 +226,7 @@ async def delete_dialog(
|
|||
):
|
||||
# If we have enough information (`Dialog.delete` gives it to us),
|
||||
# then we know we don't have to kick ourselves in deactivated chats.
|
||||
if isinstance(entity, types.Chat):
|
||||
if isinstance(entity, _tl.Chat):
|
||||
deactivated = entity.deactivated
|
||||
else:
|
||||
deactivated = False
|
||||
|
@ -235,12 +234,12 @@ async def delete_dialog(
|
|||
entity = await self.get_input_entity(entity)
|
||||
ty = helpers._entity_type(entity)
|
||||
if ty == helpers._EntityType.CHANNEL:
|
||||
return await self(functions.channels.LeaveChannelRequest(entity))
|
||||
return await self(_tl.fn.channels.LeaveChannel(entity))
|
||||
|
||||
if ty == helpers._EntityType.CHAT and not deactivated:
|
||||
try:
|
||||
result = await self(functions.messages.DeleteChatUserRequest(
|
||||
entity.chat_id, types.InputUserSelf(), revoke_history=revoke
|
||||
result = await self(_tl.fn.messages.DeleteChatUser(
|
||||
entity.chat_id, _tl.InputUserSelf(), revoke_history=revoke
|
||||
))
|
||||
except errors.PeerIdInvalidError:
|
||||
# Happens if we didn't have the deactivated information
|
||||
|
@ -249,6 +248,6 @@ async def delete_dialog(
|
|||
result = None
|
||||
|
||||
if not await self.is_bot():
|
||||
await self(functions.messages.DeleteHistoryRequest(entity, 0, revoke=revoke))
|
||||
await self(_tl.fn.messages.DeleteHistory(entity, 0, revoke=revoke))
|
||||
|
||||
return result
|
||||
|
|
|
@ -8,9 +8,8 @@ import asyncio
|
|||
|
||||
from ..crypto import AES
|
||||
|
||||
from .. import utils, helpers, errors, hints
|
||||
from .. import utils, helpers, errors, hints, _tl
|
||||
from ..requestiter import RequestIter
|
||||
from ..tl import TLObject, types, functions
|
||||
|
||||
try:
|
||||
import aiohttp
|
||||
|
@ -31,7 +30,7 @@ class _DirectDownloadIter(RequestIter):
|
|||
async def _init(
|
||||
self, file, dc_id, offset, stride, chunk_size, request_size, file_size, msg_data
|
||||
):
|
||||
self.request = functions.upload.GetFileRequest(
|
||||
self.request = _tl.fn.upload.GetFile(
|
||||
file, offset=offset, limit=request_size)
|
||||
|
||||
self.total = file_size
|
||||
|
@ -50,7 +49,7 @@ class _DirectDownloadIter(RequestIter):
|
|||
self._sender = await self.client._borrow_exported_sender(dc_id)
|
||||
except errors.DcIdInvalidError:
|
||||
# Can't export a sender for the ID we are currently in
|
||||
config = await self.client(functions.help.GetConfigRequest())
|
||||
config = await self.client(_tl.fn.help.GetConfig())
|
||||
for option in config.dc_options:
|
||||
if option.ip_address == self.client.session.server_address:
|
||||
self.client.session.set_dc(
|
||||
|
@ -75,7 +74,7 @@ class _DirectDownloadIter(RequestIter):
|
|||
try:
|
||||
result = await self.client._call(self._sender, self.request)
|
||||
self._timed_out = False
|
||||
if isinstance(result, types.upload.FileCdnRedirect):
|
||||
if isinstance(result, _tl.upload.FileCdnRedirect):
|
||||
raise NotImplementedError # TODO Implement
|
||||
else:
|
||||
return result.bytes
|
||||
|
@ -99,7 +98,7 @@ class _DirectDownloadIter(RequestIter):
|
|||
except errors.FilerefUpgradeNeededError as e:
|
||||
# Only implemented for documents which are the ones that may take that long to download
|
||||
if not self._msg_data \
|
||||
or not isinstance(self.request.location, types.InputDocumentFileLocation) \
|
||||
or not isinstance(self.request.location, _tl.InputDocumentFileLocation) \
|
||||
or self.request.location.thumb_size != '':
|
||||
raise
|
||||
|
||||
|
@ -107,7 +106,7 @@ class _DirectDownloadIter(RequestIter):
|
|||
chat, msg_id = self._msg_data
|
||||
msg = await self.client.get_messages(chat, ids=msg_id)
|
||||
|
||||
if not isinstance(msg.media, types.MessageMediaDocument):
|
||||
if not isinstance(msg.media, _tl.MessageMediaDocument):
|
||||
raise
|
||||
|
||||
document = msg.media.document
|
||||
|
@ -200,7 +199,7 @@ async def download_profile_photo(
|
|||
ENTITIES = (0x2da17977, 0xc5af5d94, 0x1f4661b9, 0xd49a2697)
|
||||
# ('InputPeer', 'InputUser', 'InputChannel')
|
||||
INPUTS = (0xc91c90b6, 0xe669bf46, 0x40f202fd)
|
||||
if not isinstance(entity, TLObject) or entity.SUBCLASS_OF_ID in INPUTS:
|
||||
if not isinstance(entity, _tl.TLObject) or entity.SUBCLASS_OF_ID in INPUTS:
|
||||
entity = await self.get_entity(entity)
|
||||
|
||||
thumb = -1 if download_big else 0
|
||||
|
@ -225,9 +224,9 @@ async def download_profile_photo(
|
|||
|
||||
photo = entity.photo
|
||||
|
||||
if isinstance(photo, (types.UserProfilePhoto, types.ChatPhoto)):
|
||||
if isinstance(photo, (_tl.UserProfilePhoto, _tl.ChatPhoto)):
|
||||
dc_id = photo.dc_id
|
||||
loc = types.InputPeerPhotoFileLocation(
|
||||
loc = _tl.InputPeerPhotoFileLocation(
|
||||
peer=await self.get_input_entity(entity),
|
||||
photo_id=photo.photo_id,
|
||||
big=download_big
|
||||
|
@ -253,7 +252,7 @@ async def download_profile_photo(
|
|||
ie = await self.get_input_entity(entity)
|
||||
ty = helpers._entity_type(ie)
|
||||
if ty == helpers._EntityType.CHANNEL:
|
||||
full = await self(functions.channels.GetFullChannelRequest(ie))
|
||||
full = await self(_tl.fn.channels.GetFullChannel(ie))
|
||||
return await self._download_photo(
|
||||
full.full_chat.chat_photo, file,
|
||||
date=None, progress_callback=None,
|
||||
|
@ -268,7 +267,7 @@ async def download_media(
|
|||
message: 'hints.MessageLike',
|
||||
file: 'hints.FileLike' = None,
|
||||
*,
|
||||
thumb: 'typing.Union[int, types.TypePhotoSize]' = None,
|
||||
thumb: 'typing.Union[int, _tl.TypePhotoSize]' = None,
|
||||
progress_callback: 'hints.ProgressCallback' = None) -> typing.Optional[typing.Union[str, bytes]]:
|
||||
# Downloading large documents may be slow enough to require a new file reference
|
||||
# to be obtained mid-download. Store (input chat, message id) so that the message
|
||||
|
@ -276,7 +275,7 @@ async def download_media(
|
|||
msg_data = None
|
||||
|
||||
# TODO This won't work for messageService
|
||||
if isinstance(message, types.Message):
|
||||
if isinstance(message, _tl.Message):
|
||||
date = message.date
|
||||
media = message.media
|
||||
msg_data = (message.input_chat, message.id) if message.input_chat else None
|
||||
|
@ -287,28 +286,28 @@ async def download_media(
|
|||
if isinstance(media, str):
|
||||
media = utils.resolve_bot_file_id(media)
|
||||
|
||||
if isinstance(media, types.MessageService):
|
||||
if isinstance(media, _tl.MessageService):
|
||||
if isinstance(message.action,
|
||||
types.MessageActionChatEditPhoto):
|
||||
_tl.MessageActionChatEditPhoto):
|
||||
media = media.photo
|
||||
|
||||
if isinstance(media, types.MessageMediaWebPage):
|
||||
if isinstance(media.webpage, types.WebPage):
|
||||
if isinstance(media, _tl.MessageMediaWebPage):
|
||||
if isinstance(media.webpage, _tl.WebPage):
|
||||
media = media.webpage.document or media.webpage.photo
|
||||
|
||||
if isinstance(media, (types.MessageMediaPhoto, types.Photo)):
|
||||
if isinstance(media, (_tl.MessageMediaPhoto, _tl.Photo)):
|
||||
return await self._download_photo(
|
||||
media, file, date, thumb, progress_callback
|
||||
)
|
||||
elif isinstance(media, (types.MessageMediaDocument, types.Document)):
|
||||
elif isinstance(media, (_tl.MessageMediaDocument, _tl.Document)):
|
||||
return await self._download_document(
|
||||
media, file, date, thumb, progress_callback, msg_data
|
||||
)
|
||||
elif isinstance(media, types.MessageMediaContact) and thumb is None:
|
||||
elif isinstance(media, _tl.MessageMediaContact) and thumb is None:
|
||||
return self._download_contact(
|
||||
media, file
|
||||
)
|
||||
elif isinstance(media, (types.WebDocument, types.WebDocumentNoProxy)) and thumb is None:
|
||||
elif isinstance(media, (_tl.WebDocument, _tl.WebDocumentNoProxy)) and thumb is None:
|
||||
return await self._download_web_document(
|
||||
media, file, progress_callback
|
||||
)
|
||||
|
@ -488,15 +487,15 @@ def _get_thumb(thumbs, thumb):
|
|||
# last while this is the smallest (layer 116). Ensure we have the
|
||||
# sizes sorted correctly with a custom function.
|
||||
def sort_thumbs(thumb):
|
||||
if isinstance(thumb, types.PhotoStrippedSize):
|
||||
if isinstance(thumb, _tl.PhotoStrippedSize):
|
||||
return 1, len(thumb.bytes)
|
||||
if isinstance(thumb, types.PhotoCachedSize):
|
||||
if isinstance(thumb, _tl.PhotoCachedSize):
|
||||
return 1, len(thumb.bytes)
|
||||
if isinstance(thumb, types.PhotoSize):
|
||||
if isinstance(thumb, _tl.PhotoSize):
|
||||
return 1, thumb.size
|
||||
if isinstance(thumb, types.PhotoSizeProgressive):
|
||||
if isinstance(thumb, _tl.PhotoSizeProgressive):
|
||||
return 1, max(thumb.sizes)
|
||||
if isinstance(thumb, types.VideoSize):
|
||||
if isinstance(thumb, _tl.VideoSize):
|
||||
return 2, thumb.size
|
||||
|
||||
# Empty size or invalid should go last
|
||||
|
@ -508,7 +507,7 @@ def _get_thumb(thumbs, thumb):
|
|||
# :tl:`PhotoPathSize` is used for animated stickers preview, and the thumb is actually
|
||||
# a SVG path of the outline. Users expect thumbnails to be JPEG files, so pretend this
|
||||
# thumb size doesn't actually exist (#1655).
|
||||
if isinstance(thumbs[i], types.PhotoPathSize):
|
||||
if isinstance(thumbs[i], _tl.PhotoPathSize):
|
||||
thumbs.pop(i)
|
||||
|
||||
if thumb is None:
|
||||
|
@ -517,15 +516,15 @@ def _get_thumb(thumbs, thumb):
|
|||
return thumbs[thumb]
|
||||
elif isinstance(thumb, str):
|
||||
return next((t for t in thumbs if t.type == thumb), None)
|
||||
elif isinstance(thumb, (types.PhotoSize, types.PhotoCachedSize,
|
||||
types.PhotoStrippedSize, types.VideoSize)):
|
||||
elif isinstance(thumb, (_tl.PhotoSize, _tl.PhotoCachedSize,
|
||||
_tl.PhotoStrippedSize, _tl.VideoSize)):
|
||||
return thumb
|
||||
else:
|
||||
return None
|
||||
|
||||
def _download_cached_photo_size(self: 'TelegramClient', size, file):
|
||||
# No need to download anything, simply write the bytes
|
||||
if isinstance(size, types.PhotoStrippedSize):
|
||||
if isinstance(size, _tl.PhotoStrippedSize):
|
||||
data = utils.stripped_photo_to_jpg(size.bytes)
|
||||
else:
|
||||
data = size.bytes
|
||||
|
@ -548,31 +547,31 @@ def _download_cached_photo_size(self: 'TelegramClient', size, file):
|
|||
async def _download_photo(self: 'TelegramClient', photo, file, date, thumb, progress_callback):
|
||||
"""Specialized version of .download_media() for photos"""
|
||||
# Determine the photo and its largest size
|
||||
if isinstance(photo, types.MessageMediaPhoto):
|
||||
if isinstance(photo, _tl.MessageMediaPhoto):
|
||||
photo = photo.photo
|
||||
if not isinstance(photo, types.Photo):
|
||||
if not isinstance(photo, _tl.Photo):
|
||||
return
|
||||
|
||||
# Include video sizes here (but they may be None so provide an empty list)
|
||||
size = self._get_thumb(photo.sizes + (photo.video_sizes or []), thumb)
|
||||
if not size or isinstance(size, types.PhotoSizeEmpty):
|
||||
if not size or isinstance(size, _tl.PhotoSizeEmpty):
|
||||
return
|
||||
|
||||
if isinstance(size, types.VideoSize):
|
||||
if isinstance(size, _tl.VideoSize):
|
||||
file = self._get_proper_filename(file, 'video', '.mp4', date=date)
|
||||
else:
|
||||
file = self._get_proper_filename(file, 'photo', '.jpg', date=date)
|
||||
|
||||
if isinstance(size, (types.PhotoCachedSize, types.PhotoStrippedSize)):
|
||||
if isinstance(size, (_tl.PhotoCachedSize, _tl.PhotoStrippedSize)):
|
||||
return self._download_cached_photo_size(size, file)
|
||||
|
||||
if isinstance(size, types.PhotoSizeProgressive):
|
||||
if isinstance(size, _tl.PhotoSizeProgressive):
|
||||
file_size = max(size.sizes)
|
||||
else:
|
||||
file_size = size.size
|
||||
|
||||
result = await self.download_file(
|
||||
types.InputPhotoFileLocation(
|
||||
_tl.InputPhotoFileLocation(
|
||||
id=photo.id,
|
||||
access_hash=photo.access_hash,
|
||||
file_reference=photo.file_reference,
|
||||
|
@ -589,10 +588,10 @@ def _get_kind_and_names(attributes):
|
|||
kind = 'document'
|
||||
possible_names = []
|
||||
for attr in attributes:
|
||||
if isinstance(attr, types.DocumentAttributeFilename):
|
||||
if isinstance(attr, _tl.DocumentAttributeFilename):
|
||||
possible_names.insert(0, attr.file_name)
|
||||
|
||||
elif isinstance(attr, types.DocumentAttributeAudio):
|
||||
elif isinstance(attr, _tl.DocumentAttributeAudio):
|
||||
kind = 'audio'
|
||||
if attr.performer and attr.title:
|
||||
possible_names.append('{} - {}'.format(
|
||||
|
@ -610,9 +609,9 @@ def _get_kind_and_names(attributes):
|
|||
async def _download_document(
|
||||
self, document, file, date, thumb, progress_callback, msg_data):
|
||||
"""Specialized version of .download_media() for documents."""
|
||||
if isinstance(document, types.MessageMediaDocument):
|
||||
if isinstance(document, _tl.MessageMediaDocument):
|
||||
document = document.document
|
||||
if not isinstance(document, types.Document):
|
||||
if not isinstance(document, _tl.Document):
|
||||
return
|
||||
|
||||
if thumb is None:
|
||||
|
@ -625,11 +624,11 @@ async def _download_document(
|
|||
else:
|
||||
file = self._get_proper_filename(file, 'photo', '.jpg', date=date)
|
||||
size = self._get_thumb(document.thumbs, thumb)
|
||||
if isinstance(size, (types.PhotoCachedSize, types.PhotoStrippedSize)):
|
||||
if isinstance(size, (_tl.PhotoCachedSize, _tl.PhotoStrippedSize)):
|
||||
return self._download_cached_photo_size(size, file)
|
||||
|
||||
result = await self._download_file(
|
||||
types.InputDocumentFileLocation(
|
||||
_tl.InputDocumentFileLocation(
|
||||
id=document.id,
|
||||
access_hash=document.access_hash,
|
||||
file_reference=document.file_reference,
|
||||
|
|
|
@ -2,8 +2,7 @@ import itertools
|
|||
import re
|
||||
import typing
|
||||
|
||||
from .. import helpers, utils
|
||||
from ..tl import types
|
||||
from .. import helpers, utils, _tl
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .telegramclient import TelegramClient
|
||||
|
@ -25,7 +24,7 @@ async def _replace_with_mention(self: 'TelegramClient', entities, i, user):
|
|||
or do nothing if it can't be found.
|
||||
"""
|
||||
try:
|
||||
entities[i] = types.InputMessageEntityMentionName(
|
||||
entities[i] = _tl.InputMessageEntityMentionName(
|
||||
entities[i].offset, entities[i].length,
|
||||
await self.get_input_entity(user)
|
||||
)
|
||||
|
@ -52,15 +51,15 @@ async def _parse_message_text(self: 'TelegramClient', message, parse_mode):
|
|||
|
||||
for i in reversed(range(len(msg_entities))):
|
||||
e = msg_entities[i]
|
||||
if isinstance(e, types.MessageEntityTextUrl):
|
||||
if isinstance(e, _tl.MessageEntityTextUrl):
|
||||
m = re.match(r'^@|\+|tg://user\?id=(\d+)', e.url)
|
||||
if m:
|
||||
user = int(m.group(1)) if m.group(1) else e.url
|
||||
is_mention = await self._replace_with_mention(msg_entities, i, user)
|
||||
if not is_mention:
|
||||
del msg_entities[i]
|
||||
elif isinstance(e, (types.MessageEntityMentionName,
|
||||
types.InputMessageEntityMentionName)):
|
||||
elif isinstance(e, (_tl.MessageEntityMentionName,
|
||||
_tl.InputMessageEntityMentionName)):
|
||||
is_mention = await self._replace_with_mention(msg_entities, i, e.user_id)
|
||||
if not is_mention:
|
||||
del msg_entities[i]
|
||||
|
@ -76,10 +75,10 @@ def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
|||
|
||||
If ``request.random_id`` is a list, this method returns a list too.
|
||||
"""
|
||||
if isinstance(result, types.UpdateShort):
|
||||
if isinstance(result, _tl.UpdateShort):
|
||||
updates = [result.update]
|
||||
entities = {}
|
||||
elif isinstance(result, (types.Updates, types.UpdatesCombined)):
|
||||
elif isinstance(result, (_tl.Updates, _tl.UpdatesCombined)):
|
||||
updates = result.updates
|
||||
entities = {utils.get_peer_id(x): x
|
||||
for x in
|
||||
|
@ -90,11 +89,11 @@ def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
|||
random_to_id = {}
|
||||
id_to_message = {}
|
||||
for update in updates:
|
||||
if isinstance(update, types.UpdateMessageID):
|
||||
if isinstance(update, _tl.UpdateMessageID):
|
||||
random_to_id[update.random_id] = update.id
|
||||
|
||||
elif isinstance(update, (
|
||||
types.UpdateNewChannelMessage, types.UpdateNewMessage)):
|
||||
_tl.UpdateNewChannelMessage, _tl.UpdateNewMessage)):
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
|
||||
# Pinning a message with `updatePinnedMessage` seems to
|
||||
|
@ -109,7 +108,7 @@ def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
|||
else:
|
||||
return update.message
|
||||
|
||||
elif (isinstance(update, types.UpdateEditMessage)
|
||||
elif (isinstance(update, _tl.UpdateEditMessage)
|
||||
and helpers._entity_type(request.peer) != helpers._EntityType.CHANNEL):
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
|
||||
|
@ -120,26 +119,26 @@ def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
|||
elif request.id == update.message.id:
|
||||
return update.message
|
||||
|
||||
elif (isinstance(update, types.UpdateEditChannelMessage)
|
||||
elif (isinstance(update, _tl.UpdateEditChannelMessage)
|
||||
and utils.get_peer_id(request.peer) ==
|
||||
utils.get_peer_id(update.message.peer_id)):
|
||||
if request.id == update.message.id:
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
return update.message
|
||||
|
||||
elif isinstance(update, types.UpdateNewScheduledMessage):
|
||||
elif isinstance(update, _tl.UpdateNewScheduledMessage):
|
||||
update.message._finish_init(self, entities, input_chat)
|
||||
# Scheduled IDs may collide with normal IDs. However, for a
|
||||
# single request there *shouldn't* be a mix between "some
|
||||
# scheduled and some not".
|
||||
id_to_message[update.message.id] = update.message
|
||||
|
||||
elif isinstance(update, types.UpdateMessagePoll):
|
||||
elif isinstance(update, _tl.UpdateMessagePoll):
|
||||
if request.media.poll.id == update.poll_id:
|
||||
m = types.Message(
|
||||
m = _tl.Message(
|
||||
id=request.id,
|
||||
peer_id=utils.get_peer(request.peer),
|
||||
media=types.MessageMediaPoll(
|
||||
media=_tl.MessageMediaPoll(
|
||||
poll=update.poll,
|
||||
results=update.results
|
||||
)
|
||||
|
|
|
@ -3,9 +3,8 @@ import itertools
|
|||
import typing
|
||||
import warnings
|
||||
|
||||
from .. import helpers, utils, errors, hints
|
||||
from .. import helpers, utils, errors, hints, _tl
|
||||
from ..requestiter import RequestIter
|
||||
from ..tl import types, functions
|
||||
|
||||
_MAX_CHUNK_SIZE = 100
|
||||
|
||||
|
@ -67,31 +66,31 @@ class _MessagesIter(RequestIter):
|
|||
# If we want to perform global a search with `from_user` we have to perform
|
||||
# a normal `messages.search`, *but* we can make the entity be `inputPeerEmpty`.
|
||||
if not self.entity and from_user:
|
||||
self.entity = types.InputPeerEmpty()
|
||||
self.entity = _tl.InputPeerEmpty()
|
||||
|
||||
if filter is None:
|
||||
filter = types.InputMessagesFilterEmpty()
|
||||
filter = _tl.InputMessagesFilterEmpty()
|
||||
else:
|
||||
filter = filter() if isinstance(filter, type) else filter
|
||||
|
||||
if not self.entity:
|
||||
self.request = functions.messages.SearchGlobalRequest(
|
||||
self.request = _tl.fn.messages.SearchGlobal(
|
||||
q=search or '',
|
||||
filter=filter,
|
||||
min_date=None,
|
||||
max_date=offset_date,
|
||||
offset_rate=0,
|
||||
offset_peer=types.InputPeerEmpty(),
|
||||
offset_peer=_tl.InputPeerEmpty(),
|
||||
offset_id=offset_id,
|
||||
limit=1
|
||||
)
|
||||
elif scheduled:
|
||||
self.request = functions.messages.GetScheduledHistoryRequest(
|
||||
self.request = _tl.fn.messages.GetScheduledHistory(
|
||||
peer=entity,
|
||||
hash=0
|
||||
)
|
||||
elif reply_to is not None:
|
||||
self.request = functions.messages.GetRepliesRequest(
|
||||
self.request = _tl.fn.messages.GetReplies(
|
||||
peer=self.entity,
|
||||
msg_id=reply_to,
|
||||
offset_id=offset_id,
|
||||
|
@ -102,7 +101,7 @@ class _MessagesIter(RequestIter):
|
|||
min_id=0,
|
||||
hash=0
|
||||
)
|
||||
elif search is not None or not isinstance(filter, types.InputMessagesFilterEmpty) or from_user:
|
||||
elif search is not None or not isinstance(filter, _tl.InputMessagesFilterEmpty) or from_user:
|
||||
# Telegram completely ignores `from_id` in private chats
|
||||
ty = helpers._entity_type(self.entity)
|
||||
if ty == helpers._EntityType.USER:
|
||||
|
@ -114,7 +113,7 @@ class _MessagesIter(RequestIter):
|
|||
# and set `from_id` to None to avoid checking it locally.
|
||||
self.from_id = None
|
||||
|
||||
self.request = functions.messages.SearchRequest(
|
||||
self.request = _tl.fn.messages.Search(
|
||||
peer=self.entity,
|
||||
q=search or '',
|
||||
filter=filter,
|
||||
|
@ -136,13 +135,13 @@ class _MessagesIter(RequestIter):
|
|||
#
|
||||
# Even better, using `filter` and `from_id` seems to always
|
||||
# trigger `RPC_CALL_FAIL` which is "internal issues"...
|
||||
if not isinstance(filter, types.InputMessagesFilterEmpty) \
|
||||
if not isinstance(filter, _tl.InputMessagesFilterEmpty) \
|
||||
and offset_date and not search and not offset_id:
|
||||
async for m in self.client.iter_messages(
|
||||
self.entity, 1, offset_date=offset_date):
|
||||
self.request.offset_id = m.id + 1
|
||||
else:
|
||||
self.request = functions.messages.GetHistoryRequest(
|
||||
self.request = _tl.fn.messages.GetHistory(
|
||||
peer=self.entity,
|
||||
limit=1,
|
||||
offset_date=offset_date,
|
||||
|
@ -156,7 +155,7 @@ class _MessagesIter(RequestIter):
|
|||
if self.limit <= 0:
|
||||
# No messages, but we still need to know the total message count
|
||||
result = await self.client(self.request)
|
||||
if isinstance(result, types.messages.MessagesNotModified):
|
||||
if isinstance(result, _tl.messages.MessagesNotModified):
|
||||
self.total = result.count
|
||||
else:
|
||||
self.total = getattr(result, 'count', len(result.messages))
|
||||
|
@ -189,7 +188,7 @@ class _MessagesIter(RequestIter):
|
|||
|
||||
messages = reversed(r.messages) if self.reverse else r.messages
|
||||
for message in messages:
|
||||
if (isinstance(message, types.MessageEmpty)
|
||||
if (isinstance(message, _tl.MessageEmpty)
|
||||
or self.from_id and message.sender_id != self.from_id):
|
||||
continue
|
||||
|
||||
|
@ -245,7 +244,7 @@ class _MessagesIter(RequestIter):
|
|||
# We want to skip the one we already have
|
||||
self.request.offset_id += 1
|
||||
|
||||
if isinstance(self.request, functions.messages.SearchRequest):
|
||||
if isinstance(self.request, _tl.fn.messages.SearchRequest):
|
||||
# Unlike getHistory and searchGlobal that use *offset* date,
|
||||
# this is *max* date. This means that doing a search in reverse
|
||||
# will break it. Since it's not really needed once we're going
|
||||
|
@ -255,11 +254,11 @@ class _MessagesIter(RequestIter):
|
|||
# getHistory, searchGlobal and getReplies call it offset_date
|
||||
self.request.offset_date = last_message.date
|
||||
|
||||
if isinstance(self.request, functions.messages.SearchGlobalRequest):
|
||||
if isinstance(self.request, _tl.fn.messages.SearchGlobalRequest):
|
||||
if last_message.input_chat:
|
||||
self.request.offset_peer = last_message.input_chat
|
||||
else:
|
||||
self.request.offset_peer = types.InputPeerEmpty()
|
||||
self.request.offset_peer = _tl.InputPeerEmpty()
|
||||
|
||||
self.request.offset_rate = getattr(response, 'next_rate', 0)
|
||||
|
||||
|
@ -287,16 +286,16 @@ class _IDsIter(RequestIter):
|
|||
if self._ty == helpers._EntityType.CHANNEL:
|
||||
try:
|
||||
r = await self.client(
|
||||
functions.channels.GetMessagesRequest(self._entity, ids))
|
||||
_tl.fn.channels.GetMessages(self._entity, ids))
|
||||
except errors.MessageIdsEmptyError:
|
||||
# All IDs were invalid, use a dummy result
|
||||
r = types.messages.MessagesNotModified(len(ids))
|
||||
r = _tl.messages.MessagesNotModified(len(ids))
|
||||
else:
|
||||
r = await self.client(functions.messages.GetMessagesRequest(ids))
|
||||
r = await self.client(_tl.fn.messages.GetMessages(ids))
|
||||
if self._entity:
|
||||
from_id = await self.client._get_peer(self._entity)
|
||||
|
||||
if isinstance(r, types.messages.MessagesNotModified):
|
||||
if isinstance(r, _tl.messages.MessagesNotModified):
|
||||
self.buffer.extend(None for _ in ids)
|
||||
return
|
||||
|
||||
|
@ -312,7 +311,7 @@ class _IDsIter(RequestIter):
|
|||
# since the user can enter arbitrary numbers which can belong to
|
||||
# arbitrary chats. Validate these unless ``from_id is None``.
|
||||
for message in r.messages:
|
||||
if isinstance(message, types.MessageEmpty) or (
|
||||
if isinstance(message, _tl.MessageEmpty) or (
|
||||
from_id and message.peer_id != from_id):
|
||||
self.buffer.append(None)
|
||||
else:
|
||||
|
@ -331,7 +330,7 @@ def iter_messages(
|
|||
min_id: int = 0,
|
||||
add_offset: int = 0,
|
||||
search: str = None,
|
||||
filter: 'typing.Union[types.TypeMessagesFilter, typing.Type[types.TypeMessagesFilter]]' = None,
|
||||
filter: 'typing.Union[_tl.TypeMessagesFilter, typing.Type[_tl.TypeMessagesFilter]]' = None,
|
||||
from_user: 'hints.EntityLike' = None,
|
||||
wait_time: float = None,
|
||||
ids: 'typing.Union[int, typing.Sequence[int]]' = None,
|
||||
|
@ -393,9 +392,9 @@ async def get_messages(self: 'TelegramClient', *args, **kwargs) -> 'hints.TotalL
|
|||
async def _get_comment_data(
|
||||
self: 'TelegramClient',
|
||||
entity: 'hints.EntityLike',
|
||||
message: 'typing.Union[int, types.Message]'
|
||||
message: 'typing.Union[int, _tl.Message]'
|
||||
):
|
||||
r = await self(functions.messages.GetDiscussionMessageRequest(
|
||||
r = await self(_tl.fn.messages.GetDiscussionMessage(
|
||||
peer=entity,
|
||||
msg_id=utils.get_message_id(message)
|
||||
))
|
||||
|
@ -408,10 +407,10 @@ async def send_message(
|
|||
entity: 'hints.EntityLike',
|
||||
message: 'hints.MessageLike' = '',
|
||||
*,
|
||||
reply_to: 'typing.Union[int, types.Message]' = None,
|
||||
attributes: 'typing.Sequence[types.TypeDocumentAttribute]' = None,
|
||||
reply_to: 'typing.Union[int, _tl.Message]' = None,
|
||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
||||
parse_mode: typing.Optional[str] = (),
|
||||
formatting_entities: typing.Optional[typing.List[types.TypeMessageEntity]] = None,
|
||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
||||
link_preview: bool = True,
|
||||
file: 'typing.Union[hints.FileLike, typing.Sequence[hints.FileLike]]' = None,
|
||||
thumb: 'hints.FileLike' = None,
|
||||
|
@ -422,8 +421,8 @@ async def send_message(
|
|||
background: bool = None,
|
||||
supports_streaming: bool = False,
|
||||
schedule: 'hints.DateLike' = None,
|
||||
comment_to: 'typing.Union[int, types.Message]' = None
|
||||
) -> 'types.Message':
|
||||
comment_to: 'typing.Union[int, _tl.Message]' = None
|
||||
) -> '_tl.Message':
|
||||
if file is not None:
|
||||
return await self.send_file(
|
||||
entity, file, caption=message, reply_to=reply_to,
|
||||
|
@ -439,7 +438,7 @@ async def send_message(
|
|||
if comment_to is not None:
|
||||
entity, reply_to = await self._get_comment_data(entity, comment_to)
|
||||
|
||||
if isinstance(message, types.Message):
|
||||
if isinstance(message, _tl.Message):
|
||||
if buttons is None:
|
||||
markup = message.reply_markup
|
||||
else:
|
||||
|
@ -449,7 +448,7 @@ async def send_message(
|
|||
silent = message.silent
|
||||
|
||||
if (message.media and not isinstance(
|
||||
message.media, types.MessageMediaWebPage)):
|
||||
message.media, _tl.MessageMediaWebPage)):
|
||||
return await self.send_file(
|
||||
entity,
|
||||
message.media,
|
||||
|
@ -462,7 +461,7 @@ async def send_message(
|
|||
schedule=schedule
|
||||
)
|
||||
|
||||
request = functions.messages.SendMessageRequest(
|
||||
request = _tl.fn.messages.SendMessage(
|
||||
peer=entity,
|
||||
message=message.message or '',
|
||||
silent=silent,
|
||||
|
@ -472,7 +471,7 @@ async def send_message(
|
|||
entities=message.entities,
|
||||
clear_draft=clear_draft,
|
||||
no_webpage=not isinstance(
|
||||
message.media, types.MessageMediaWebPage),
|
||||
message.media, _tl.MessageMediaWebPage),
|
||||
schedule_date=schedule
|
||||
)
|
||||
message = message.message
|
||||
|
@ -484,7 +483,7 @@ async def send_message(
|
|||
'The message cannot be empty unless a file is provided'
|
||||
)
|
||||
|
||||
request = functions.messages.SendMessageRequest(
|
||||
request = _tl.fn.messages.SendMessage(
|
||||
peer=entity,
|
||||
message=message,
|
||||
entities=formatting_entities,
|
||||
|
@ -498,8 +497,8 @@ async def send_message(
|
|||
)
|
||||
|
||||
result = await self(request)
|
||||
if isinstance(result, types.UpdateShortSentMessage):
|
||||
message = types.Message(
|
||||
if isinstance(result, _tl.UpdateShortSentMessage):
|
||||
message = _tl.Message(
|
||||
id=result.id,
|
||||
peer_id=await self._get_peer(entity),
|
||||
message=message,
|
||||
|
@ -526,7 +525,7 @@ async def forward_messages(
|
|||
silent: bool = None,
|
||||
as_album: bool = None,
|
||||
schedule: 'hints.DateLike' = None
|
||||
) -> 'typing.Sequence[types.Message]':
|
||||
) -> 'typing.Sequence[_tl.Message]':
|
||||
if as_album is not None:
|
||||
warnings.warn('the as_album argument is deprecated and no longer has any effect')
|
||||
|
||||
|
@ -548,7 +547,7 @@ async def forward_messages(
|
|||
return from_peer_id
|
||||
|
||||
raise ValueError('from_peer must be given if integer IDs are used')
|
||||
elif isinstance(m, types.Message):
|
||||
elif isinstance(m, _tl.Message):
|
||||
return m.chat_id
|
||||
else:
|
||||
raise TypeError('Cannot forward messages of type {}'.format(type(m)))
|
||||
|
@ -562,7 +561,7 @@ async def forward_messages(
|
|||
chat = await chunk[0].get_input_chat()
|
||||
chunk = [m.id for m in chunk]
|
||||
|
||||
req = functions.messages.ForwardMessagesRequest(
|
||||
req = _tl.fn.messages.ForwardMessages(
|
||||
from_peer=chat,
|
||||
id=chunk,
|
||||
to_peer=entity,
|
||||
|
@ -578,13 +577,13 @@ async def forward_messages(
|
|||
|
||||
async def edit_message(
|
||||
self: 'TelegramClient',
|
||||
entity: 'typing.Union[hints.EntityLike, types.Message]',
|
||||
entity: 'typing.Union[hints.EntityLike, _tl.Message]',
|
||||
message: 'hints.MessageLike' = None,
|
||||
text: str = None,
|
||||
*,
|
||||
parse_mode: str = (),
|
||||
attributes: 'typing.Sequence[types.TypeDocumentAttribute]' = None,
|
||||
formatting_entities: typing.Optional[typing.List[types.TypeMessageEntity]] = None,
|
||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
||||
link_preview: bool = True,
|
||||
file: 'hints.FileLike' = None,
|
||||
thumb: 'hints.FileLike' = None,
|
||||
|
@ -592,11 +591,11 @@ async def edit_message(
|
|||
buttons: 'hints.MarkupLike' = None,
|
||||
supports_streaming: bool = False,
|
||||
schedule: 'hints.DateLike' = None
|
||||
) -> 'types.Message':
|
||||
if isinstance(entity, types.InputBotInlineMessageID):
|
||||
) -> '_tl.Message':
|
||||
if isinstance(entity, _tl.InputBotInlineMessageID):
|
||||
text = text or message
|
||||
message = entity
|
||||
elif isinstance(entity, types.Message):
|
||||
elif isinstance(entity, _tl.Message):
|
||||
text = message # Shift the parameters to the right
|
||||
message = entity
|
||||
entity = entity.peer_id
|
||||
|
@ -609,8 +608,8 @@ async def edit_message(
|
|||
attributes=attributes,
|
||||
force_document=force_document)
|
||||
|
||||
if isinstance(entity, types.InputBotInlineMessageID):
|
||||
request = functions.messages.EditInlineBotMessageRequest(
|
||||
if isinstance(entity, _tl.InputBotInlineMessageID):
|
||||
request = _tl.fn.messages.EditInlineBotMessage(
|
||||
id=entity,
|
||||
message=text,
|
||||
no_webpage=not link_preview,
|
||||
|
@ -631,7 +630,7 @@ async def edit_message(
|
|||
return await self(request)
|
||||
|
||||
entity = await self.get_input_entity(entity)
|
||||
request = functions.messages.EditMessageRequest(
|
||||
request = _tl.fn.messages.EditMessage(
|
||||
peer=entity,
|
||||
id=utils.get_message_id(message),
|
||||
message=text,
|
||||
|
@ -649,13 +648,13 @@ async def delete_messages(
|
|||
entity: 'hints.EntityLike',
|
||||
message_ids: 'typing.Union[hints.MessageIDLike, typing.Sequence[hints.MessageIDLike]]',
|
||||
*,
|
||||
revoke: bool = True) -> 'typing.Sequence[types.messages.AffectedMessages]':
|
||||
revoke: bool = True) -> 'typing.Sequence[_tl.messages.AffectedMessages]':
|
||||
if not utils.is_list_like(message_ids):
|
||||
message_ids = (message_ids,)
|
||||
|
||||
message_ids = (
|
||||
m.id if isinstance(m, (
|
||||
types.Message, types.MessageService, types.MessageEmpty))
|
||||
_tl.Message, _tl.MessageService, _tl.MessageEmpty))
|
||||
else int(m) for m in message_ids
|
||||
)
|
||||
|
||||
|
@ -667,10 +666,10 @@ async def delete_messages(
|
|||
ty = helpers._EntityType.USER
|
||||
|
||||
if ty == helpers._EntityType.CHANNEL:
|
||||
return await self([functions.channels.DeleteMessagesRequest(
|
||||
return await self([_tl.fn.channels.DeleteMessages(
|
||||
entity, list(c)) for c in utils.chunks(message_ids)])
|
||||
else:
|
||||
return await self([functions.messages.DeleteMessagesRequest(
|
||||
return await self([_tl.fn.messages.DeleteMessages(
|
||||
list(c), revoke) for c in utils.chunks(message_ids)])
|
||||
|
||||
async def send_read_acknowledge(
|
||||
|
@ -691,16 +690,16 @@ async def send_read_acknowledge(
|
|||
|
||||
entity = await self.get_input_entity(entity)
|
||||
if clear_mentions:
|
||||
await self(functions.messages.ReadMentionsRequest(entity))
|
||||
await self(_tl.fn.messages.ReadMentions(entity))
|
||||
if max_id is None:
|
||||
return True
|
||||
|
||||
if max_id is not None:
|
||||
if helpers._entity_type(entity) == helpers._EntityType.CHANNEL:
|
||||
return await self(functions.channels.ReadHistoryRequest(
|
||||
return await self(_tl.fn.channels.ReadHistory(
|
||||
utils.get_input_channel(entity), max_id=max_id))
|
||||
else:
|
||||
return await self(functions.messages.ReadHistoryRequest(
|
||||
return await self(_tl.fn.messages.ReadHistory(
|
||||
entity, max_id=max_id))
|
||||
|
||||
return False
|
||||
|
@ -728,10 +727,10 @@ async def _pin(self, entity, message, *, unpin, notify=False, pm_oneside=False):
|
|||
message = utils.get_message_id(message) or 0
|
||||
entity = await self.get_input_entity(entity)
|
||||
if message <= 0: # old behaviour accepted negative IDs to unpin
|
||||
await self(functions.messages.UnpinAllMessagesRequest(entity))
|
||||
await self(_tl.fn.messages.UnpinAllMessages(entity))
|
||||
return
|
||||
|
||||
request = functions.messages.UpdatePinnedMessageRequest(
|
||||
request = _tl.fn.messages.UpdatePinnedMessage(
|
||||
peer=entity,
|
||||
id=message,
|
||||
silent=not notify,
|
||||
|
|
|
@ -7,15 +7,13 @@ import platform
|
|||
import time
|
||||
import typing
|
||||
|
||||
from .. import version, helpers, __name__ as __base_name__
|
||||
from .. import version, helpers, __name__ as __base_name__, _tl
|
||||
from ..crypto import rsa
|
||||
from ..entitycache import EntityCache
|
||||
from ..extensions import markdown
|
||||
from ..network import MTProtoSender, Connection, ConnectionTcpFull, TcpMTProxy
|
||||
from ..sessions import Session, SQLiteSession, MemorySession
|
||||
from ..statecache import StateCache
|
||||
from ..tl import functions, types
|
||||
from ..tl.alltlobjects import LAYER
|
||||
|
||||
DEFAULT_DC_ID = 2
|
||||
DEFAULT_IPV4_IP = '149.154.167.51'
|
||||
|
@ -122,7 +120,7 @@ def init(
|
|||
import warnings
|
||||
warnings.warn(
|
||||
'The sqlite3 module is not available under this '
|
||||
'Python installation and no custom session '
|
||||
'Python installation and no _ session '
|
||||
'instance was given; using MemorySession.\n'
|
||||
'You will need to re-login every time unless '
|
||||
'you use another session storage'
|
||||
|
@ -198,7 +196,7 @@ def init(
|
|||
assert isinstance(connection, type)
|
||||
self._connection = connection
|
||||
init_proxy = None if not issubclass(connection, TcpMTProxy) else \
|
||||
types.InputClientProxy(*connection.address_info(proxy))
|
||||
_tl.InputClientProxy(*connection.address_info(proxy))
|
||||
|
||||
# Used on connection. Capture the variables in a lambda since
|
||||
# exporting clients need to create this InvokeWithLayerRequest.
|
||||
|
@ -212,7 +210,7 @@ def init(
|
|||
default_device_model = system.machine
|
||||
default_system_version = re.sub(r'-.+','',system.release)
|
||||
|
||||
self._init_request = functions.InitConnectionRequest(
|
||||
self._init_request = _tl.fn.InitConnection(
|
||||
api_id=self.api_id,
|
||||
device_model=device_model or default_device_model or 'Unknown',
|
||||
system_version=system_version or default_system_version or '1.0',
|
||||
|
@ -322,10 +320,10 @@ async def connect(self: 'TelegramClient') -> None:
|
|||
self.session.auth_key = self._sender.auth_key
|
||||
self.session.save()
|
||||
|
||||
self._init_request.query = functions.help.GetConfigRequest()
|
||||
self._init_request.query = _tl.fn.help.GetConfig()
|
||||
|
||||
await self._sender.send(functions.InvokeWithLayerRequest(
|
||||
LAYER, self._init_request
|
||||
await self._sender.send(_tl.fn.InvokeWithLayer(
|
||||
_tl.alltlobjects.LAYER, self._init_request
|
||||
))
|
||||
|
||||
self._updates_handle = self.loop.create_task(self._update_loop())
|
||||
|
@ -339,7 +337,7 @@ async def disconnect(self: 'TelegramClient'):
|
|||
|
||||
def set_proxy(self: 'TelegramClient', proxy: typing.Union[tuple, dict]):
|
||||
init_proxy = None if not issubclass(self._connection, TcpMTProxy) else \
|
||||
types.InputClientProxy(*self._connection.address_info(proxy))
|
||||
_tl.InputClientProxy(*self._connection.address_info(proxy))
|
||||
|
||||
self._init_request.proxy = init_proxy
|
||||
self._proxy = proxy
|
||||
|
@ -386,7 +384,7 @@ async def _disconnect_coro(self: 'TelegramClient'):
|
|||
|
||||
pts, date = self._state_cache[None]
|
||||
if pts and date:
|
||||
self.session.set_update_state(0, types.updates.State(
|
||||
self.session.set_update_state(0, _tl.updates.State(
|
||||
pts=pts,
|
||||
qts=0,
|
||||
date=date,
|
||||
|
@ -436,10 +434,10 @@ async def _get_dc(self: 'TelegramClient', dc_id, cdn=False):
|
|||
"""Gets the Data Center (DC) associated to 'dc_id'"""
|
||||
cls = self.__class__
|
||||
if not cls._config:
|
||||
cls._config = await self(functions.help.GetConfigRequest())
|
||||
cls._config = await self(_tl.fn.help.GetConfig())
|
||||
|
||||
if cdn and not self._cdn_config:
|
||||
cls._cdn_config = await self(functions.help.GetCdnConfigRequest())
|
||||
cls._cdn_config = await self(_tl.fn.help.GetCdnConfig())
|
||||
for pk in cls._cdn_config.public_keys:
|
||||
rsa.add_key(pk.public_key)
|
||||
|
||||
|
@ -481,9 +479,9 @@ async def _create_exported_sender(self: 'TelegramClient', dc_id):
|
|||
local_addr=self._local_addr
|
||||
))
|
||||
self._log[__name__].info('Exporting auth for new borrowed sender in %s', dc)
|
||||
auth = await self(functions.auth.ExportAuthorizationRequest(dc_id))
|
||||
self._init_request.query = functions.auth.ImportAuthorizationRequest(id=auth.id, bytes=auth.bytes)
|
||||
req = functions.InvokeWithLayerRequest(LAYER, self._init_request)
|
||||
auth = await self(_tl.fn.auth.ExportAuthorization(dc_id))
|
||||
self._init_request.query = _tl.fn.auth.ImportAuthorization(id=auth.id, bytes=auth.bytes)
|
||||
req = _tl.fn.InvokeWithLayer(LAYER, self._init_request)
|
||||
await sender.send(req)
|
||||
return sender
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ from . import (
|
|||
account, auth, bots, buttons, chats, dialogs, downloads, messageparse, messages,
|
||||
telegrambaseclient, updates, uploads, users
|
||||
)
|
||||
from .. import helpers, version
|
||||
from ..tl import types, custom
|
||||
from .. import helpers, version, _tl
|
||||
from ..network import ConnectionTcpFull
|
||||
from ..events.common import EventBuilder, EventCommon
|
||||
|
||||
|
@ -369,7 +368,7 @@ class TelegramClient:
|
|||
*,
|
||||
password: str = None,
|
||||
bot_token: str = None,
|
||||
phone_code_hash: str = None) -> 'typing.Union[types.User, types.auth.SentCode]':
|
||||
phone_code_hash: str = None) -> 'typing.Union[_tl.User, _tl.auth.SentCode]':
|
||||
"""
|
||||
Logs in to Telegram to an existing user or bot account.
|
||||
|
||||
|
@ -428,7 +427,7 @@ class TelegramClient:
|
|||
last_name: str = '',
|
||||
*,
|
||||
phone: str = None,
|
||||
phone_code_hash: str = None) -> 'types.User':
|
||||
phone_code_hash: str = None) -> '_tl.User':
|
||||
"""
|
||||
Signs up to Telegram as a new user account.
|
||||
|
||||
|
@ -477,7 +476,7 @@ class TelegramClient:
|
|||
self: 'TelegramClient',
|
||||
phone: str,
|
||||
*,
|
||||
force_sms: bool = False) -> 'types.auth.SentCode':
|
||||
force_sms: bool = False) -> '_tl.auth.SentCode':
|
||||
"""
|
||||
Sends the Telegram code needed to login to the given phone number.
|
||||
|
||||
|
@ -630,7 +629,7 @@ class TelegramClient:
|
|||
*,
|
||||
entity: 'hints.EntityLike' = None,
|
||||
offset: str = None,
|
||||
geo_point: 'types.GeoPoint' = None) -> custom.InlineResults:
|
||||
geo_point: '_tl.GeoPoint' = None) -> custom.InlineResults:
|
||||
"""
|
||||
Makes an inline query to the specified bot (``@vote New Poll``).
|
||||
|
||||
|
@ -679,7 +678,7 @@ class TelegramClient:
|
|||
@staticmethod
|
||||
def build_reply_markup(
|
||||
buttons: 'typing.Optional[hints.MarkupLike]',
|
||||
inline_only: bool = False) -> 'typing.Optional[types.TypeReplyMarkup]':
|
||||
inline_only: bool = False) -> 'typing.Optional[_tl.TypeReplyMarkup]':
|
||||
"""
|
||||
Builds a :tl:`ReplyInlineMarkup` or :tl:`ReplyKeyboardMarkup` for
|
||||
the given buttons.
|
||||
|
@ -722,7 +721,7 @@ class TelegramClient:
|
|||
limit: float = None,
|
||||
*,
|
||||
search: str = '',
|
||||
filter: 'types.TypeChannelParticipantsFilter' = None,
|
||||
filter: '_tl.TypeChannelParticipantsFilter' = None,
|
||||
aggressive: bool = False) -> chats._ParticipantsIter:
|
||||
"""
|
||||
Iterator over the participants belonging to the specified chat.
|
||||
|
@ -1018,7 +1017,7 @@ class TelegramClient:
|
|||
def action(
|
||||
self: 'TelegramClient',
|
||||
entity: 'hints.EntityLike',
|
||||
action: 'typing.Union[str, types.TypeSendMessageAction]',
|
||||
action: 'typing.Union[str, _tl.TypeSendMessageAction]',
|
||||
*,
|
||||
delay: float = 4,
|
||||
auto_cancel: bool = True) -> 'typing.Union[_ChatAction, typing.Coroutine]':
|
||||
|
@ -1109,7 +1108,7 @@ class TelegramClient:
|
|||
manage_call: bool = None,
|
||||
anonymous: bool = None,
|
||||
is_admin: bool = None,
|
||||
title: str = None) -> types.Updates:
|
||||
title: str = None) -> _tl.Updates:
|
||||
"""
|
||||
Edits admin permissions for someone in a chat.
|
||||
|
||||
|
@ -1216,7 +1215,7 @@ class TelegramClient:
|
|||
send_polls: bool = True,
|
||||
change_info: bool = True,
|
||||
invite_users: bool = True,
|
||||
pin_messages: bool = True) -> types.Updates:
|
||||
pin_messages: bool = True) -> _tl.Updates:
|
||||
"""
|
||||
Edits user restrictions in a chat.
|
||||
|
||||
|
@ -1396,7 +1395,7 @@ class TelegramClient:
|
|||
async def get_stats(
|
||||
self: 'TelegramClient',
|
||||
entity: 'hints.EntityLike',
|
||||
message: 'typing.Union[int, types.Message]' = None,
|
||||
message: 'typing.Union[int, _tl.Message]' = None,
|
||||
):
|
||||
"""
|
||||
Retrieves statistics from the given megagroup or broadcast channel.
|
||||
|
@ -1449,7 +1448,7 @@ class TelegramClient:
|
|||
*,
|
||||
offset_date: 'hints.DateLike' = None,
|
||||
offset_id: int = 0,
|
||||
offset_peer: 'hints.EntityLike' = types.InputPeerEmpty(),
|
||||
offset_peer: 'hints.EntityLike' = _tl.InputPeerEmpty(),
|
||||
ignore_pinned: bool = False,
|
||||
ignore_migrated: bool = False,
|
||||
folder: int = None,
|
||||
|
@ -1604,7 +1603,7 @@ class TelegramClient:
|
|||
folder: typing.Union[int, typing.Sequence[int]] = None,
|
||||
*,
|
||||
unpack=None
|
||||
) -> types.Updates:
|
||||
) -> _tl.Updates:
|
||||
"""
|
||||
Edits the folder used by one or more dialogs to archive them.
|
||||
|
||||
|
@ -1756,7 +1755,7 @@ class TelegramClient:
|
|||
message: 'hints.MessageLike',
|
||||
file: 'hints.FileLike' = None,
|
||||
*,
|
||||
thumb: 'typing.Union[int, types.TypePhotoSize]' = None,
|
||||
thumb: 'typing.Union[int, _tl.TypePhotoSize]' = None,
|
||||
progress_callback: 'hints.ProgressCallback' = None) -> typing.Optional[typing.Union[str, bytes]]:
|
||||
"""
|
||||
Downloads the given media from a message object.
|
||||
|
@ -1850,7 +1849,7 @@ class TelegramClient:
|
|||
input_location (:tl:`InputFileLocation`):
|
||||
The file location from which the file will be downloaded.
|
||||
See `telethon.utils.get_input_location` source for a complete
|
||||
list of supported types.
|
||||
list of supported _tl.
|
||||
|
||||
file (`str` | `file`, optional):
|
||||
The output file path, directory, or stream-like object.
|
||||
|
@ -2048,7 +2047,7 @@ class TelegramClient:
|
|||
min_id: int = 0,
|
||||
add_offset: int = 0,
|
||||
search: str = None,
|
||||
filter: 'typing.Union[types.TypeMessagesFilter, typing.Type[types.TypeMessagesFilter]]' = None,
|
||||
filter: 'typing.Union[_tl.TypeMessagesFilter, typing.Type[_tl.TypeMessagesFilter]]' = None,
|
||||
from_user: 'hints.EntityLike' = None,
|
||||
wait_time: float = None,
|
||||
ids: 'typing.Union[int, typing.Sequence[int]]' = None,
|
||||
|
@ -2258,10 +2257,10 @@ class TelegramClient:
|
|||
entity: 'hints.EntityLike',
|
||||
message: 'hints.MessageLike' = '',
|
||||
*,
|
||||
reply_to: 'typing.Union[int, types.Message]' = None,
|
||||
attributes: 'typing.Sequence[types.TypeDocumentAttribute]' = None,
|
||||
reply_to: 'typing.Union[int, _tl.Message]' = None,
|
||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
||||
parse_mode: typing.Optional[str] = (),
|
||||
formatting_entities: typing.Optional[typing.List[types.TypeMessageEntity]] = None,
|
||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
||||
link_preview: bool = True,
|
||||
file: 'typing.Union[hints.FileLike, typing.Sequence[hints.FileLike]]' = None,
|
||||
thumb: 'hints.FileLike' = None,
|
||||
|
@ -2272,8 +2271,8 @@ class TelegramClient:
|
|||
background: bool = None,
|
||||
supports_streaming: bool = False,
|
||||
schedule: 'hints.DateLike' = None,
|
||||
comment_to: 'typing.Union[int, types.Message]' = None
|
||||
) -> 'types.Message':
|
||||
comment_to: 'typing.Union[int, _tl.Message]' = None
|
||||
) -> '_tl.Message':
|
||||
"""
|
||||
Sends a message to the specified user, chat or channel.
|
||||
|
||||
|
@ -2458,7 +2457,7 @@ class TelegramClient:
|
|||
silent: bool = None,
|
||||
as_album: bool = None,
|
||||
schedule: 'hints.DateLike' = None
|
||||
) -> 'typing.Sequence[types.Message]':
|
||||
) -> 'typing.Sequence[_tl.Message]':
|
||||
"""
|
||||
Forwards the given messages to the specified entity.
|
||||
|
||||
|
@ -2531,13 +2530,13 @@ class TelegramClient:
|
|||
|
||||
async def edit_message(
|
||||
self: 'TelegramClient',
|
||||
entity: 'typing.Union[hints.EntityLike, types.Message]',
|
||||
entity: 'typing.Union[hints.EntityLike, _tl.Message]',
|
||||
message: 'hints.MessageLike' = None,
|
||||
text: str = None,
|
||||
*,
|
||||
parse_mode: str = (),
|
||||
attributes: 'typing.Sequence[types.TypeDocumentAttribute]' = None,
|
||||
formatting_entities: typing.Optional[typing.List[types.TypeMessageEntity]] = None,
|
||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
||||
link_preview: bool = True,
|
||||
file: 'hints.FileLike' = None,
|
||||
thumb: 'hints.FileLike' = None,
|
||||
|
@ -2545,7 +2544,7 @@ class TelegramClient:
|
|||
buttons: 'hints.MarkupLike' = None,
|
||||
supports_streaming: bool = False,
|
||||
schedule: 'hints.DateLike' = None
|
||||
) -> 'types.Message':
|
||||
) -> '_tl.Message':
|
||||
"""
|
||||
Edits the given message to change its text or media.
|
||||
|
||||
|
@ -2663,7 +2662,7 @@ class TelegramClient:
|
|||
entity: 'hints.EntityLike',
|
||||
message_ids: 'typing.Union[hints.MessageIDLike, typing.Sequence[hints.MessageIDLike]]',
|
||||
*,
|
||||
revoke: bool = True) -> 'typing.Sequence[types.messages.AffectedMessages]':
|
||||
revoke: bool = True) -> 'typing.Sequence[_tl.messages.AffectedMessages]':
|
||||
"""
|
||||
Deletes the given messages, optionally "for everyone".
|
||||
|
||||
|
@ -3171,11 +3170,11 @@ class TelegramClient:
|
|||
clear_draft: bool = False,
|
||||
progress_callback: 'hints.ProgressCallback' = None,
|
||||
reply_to: 'hints.MessageIDLike' = None,
|
||||
attributes: 'typing.Sequence[types.TypeDocumentAttribute]' = None,
|
||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
||||
thumb: 'hints.FileLike' = None,
|
||||
allow_cache: bool = True,
|
||||
parse_mode: str = (),
|
||||
formatting_entities: typing.Optional[typing.List[types.TypeMessageEntity]] = None,
|
||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
||||
voice_note: bool = False,
|
||||
video_note: bool = False,
|
||||
buttons: 'hints.MarkupLike' = None,
|
||||
|
@ -3183,9 +3182,9 @@ class TelegramClient:
|
|||
background: bool = None,
|
||||
supports_streaming: bool = False,
|
||||
schedule: 'hints.DateLike' = None,
|
||||
comment_to: 'typing.Union[int, types.Message]' = None,
|
||||
comment_to: 'typing.Union[int, _tl.Message]' = None,
|
||||
ttl: int = None,
|
||||
**kwargs) -> 'types.Message':
|
||||
**kwargs) -> '_tl.Message':
|
||||
"""
|
||||
Sends message with the given file to the specified entity.
|
||||
|
||||
|
@ -3392,11 +3391,11 @@ class TelegramClient:
|
|||
|
||||
# Dices, including dart and other future emoji
|
||||
from telethon.tl import types
|
||||
await client.send_file(chat, types.InputMediaDice(''))
|
||||
await client.send_file(chat, types.InputMediaDice('🎯'))
|
||||
await client.send_file(chat, _tl.InputMediaDice(''))
|
||||
await client.send_file(chat, _tl.InputMediaDice('🎯'))
|
||||
|
||||
# Contacts
|
||||
await client.send_file(chat, types.InputMediaContact(
|
||||
await client.send_file(chat, _tl.InputMediaContact(
|
||||
phone_number='+34 123 456 789',
|
||||
first_name='Example',
|
||||
last_name='',
|
||||
|
@ -3415,7 +3414,7 @@ class TelegramClient:
|
|||
use_cache: type = None,
|
||||
key: bytes = None,
|
||||
iv: bytes = None,
|
||||
progress_callback: 'hints.ProgressCallback' = None) -> 'types.TypeInputFile':
|
||||
progress_callback: 'hints.ProgressCallback' = None) -> '_tl.TypeInputFile':
|
||||
"""
|
||||
Uploads a file to Telegram's servers, without sending it.
|
||||
|
||||
|
@ -3522,7 +3521,7 @@ class TelegramClient:
|
|||
return users.call(self._sender, request, ordered=ordered)
|
||||
|
||||
async def get_me(self: 'TelegramClient', input_peer: bool = False) \
|
||||
-> 'typing.Union[types.User, types.InputPeerUser]':
|
||||
-> 'typing.Union[_tl.User, _tl.InputPeerUser]':
|
||||
"""
|
||||
Gets "me", the current :tl:`User` who is logged in.
|
||||
|
||||
|
@ -3633,7 +3632,7 @@ class TelegramClient:
|
|||
|
||||
async def get_input_entity(
|
||||
self: 'TelegramClient',
|
||||
peer: 'hints.EntityLike') -> 'types.TypeInputPeer':
|
||||
peer: 'hints.EntityLike') -> '_tl.TypeInputPeer':
|
||||
"""
|
||||
Turns the given entity into its input entity version.
|
||||
|
||||
|
|
|
@ -8,9 +8,8 @@ import traceback
|
|||
import typing
|
||||
import logging
|
||||
|
||||
from .. import events, utils, errors
|
||||
from .. import events, utils, errors, _tl
|
||||
from ..events.common import EventBuilder, EventCommon
|
||||
from ..tl import types, functions
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from .telegramclient import TelegramClient
|
||||
|
@ -22,7 +21,7 @@ Callback = typing.Callable[[typing.Any], typing.Any]
|
|||
async def _run_until_disconnected(self: 'TelegramClient'):
|
||||
try:
|
||||
# Make a high-level request to notify that we want updates
|
||||
await self(functions.updates.GetStateRequest())
|
||||
await self(_tl.fn.updates.GetState())
|
||||
return await self.disconnected
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
@ -32,7 +31,7 @@ async def _run_until_disconnected(self: 'TelegramClient'):
|
|||
async def set_receive_updates(self: 'TelegramClient', receive_updates):
|
||||
self._no_updates = not receive_updates
|
||||
if receive_updates:
|
||||
await self(functions.updates.GetStateRequest())
|
||||
await self(_tl.fn.updates.GetState())
|
||||
|
||||
async def run_until_disconnected(self: 'TelegramClient'):
|
||||
return await self._run_until_disconnected()
|
||||
|
@ -91,24 +90,24 @@ async def catch_up(self: 'TelegramClient'):
|
|||
self.session.catching_up = True
|
||||
try:
|
||||
while True:
|
||||
d = await self(functions.updates.GetDifferenceRequest(
|
||||
d = await self(_tl.fn.updates.GetDifference(
|
||||
pts, date, 0
|
||||
))
|
||||
if isinstance(d, (types.updates.DifferenceSlice,
|
||||
types.updates.Difference)):
|
||||
if isinstance(d, types.updates.Difference):
|
||||
if isinstance(d, (_tl.updates.DifferenceSlice,
|
||||
_tl.updates.Difference)):
|
||||
if isinstance(d, _tl.updates.Difference):
|
||||
state = d.state
|
||||
else:
|
||||
state = d.intermediate_state
|
||||
|
||||
pts, date = state.pts, state.date
|
||||
self._handle_update(types.Updates(
|
||||
self._handle_update(_tl.Updates(
|
||||
users=d.users,
|
||||
chats=d.chats,
|
||||
date=state.date,
|
||||
seq=state.seq,
|
||||
updates=d.other_updates + [
|
||||
types.UpdateNewMessage(m, 0, 0)
|
||||
_tl.UpdateNewMessage(m, 0, 0)
|
||||
for m in d.new_messages
|
||||
]
|
||||
))
|
||||
|
@ -128,9 +127,9 @@ async def catch_up(self: 'TelegramClient'):
|
|||
# some). This can be used to detect collisions (i.e.
|
||||
# it would return an update we have already seen).
|
||||
else:
|
||||
if isinstance(d, types.updates.DifferenceEmpty):
|
||||
if isinstance(d, _tl.updates.DifferenceEmpty):
|
||||
date = d.date
|
||||
elif isinstance(d, types.updates.DifferenceTooLong):
|
||||
elif isinstance(d, _tl.updates.DifferenceTooLong):
|
||||
pts = d.pts
|
||||
break
|
||||
except (ConnectionError, asyncio.CancelledError):
|
||||
|
@ -148,12 +147,12 @@ def _handle_update(self: 'TelegramClient', update):
|
|||
self.session.process_entities(update)
|
||||
self._entity_cache.add(update)
|
||||
|
||||
if isinstance(update, (types.Updates, types.UpdatesCombined)):
|
||||
if isinstance(update, (_tl.Updates, _tl.UpdatesCombined)):
|
||||
entities = {utils.get_peer_id(x): x for x in
|
||||
itertools.chain(update.users, update.chats)}
|
||||
for u in update.updates:
|
||||
self._process_update(u, update.updates, entities=entities)
|
||||
elif isinstance(update, types.UpdateShort):
|
||||
elif isinstance(update, _tl.UpdateShort):
|
||||
self._process_update(update.update, None)
|
||||
else:
|
||||
self._process_update(update, None)
|
||||
|
@ -230,7 +229,7 @@ async def _update_loop(self: 'TelegramClient'):
|
|||
continue
|
||||
|
||||
try:
|
||||
await self(functions.updates.GetStateRequest())
|
||||
await self(_tl.fn.updates.GetState())
|
||||
except (ConnectionError, asyncio.CancelledError):
|
||||
return
|
||||
|
||||
|
@ -359,7 +358,7 @@ async def _get_difference(self: 'TelegramClient', update, channel_id, pts_date):
|
|||
assert isinstance(channel_id, int), 'channel_id was {}, not int in {}'.format(type(channel_id), update)
|
||||
try:
|
||||
# Wrap the ID inside a peer to ensure we get a channel back.
|
||||
where = await self.get_input_entity(types.PeerChannel(channel_id))
|
||||
where = await self.get_input_entity(_tl.PeerChannel(channel_id))
|
||||
except ValueError:
|
||||
# There's a high chance that this fails, since
|
||||
# we are getting the difference to fetch entities.
|
||||
|
@ -367,15 +366,15 @@ async def _get_difference(self: 'TelegramClient', update, channel_id, pts_date):
|
|||
|
||||
if not pts_date:
|
||||
# First-time, can't get difference. Get pts instead.
|
||||
result = await self(functions.channels.GetFullChannelRequest(
|
||||
result = await self(_tl.fn.channels.GetFullChannel(
|
||||
utils.get_input_channel(where)
|
||||
))
|
||||
self._state_cache[channel_id] = result.full_chat.pts
|
||||
return
|
||||
|
||||
result = await self(functions.updates.GetChannelDifferenceRequest(
|
||||
result = await self(_tl.fn.updates.GetChannelDifference(
|
||||
channel=where,
|
||||
filter=types.ChannelMessagesFilterEmpty(),
|
||||
filter=_tl.ChannelMessagesFilterEmpty(),
|
||||
pts=pts_date, # just pts
|
||||
limit=100,
|
||||
force=True
|
||||
|
@ -383,20 +382,20 @@ async def _get_difference(self: 'TelegramClient', update, channel_id, pts_date):
|
|||
else:
|
||||
if not pts_date[0]:
|
||||
# First-time, can't get difference. Get pts instead.
|
||||
result = await self(functions.updates.GetStateRequest())
|
||||
result = await self(_tl.fn.updates.GetState())
|
||||
self._state_cache[None] = result.pts, result.date
|
||||
return
|
||||
|
||||
result = await self(functions.updates.GetDifferenceRequest(
|
||||
result = await self(_tl.fn.updates.GetDifference(
|
||||
pts=pts_date[0],
|
||||
date=pts_date[1],
|
||||
qts=0
|
||||
))
|
||||
|
||||
if isinstance(result, (types.updates.Difference,
|
||||
types.updates.DifferenceSlice,
|
||||
types.updates.ChannelDifference,
|
||||
types.updates.ChannelDifferenceTooLong)):
|
||||
if isinstance(result, (_tl.updates.Difference,
|
||||
_tl.updates.DifferenceSlice,
|
||||
_tl.updates.ChannelDifference,
|
||||
_tl.updates.ChannelDifferenceTooLong)):
|
||||
update._entities.update({
|
||||
utils.get_peer_id(x): x for x in
|
||||
itertools.chain(result.users, result.chats)
|
||||
|
|
|
@ -9,8 +9,7 @@ from io import BytesIO
|
|||
|
||||
from ..crypto import AES
|
||||
|
||||
from .. import utils, helpers, hints
|
||||
from ..tl import types, functions, custom
|
||||
from .. import utils, helpers, hints, _tl
|
||||
|
||||
try:
|
||||
import PIL
|
||||
|
@ -99,11 +98,11 @@ async def send_file(
|
|||
clear_draft: bool = False,
|
||||
progress_callback: 'hints.ProgressCallback' = None,
|
||||
reply_to: 'hints.MessageIDLike' = None,
|
||||
attributes: 'typing.Sequence[types.TypeDocumentAttribute]' = None,
|
||||
attributes: 'typing.Sequence[_tl.TypeDocumentAttribute]' = None,
|
||||
thumb: 'hints.FileLike' = None,
|
||||
allow_cache: bool = True,
|
||||
parse_mode: str = (),
|
||||
formatting_entities: typing.Optional[typing.List[types.TypeMessageEntity]] = None,
|
||||
formatting_entities: typing.Optional[typing.List[_tl.TypeMessageEntity]] = None,
|
||||
voice_note: bool = False,
|
||||
video_note: bool = False,
|
||||
buttons: 'hints.MarkupLike' = None,
|
||||
|
@ -111,9 +110,9 @@ async def send_file(
|
|||
background: bool = None,
|
||||
supports_streaming: bool = False,
|
||||
schedule: 'hints.DateLike' = None,
|
||||
comment_to: 'typing.Union[int, types.Message]' = None,
|
||||
comment_to: 'typing.Union[int, _tl.Message]' = None,
|
||||
ttl: int = None,
|
||||
**kwargs) -> 'types.Message':
|
||||
**kwargs) -> '_tl.Message':
|
||||
# TODO Properly implement allow_cache to reuse the sha256 of the file
|
||||
# i.e. `None` was used
|
||||
if not file:
|
||||
|
@ -182,7 +181,7 @@ async def send_file(
|
|||
raise TypeError('Cannot use {!r} as file'.format(file))
|
||||
|
||||
markup = self.build_reply_markup(buttons)
|
||||
request = functions.messages.SendMediaRequest(
|
||||
request = _tl.fn.messages.SendMedia(
|
||||
entity, media, reply_to_msg_id=reply_to, message=caption,
|
||||
entities=msg_entities, reply_markup=markup, silent=silent,
|
||||
schedule_date=schedule, clear_draft=clear_draft,
|
||||
|
@ -225,14 +224,14 @@ async def _send_album(self: 'TelegramClient', entity, files, caption='',
|
|||
fh, fm, _ = await self._file_to_media(
|
||||
file, supports_streaming=supports_streaming,
|
||||
force_document=force_document, ttl=ttl)
|
||||
if isinstance(fm, (types.InputMediaUploadedPhoto, types.InputMediaPhotoExternal)):
|
||||
r = await self(functions.messages.UploadMediaRequest(
|
||||
if isinstance(fm, (_tl.InputMediaUploadedPhoto, _tl.InputMediaPhotoExternal)):
|
||||
r = await self(_tl.fn.messages.UploadMedia(
|
||||
entity, media=fm
|
||||
))
|
||||
|
||||
fm = utils.get_input_media(r.photo)
|
||||
elif isinstance(fm, types.InputMediaUploadedDocument):
|
||||
r = await self(functions.messages.UploadMediaRequest(
|
||||
elif isinstance(fm, _tl.InputMediaUploadedDocument):
|
||||
r = await self(_tl.fn.messages.UploadMedia(
|
||||
entity, media=fm
|
||||
))
|
||||
|
||||
|
@ -243,7 +242,7 @@ async def _send_album(self: 'TelegramClient', entity, files, caption='',
|
|||
caption, msg_entities = captions.pop()
|
||||
else:
|
||||
caption, msg_entities = '', None
|
||||
media.append(types.InputSingleMedia(
|
||||
media.append(_tl.InputSingleMedia(
|
||||
fm,
|
||||
message=caption,
|
||||
entities=msg_entities
|
||||
|
@ -251,7 +250,7 @@ async def _send_album(self: 'TelegramClient', entity, files, caption='',
|
|||
))
|
||||
|
||||
# Now we can construct the multi-media request
|
||||
request = functions.messages.SendMultiMediaRequest(
|
||||
request = _tl.fn.messages.SendMultiMedia(
|
||||
entity, reply_to_msg_id=reply_to, multi_media=media,
|
||||
silent=silent, schedule_date=schedule, clear_draft=clear_draft,
|
||||
background=background
|
||||
|
@ -271,8 +270,8 @@ async def upload_file(
|
|||
use_cache: type = None,
|
||||
key: bytes = None,
|
||||
iv: bytes = None,
|
||||
progress_callback: 'hints.ProgressCallback' = None) -> 'types.TypeInputFile':
|
||||
if isinstance(file, (types.InputFile, types.InputFileBig)):
|
||||
progress_callback: 'hints.ProgressCallback' = None) -> '_tl.TypeInputFile':
|
||||
if isinstance(file, (_tl.InputFile, _tl.InputFileBig)):
|
||||
return file # Already uploaded
|
||||
|
||||
pos = 0
|
||||
|
@ -343,10 +342,10 @@ async def upload_file(
|
|||
# The SavePartRequest is different depending on whether
|
||||
# the file is too large or not (over or less than 10MB)
|
||||
if is_big:
|
||||
request = functions.upload.SaveBigFilePartRequest(
|
||||
request = _tl.fn.upload.SaveBigFilePart(
|
||||
file_id, part_index, part_count, part)
|
||||
else:
|
||||
request = functions.upload.SaveFilePartRequest(
|
||||
request = _tl.fn.upload.SaveFilePart(
|
||||
file_id, part_index, part)
|
||||
|
||||
result = await self(request)
|
||||
|
@ -360,9 +359,9 @@ async def upload_file(
|
|||
'Failed to upload file part {}.'.format(part_index))
|
||||
|
||||
if is_big:
|
||||
return types.InputFileBig(file_id, part_count, file_name)
|
||||
return _tl.InputFileBig(file_id, part_count, file_name)
|
||||
else:
|
||||
return custom.InputSizedFile(
|
||||
return _tl.custom.InputSizedFile(
|
||||
file_id, part_count, file_name, md5=hash_md5, size=file_size
|
||||
)
|
||||
|
||||
|
@ -385,7 +384,7 @@ async def _file_to_media(
|
|||
|
||||
# `aiofiles` do not base `io.IOBase` but do have `read`, so we
|
||||
# just check for the read attribute to see if it's file-like.
|
||||
if not isinstance(file, (str, bytes, types.InputFile, types.InputFileBig))\
|
||||
if not isinstance(file, (str, bytes, _tl.InputFile, _tl.InputFileBig))\
|
||||
and not hasattr(file, 'read'):
|
||||
# The user may pass a Message containing media (or the media,
|
||||
# or anything similar) that should be treated as a file. Try
|
||||
|
@ -411,7 +410,7 @@ async def _file_to_media(
|
|||
media = None
|
||||
file_handle = None
|
||||
|
||||
if isinstance(file, (types.InputFile, types.InputFileBig)):
|
||||
if isinstance(file, (_tl.InputFile, _tl.InputFileBig)):
|
||||
file_handle = file
|
||||
elif not isinstance(file, str) or os.path.isfile(file):
|
||||
file_handle = await self.upload_file(
|
||||
|
@ -421,9 +420,9 @@ async def _file_to_media(
|
|||
)
|
||||
elif re.match('https?://', file):
|
||||
if as_image:
|
||||
media = types.InputMediaPhotoExternal(file, ttl_seconds=ttl)
|
||||
media = _tl.InputMediaPhotoExternal(file, ttl_seconds=ttl)
|
||||
else:
|
||||
media = types.InputMediaDocumentExternal(file, ttl_seconds=ttl)
|
||||
media = _tl.InputMediaDocumentExternal(file, ttl_seconds=ttl)
|
||||
else:
|
||||
bot_file = utils.resolve_bot_file_id(file)
|
||||
if bot_file:
|
||||
|
@ -437,7 +436,7 @@ async def _file_to_media(
|
|||
'an HTTP URL or a valid bot-API-like file ID'.format(file)
|
||||
)
|
||||
elif as_image:
|
||||
media = types.InputMediaUploadedPhoto(file_handle, ttl_seconds=ttl)
|
||||
media = _tl.InputMediaUploadedPhoto(file_handle, ttl_seconds=ttl)
|
||||
else:
|
||||
attributes, mime_type = utils.get_attributes(
|
||||
file,
|
||||
|
@ -457,7 +456,7 @@ async def _file_to_media(
|
|||
thumb = str(thumb.absolute())
|
||||
thumb = await self.upload_file(thumb, file_size=file_size)
|
||||
|
||||
media = types.InputMediaUploadedDocument(
|
||||
media = _tl.InputMediaUploadedDocument(
|
||||
file=file_handle,
|
||||
mime_type=mime_type,
|
||||
attributes=attributes,
|
||||
|
|
|
@ -4,10 +4,9 @@ import itertools
|
|||
import time
|
||||
import typing
|
||||
|
||||
from .. import errors, helpers, utils, hints
|
||||
from .. import errors, helpers, utils, hints, _tl
|
||||
from ..errors import MultiError, RPCError
|
||||
from ..helpers import retry_range
|
||||
from ..tl import TLRequest, types, functions
|
||||
|
||||
_NOT_A_REQUEST = lambda: TypeError('You can only invoke requests, not types!')
|
||||
|
||||
|
@ -48,7 +47,7 @@ async def call(self: 'TelegramClient', sender, request, ordered=False, flood_sle
|
|||
raise errors.FloodWaitError(request=r, capture=diff)
|
||||
|
||||
if self._no_updates:
|
||||
r = functions.InvokeWithoutUpdatesRequest(r)
|
||||
r = _tl.fn.InvokeWithoutUpdates(r)
|
||||
|
||||
request_index = 0
|
||||
last_error = None
|
||||
|
@ -128,13 +127,13 @@ async def call(self: 'TelegramClient', sender, request, ordered=False, flood_sle
|
|||
|
||||
|
||||
async def get_me(self: 'TelegramClient', input_peer: bool = False) \
|
||||
-> 'typing.Union[types.User, types.InputPeerUser]':
|
||||
-> 'typing.Union[_tl.User, _tl.InputPeerUser]':
|
||||
if input_peer and self._self_input_peer:
|
||||
return self._self_input_peer
|
||||
|
||||
try:
|
||||
me = (await self(
|
||||
functions.users.GetUsersRequest([types.InputUserSelf()])))[0]
|
||||
_tl.fn.users.GetUsers([_tl.InputUserSelf()])))[0]
|
||||
|
||||
self._bot = me.bot
|
||||
if not self._self_input_peer:
|
||||
|
@ -165,7 +164,7 @@ async def is_user_authorized(self: 'TelegramClient') -> bool:
|
|||
if self._authorized is None:
|
||||
try:
|
||||
# Any request that requires authorization will work
|
||||
await self(functions.updates.GetStateRequest())
|
||||
await self(_tl.fn.updates.GetState())
|
||||
self._authorized = True
|
||||
except errors.RPCError:
|
||||
self._authorized = False
|
||||
|
@ -209,14 +208,14 @@ async def get_entity(
|
|||
tmp = []
|
||||
while users:
|
||||
curr, users = users[:200], users[200:]
|
||||
tmp.extend(await self(functions.users.GetUsersRequest(curr)))
|
||||
tmp.extend(await self(_tl.fn.users.GetUsers(curr)))
|
||||
users = tmp
|
||||
if chats: # TODO Handle chats slice?
|
||||
chats = (await self(
|
||||
functions.messages.GetChatsRequest([x.chat_id for x in chats]))).chats
|
||||
_tl.fn.messages.GetChats([x.chat_id for x in chats]))).chats
|
||||
if channels:
|
||||
channels = (await self(
|
||||
functions.channels.GetChannelsRequest(channels))).chats
|
||||
_tl.fn.channels.GetChannels(channels))).chats
|
||||
|
||||
# Merge users, chats and channels into a single dictionary
|
||||
id_entity = {
|
||||
|
@ -232,19 +231,19 @@ async def get_entity(
|
|||
for x in inputs:
|
||||
if isinstance(x, str):
|
||||
result.append(await self._get_entity_from_string(x))
|
||||
elif not isinstance(x, types.InputPeerSelf):
|
||||
elif not isinstance(x, _tl.InputPeerSelf):
|
||||
result.append(id_entity[utils.get_peer_id(x)])
|
||||
else:
|
||||
result.append(next(
|
||||
u for u in id_entity.values()
|
||||
if isinstance(u, types.User) and u.is_self
|
||||
if isinstance(u, _tl.User) and u.is_self
|
||||
))
|
||||
|
||||
return result[0] if single else result
|
||||
|
||||
async def get_input_entity(
|
||||
self: 'TelegramClient',
|
||||
peer: 'hints.EntityLike') -> 'types.TypeInputPeer':
|
||||
peer: 'hints.EntityLike') -> '_tl.TypeInputPeer':
|
||||
# Short-circuit if the input parameter directly maps to an InputPeer
|
||||
try:
|
||||
return utils.get_input_peer(peer)
|
||||
|
@ -261,7 +260,7 @@ async def get_input_entity(
|
|||
|
||||
# Then come known strings that take precedence
|
||||
if peer in ('me', 'self'):
|
||||
return types.InputPeerSelf()
|
||||
return _tl.InputPeerSelf()
|
||||
|
||||
# No InputPeer, cached peer, or known string. Fetch from disk cache
|
||||
try:
|
||||
|
@ -279,10 +278,10 @@ async def get_input_entity(
|
|||
# If we're not a bot but the user is in our contacts, it seems to work
|
||||
# regardless. These are the only two special-cased requests.
|
||||
peer = utils.get_peer(peer)
|
||||
if isinstance(peer, types.PeerUser):
|
||||
users = await self(functions.users.GetUsersRequest([
|
||||
types.InputUser(peer.user_id, access_hash=0)]))
|
||||
if users and not isinstance(users[0], types.UserEmpty):
|
||||
if isinstance(peer, _tl.PeerUser):
|
||||
users = await self(_tl.fn.users.GetUsers([
|
||||
_tl.InputUser(peer.user_id, access_hash=0)]))
|
||||
if users and not isinstance(users[0], _tl.UserEmpty):
|
||||
# If the user passed a valid ID they expect to work for
|
||||
# channels but would be valid for users, we get UserEmpty.
|
||||
# Avoid returning the invalid empty input peer for that.
|
||||
|
@ -291,12 +290,12 @@ async def get_input_entity(
|
|||
# it's not, work as a chat and try to validate it through
|
||||
# another request, but that becomes too much work.
|
||||
return utils.get_input_peer(users[0])
|
||||
elif isinstance(peer, types.PeerChat):
|
||||
return types.InputPeerChat(peer.chat_id)
|
||||
elif isinstance(peer, types.PeerChannel):
|
||||
elif isinstance(peer, _tl.PeerChat):
|
||||
return _tl.InputPeerChat(peer.chat_id)
|
||||
elif isinstance(peer, _tl.PeerChannel):
|
||||
try:
|
||||
channels = await self(functions.channels.GetChannelsRequest([
|
||||
types.InputChannel(peer.channel_id, access_hash=0)]))
|
||||
channels = await self(_tl.fn.channels.GetChannels([
|
||||
_tl.InputChannel(peer.channel_id, access_hash=0)]))
|
||||
return utils.get_input_peer(channels.chats[0])
|
||||
except errors.ChannelInvalidError:
|
||||
pass
|
||||
|
@ -326,7 +325,7 @@ async def get_peer_id(
|
|||
except AttributeError:
|
||||
peer = await self.get_input_entity(peer)
|
||||
|
||||
if isinstance(peer, types.InputPeerSelf):
|
||||
if isinstance(peer, _tl.InputPeerSelf):
|
||||
peer = await self.get_me(input_peer=True)
|
||||
|
||||
return utils.get_peer_id(peer, add_mark=add_mark)
|
||||
|
@ -348,7 +347,7 @@ async def _get_entity_from_string(self: 'TelegramClient', string):
|
|||
if phone:
|
||||
try:
|
||||
for user in (await self(
|
||||
functions.contacts.GetContactsRequest(0))).users:
|
||||
_tl.fn.contacts.GetContacts(0))).users:
|
||||
if user.phone == phone:
|
||||
return user
|
||||
except errors.BotMethodInvalidError:
|
||||
|
@ -360,26 +359,26 @@ async def _get_entity_from_string(self: 'TelegramClient', string):
|
|||
username, is_join_chat = utils.parse_username(string)
|
||||
if is_join_chat:
|
||||
invite = await self(
|
||||
functions.messages.CheckChatInviteRequest(username))
|
||||
_tl.fn.messages.CheckChatInvite(username))
|
||||
|
||||
if isinstance(invite, types.ChatInvite):
|
||||
if isinstance(invite, _tl.ChatInvite):
|
||||
raise ValueError(
|
||||
'Cannot get entity from a channel (or group) '
|
||||
'that you are not part of. Join the group and retry'
|
||||
)
|
||||
elif isinstance(invite, types.ChatInviteAlready):
|
||||
elif isinstance(invite, _tl.ChatInviteAlready):
|
||||
return invite.chat
|
||||
elif username:
|
||||
try:
|
||||
result = await self(
|
||||
functions.contacts.ResolveUsernameRequest(username))
|
||||
_tl.fn.contacts.ResolveUsername(username))
|
||||
except errors.UsernameNotOccupiedError as e:
|
||||
raise ValueError('No user has "{}" as username'
|
||||
.format(username)) from e
|
||||
|
||||
try:
|
||||
pid = utils.get_peer_id(result.peer, add_mark=False)
|
||||
if isinstance(result.peer, types.PeerUser):
|
||||
if isinstance(result.peer, _tl.PeerUser):
|
||||
return next(x for x in result.users if x.id == pid)
|
||||
else:
|
||||
return next(x for x in result.chats if x.id == pid)
|
||||
|
@ -407,11 +406,11 @@ async def _get_input_dialog(self: 'TelegramClient', dialog):
|
|||
dialog.peer = await self.get_input_entity(dialog.peer)
|
||||
return dialog
|
||||
elif dialog.SUBCLASS_OF_ID == 0xc91c90b6: # crc32(b'InputPeer')
|
||||
return types.InputDialogPeer(dialog)
|
||||
return _tl.InputDialogPeer(dialog)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
return types.InputDialogPeer(await self.get_input_entity(dialog))
|
||||
return _tl.InputDialogPeer(await self.get_input_entity(dialog))
|
||||
|
||||
async def _get_input_notify(self: 'TelegramClient', notify):
|
||||
"""
|
||||
|
@ -421,10 +420,10 @@ async def _get_input_notify(self: 'TelegramClient', notify):
|
|||
"""
|
||||
try:
|
||||
if notify.SUBCLASS_OF_ID == 0x58981615:
|
||||
if isinstance(notify, types.InputNotifyPeer):
|
||||
if isinstance(notify, _tl.InputNotifyPeer):
|
||||
notify.peer = await self.get_input_entity(notify.peer)
|
||||
return notify
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
return types.InputNotifyPeer(await self.get_input_entity(notify))
|
||||
return _tl.InputNotifyPeer(await self.get_input_entity(notify))
|
||||
|
|
|
@ -3,8 +3,7 @@ This module holds the CdnDecrypter utility class.
|
|||
"""
|
||||
from hashlib import sha256
|
||||
|
||||
from ..tl.functions.upload import GetCdnFileRequest, ReuploadCdnFileRequest
|
||||
from ..tl.types.upload import CdnFileReuploadNeeded, CdnFile
|
||||
from .. import _tl
|
||||
from ..crypto import AESModeCTR
|
||||
from ..errors import CdnFileTamperedError
|
||||
|
||||
|
@ -52,14 +51,14 @@ class CdnDecrypter:
|
|||
cdn_aes, cdn_redirect.cdn_file_hashes
|
||||
)
|
||||
|
||||
cdn_file = await cdn_client(GetCdnFileRequest(
|
||||
cdn_file = await cdn_client(_tl.fn.upload.GetCdnFile(
|
||||
file_token=cdn_redirect.file_token,
|
||||
offset=cdn_redirect.cdn_file_hashes[0].offset,
|
||||
limit=cdn_redirect.cdn_file_hashes[0].limit
|
||||
))
|
||||
if isinstance(cdn_file, CdnFileReuploadNeeded):
|
||||
if isinstance(cdn_file, _tl.upload.CdnFileReuploadNeeded):
|
||||
# We need to use the original client here
|
||||
await client(ReuploadCdnFileRequest(
|
||||
await client(_tl.fn.upload.ReuploadCdnFile(
|
||||
file_token=cdn_redirect.file_token,
|
||||
request_token=cdn_file.request_token
|
||||
))
|
||||
|
@ -82,13 +81,13 @@ class CdnDecrypter:
|
|||
"""
|
||||
if self.cdn_file_hashes:
|
||||
cdn_hash = self.cdn_file_hashes.pop(0)
|
||||
cdn_file = self.client(GetCdnFileRequest(
|
||||
cdn_file = self.client(_tl.fn.upload.GetCdnFile(
|
||||
self.file_token, cdn_hash.offset, cdn_hash.limit
|
||||
))
|
||||
cdn_file.bytes = self.cdn_aes.encrypt(cdn_file.bytes)
|
||||
self.check(cdn_file.bytes, cdn_hash)
|
||||
else:
|
||||
cdn_file = CdnFile(bytes(0))
|
||||
cdn_file = _tl.upload.CdnFile(bytes(0))
|
||||
|
||||
return cdn_file
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ except ImportError:
|
|||
rsa = None
|
||||
raise ImportError('Missing module "rsa", please install via pip.')
|
||||
|
||||
from ..tl import TLObject
|
||||
from .. import _tl
|
||||
|
||||
|
||||
# {fingerprint: (Crypto.PublicKey.RSA._RSAobj, old)} dictionary
|
||||
|
@ -41,8 +41,8 @@ def _compute_fingerprint(key):
|
|||
:param key: the Crypto.RSA key.
|
||||
:return: its 8-bytes-long fingerprint.
|
||||
"""
|
||||
n = TLObject.serialize_bytes(get_byte_array(key.n))
|
||||
e = TLObject.serialize_bytes(get_byte_array(key.e))
|
||||
n = _tl.TLObject.serialize_bytes(get_byte_array(key.n))
|
||||
e = _tl.TLObject.serialize_bytes(get_byte_array(key.e))
|
||||
# Telegram uses the last 8 bytes as the fingerprint
|
||||
return struct.unpack('<q', sha1(n + e).digest()[-8:])[0]
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ from io import BytesIO
|
|||
from struct import unpack
|
||||
|
||||
from ..errors import TypeNotFoundError
|
||||
from ..tl.alltlobjects import tlobjects
|
||||
from ..tl.core import core_objects
|
||||
from .. import _tl
|
||||
|
||||
_EPOCH_NAIVE = datetime(*time.gmtime(0)[:6])
|
||||
_EPOCH = _EPOCH_NAIVE.replace(tzinfo=timezone.utc)
|
||||
|
@ -118,7 +117,7 @@ class BinaryReader:
|
|||
def tgread_object(self):
|
||||
"""Reads a Telegram object."""
|
||||
constructor_id = self.read_int(signed=False)
|
||||
clazz = tlobjects.get(constructor_id, None)
|
||||
clazz = _tl.tlobjects.get(constructor_id, None)
|
||||
if clazz is None:
|
||||
# The class was None, but there's still a
|
||||
# chance of it being a manually parsed value like bool!
|
||||
|
@ -130,7 +129,7 @@ class BinaryReader:
|
|||
elif value == 0x1cb5c415: # Vector
|
||||
return [self.tgread_object() for _ in range(self.read_int())]
|
||||
|
||||
clazz = core_objects.get(constructor_id, None)
|
||||
clazz = _tl.core.get(constructor_id, None)
|
||||
if clazz is None:
|
||||
# If there was still no luck, give up
|
||||
self.seek(-4) # Go back
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import inspect
|
||||
import itertools
|
||||
|
||||
from . import utils
|
||||
from .tl import types
|
||||
from . import utils, _tl
|
||||
|
||||
# Which updates have the following fields?
|
||||
_has_field = {
|
||||
|
@ -25,8 +24,8 @@ _has_field = {
|
|||
|
||||
|
||||
def _fill():
|
||||
for name in dir(types):
|
||||
update = getattr(types, name)
|
||||
for name in dir(_tl):
|
||||
update = getattr(_tl, name)
|
||||
if getattr(update, 'SUBCLASS_OF_ID', None) == 0x9f89304e:
|
||||
cid = update.CONSTRUCTOR_ID
|
||||
sig = inspect.signature(update.__init__)
|
||||
|
@ -84,7 +83,7 @@ class EntityCache:
|
|||
except TypeError:
|
||||
raise KeyError('Invalid key will not have entity') from None
|
||||
|
||||
for cls in (types.PeerUser, types.PeerChat, types.PeerChannel):
|
||||
for cls in (_tl.PeerUser, _tl.PeerChat, _tl.PeerChannel):
|
||||
result = self.__dict__.get(utils.get_peer_id(cls(item)))
|
||||
if result:
|
||||
return result
|
||||
|
@ -111,7 +110,7 @@ class EntityCache:
|
|||
"""
|
||||
# This method is called pretty often and we want it to have the lowest
|
||||
# overhead possible. For that, we avoid `isinstance` and constantly
|
||||
# getting attributes out of `types.` by "caching" the constructor IDs
|
||||
# getting attributes out of `_tl.` by "caching" the constructor IDs
|
||||
# in sets inside the arguments, and using local variables.
|
||||
dct = self.__dict__
|
||||
cid = update.CONSTRUCTOR_ID
|
||||
|
@ -120,11 +119,11 @@ class EntityCache:
|
|||
return False
|
||||
|
||||
if cid in has_chat_id and \
|
||||
utils.get_peer_id(types.PeerChat(update.chat_id)) not in dct:
|
||||
utils.get_peer_id(_tl.PeerChat(update.chat_id)) not in dct:
|
||||
return False
|
||||
|
||||
if cid in has_channel_id and \
|
||||
utils.get_peer_id(types.PeerChannel(update.channel_id)) not in dct:
|
||||
utils.get_peer_id(_tl.PeerChannel(update.channel_id)) not in dct:
|
||||
return False
|
||||
|
||||
if cid in has_peer and \
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
import datetime
|
||||
import typing
|
||||
|
||||
from . import helpers
|
||||
from .tl import types, custom
|
||||
from . import helpers, _tl
|
||||
|
||||
Phone = str
|
||||
Username = str
|
||||
PeerID = int
|
||||
Entity = typing.Union[types.User, types.Chat, types.Channel]
|
||||
FullEntity = typing.Union[types.UserFull, types.messages.ChatFull, types.ChatFull, types.ChannelFull]
|
||||
Entity = typing.Union[_tl.User, _tl.Chat, _tl.Channel]
|
||||
FullEntity = typing.Union[_tl.UserFull, _tl.messages.ChatFull, _tl.ChatFull, _tl.ChannelFull]
|
||||
|
||||
EntityLike = typing.Union[
|
||||
Phone,
|
||||
Username,
|
||||
PeerID,
|
||||
types.TypePeer,
|
||||
types.TypeInputPeer,
|
||||
_tl.TypePeer,
|
||||
_tl.TypeInputPeer,
|
||||
Entity,
|
||||
FullEntity
|
||||
]
|
||||
EntitiesLike = typing.Union[EntityLike, typing.Sequence[EntityLike]]
|
||||
|
||||
ButtonLike = typing.Union[types.TypeKeyboardButton, custom.Button]
|
||||
ButtonLike = typing.Union[_tl.TypeKeyboardButton, custom.Button]
|
||||
MarkupLike = typing.Union[
|
||||
types.TypeReplyMarkup,
|
||||
_tl.TypeReplyMarkup,
|
||||
ButtonLike,
|
||||
typing.Sequence[ButtonLike],
|
||||
typing.Sequence[typing.Sequence[ButtonLike]]
|
||||
|
@ -42,9 +41,9 @@ FileLike = typing.Union[
|
|||
BotFileID,
|
||||
bytes,
|
||||
typing.BinaryIO,
|
||||
types.TypeMessageMedia,
|
||||
types.TypeInputFile,
|
||||
types.TypeInputFileLocation
|
||||
_tl.TypeMessageMedia,
|
||||
_tl.TypeInputFile,
|
||||
_tl.TypeInputFileLocation
|
||||
]
|
||||
|
||||
# Can't use `typing.Type` in Python 3.5.2
|
||||
|
@ -61,7 +60,7 @@ except TypeError:
|
|||
typing.BinaryIO
|
||||
]
|
||||
|
||||
MessageLike = typing.Union[str, types.Message]
|
||||
MessageIDLike = typing.Union[int, types.Message, types.TypeInputMessage]
|
||||
MessageLike = typing.Union[str, _tl.Message]
|
||||
MessageIDLike = typing.Union[int, _tl.Message, _tl.TypeInputMessage]
|
||||
|
||||
ProgressCallback = typing.Callable[[int, int], None]
|
||||
|
|
|
@ -7,14 +7,7 @@ from html import escape
|
|||
from html.parser import HTMLParser
|
||||
from typing import Iterable, Optional, Tuple, List
|
||||
|
||||
from .. import helpers
|
||||
from ..tl.types import (
|
||||
MessageEntityBold, MessageEntityItalic, MessageEntityCode,
|
||||
MessageEntityPre, MessageEntityEmail, MessageEntityUrl,
|
||||
MessageEntityTextUrl, MessageEntityMentionName,
|
||||
MessageEntityUnderline, MessageEntityStrike, MessageEntityBlockquote,
|
||||
TypeMessageEntity
|
||||
)
|
||||
from .. import helpers, _tl
|
||||
|
||||
|
||||
# Helpers from markdown.py
|
||||
|
@ -46,15 +39,15 @@ class HTMLToTelegramParser(HTMLParser):
|
|||
EntityType = None
|
||||
args = {}
|
||||
if tag == 'strong' or tag == 'b':
|
||||
EntityType = MessageEntityBold
|
||||
EntityType = _tl.MessageEntityBold
|
||||
elif tag == 'em' or tag == 'i':
|
||||
EntityType = MessageEntityItalic
|
||||
EntityType = _tl.MessageEntityItalic
|
||||
elif tag == 'u':
|
||||
EntityType = MessageEntityUnderline
|
||||
EntityType = _tl.MessageEntityUnderline
|
||||
elif tag == 'del' or tag == 's':
|
||||
EntityType = MessageEntityStrike
|
||||
EntityType = _tl.MessageEntityStrike
|
||||
elif tag == 'blockquote':
|
||||
EntityType = MessageEntityBlockquote
|
||||
EntityType = _tl.MessageEntityBlockquote
|
||||
elif tag == 'code':
|
||||
try:
|
||||
# If we're in the middle of a <pre> tag, this <code> tag is
|
||||
|
@ -69,9 +62,9 @@ class HTMLToTelegramParser(HTMLParser):
|
|||
except KeyError:
|
||||
pass
|
||||
except KeyError:
|
||||
EntityType = MessageEntityCode
|
||||
EntityType = _tl.MessageEntityCode
|
||||
elif tag == 'pre':
|
||||
EntityType = MessageEntityPre
|
||||
EntityType = _tl.MessageEntityPre
|
||||
args['language'] = ''
|
||||
elif tag == 'a':
|
||||
try:
|
||||
|
@ -80,12 +73,12 @@ class HTMLToTelegramParser(HTMLParser):
|
|||
return
|
||||
if url.startswith('mailto:'):
|
||||
url = url[len('mailto:'):]
|
||||
EntityType = MessageEntityEmail
|
||||
EntityType = _tl.MessageEntityEmail
|
||||
else:
|
||||
if self.get_starttag_text() == url:
|
||||
EntityType = MessageEntityUrl
|
||||
EntityType = _tl.MessageEntityUrl
|
||||
else:
|
||||
EntityType = MessageEntityTextUrl
|
||||
EntityType = _tl.MessageEntityTextUrl
|
||||
args['url'] = url
|
||||
url = None
|
||||
self._open_tags_meta.popleft()
|
||||
|
@ -121,10 +114,10 @@ class HTMLToTelegramParser(HTMLParser):
|
|||
self.entities.append(entity)
|
||||
|
||||
|
||||
def parse(html: str) -> Tuple[str, List[TypeMessageEntity]]:
|
||||
def parse(html: str) -> Tuple[str, List[_tl.TypeMessageEntity]]:
|
||||
"""
|
||||
Parses the given HTML message and returns its stripped representation
|
||||
plus a list of the MessageEntity's that were found.
|
||||
plus a list of the _tl.MessageEntity's that were found.
|
||||
|
||||
:param html: the message with HTML to be parsed.
|
||||
:return: a tuple consisting of (clean message, [message entities]).
|
||||
|
@ -138,14 +131,14 @@ def parse(html: str) -> Tuple[str, List[TypeMessageEntity]]:
|
|||
return _del_surrogate(text), parser.entities
|
||||
|
||||
|
||||
def unparse(text: str, entities: Iterable[TypeMessageEntity], _offset: int = 0,
|
||||
def unparse(text: str, entities: Iterable[_tl.TypeMessageEntity], _offset: int = 0,
|
||||
_length: Optional[int] = None) -> str:
|
||||
"""
|
||||
Performs the reverse operation to .parse(), effectively returning HTML
|
||||
given a normal text and its MessageEntity's.
|
||||
given a normal text and its _tl.MessageEntity's.
|
||||
|
||||
:param text: the text to be reconverted into HTML.
|
||||
:param entities: the MessageEntity's applied to the text.
|
||||
:param entities: the _tl.MessageEntity's applied to the text.
|
||||
:return: a HTML representation of the combination of both inputs.
|
||||
"""
|
||||
if not text:
|
||||
|
@ -185,19 +178,19 @@ def unparse(text: str, entities: Iterable[TypeMessageEntity], _offset: int = 0,
|
|||
_offset=entity.offset, _length=length)
|
||||
entity_type = type(entity)
|
||||
|
||||
if entity_type == MessageEntityBold:
|
||||
if entity_type == _tl.MessageEntityBold:
|
||||
html.append('<strong>{}</strong>'.format(entity_text))
|
||||
elif entity_type == MessageEntityItalic:
|
||||
elif entity_type == _tl.MessageEntityItalic:
|
||||
html.append('<em>{}</em>'.format(entity_text))
|
||||
elif entity_type == MessageEntityCode:
|
||||
elif entity_type == _tl.MessageEntityCode:
|
||||
html.append('<code>{}</code>'.format(entity_text))
|
||||
elif entity_type == MessageEntityUnderline:
|
||||
elif entity_type == _tl.MessageEntityUnderline:
|
||||
html.append('<u>{}</u>'.format(entity_text))
|
||||
elif entity_type == MessageEntityStrike:
|
||||
elif entity_type == _tl.MessageEntityStrike:
|
||||
html.append('<del>{}</del>'.format(entity_text))
|
||||
elif entity_type == MessageEntityBlockquote:
|
||||
elif entity_type == _tl.MessageEntityBlockquote:
|
||||
html.append('<blockquote>{}</blockquote>'.format(entity_text))
|
||||
elif entity_type == MessageEntityPre:
|
||||
elif entity_type == _tl.MessageEntityPre:
|
||||
if entity.language:
|
||||
html.append(
|
||||
"<pre>\n"
|
||||
|
@ -208,14 +201,14 @@ def unparse(text: str, entities: Iterable[TypeMessageEntity], _offset: int = 0,
|
|||
else:
|
||||
html.append('<pre><code>{}</code></pre>'
|
||||
.format(entity_text))
|
||||
elif entity_type == MessageEntityEmail:
|
||||
elif entity_type == _tl.MessageEntityEmail:
|
||||
html.append('<a href="mailto:{0}">{0}</a>'.format(entity_text))
|
||||
elif entity_type == MessageEntityUrl:
|
||||
elif entity_type == _tl.MessageEntityUrl:
|
||||
html.append('<a href="{0}">{0}</a>'.format(entity_text))
|
||||
elif entity_type == MessageEntityTextUrl:
|
||||
elif entity_type == _tl.MessageEntityTextUrl:
|
||||
html.append('<a href="{}">{}</a>'
|
||||
.format(escape(entity.url), entity_text))
|
||||
elif entity_type == MessageEntityMentionName:
|
||||
elif entity_type == _tl.MessageEntityMentionName:
|
||||
html.append('<a href="tg://user?id={}">{}</a>'
|
||||
.format(entity.user_id, entity_text))
|
||||
else:
|
||||
|
|
|
@ -7,19 +7,14 @@ import re
|
|||
import warnings
|
||||
|
||||
from ..helpers import add_surrogate, del_surrogate, within_surrogate, strip_text
|
||||
from ..tl import TLObject
|
||||
from ..tl.types import (
|
||||
MessageEntityBold, MessageEntityItalic, MessageEntityCode,
|
||||
MessageEntityPre, MessageEntityTextUrl, MessageEntityMentionName,
|
||||
MessageEntityStrike
|
||||
)
|
||||
from .. import _tl
|
||||
|
||||
DEFAULT_DELIMITERS = {
|
||||
'**': MessageEntityBold,
|
||||
'__': MessageEntityItalic,
|
||||
'~~': MessageEntityStrike,
|
||||
'`': MessageEntityCode,
|
||||
'```': MessageEntityPre
|
||||
'**': _tl.MessageEntityBold,
|
||||
'__': _tl.MessageEntityItalic,
|
||||
'~~': _tl.MessageEntityStrike,
|
||||
'`': _tl.MessageEntityCode,
|
||||
'```': _tl.MessageEntityPre
|
||||
}
|
||||
|
||||
DEFAULT_URL_RE = re.compile(r'\[([\S\s]+?)\]\((.+?)\)')
|
||||
|
@ -33,7 +28,7 @@ def overlap(a, b, x, y):
|
|||
def parse(message, delimiters=None, url_re=None):
|
||||
"""
|
||||
Parses the given markdown message and returns its stripped representation
|
||||
plus a list of the MessageEntity's that were found.
|
||||
plus a list of the _tl.MessageEntity's that were found.
|
||||
|
||||
:param message: the message with markdown-like syntax to be parsed.
|
||||
:param delimiters: the delimiters to be used, {delimiter: type}.
|
||||
|
@ -98,13 +93,13 @@ def parse(message, delimiters=None, url_re=None):
|
|||
|
||||
# Append the found entity
|
||||
ent = delimiters[delim]
|
||||
if ent == MessageEntityPre:
|
||||
if ent == _tl.MessageEntityPre:
|
||||
result.append(ent(i, end - i - len(delim), '')) # has 'lang'
|
||||
else:
|
||||
result.append(ent(i, end - i - len(delim)))
|
||||
|
||||
# No nested entities inside code blocks
|
||||
if ent in (MessageEntityCode, MessageEntityPre):
|
||||
if ent in (_tl.MessageEntityCode, _tl.MessageEntityPre):
|
||||
i = end - len(delim)
|
||||
|
||||
continue
|
||||
|
@ -125,7 +120,7 @@ def parse(message, delimiters=None, url_re=None):
|
|||
if ent.offset + ent.length > m.start():
|
||||
ent.length -= delim_size
|
||||
|
||||
result.append(MessageEntityTextUrl(
|
||||
result.append(_tl.MessageEntityTextUrl(
|
||||
offset=m.start(), length=len(m.group(1)),
|
||||
url=del_surrogate(m.group(2))
|
||||
))
|
||||
|
@ -141,10 +136,10 @@ def parse(message, delimiters=None, url_re=None):
|
|||
def unparse(text, entities, delimiters=None, url_fmt=None):
|
||||
"""
|
||||
Performs the reverse operation to .parse(), effectively returning
|
||||
markdown-like syntax given a normal text and its MessageEntity's.
|
||||
markdown-like syntax given a normal text and its _tl.MessageEntity's.
|
||||
|
||||
:param text: the text to be reconverted into markdown.
|
||||
:param entities: the MessageEntity's applied to the text.
|
||||
:param entities: the _tl.MessageEntity's applied to the text.
|
||||
:return: a markdown-like text representing the combination of both inputs.
|
||||
"""
|
||||
if not text or not entities:
|
||||
|
@ -158,7 +153,7 @@ def unparse(text, entities, delimiters=None, url_fmt=None):
|
|||
if url_fmt is not None:
|
||||
warnings.warn('url_fmt is deprecated') # since it complicates everything *a lot*
|
||||
|
||||
if isinstance(entities, TLObject):
|
||||
if isinstance(entities, _tl.TLObject):
|
||||
entities = (entities,)
|
||||
|
||||
text = add_surrogate(text)
|
||||
|
@ -173,9 +168,9 @@ def unparse(text, entities, delimiters=None, url_fmt=None):
|
|||
insert_at.append((e, delimiter))
|
||||
else:
|
||||
url = None
|
||||
if isinstance(entity, MessageEntityTextUrl):
|
||||
if isinstance(entity, _tl.MessageEntityTextUrl):
|
||||
url = entity.url
|
||||
elif isinstance(entity, MessageEntityMentionName):
|
||||
elif isinstance(entity, _tl.MessageEntityMentionName):
|
||||
url = 'tg://user?id={}'.format(entity.user_id)
|
||||
if url:
|
||||
insert_at.append((s, '['))
|
||||
|
|
|
@ -2,7 +2,7 @@ import hashlib
|
|||
import os
|
||||
|
||||
from .crypto import factorization
|
||||
from .tl import types
|
||||
from . import _tl
|
||||
|
||||
|
||||
def check_prime_and_good_check(prime: int, g: int):
|
||||
|
@ -110,7 +110,7 @@ def pbkdf2sha512(password: bytes, salt: bytes, iterations: int):
|
|||
return hashlib.pbkdf2_hmac('sha512', password, salt, iterations)
|
||||
|
||||
|
||||
def compute_hash(algo: types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow,
|
||||
def compute_hash(algo: _tl.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow,
|
||||
password: str):
|
||||
hash1 = sha256(algo.salt1, password.encode('utf-8'), algo.salt1)
|
||||
hash2 = sha256(algo.salt2, hash1, algo.salt2)
|
||||
|
@ -118,7 +118,7 @@ def compute_hash(algo: types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter1000
|
|||
return sha256(algo.salt2, hash3, algo.salt2)
|
||||
|
||||
|
||||
def compute_digest(algo: types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow,
|
||||
def compute_digest(algo: _tl.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow,
|
||||
password: str):
|
||||
try:
|
||||
check_prime_and_good(algo.p, algo.g)
|
||||
|
@ -133,9 +133,9 @@ def compute_digest(algo: types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter10
|
|||
|
||||
|
||||
# https://github.com/telegramdesktop/tdesktop/blob/18b74b90451a7db2379a9d753c9cbaf8734b4d5d/Telegram/SourceFiles/core/core_cloud_password.cpp
|
||||
def compute_check(request: types.account.Password, password: str):
|
||||
def compute_check(request: _tl.account.Password, password: str):
|
||||
algo = request.current_algo
|
||||
if not isinstance(algo, types.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow):
|
||||
if not isinstance(algo, _tl.PasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow):
|
||||
raise ValueError('unsupported password algorithm {}'
|
||||
.format(algo.__class__.__name__))
|
||||
|
||||
|
@ -190,5 +190,5 @@ def compute_check(request: types.account.Password, password: str):
|
|||
K
|
||||
)
|
||||
|
||||
return types.InputCheckPasswordSRP(
|
||||
return _tl.InputCheckPasswordSRP(
|
||||
request.srp_id, bytes(a_for_hash), bytes(M1))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import inspect
|
||||
|
||||
from .tl import types
|
||||
from . import _tl
|
||||
|
||||
|
||||
# Which updates have the following fields?
|
||||
|
@ -9,8 +9,8 @@ _has_channel_id = []
|
|||
|
||||
# TODO EntityCache does the same. Reuse?
|
||||
def _fill():
|
||||
for name in dir(types):
|
||||
update = getattr(types, name)
|
||||
for name in dir(_tl):
|
||||
update = getattr(_tl, name)
|
||||
if getattr(update, 'SUBCLASS_OF_ID', None) == 0x9f89304e:
|
||||
cid = update.CONSTRUCTOR_ID
|
||||
sig = inspect.signature(update.__init__)
|
||||
|
@ -51,41 +51,41 @@ class StateCache:
|
|||
*,
|
||||
channel_id=None,
|
||||
has_pts=frozenset(x.CONSTRUCTOR_ID for x in (
|
||||
types.UpdateNewMessage,
|
||||
types.UpdateDeleteMessages,
|
||||
types.UpdateReadHistoryInbox,
|
||||
types.UpdateReadHistoryOutbox,
|
||||
types.UpdateWebPage,
|
||||
types.UpdateReadMessagesContents,
|
||||
types.UpdateEditMessage,
|
||||
types.updates.State,
|
||||
types.updates.DifferenceTooLong,
|
||||
types.UpdateShortMessage,
|
||||
types.UpdateShortChatMessage,
|
||||
types.UpdateShortSentMessage
|
||||
_tl.UpdateNewMessage,
|
||||
_tl.UpdateDeleteMessages,
|
||||
_tl.UpdateReadHistoryInbox,
|
||||
_tl.UpdateReadHistoryOutbox,
|
||||
_tl.UpdateWebPage,
|
||||
_tl.UpdateReadMessagesContents,
|
||||
_tl.UpdateEditMessage,
|
||||
_tl.updates.State,
|
||||
_tl.updates.DifferenceTooLong,
|
||||
_tl.UpdateShortMessage,
|
||||
_tl.UpdateShortChatMessage,
|
||||
_tl.UpdateShortSentMessage
|
||||
)),
|
||||
has_date=frozenset(x.CONSTRUCTOR_ID for x in (
|
||||
types.UpdateUserPhoto,
|
||||
types.UpdateEncryption,
|
||||
types.UpdateEncryptedMessagesRead,
|
||||
types.UpdateChatParticipantAdd,
|
||||
types.updates.DifferenceEmpty,
|
||||
types.UpdateShortMessage,
|
||||
types.UpdateShortChatMessage,
|
||||
types.UpdateShort,
|
||||
types.UpdatesCombined,
|
||||
types.Updates,
|
||||
types.UpdateShortSentMessage,
|
||||
_tl.UpdateUserPhoto,
|
||||
_tl.UpdateEncryption,
|
||||
_tl.UpdateEncryptedMessagesRead,
|
||||
_tl.UpdateChatParticipantAdd,
|
||||
_tl.updates.DifferenceEmpty,
|
||||
_tl.UpdateShortMessage,
|
||||
_tl.UpdateShortChatMessage,
|
||||
_tl.UpdateShort,
|
||||
_tl.UpdatesCombined,
|
||||
_tl.Updates,
|
||||
_tl.UpdateShortSentMessage,
|
||||
)),
|
||||
has_channel_pts=frozenset(x.CONSTRUCTOR_ID for x in (
|
||||
types.UpdateChannelTooLong,
|
||||
types.UpdateNewChannelMessage,
|
||||
types.UpdateDeleteChannelMessages,
|
||||
types.UpdateEditChannelMessage,
|
||||
types.UpdateChannelWebPage,
|
||||
types.updates.ChannelDifferenceEmpty,
|
||||
types.updates.ChannelDifferenceTooLong,
|
||||
types.updates.ChannelDifference
|
||||
_tl.UpdateChannelTooLong,
|
||||
_tl.UpdateNewChannelMessage,
|
||||
_tl.UpdateDeleteChannelMessages,
|
||||
_tl.UpdateEditChannelMessage,
|
||||
_tl.UpdateChannelWebPage,
|
||||
_tl.updates.ChannelDifferenceEmpty,
|
||||
_tl.updates.ChannelDifferenceTooLong,
|
||||
_tl.updates.ChannelDifference
|
||||
)),
|
||||
check_only=False
|
||||
):
|
||||
|
@ -120,8 +120,8 @@ class StateCache:
|
|||
has_channel_id=frozenset(_has_channel_id),
|
||||
# Hardcoded because only some with message are for channels
|
||||
has_message=frozenset(x.CONSTRUCTOR_ID for x in (
|
||||
types.UpdateNewChannelMessage,
|
||||
types.UpdateEditChannelMessage
|
||||
_tl.UpdateNewChannelMessage,
|
||||
_tl.UpdateEditChannelMessage
|
||||
))
|
||||
):
|
||||
"""
|
||||
|
|
|
@ -21,7 +21,7 @@ from types import GeneratorType
|
|||
|
||||
from .extensions import markdown, html
|
||||
from .helpers import add_surrogate, del_surrogate, strip_text
|
||||
from .tl import types
|
||||
from . import _tl
|
||||
|
||||
try:
|
||||
import hachoir
|
||||
|
@ -32,26 +32,26 @@ except ImportError:
|
|||
|
||||
# Register some of the most common mime-types to avoid any issues.
|
||||
# See https://github.com/LonamiWebs/Telethon/issues/1096.
|
||||
mimetypes.add_type('image/png', '.png')
|
||||
mimetypes.add_type('image/jpeg', '.jpeg')
|
||||
mimetypes.add_type('image/webp', '.webp')
|
||||
mimetypes.add_type('image/gif', '.gif')
|
||||
mimetypes.add_type('image/bmp', '.bmp')
|
||||
mimetypes.add_type('image/x-tga', '.tga')
|
||||
mimetypes.add_type('image/tiff', '.tiff')
|
||||
mimetypes.add_type('image/vnd.adobe.photoshop', '.psd')
|
||||
mime_tl.add_type('image/png', '.png')
|
||||
mime_tl.add_type('image/jpeg', '.jpeg')
|
||||
mime_tl.add_type('image/webp', '.webp')
|
||||
mime_tl.add_type('image/gif', '.gif')
|
||||
mime_tl.add_type('image/bmp', '.bmp')
|
||||
mime_tl.add_type('image/x-tga', '.tga')
|
||||
mime_tl.add_type('image/tiff', '.tiff')
|
||||
mime_tl.add_type('image/vnd.adobe.photoshop', '.psd')
|
||||
|
||||
mimetypes.add_type('video/mp4', '.mp4')
|
||||
mimetypes.add_type('video/quicktime', '.mov')
|
||||
mimetypes.add_type('video/avi', '.avi')
|
||||
mime_tl.add_type('video/mp4', '.mp4')
|
||||
mime_tl.add_type('video/quicktime', '.mov')
|
||||
mime_tl.add_type('video/avi', '.avi')
|
||||
|
||||
mimetypes.add_type('audio/mpeg', '.mp3')
|
||||
mimetypes.add_type('audio/m4a', '.m4a')
|
||||
mimetypes.add_type('audio/aac', '.aac')
|
||||
mimetypes.add_type('audio/ogg', '.ogg')
|
||||
mimetypes.add_type('audio/flac', '.flac')
|
||||
mime_tl.add_type('audio/mpeg', '.mp3')
|
||||
mime_tl.add_type('audio/m4a', '.m4a')
|
||||
mime_tl.add_type('audio/aac', '.aac')
|
||||
mime_tl.add_type('audio/ogg', '.ogg')
|
||||
mime_tl.add_type('audio/flac', '.flac')
|
||||
|
||||
mimetypes.add_type('application/x-tgsticker', '.tgs')
|
||||
mime_tl.add_type('application/x-tgsticker', '.tgs')
|
||||
|
||||
USERNAME_RE = re.compile(
|
||||
r'@|(?:https?://)?(?:www\.)?(?:telegram\.(?:me|dog)|t\.me)/(@|joinchat/)?'
|
||||
|
@ -92,7 +92,7 @@ def get_display_name(entity):
|
|||
Gets the display name for the given :tl:`User`,
|
||||
:tl:`Chat` or :tl:`Channel`. Returns an empty string otherwise.
|
||||
"""
|
||||
if isinstance(entity, types.User):
|
||||
if isinstance(entity, _tl.User):
|
||||
if entity.last_name and entity.first_name:
|
||||
return '{} {}'.format(entity.first_name, entity.last_name)
|
||||
elif entity.first_name:
|
||||
|
@ -102,7 +102,7 @@ def get_display_name(entity):
|
|||
else:
|
||||
return ''
|
||||
|
||||
elif isinstance(entity, (types.Chat, types.ChatForbidden, types.Channel)):
|
||||
elif isinstance(entity, (_tl.Chat, _tl.ChatForbidden, _tl.Channel)):
|
||||
return entity.title
|
||||
|
||||
return ''
|
||||
|
@ -117,14 +117,14 @@ def get_extension(media):
|
|||
return '.jpg'
|
||||
except TypeError:
|
||||
# These cases are not handled by input photo because it can't
|
||||
if isinstance(media, (types.UserProfilePhoto, types.ChatPhoto)):
|
||||
if isinstance(media, (_tl.UserProfilePhoto, _tl.ChatPhoto)):
|
||||
return '.jpg'
|
||||
|
||||
# Documents will come with a mime type
|
||||
if isinstance(media, types.MessageMediaDocument):
|
||||
if isinstance(media, _tl.MessageMediaDocument):
|
||||
media = media.document
|
||||
if isinstance(media, (
|
||||
types.Document, types.WebDocument, types.WebDocumentNoProxy)):
|
||||
_tl.Document, _tl.WebDocument, _tl.WebDocumentNoProxy)):
|
||||
if media.mime_type == 'application/octet-stream':
|
||||
# Octet stream are just bytes, which have no default extension
|
||||
return ''
|
||||
|
@ -184,53 +184,53 @@ def get_input_peer(entity, allow_self=True, check_hash=True):
|
|||
else:
|
||||
_raise_cast_fail(entity, 'InputPeer')
|
||||
|
||||
if isinstance(entity, types.User):
|
||||
if isinstance(entity, _tl.User):
|
||||
if entity.is_self and allow_self:
|
||||
return types.InputPeerSelf()
|
||||
return _tl.InputPeerSelf()
|
||||
elif (entity.access_hash is not None and not entity.min) or not check_hash:
|
||||
return types.InputPeerUser(entity.id, entity.access_hash)
|
||||
return _tl.InputPeerUser(entity.id, entity.access_hash)
|
||||
else:
|
||||
raise TypeError('User without access_hash or min info cannot be input')
|
||||
|
||||
if isinstance(entity, (types.Chat, types.ChatEmpty, types.ChatForbidden)):
|
||||
return types.InputPeerChat(entity.id)
|
||||
if isinstance(entity, (_tl.Chat, _tl.ChatEmpty, _tl.ChatForbidden)):
|
||||
return _tl.InputPeerChat(entity.id)
|
||||
|
||||
if isinstance(entity, types.Channel):
|
||||
if isinstance(entity, _tl.Channel):
|
||||
if (entity.access_hash is not None and not entity.min) or not check_hash:
|
||||
return types.InputPeerChannel(entity.id, entity.access_hash)
|
||||
return _tl.InputPeerChannel(entity.id, entity.access_hash)
|
||||
else:
|
||||
raise TypeError('Channel without access_hash or min info cannot be input')
|
||||
if isinstance(entity, types.ChannelForbidden):
|
||||
if isinstance(entity, _tl.ChannelForbidden):
|
||||
# "channelForbidden are never min", and since their hash is
|
||||
# also not optional, we assume that this truly is the case.
|
||||
return types.InputPeerChannel(entity.id, entity.access_hash)
|
||||
return _tl.InputPeerChannel(entity.id, entity.access_hash)
|
||||
|
||||
if isinstance(entity, types.InputUser):
|
||||
return types.InputPeerUser(entity.user_id, entity.access_hash)
|
||||
if isinstance(entity, _tl.InputUser):
|
||||
return _tl.InputPeerUser(entity.user_id, entity.access_hash)
|
||||
|
||||
if isinstance(entity, types.InputChannel):
|
||||
return types.InputPeerChannel(entity.channel_id, entity.access_hash)
|
||||
if isinstance(entity, _tl.InputChannel):
|
||||
return _tl.InputPeerChannel(entity.channel_id, entity.access_hash)
|
||||
|
||||
if isinstance(entity, types.InputUserSelf):
|
||||
return types.InputPeerSelf()
|
||||
if isinstance(entity, _tl.InputUserSelf):
|
||||
return _tl.InputPeerSelf()
|
||||
|
||||
if isinstance(entity, types.InputUserFromMessage):
|
||||
return types.InputPeerUserFromMessage(entity.peer, entity.msg_id, entity.user_id)
|
||||
if isinstance(entity, _tl.InputUserFromMessage):
|
||||
return _tl.InputPeerUserFromMessage(entity.peer, entity.msg_id, entity.user_id)
|
||||
|
||||
if isinstance(entity, types.InputChannelFromMessage):
|
||||
return types.InputPeerChannelFromMessage(entity.peer, entity.msg_id, entity.channel_id)
|
||||
if isinstance(entity, _tl.InputChannelFromMessage):
|
||||
return _tl.InputPeerChannelFromMessage(entity.peer, entity.msg_id, entity.channel_id)
|
||||
|
||||
if isinstance(entity, types.UserEmpty):
|
||||
return types.InputPeerEmpty()
|
||||
if isinstance(entity, _tl.UserEmpty):
|
||||
return _tl.InputPeerEmpty()
|
||||
|
||||
if isinstance(entity, types.UserFull):
|
||||
if isinstance(entity, _tl.UserFull):
|
||||
return get_input_peer(entity.user)
|
||||
|
||||
if isinstance(entity, types.ChatFull):
|
||||
return types.InputPeerChat(entity.id)
|
||||
if isinstance(entity, _tl.ChatFull):
|
||||
return _tl.InputPeerChat(entity.id)
|
||||
|
||||
if isinstance(entity, types.PeerChat):
|
||||
return types.InputPeerChat(entity.chat_id)
|
||||
if isinstance(entity, _tl.PeerChat):
|
||||
return _tl.InputPeerChat(entity.chat_id)
|
||||
|
||||
_raise_cast_fail(entity, 'InputPeer')
|
||||
|
||||
|
@ -251,14 +251,14 @@ def get_input_channel(entity):
|
|||
except AttributeError:
|
||||
_raise_cast_fail(entity, 'InputChannel')
|
||||
|
||||
if isinstance(entity, (types.Channel, types.ChannelForbidden)):
|
||||
return types.InputChannel(entity.id, entity.access_hash or 0)
|
||||
if isinstance(entity, (_tl.Channel, _tl.ChannelForbidden)):
|
||||
return _tl.InputChannel(entity.id, entity.access_hash or 0)
|
||||
|
||||
if isinstance(entity, types.InputPeerChannel):
|
||||
return types.InputChannel(entity.channel_id, entity.access_hash)
|
||||
if isinstance(entity, _tl.InputPeerChannel):
|
||||
return _tl.InputChannel(entity.channel_id, entity.access_hash)
|
||||
|
||||
if isinstance(entity, types.InputPeerChannelFromMessage):
|
||||
return types.InputChannelFromMessage(entity.peer, entity.msg_id, entity.channel_id)
|
||||
if isinstance(entity, _tl.InputPeerChannelFromMessage):
|
||||
return _tl.InputChannelFromMessage(entity.peer, entity.msg_id, entity.channel_id)
|
||||
|
||||
_raise_cast_fail(entity, 'InputChannel')
|
||||
|
||||
|
@ -279,26 +279,26 @@ def get_input_user(entity):
|
|||
except AttributeError:
|
||||
_raise_cast_fail(entity, 'InputUser')
|
||||
|
||||
if isinstance(entity, types.User):
|
||||
if isinstance(entity, _tl.User):
|
||||
if entity.is_self:
|
||||
return types.InputUserSelf()
|
||||
return _tl.InputUserSelf()
|
||||
else:
|
||||
return types.InputUser(entity.id, entity.access_hash or 0)
|
||||
return _tl.InputUser(entity.id, entity.access_hash or 0)
|
||||
|
||||
if isinstance(entity, types.InputPeerSelf):
|
||||
return types.InputUserSelf()
|
||||
if isinstance(entity, _tl.InputPeerSelf):
|
||||
return _tl.InputUserSelf()
|
||||
|
||||
if isinstance(entity, (types.UserEmpty, types.InputPeerEmpty)):
|
||||
return types.InputUserEmpty()
|
||||
if isinstance(entity, (_tl.UserEmpty, _tl.InputPeerEmpty)):
|
||||
return _tl.InputUserEmpty()
|
||||
|
||||
if isinstance(entity, types.UserFull):
|
||||
if isinstance(entity, _tl.UserFull):
|
||||
return get_input_user(entity.user)
|
||||
|
||||
if isinstance(entity, types.InputPeerUser):
|
||||
return types.InputUser(entity.user_id, entity.access_hash)
|
||||
if isinstance(entity, _tl.InputPeerUser):
|
||||
return _tl.InputUser(entity.user_id, entity.access_hash)
|
||||
|
||||
if isinstance(entity, types.InputPeerUserFromMessage):
|
||||
return types.InputUserFromMessage(entity.peer, entity.msg_id, entity.user_id)
|
||||
if isinstance(entity, _tl.InputPeerUserFromMessage):
|
||||
return _tl.InputUserFromMessage(entity.peer, entity.msg_id, entity.user_id)
|
||||
|
||||
_raise_cast_fail(entity, 'InputUser')
|
||||
|
||||
|
@ -309,12 +309,12 @@ def get_input_dialog(dialog):
|
|||
if dialog.SUBCLASS_OF_ID == 0xa21c9795: # crc32(b'InputDialogPeer')
|
||||
return dialog
|
||||
if dialog.SUBCLASS_OF_ID == 0xc91c90b6: # crc32(b'InputPeer')
|
||||
return types.InputDialogPeer(dialog)
|
||||
return _tl.InputDialogPeer(dialog)
|
||||
except AttributeError:
|
||||
_raise_cast_fail(dialog, 'InputDialogPeer')
|
||||
|
||||
try:
|
||||
return types.InputDialogPeer(get_input_peer(dialog))
|
||||
return _tl.InputDialogPeer(get_input_peer(dialog))
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
@ -329,18 +329,18 @@ def get_input_document(document):
|
|||
except AttributeError:
|
||||
_raise_cast_fail(document, 'InputDocument')
|
||||
|
||||
if isinstance(document, types.Document):
|
||||
return types.InputDocument(
|
||||
if isinstance(document, _tl.Document):
|
||||
return _tl.InputDocument(
|
||||
id=document.id, access_hash=document.access_hash,
|
||||
file_reference=document.file_reference)
|
||||
|
||||
if isinstance(document, types.DocumentEmpty):
|
||||
return types.InputDocumentEmpty()
|
||||
if isinstance(document, _tl.DocumentEmpty):
|
||||
return _tl.InputDocumentEmpty()
|
||||
|
||||
if isinstance(document, types.MessageMediaDocument):
|
||||
if isinstance(document, _tl.MessageMediaDocument):
|
||||
return get_input_document(document.document)
|
||||
|
||||
if isinstance(document, types.Message):
|
||||
if isinstance(document, _tl.Message):
|
||||
return get_input_document(document.media)
|
||||
|
||||
_raise_cast_fail(document, 'InputDocument')
|
||||
|
@ -354,32 +354,32 @@ def get_input_photo(photo):
|
|||
except AttributeError:
|
||||
_raise_cast_fail(photo, 'InputPhoto')
|
||||
|
||||
if isinstance(photo, types.Message):
|
||||
if isinstance(photo, _tl.Message):
|
||||
photo = photo.media
|
||||
|
||||
if isinstance(photo, (types.photos.Photo, types.MessageMediaPhoto)):
|
||||
if isinstance(photo, (_tl.photos.Photo, _tl.MessageMediaPhoto)):
|
||||
photo = photo.photo
|
||||
|
||||
if isinstance(photo, types.Photo):
|
||||
return types.InputPhoto(id=photo.id, access_hash=photo.access_hash,
|
||||
if isinstance(photo, _tl.Photo):
|
||||
return _tl.InputPhoto(id=photo.id, access_hash=photo.access_hash,
|
||||
file_reference=photo.file_reference)
|
||||
|
||||
if isinstance(photo, types.PhotoEmpty):
|
||||
return types.InputPhotoEmpty()
|
||||
if isinstance(photo, _tl.PhotoEmpty):
|
||||
return _tl.InputPhotoEmpty()
|
||||
|
||||
if isinstance(photo, types.messages.ChatFull):
|
||||
if isinstance(photo, _tl.messages.ChatFull):
|
||||
photo = photo.full_chat
|
||||
|
||||
if isinstance(photo, types.ChannelFull):
|
||||
if isinstance(photo, _tl.ChannelFull):
|
||||
return get_input_photo(photo.chat_photo)
|
||||
elif isinstance(photo, types.UserFull):
|
||||
elif isinstance(photo, _tl.UserFull):
|
||||
return get_input_photo(photo.profile_photo)
|
||||
elif isinstance(photo, (types.Channel, types.Chat, types.User)):
|
||||
elif isinstance(photo, (_tl.Channel, _tl.Chat, _tl.User)):
|
||||
return get_input_photo(photo.photo)
|
||||
|
||||
if isinstance(photo, (types.UserEmpty, types.ChatEmpty,
|
||||
types.ChatForbidden, types.ChannelForbidden)):
|
||||
return types.InputPhotoEmpty()
|
||||
if isinstance(photo, (_tl.UserEmpty, _tl.ChatEmpty,
|
||||
_tl.ChatForbidden, _tl.ChannelForbidden)):
|
||||
return _tl.InputPhotoEmpty()
|
||||
|
||||
_raise_cast_fail(photo, 'InputPhoto')
|
||||
|
||||
|
@ -390,15 +390,15 @@ def get_input_chat_photo(photo):
|
|||
if photo.SUBCLASS_OF_ID == 0xd4eb2d74: # crc32(b'InputChatPhoto')
|
||||
return photo
|
||||
elif photo.SUBCLASS_OF_ID == 0xe7655f1f: # crc32(b'InputFile'):
|
||||
return types.InputChatUploadedPhoto(photo)
|
||||
return _tl.InputChatUploadedPhoto(photo)
|
||||
except AttributeError:
|
||||
_raise_cast_fail(photo, 'InputChatPhoto')
|
||||
|
||||
photo = get_input_photo(photo)
|
||||
if isinstance(photo, types.InputPhoto):
|
||||
return types.InputChatPhoto(photo)
|
||||
elif isinstance(photo, types.InputPhotoEmpty):
|
||||
return types.InputChatPhotoEmpty()
|
||||
if isinstance(photo, _tl.InputPhoto):
|
||||
return _tl.InputChatPhoto(photo)
|
||||
elif isinstance(photo, _tl.InputPhotoEmpty):
|
||||
return _tl.InputChatPhotoEmpty()
|
||||
|
||||
_raise_cast_fail(photo, 'InputChatPhoto')
|
||||
|
||||
|
@ -411,16 +411,16 @@ def get_input_geo(geo):
|
|||
except AttributeError:
|
||||
_raise_cast_fail(geo, 'InputGeoPoint')
|
||||
|
||||
if isinstance(geo, types.GeoPoint):
|
||||
return types.InputGeoPoint(lat=geo.lat, long=geo.long)
|
||||
if isinstance(geo, _tl.GeoPoint):
|
||||
return _tl.InputGeoPoint(lat=geo.lat, long=geo.long)
|
||||
|
||||
if isinstance(geo, types.GeoPointEmpty):
|
||||
return types.InputGeoPointEmpty()
|
||||
if isinstance(geo, _tl.GeoPointEmpty):
|
||||
return _tl.InputGeoPointEmpty()
|
||||
|
||||
if isinstance(geo, types.MessageMediaGeo):
|
||||
if isinstance(geo, _tl.MessageMediaGeo):
|
||||
return get_input_geo(geo.geo)
|
||||
|
||||
if isinstance(geo, types.Message):
|
||||
if isinstance(geo, _tl.Message):
|
||||
return get_input_geo(geo.media)
|
||||
|
||||
_raise_cast_fail(geo, 'InputGeoPoint')
|
||||
|
@ -443,39 +443,39 @@ def get_input_media(
|
|||
if media.SUBCLASS_OF_ID == 0xfaf846f4: # crc32(b'InputMedia')
|
||||
return media
|
||||
elif media.SUBCLASS_OF_ID == 0x846363e0: # crc32(b'InputPhoto')
|
||||
return types.InputMediaPhoto(media, ttl_seconds=ttl)
|
||||
return _tl.InputMediaPhoto(media, ttl_seconds=ttl)
|
||||
elif media.SUBCLASS_OF_ID == 0xf33fdb68: # crc32(b'InputDocument')
|
||||
return types.InputMediaDocument(media, ttl_seconds=ttl)
|
||||
return _tl.InputMediaDocument(media, ttl_seconds=ttl)
|
||||
except AttributeError:
|
||||
_raise_cast_fail(media, 'InputMedia')
|
||||
|
||||
if isinstance(media, types.MessageMediaPhoto):
|
||||
return types.InputMediaPhoto(
|
||||
if isinstance(media, _tl.MessageMediaPhoto):
|
||||
return _tl.InputMediaPhoto(
|
||||
id=get_input_photo(media.photo),
|
||||
ttl_seconds=ttl or media.ttl_seconds
|
||||
)
|
||||
|
||||
if isinstance(media, (types.Photo, types.photos.Photo, types.PhotoEmpty)):
|
||||
return types.InputMediaPhoto(
|
||||
if isinstance(media, (_tl.Photo, _tl.photos.Photo, _tl.PhotoEmpty)):
|
||||
return _tl.InputMediaPhoto(
|
||||
id=get_input_photo(media),
|
||||
ttl_seconds=ttl
|
||||
)
|
||||
|
||||
if isinstance(media, types.MessageMediaDocument):
|
||||
return types.InputMediaDocument(
|
||||
if isinstance(media, _tl.MessageMediaDocument):
|
||||
return _tl.InputMediaDocument(
|
||||
id=get_input_document(media.document),
|
||||
ttl_seconds=ttl or media.ttl_seconds
|
||||
)
|
||||
|
||||
if isinstance(media, (types.Document, types.DocumentEmpty)):
|
||||
return types.InputMediaDocument(
|
||||
if isinstance(media, (_tl.Document, _tl.DocumentEmpty)):
|
||||
return _tl.InputMediaDocument(
|
||||
id=get_input_document(media),
|
||||
ttl_seconds=ttl
|
||||
)
|
||||
|
||||
if isinstance(media, (types.InputFile, types.InputFileBig)):
|
||||
if isinstance(media, (_tl.InputFile, _tl.InputFileBig)):
|
||||
if is_photo:
|
||||
return types.InputMediaUploadedPhoto(file=media, ttl_seconds=ttl)
|
||||
return _tl.InputMediaUploadedPhoto(file=media, ttl_seconds=ttl)
|
||||
else:
|
||||
attrs, mime = get_attributes(
|
||||
media,
|
||||
|
@ -485,29 +485,29 @@ def get_input_media(
|
|||
video_note=video_note,
|
||||
supports_streaming=supports_streaming
|
||||
)
|
||||
return types.InputMediaUploadedDocument(
|
||||
return _tl.InputMediaUploadedDocument(
|
||||
file=media, mime_type=mime, attributes=attrs, force_file=force_document,
|
||||
ttl_seconds=ttl)
|
||||
|
||||
if isinstance(media, types.MessageMediaGame):
|
||||
return types.InputMediaGame(id=types.InputGameID(
|
||||
if isinstance(media, _tl.MessageMediaGame):
|
||||
return _tl.InputMediaGame(id=_tl.InputGameID(
|
||||
id=media.game.id,
|
||||
access_hash=media.game.access_hash
|
||||
))
|
||||
|
||||
if isinstance(media, types.MessageMediaContact):
|
||||
return types.InputMediaContact(
|
||||
if isinstance(media, _tl.MessageMediaContact):
|
||||
return _tl.InputMediaContact(
|
||||
phone_number=media.phone_number,
|
||||
first_name=media.first_name,
|
||||
last_name=media.last_name,
|
||||
vcard=''
|
||||
)
|
||||
|
||||
if isinstance(media, types.MessageMediaGeo):
|
||||
return types.InputMediaGeoPoint(geo_point=get_input_geo(media.geo))
|
||||
if isinstance(media, _tl.MessageMediaGeo):
|
||||
return _tl.InputMediaGeoPoint(geo_point=get_input_geo(media.geo))
|
||||
|
||||
if isinstance(media, types.MessageMediaVenue):
|
||||
return types.InputMediaVenue(
|
||||
if isinstance(media, _tl.MessageMediaVenue):
|
||||
return _tl.InputMediaVenue(
|
||||
geo_point=get_input_geo(media.geo),
|
||||
title=media.title,
|
||||
address=media.address,
|
||||
|
@ -516,19 +516,19 @@ def get_input_media(
|
|||
venue_type=''
|
||||
)
|
||||
|
||||
if isinstance(media, types.MessageMediaDice):
|
||||
return types.InputMediaDice(media.emoticon)
|
||||
if isinstance(media, _tl.MessageMediaDice):
|
||||
return _tl.InputMediaDice(media.emoticon)
|
||||
|
||||
if isinstance(media, (
|
||||
types.MessageMediaEmpty, types.MessageMediaUnsupported,
|
||||
types.ChatPhotoEmpty, types.UserProfilePhotoEmpty,
|
||||
types.ChatPhoto, types.UserProfilePhoto)):
|
||||
return types.InputMediaEmpty()
|
||||
_tl.MessageMediaEmpty, _tl.MessageMediaUnsupported,
|
||||
_tl.ChatPhotoEmpty, _tl.UserProfilePhotoEmpty,
|
||||
_tl.ChatPhoto, _tl.UserProfilePhoto)):
|
||||
return _tl.InputMediaEmpty()
|
||||
|
||||
if isinstance(media, types.Message):
|
||||
if isinstance(media, _tl.Message):
|
||||
return get_input_media(media.media, is_photo=is_photo, ttl=ttl)
|
||||
|
||||
if isinstance(media, types.MessageMediaPoll):
|
||||
if isinstance(media, _tl.MessageMediaPoll):
|
||||
if media.poll.quiz:
|
||||
if not media.results.results:
|
||||
# A quiz has correct answers, which we don't know until answered.
|
||||
|
@ -539,15 +539,15 @@ def get_input_media(
|
|||
else:
|
||||
correct_answers = None
|
||||
|
||||
return types.InputMediaPoll(
|
||||
return _tl.InputMediaPoll(
|
||||
poll=media.poll,
|
||||
correct_answers=correct_answers,
|
||||
solution=media.results.solution,
|
||||
solution_entities=media.results.solution_entities,
|
||||
)
|
||||
|
||||
if isinstance(media, types.Poll):
|
||||
return types.InputMediaPoll(media)
|
||||
if isinstance(media, _tl.Poll):
|
||||
return _tl.InputMediaPoll(media)
|
||||
|
||||
_raise_cast_fail(media, 'InputMedia')
|
||||
|
||||
|
@ -556,11 +556,11 @@ def get_input_message(message):
|
|||
"""Similar to :meth:`get_input_peer`, but for input messages."""
|
||||
try:
|
||||
if isinstance(message, int): # This case is really common too
|
||||
return types.InputMessageID(message)
|
||||
return _tl.InputMessageID(message)
|
||||
elif message.SUBCLASS_OF_ID == 0x54b6bcc5: # crc32(b'InputMessage'):
|
||||
return message
|
||||
elif message.SUBCLASS_OF_ID == 0x790009e3: # crc32(b'Message'):
|
||||
return types.InputMessageID(message.id)
|
||||
return _tl.InputMessageID(message.id)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
@ -573,7 +573,7 @@ def get_input_group_call(call):
|
|||
if call.SUBCLASS_OF_ID == 0x58611ab1: # crc32(b'InputGroupCall')
|
||||
return call
|
||||
elif call.SUBCLASS_OF_ID == 0x20b4f320: # crc32(b'GroupCall')
|
||||
return types.InputGroupCall(id=call.id, access_hash=call.access_hash)
|
||||
return _tl.InputGroupCall(id=call.id, access_hash=call.access_hash)
|
||||
except AttributeError:
|
||||
_raise_cast_fail(call, 'InputGroupCall')
|
||||
|
||||
|
@ -675,10 +675,10 @@ def get_attributes(file, *, attributes=None, mime_type=None,
|
|||
# Note: ``file.name`` works for :tl:`InputFile` and some `IOBase` streams
|
||||
name = file if isinstance(file, str) else getattr(file, 'name', 'unnamed')
|
||||
if mime_type is None:
|
||||
mime_type = mimetypes.guess_type(name)[0]
|
||||
mime_type = mime_tl.guess_type(name)[0]
|
||||
|
||||
attr_dict = {types.DocumentAttributeFilename:
|
||||
types.DocumentAttributeFilename(os.path.basename(name))}
|
||||
attr_dict = {_tl.DocumentAttributeFilename:
|
||||
_tl.DocumentAttributeFilename(os.path.basename(name))}
|
||||
|
||||
if is_audio(file):
|
||||
m = _get_metadata(file)
|
||||
|
@ -690,8 +690,8 @@ def get_attributes(file, *, attributes=None, mime_type=None,
|
|||
else:
|
||||
performer = None
|
||||
|
||||
attr_dict[types.DocumentAttributeAudio] = \
|
||||
types.DocumentAttributeAudio(
|
||||
attr_dict[_tl.DocumentAttributeAudio] = \
|
||||
_tl.DocumentAttributeAudio(
|
||||
voice=voice_note,
|
||||
title=m.get('title') if m.has('title') else None,
|
||||
performer=performer,
|
||||
|
@ -702,7 +702,7 @@ def get_attributes(file, *, attributes=None, mime_type=None,
|
|||
if not force_document and is_video(file):
|
||||
m = _get_metadata(file)
|
||||
if m:
|
||||
doc = types.DocumentAttributeVideo(
|
||||
doc = _tl.DocumentAttributeVideo(
|
||||
round_message=video_note,
|
||||
w=m.get('width') if m.has('width') else 1,
|
||||
h=m.get('height') if m.has('height') else 1,
|
||||
|
@ -719,22 +719,22 @@ def get_attributes(file, *, attributes=None, mime_type=None,
|
|||
if t_m and t_m.has("height"):
|
||||
height = t_m.get("height")
|
||||
|
||||
doc = types.DocumentAttributeVideo(
|
||||
doc = _tl.DocumentAttributeVideo(
|
||||
0, width, height, round_message=video_note,
|
||||
supports_streaming=supports_streaming)
|
||||
else:
|
||||
doc = types.DocumentAttributeVideo(
|
||||
doc = _tl.DocumentAttributeVideo(
|
||||
0, 1, 1, round_message=video_note,
|
||||
supports_streaming=supports_streaming)
|
||||
|
||||
attr_dict[types.DocumentAttributeVideo] = doc
|
||||
attr_dict[_tl.DocumentAttributeVideo] = doc
|
||||
|
||||
if voice_note:
|
||||
if types.DocumentAttributeAudio in attr_dict:
|
||||
attr_dict[types.DocumentAttributeAudio].voice = True
|
||||
if _tl.DocumentAttributeAudio in attr_dict:
|
||||
attr_dict[_tl.DocumentAttributeAudio].voice = True
|
||||
else:
|
||||
attr_dict[types.DocumentAttributeAudio] = \
|
||||
types.DocumentAttributeAudio(0, voice=True)
|
||||
attr_dict[_tl.DocumentAttributeAudio] = \
|
||||
_tl.DocumentAttributeAudio(0, voice=True)
|
||||
|
||||
# Now override the attributes if any. As we have a dict of
|
||||
# {cls: instance}, we can override any class with the list
|
||||
|
@ -803,23 +803,23 @@ def _get_file_info(location):
|
|||
except AttributeError:
|
||||
_raise_cast_fail(location, 'InputFileLocation')
|
||||
|
||||
if isinstance(location, types.Message):
|
||||
if isinstance(location, _tl.Message):
|
||||
location = location.media
|
||||
|
||||
if isinstance(location, types.MessageMediaDocument):
|
||||
if isinstance(location, _tl.MessageMediaDocument):
|
||||
location = location.document
|
||||
elif isinstance(location, types.MessageMediaPhoto):
|
||||
elif isinstance(location, _tl.MessageMediaPhoto):
|
||||
location = location.photo
|
||||
|
||||
if isinstance(location, types.Document):
|
||||
return _FileInfo(location.dc_id, types.InputDocumentFileLocation(
|
||||
if isinstance(location, _tl.Document):
|
||||
return _FileInfo(location.dc_id, _tl.InputDocumentFileLocation(
|
||||
id=location.id,
|
||||
access_hash=location.access_hash,
|
||||
file_reference=location.file_reference,
|
||||
thumb_size='' # Presumably to download one of its thumbnails
|
||||
), location.size)
|
||||
elif isinstance(location, types.Photo):
|
||||
return _FileInfo(location.dc_id, types.InputPhotoFileLocation(
|
||||
elif isinstance(location, _tl.Photo):
|
||||
return _FileInfo(location.dc_id, _tl.InputPhotoFileLocation(
|
||||
id=location.id,
|
||||
access_hash=location.access_hash,
|
||||
file_reference=location.file_reference,
|
||||
|
@ -860,7 +860,7 @@ def is_image(file):
|
|||
if match:
|
||||
return True
|
||||
else:
|
||||
return isinstance(resolve_bot_file_id(file), types.Photo)
|
||||
return isinstance(resolve_bot_file_id(file), _tl.Photo)
|
||||
|
||||
|
||||
def is_gif(file):
|
||||
|
@ -881,7 +881,7 @@ def is_audio(file):
|
|||
return False
|
||||
else:
|
||||
file = 'a' + ext
|
||||
return (mimetypes.guess_type(file)[0] or '').startswith('audio/')
|
||||
return (mime_tl.guess_type(file)[0] or '').startswith('audio/')
|
||||
|
||||
|
||||
def is_video(file):
|
||||
|
@ -895,7 +895,7 @@ def is_video(file):
|
|||
return False
|
||||
else:
|
||||
file = 'a' + ext
|
||||
return (mimetypes.guess_type(file)[0] or '').startswith('video/')
|
||||
return (mime_tl.guess_type(file)[0] or '').startswith('video/')
|
||||
|
||||
|
||||
def is_list_like(obj):
|
||||
|
@ -971,27 +971,27 @@ def get_peer(peer):
|
|||
elif peer.SUBCLASS_OF_ID == 0x2d45687:
|
||||
return peer
|
||||
elif isinstance(peer, (
|
||||
types.contacts.ResolvedPeer, types.InputNotifyPeer,
|
||||
types.TopPeer, types.Dialog, types.DialogPeer)):
|
||||
_tl.contacts.ResolvedPeer, _tl.InputNotifyPeer,
|
||||
_tl.TopPeer, _tl.Dialog, _tl.DialogPeer)):
|
||||
return peer.peer
|
||||
elif isinstance(peer, types.ChannelFull):
|
||||
return types.PeerChannel(peer.id)
|
||||
elif isinstance(peer, types.UserEmpty):
|
||||
return types.PeerUser(peer.id)
|
||||
elif isinstance(peer, types.ChatEmpty):
|
||||
return types.PeerChat(peer.id)
|
||||
elif isinstance(peer, _tl.ChannelFull):
|
||||
return _tl.PeerChannel(peer.id)
|
||||
elif isinstance(peer, _tl.UserEmpty):
|
||||
return _tl.PeerUser(peer.id)
|
||||
elif isinstance(peer, _tl.ChatEmpty):
|
||||
return _tl.PeerChat(peer.id)
|
||||
|
||||
if peer.SUBCLASS_OF_ID in (0x7d7c6f86, 0xd9c7fc18):
|
||||
# ChatParticipant, ChannelParticipant
|
||||
return types.PeerUser(peer.user_id)
|
||||
return _tl.PeerUser(peer.user_id)
|
||||
|
||||
peer = get_input_peer(peer, allow_self=False, check_hash=False)
|
||||
if isinstance(peer, (types.InputPeerUser, types.InputPeerUserFromMessage)):
|
||||
return types.PeerUser(peer.user_id)
|
||||
elif isinstance(peer, types.InputPeerChat):
|
||||
return types.PeerChat(peer.chat_id)
|
||||
elif isinstance(peer, (types.InputPeerChannel, types.InputPeerChannelFromMessage)):
|
||||
return types.PeerChannel(peer.channel_id)
|
||||
if isinstance(peer, (_tl.InputPeerUser, _tl.InputPeerUserFromMessage)):
|
||||
return _tl.PeerUser(peer.user_id)
|
||||
elif isinstance(peer, _tl.InputPeerChat):
|
||||
return _tl.PeerChat(peer.chat_id)
|
||||
elif isinstance(peer, (_tl.InputPeerChannel, _tl.InputPeerChannelFromMessage)):
|
||||
return _tl.PeerChannel(peer.channel_id)
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
_raise_cast_fail(peer, 'Peer')
|
||||
|
@ -1017,7 +1017,7 @@ def get_peer_id(peer, add_mark=True):
|
|||
return peer if add_mark else resolve_id(peer)[0]
|
||||
|
||||
# Tell the user to use their client to resolve InputPeerSelf if we got one
|
||||
if isinstance(peer, types.InputPeerSelf):
|
||||
if isinstance(peer, _tl.InputPeerSelf):
|
||||
_raise_cast_fail(peer, 'int (you might want to use client.get_peer_id)')
|
||||
|
||||
try:
|
||||
|
@ -1025,15 +1025,15 @@ def get_peer_id(peer, add_mark=True):
|
|||
except TypeError:
|
||||
_raise_cast_fail(peer, 'int')
|
||||
|
||||
if isinstance(peer, types.PeerUser):
|
||||
if isinstance(peer, _tl.PeerUser):
|
||||
return peer.user_id
|
||||
elif isinstance(peer, types.PeerChat):
|
||||
elif isinstance(peer, _tl.PeerChat):
|
||||
# Check in case the user mixed things up to avoid blowing up
|
||||
if not (0 < peer.chat_id <= 0x7fffffff):
|
||||
peer.chat_id = resolve_id(peer.chat_id)[0]
|
||||
|
||||
return -peer.chat_id if add_mark else peer.chat_id
|
||||
else: # if isinstance(peer, types.PeerChannel):
|
||||
else: # if isinstance(peer, _tl.PeerChannel):
|
||||
# Check in case the user mixed things up to avoid blowing up
|
||||
if not (0 < peer.channel_id <= 0x7fffffff):
|
||||
peer.channel_id = resolve_id(peer.channel_id)[0]
|
||||
|
@ -1048,14 +1048,14 @@ def get_peer_id(peer, add_mark=True):
|
|||
def resolve_id(marked_id):
|
||||
"""Given a marked ID, returns the original ID and its :tl:`Peer` type."""
|
||||
if marked_id >= 0:
|
||||
return marked_id, types.PeerUser
|
||||
return marked_id, _tl.PeerUser
|
||||
|
||||
marked_id = -marked_id
|
||||
if marked_id > 1000000000000:
|
||||
marked_id -= 1000000000000
|
||||
return marked_id, types.PeerChannel
|
||||
return marked_id, _tl.PeerChannel
|
||||
else:
|
||||
return marked_id, types.PeerChat
|
||||
return marked_id, _tl.PeerChat
|
||||
|
||||
|
||||
def _rle_decode(data):
|
||||
|
@ -1159,12 +1159,12 @@ def resolve_bot_file_id(file_id):
|
|||
|
||||
attributes = []
|
||||
if file_type == 3 or file_type == 9:
|
||||
attributes.append(types.DocumentAttributeAudio(
|
||||
attributes.append(_tl.DocumentAttributeAudio(
|
||||
duration=0,
|
||||
voice=file_type == 3
|
||||
))
|
||||
elif file_type == 4 or file_type == 13:
|
||||
attributes.append(types.DocumentAttributeVideo(
|
||||
attributes.append(_tl.DocumentAttributeVideo(
|
||||
duration=0,
|
||||
w=0,
|
||||
h=0,
|
||||
|
@ -1172,14 +1172,14 @@ def resolve_bot_file_id(file_id):
|
|||
))
|
||||
# elif file_type == 5: # other, cannot know which
|
||||
elif file_type == 8:
|
||||
attributes.append(types.DocumentAttributeSticker(
|
||||
attributes.append(_tl.DocumentAttributeSticker(
|
||||
alt='',
|
||||
stickerset=types.InputStickerSetEmpty()
|
||||
stickerset=_tl.InputStickerSetEmpty()
|
||||
))
|
||||
elif file_type == 10:
|
||||
attributes.append(types.DocumentAttributeAnimated())
|
||||
attributes.append(_tl.DocumentAttributeAnimated())
|
||||
|
||||
return types.Document(
|
||||
return _tl.Document(
|
||||
id=media_id,
|
||||
access_hash=access_hash,
|
||||
date=None,
|
||||
|
@ -1210,12 +1210,12 @@ def resolve_bot_file_id(file_id):
|
|||
|
||||
# Thumbnails (small) always have ID 0; otherwise size 'x'
|
||||
photo_size = 's' if media_id or access_hash else 'x'
|
||||
return types.Photo(
|
||||
return _tl.Photo(
|
||||
id=media_id,
|
||||
access_hash=access_hash,
|
||||
file_reference=b'',
|
||||
date=None,
|
||||
sizes=[types.PhotoSize(
|
||||
sizes=[_tl.PhotoSize(
|
||||
type=photo_size,
|
||||
w=0,
|
||||
h=0,
|
||||
|
@ -1235,21 +1235,21 @@ def pack_bot_file_id(file):
|
|||
|
||||
If an invalid parameter is given, it will ``return None``.
|
||||
"""
|
||||
if isinstance(file, types.MessageMediaDocument):
|
||||
if isinstance(file, _tl.MessageMediaDocument):
|
||||
file = file.document
|
||||
elif isinstance(file, types.MessageMediaPhoto):
|
||||
elif isinstance(file, _tl.MessageMediaPhoto):
|
||||
file = file.photo
|
||||
|
||||
if isinstance(file, types.Document):
|
||||
if isinstance(file, _tl.Document):
|
||||
file_type = 5
|
||||
for attribute in file.attributes:
|
||||
if isinstance(attribute, types.DocumentAttributeAudio):
|
||||
if isinstance(attribute, _tl.DocumentAttributeAudio):
|
||||
file_type = 3 if attribute.voice else 9
|
||||
elif isinstance(attribute, types.DocumentAttributeVideo):
|
||||
elif isinstance(attribute, _tl.DocumentAttributeVideo):
|
||||
file_type = 13 if attribute.round_message else 4
|
||||
elif isinstance(attribute, types.DocumentAttributeSticker):
|
||||
elif isinstance(attribute, _tl.DocumentAttributeSticker):
|
||||
file_type = 8
|
||||
elif isinstance(attribute, types.DocumentAttributeAnimated):
|
||||
elif isinstance(attribute, _tl.DocumentAttributeAnimated):
|
||||
file_type = 10
|
||||
else:
|
||||
continue
|
||||
|
@ -1258,9 +1258,9 @@ def pack_bot_file_id(file):
|
|||
return _encode_telegram_base64(_rle_encode(struct.pack(
|
||||
'<iiqqb', file_type, file.dc_id, file.id, file.access_hash, 2)))
|
||||
|
||||
elif isinstance(file, types.Photo):
|
||||
elif isinstance(file, _tl.Photo):
|
||||
size = next((x for x in reversed(file.sizes) if isinstance(
|
||||
x, (types.PhotoSize, types.PhotoCachedSize))), None)
|
||||
x, (_tl.PhotoSize, _tl.PhotoCachedSize))), None)
|
||||
|
||||
if not size:
|
||||
return None
|
||||
|
@ -1326,7 +1326,7 @@ def resolve_inline_message_id(inline_msg_id):
|
|||
try:
|
||||
dc_id, message_id, pid, access_hash = \
|
||||
struct.unpack('<iiiq', _decode_telegram_base64(inline_msg_id))
|
||||
peer = types.PeerChannel(-pid) if pid < 0 else types.PeerUser(pid)
|
||||
peer = _tl.PeerChannel(-pid) if pid < 0 else _tl.PeerUser(pid)
|
||||
return message_id, peer, dc_id, access_hash
|
||||
except (struct.error, TypeError):
|
||||
return None, None, None, None
|
||||
|
@ -1360,14 +1360,14 @@ def encode_waveform(waveform):
|
|||
file = 'my.ogg'
|
||||
|
||||
# Send 'my.ogg' with a ascending-triangle waveform
|
||||
await client.send_file(chat, file, attributes=[types.DocumentAttributeAudio(
|
||||
await client.send_file(chat, file, attributes=[_tl.DocumentAttributeAudio(
|
||||
duration=7,
|
||||
voice=True,
|
||||
waveform=utils.encode_waveform(bytes(range(2 ** 5)) # 2**5 because 5-bit
|
||||
)]
|
||||
|
||||
# Send 'my.ogg' with a square waveform
|
||||
await client.send_file(chat, file, attributes=[types.DocumentAttributeAudio(
|
||||
await client.send_file(chat, file, attributes=[_tl.DocumentAttributeAudio(
|
||||
duration=7,
|
||||
voice=True,
|
||||
waveform=utils.encode_waveform(bytes((31, 31, 15, 15, 15, 15, 31, 31)) * 4)
|
||||
|
@ -1542,18 +1542,18 @@ def stripped_photo_to_jpg(stripped):
|
|||
|
||||
|
||||
def _photo_size_byte_count(size):
|
||||
if isinstance(size, types.PhotoSize):
|
||||
if isinstance(size, _tl.PhotoSize):
|
||||
return size.size
|
||||
elif isinstance(size, types.PhotoStrippedSize):
|
||||
elif isinstance(size, _tl.PhotoStrippedSize):
|
||||
if len(size.bytes) < 3 or size.bytes[0] != 1:
|
||||
return len(size.bytes)
|
||||
|
||||
return len(size.bytes) + 622
|
||||
elif isinstance(size, types.PhotoCachedSize):
|
||||
elif isinstance(size, _tl.PhotoCachedSize):
|
||||
return len(size.bytes)
|
||||
elif isinstance(size, types.PhotoSizeEmpty):
|
||||
elif isinstance(size, _tl.PhotoSizeEmpty):
|
||||
return 0
|
||||
elif isinstance(size, types.PhotoSizeProgressive):
|
||||
elif isinstance(size, _tl.PhotoSizeProgressive):
|
||||
return max(size.sizes)
|
||||
else:
|
||||
return None
|
||||
|
|
|
@ -6,17 +6,10 @@ import os
|
|||
import time
|
||||
from hashlib import sha1
|
||||
|
||||
from ..tl.types import (
|
||||
ResPQ, PQInnerData, ServerDHParamsFail, ServerDHParamsOk,
|
||||
ServerDHInnerData, ClientDHInnerData, DhGenOk, DhGenRetry, DhGenFail
|
||||
)
|
||||
from .. import helpers
|
||||
from .. import helpers, _tl
|
||||
from ..crypto import AES, AuthKey, Factorization, rsa
|
||||
from ..errors import SecurityError
|
||||
from ..extensions import BinaryReader
|
||||
from ..tl.functions import (
|
||||
ReqPqMultiRequest, ReqDHParamsRequest, SetClientDHParamsRequest
|
||||
)
|
||||
|
||||
|
||||
async def do_authentication(sender):
|
||||
|
@ -28,8 +21,8 @@ async def do_authentication(sender):
|
|||
"""
|
||||
# Step 1 sending: PQ Request, endianness doesn't matter since it's random
|
||||
nonce = int.from_bytes(os.urandom(16), 'big', signed=True)
|
||||
res_pq = await sender.send(ReqPqMultiRequest(nonce))
|
||||
assert isinstance(res_pq, ResPQ), 'Step 1 answer was %s' % res_pq
|
||||
res_pq = await sender.send(_tl.fn.ReqPqMulti(nonce))
|
||||
assert isinstance(res_pq, _tl.ResPQ), 'Step 1 answer was %s' % res_pq
|
||||
|
||||
if res_pq.nonce != nonce:
|
||||
raise SecurityError('Step 1 invalid nonce from server')
|
||||
|
@ -41,7 +34,7 @@ async def do_authentication(sender):
|
|||
p, q = rsa.get_byte_array(p), rsa.get_byte_array(q)
|
||||
new_nonce = int.from_bytes(os.urandom(32), 'little', signed=True)
|
||||
|
||||
pq_inner_data = bytes(PQInnerData(
|
||||
pq_inner_data = bytes(_tl.PQInnerData(
|
||||
pq=rsa.get_byte_array(pq), p=p, q=q,
|
||||
nonce=res_pq.nonce,
|
||||
server_nonce=res_pq.server_nonce,
|
||||
|
@ -72,7 +65,7 @@ async def do_authentication(sender):
|
|||
)
|
||||
)
|
||||
|
||||
server_dh_params = await sender.send(ReqDHParamsRequest(
|
||||
server_dh_params = await sender.send(_tl.fn.ReqDHParams(
|
||||
nonce=res_pq.nonce,
|
||||
server_nonce=res_pq.server_nonce,
|
||||
p=p, q=q,
|
||||
|
@ -81,7 +74,7 @@ async def do_authentication(sender):
|
|||
))
|
||||
|
||||
assert isinstance(
|
||||
server_dh_params, (ServerDHParamsOk, ServerDHParamsFail)),\
|
||||
server_dh_params, (_tl.ServerDHParamsOk, _tl.ServerDHParamsFail)),\
|
||||
'Step 2.1 answer was %s' % server_dh_params
|
||||
|
||||
if server_dh_params.nonce != res_pq.nonce:
|
||||
|
@ -90,7 +83,7 @@ async def do_authentication(sender):
|
|||
if server_dh_params.server_nonce != res_pq.server_nonce:
|
||||
raise SecurityError('Step 2 invalid server nonce from server')
|
||||
|
||||
if isinstance(server_dh_params, ServerDHParamsFail):
|
||||
if isinstance(server_dh_params, _tl.ServerDHParamsFail):
|
||||
nnh = int.from_bytes(
|
||||
sha1(new_nonce.to_bytes(32, 'little', signed=True)).digest()[4:20],
|
||||
'little', signed=True
|
||||
|
@ -98,7 +91,7 @@ async def do_authentication(sender):
|
|||
if server_dh_params.new_nonce_hash != nnh:
|
||||
raise SecurityError('Step 2 invalid DH fail nonce from server')
|
||||
|
||||
assert isinstance(server_dh_params, ServerDHParamsOk),\
|
||||
assert isinstance(server_dh_params, _tl.ServerDHParamsOk),\
|
||||
'Step 2.2 answer was %s' % server_dh_params
|
||||
|
||||
# Step 3 sending: Complete DH Exchange
|
||||
|
@ -116,7 +109,7 @@ async def do_authentication(sender):
|
|||
with BinaryReader(plain_text_answer) as reader:
|
||||
reader.read(20) # hash sum
|
||||
server_dh_inner = reader.tgread_object()
|
||||
assert isinstance(server_dh_inner, ServerDHInnerData),\
|
||||
assert isinstance(server_dh_inner, _tl.ServerDHInnerData),\
|
||||
'Step 3 answer was %s' % server_dh_inner
|
||||
|
||||
if server_dh_inner.nonce != res_pq.nonce:
|
||||
|
@ -157,7 +150,7 @@ async def do_authentication(sender):
|
|||
raise SecurityError('g_b is not within (2^{2048-64}, dh_prime - 2^{2048-64})')
|
||||
|
||||
# Prepare client DH Inner Data
|
||||
client_dh_inner = bytes(ClientDHInnerData(
|
||||
client_dh_inner = bytes(_tl.ClientDHInnerData(
|
||||
nonce=res_pq.nonce,
|
||||
server_nonce=res_pq.server_nonce,
|
||||
retry_id=0, # TODO Actual retry ID
|
||||
|
@ -170,13 +163,13 @@ async def do_authentication(sender):
|
|||
client_dh_encrypted = AES.encrypt_ige(client_dh_inner_hashed, key, iv)
|
||||
|
||||
# Prepare Set client DH params
|
||||
dh_gen = await sender.send(SetClientDHParamsRequest(
|
||||
dh_gen = await sender.send(_tl.fn.SetClientDHParams(
|
||||
nonce=res_pq.nonce,
|
||||
server_nonce=res_pq.server_nonce,
|
||||
encrypted_data=client_dh_encrypted,
|
||||
))
|
||||
|
||||
nonce_types = (DhGenOk, DhGenRetry, DhGenFail)
|
||||
nonce_types = (_tl.DhGenOk, _tl.DhGenRetry, _tl.DhGenFail)
|
||||
assert isinstance(dh_gen, nonce_types), 'Step 3.1 answer was %s' % dh_gen
|
||||
name = dh_gen.__class__.__name__
|
||||
if dh_gen.nonce != res_pq.nonce:
|
||||
|
@ -194,7 +187,7 @@ async def do_authentication(sender):
|
|||
if dh_hash != new_nonce_hash:
|
||||
raise SecurityError('Step 3 invalid new nonce hash')
|
||||
|
||||
if not isinstance(dh_gen, DhGenOk):
|
||||
if not isinstance(dh_gen, _tl.DhGenOk):
|
||||
raise AssertionError('Step 3.2 answer was %s' % dh_gen)
|
||||
|
||||
return auth_key, time_offset
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
from .tlobject import TLObject, TLRequest
|
|
@ -140,7 +140,7 @@ class Dialog:
|
|||
# Un-archiving
|
||||
dialog.archive(0)
|
||||
"""
|
||||
return await self._client(functions.folders.EditPeerFoldersRequest([
|
||||
return await self._client(_tl.fn.folders.EditPeerFolders([
|
||||
types.InputFolderPeer(self.input_entity, folder_id=folder)
|
||||
]))
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import datetime
|
||||
|
||||
from .. import TLObject
|
||||
from ..functions.messages import SaveDraftRequest
|
||||
from ..types import DraftMessage
|
||||
from ... import _tl
|
||||
from ...errors import RPCError
|
||||
from ...extensions import markdown
|
||||
from ...utils import get_input_peer, get_peer
|
||||
|
@ -30,8 +28,8 @@ class Draft:
|
|||
self._entity = entity
|
||||
self._input_entity = get_input_peer(entity) if entity else None
|
||||
|
||||
if not draft or not isinstance(draft, DraftMessage):
|
||||
draft = DraftMessage('', None, None, None, None)
|
||||
if not draft or not isinstance(draft, _tl.DraftMessage):
|
||||
draft = _tl.DraftMessage('', None, None, None, None)
|
||||
|
||||
self._text = markdown.unparse(draft.message, draft.entities)
|
||||
self._raw_text = draft.message
|
||||
|
@ -134,7 +132,7 @@ class Draft:
|
|||
raw_text, entities =\
|
||||
await self._client._parse_message_text(text, parse_mode)
|
||||
|
||||
result = await self._client(SaveDraftRequest(
|
||||
result = await self._client(_tl.fn.SaveDraftRequest(
|
||||
peer=self._peer,
|
||||
message=raw_text,
|
||||
no_webpage=not link_preview,
|
||||
|
@ -184,7 +182,7 @@ class Draft:
|
|||
}
|
||||
|
||||
def __str__(self):
|
||||
return TLObject.pretty_format(self.to_dict())
|
||||
return _tl.TLObject.pretty_format(self.to_dict())
|
||||
|
||||
def stringify(self):
|
||||
return TLObject.pretty_format(self.to_dict(), indent=0)
|
||||
return _tl.TLObject.pretty_format(self.to_dict(), indent=0)
|
||||
|
|
|
@ -197,7 +197,7 @@ class InlineBuilder:
|
|||
if isinstance(media, types.InputPhoto):
|
||||
fh = media
|
||||
else:
|
||||
r = await self._client(functions.messages.UploadMediaRequest(
|
||||
r = await self._client(_tl.fn.messages.UploadMedia(
|
||||
types.InputPeerSelf(), media=media
|
||||
))
|
||||
fh = utils.get_input_photo(r.photo)
|
||||
|
@ -317,7 +317,7 @@ class InlineBuilder:
|
|||
if isinstance(media, types.InputDocument):
|
||||
fh = media
|
||||
else:
|
||||
r = await self._client(functions.messages.UploadMediaRequest(
|
||||
r = await self._client(_tl.fn.messages.UploadMedia(
|
||||
types.InputPeerSelf(), media=media
|
||||
))
|
||||
fh = utils.get_input_document(r.document)
|
||||
|
|
|
@ -150,7 +150,7 @@ class InlineResult:
|
|||
else:
|
||||
reply_id = None if reply_to is None else utils.get_message_id(reply_to)
|
||||
|
||||
req = functions.messages.SendInlineBotResultRequest(
|
||||
req = _tl.fn.messages.SendInlineBotResult(
|
||||
peer=entity,
|
||||
query_id=self._query_id,
|
||||
id=self.result.id,
|
||||
|
|
|
@ -986,7 +986,7 @@ class Message(ChatGetter, SenderGetter, TLObject):
|
|||
if options is None:
|
||||
options = []
|
||||
return await self._client(
|
||||
functions.messages.SendVoteRequest(
|
||||
_tl.fn.messages.SendVote(
|
||||
peer=self._input_chat,
|
||||
msg_id=self.id,
|
||||
options=options
|
||||
|
|
|
@ -96,10 +96,10 @@ class MessageButton:
|
|||
self._chat, self.button.text, parse_mode=None)
|
||||
elif isinstance(self.button, types.KeyboardButtonCallback):
|
||||
if password is not None:
|
||||
pwd = await self._client(functions.account.GetPasswordRequest())
|
||||
pwd = await self._client(_tl.fn.account.GetPassword())
|
||||
password = pwd_mod.compute_check(pwd, password)
|
||||
|
||||
req = functions.messages.GetBotCallbackAnswerRequest(
|
||||
req = _tl.fn.messages.GetBotCallbackAnswer(
|
||||
peer=self._chat, msg_id=self._msg_id, data=self.button.data,
|
||||
password=password
|
||||
)
|
||||
|
@ -108,13 +108,13 @@ class MessageButton:
|
|||
except BotResponseTimeoutError:
|
||||
return None
|
||||
elif isinstance(self.button, types.KeyboardButtonSwitchInline):
|
||||
return await self._client(functions.messages.StartBotRequest(
|
||||
return await self._client(_tl.fn.messages.StartBot(
|
||||
bot=self._bot, peer=self._chat, start_param=self.button.query
|
||||
))
|
||||
elif isinstance(self.button, types.KeyboardButtonUrl):
|
||||
return webbrowser.open(self.button.url)
|
||||
elif isinstance(self.button, types.KeyboardButtonGame):
|
||||
req = functions.messages.GetBotCallbackAnswerRequest(
|
||||
req = _tl.fn.messages.GetBotCallbackAnswer(
|
||||
peer=self._chat, msg_id=self._msg_id, game=True
|
||||
)
|
||||
try:
|
||||
|
|
|
@ -15,7 +15,7 @@ class QRLogin:
|
|||
"""
|
||||
def __init__(self, client, ignored_ids):
|
||||
self._client = client
|
||||
self._request = functions.auth.ExportLoginTokenRequest(
|
||||
self._request = _tl.fn.auth.ExportLoginToken(
|
||||
self._client.api_id, self._client.api_hash, ignored_ids)
|
||||
self._resp = None
|
||||
|
||||
|
@ -108,7 +108,7 @@ class QRLogin:
|
|||
resp = await self._client(self._request)
|
||||
if isinstance(resp, types.auth.LoginTokenMigrateTo):
|
||||
await self._client._switch_dc(resp.dc_id)
|
||||
resp = await self._client(functions.auth.ImportLoginTokenRequest(resp.token))
|
||||
resp = await self._client(_tl.fn.auth.ImportLoginToken(resp.token))
|
||||
# resp should now be auth.loginTokenSuccess
|
||||
|
||||
if isinstance(resp, types.auth.LoginTokenSuccess):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Errors not related to the Telegram API itself"""
|
||||
import struct
|
||||
|
||||
from ..tl import TLRequest
|
||||
from .. import _tl
|
||||
|
||||
|
||||
class ReadCancelledError(Exception):
|
||||
|
@ -138,7 +138,7 @@ class MultiError(Exception):
|
|||
raise TypeError(
|
||||
"Expected an exception object, not '%r'" % e
|
||||
)
|
||||
if not isinstance(req, TLRequest):
|
||||
if not isinstance(req, _tl.TLRequest):
|
||||
raise TypeError(
|
||||
"Expected TLRequest object, not '%r'" % req
|
||||
)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from ..tl import functions
|
||||
from .. import _tl
|
||||
|
||||
_NESTS_QUERY = (
|
||||
functions.InvokeAfterMsgRequest,
|
||||
functions.InvokeAfterMsgsRequest,
|
||||
functions.InitConnectionRequest,
|
||||
functions.InvokeWithLayerRequest,
|
||||
functions.InvokeWithoutUpdatesRequest,
|
||||
functions.InvokeWithMessagesRangeRequest,
|
||||
functions.InvokeWithTakeoutRequest,
|
||||
_tl.fn.InvokeAfterMsg,
|
||||
_tl.fn.InvokeAfterMsgs,
|
||||
_tl.fn.InitConnection,
|
||||
_tl.fn.InvokeWithLayer,
|
||||
_tl.fn.InvokeWithoutUpdates,
|
||||
_tl.fn.InvokeWithMessagesRange,
|
||||
_tl.fn.InvokeWithTakeout,
|
||||
)
|
||||
|
||||
class RPCError(Exception):
|
||||
|
|
|
@ -3,9 +3,7 @@ import time
|
|||
import weakref
|
||||
|
||||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from .. import utils
|
||||
from ..tl import types
|
||||
from ..tl.custom.sendergetter import SenderGetter
|
||||
from .. import utils, _tl
|
||||
|
||||
_IGNORE_MAX_SIZE = 100 # len()
|
||||
_IGNORE_MAX_AGE = 5 # seconds
|
||||
|
@ -101,8 +99,8 @@ class Album(EventBuilder):
|
|||
return # We only care about albums which come inside the same Updates
|
||||
|
||||
if isinstance(update,
|
||||
(types.UpdateNewMessage, types.UpdateNewChannelMessage)):
|
||||
if not isinstance(update.message, types.Message):
|
||||
(_tl.UpdateNewMessage, _tl.UpdateNewChannelMessage)):
|
||||
if not isinstance(update.message, _tl.Message):
|
||||
return # We don't care about MessageService's here
|
||||
|
||||
group = update.message.grouped_id
|
||||
|
@ -130,8 +128,8 @@ class Album(EventBuilder):
|
|||
# Figure out which updates share the same group and use those
|
||||
return cls.Event([
|
||||
u.message for u in others
|
||||
if (isinstance(u, (types.UpdateNewMessage, types.UpdateNewChannelMessage))
|
||||
and isinstance(u.message, types.Message)
|
||||
if (isinstance(u, (_tl.UpdateNewMessage, _tl.UpdateNewChannelMessage))
|
||||
and isinstance(u.message, _tl.Message)
|
||||
and u.message.grouped_id == group)
|
||||
])
|
||||
|
||||
|
@ -140,7 +138,7 @@ class Album(EventBuilder):
|
|||
if len(event.messages) > 1:
|
||||
return super().filter(event)
|
||||
|
||||
class Event(EventCommon, SenderGetter):
|
||||
class Event(EventCommon, _tl.custom.sendergetter.SenderGetter):
|
||||
"""
|
||||
Represents the event of a new album.
|
||||
|
||||
|
@ -150,7 +148,7 @@ class Album(EventBuilder):
|
|||
"""
|
||||
def __init__(self, messages):
|
||||
message = messages[0]
|
||||
if not message.out and isinstance(message.peer_id, types.PeerUser):
|
||||
if not message.out and isinstance(message.peer_id, _tl.PeerUser):
|
||||
# Incoming message (e.g. from a bot) has peer_id=us, and
|
||||
# from_id=bot (the actual "chat" from a user's perspective).
|
||||
chat_peer = message.from_id
|
||||
|
@ -160,7 +158,7 @@ class Album(EventBuilder):
|
|||
super().__init__(chat_peer=chat_peer,
|
||||
msg_id=message.id, broadcast=bool(message.post))
|
||||
|
||||
SenderGetter.__init__(self, message.sender_id)
|
||||
_tl.custom.sendergetter.SenderGetter.__init__(self, message.sender_id)
|
||||
self.messages = messages
|
||||
|
||||
def _set_client(self, client):
|
||||
|
|
|
@ -2,9 +2,7 @@ import re
|
|||
import struct
|
||||
|
||||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from .. import utils
|
||||
from ..tl import types, functions
|
||||
from ..tl.custom.sendergetter import SenderGetter
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
@ -88,13 +86,13 @@ class CallbackQuery(EventBuilder):
|
|||
|
||||
@classmethod
|
||||
def build(cls, update, others=None, self_id=None):
|
||||
if isinstance(update, types.UpdateBotCallbackQuery):
|
||||
if isinstance(update, _tl.UpdateBotCallbackQuery):
|
||||
return cls.Event(update, update.peer, update.msg_id)
|
||||
elif isinstance(update, types.UpdateInlineBotCallbackQuery):
|
||||
elif isinstance(update, _tl.UpdateInlineBotCallbackQuery):
|
||||
# See https://github.com/LonamiWebs/Telethon/pull/1005
|
||||
# The long message ID is actually just msg_id + peer_id
|
||||
mid, pid = struct.unpack('<ii', struct.pack('<q', update.msg_id.id))
|
||||
peer = types.PeerChannel(-pid) if pid < 0 else types.PeerUser(pid)
|
||||
peer = _tl.PeerChannel(-pid) if pid < 0 else _tl.PeerUser(pid)
|
||||
return cls.Event(update, peer, mid)
|
||||
|
||||
def filter(self, event):
|
||||
|
@ -123,7 +121,7 @@ class CallbackQuery(EventBuilder):
|
|||
return self.func(event)
|
||||
return True
|
||||
|
||||
class Event(EventCommon, SenderGetter):
|
||||
class Event(EventCommon, _tl.custom.sendergetter.SenderGetter):
|
||||
"""
|
||||
Represents the event of a new callback query.
|
||||
|
||||
|
@ -141,7 +139,7 @@ class CallbackQuery(EventBuilder):
|
|||
"""
|
||||
def __init__(self, query, peer, msg_id):
|
||||
super().__init__(peer, msg_id=msg_id)
|
||||
SenderGetter.__init__(self, query.user_id)
|
||||
_tl.custom.sendergetter.SenderGetter.__init__(self, query.user_id)
|
||||
self.query = query
|
||||
self.data_match = None
|
||||
self.pattern_match = None
|
||||
|
@ -242,7 +240,7 @@ class CallbackQuery(EventBuilder):
|
|||
|
||||
self._answered = True
|
||||
return await self._client(
|
||||
functions.messages.SetBotCallbackAnswerRequest(
|
||||
_tl.fn.messages.SetBotCallbackAnswerRequest(
|
||||
query_id=self.query.query_id,
|
||||
cache_time=cache_time,
|
||||
alert=alert,
|
||||
|
@ -264,7 +262,7 @@ class CallbackQuery(EventBuilder):
|
|||
chat, so methods like `respond` or `delete` won't work (but
|
||||
`edit` will always work).
|
||||
"""
|
||||
return isinstance(self.query, types.UpdateInlineBotCallbackQuery)
|
||||
return isinstance(self.query, _tl.UpdateInlineBotCallbackQuery)
|
||||
|
||||
async def respond(self, *args, **kwargs):
|
||||
"""
|
||||
|
@ -312,7 +310,7 @@ class CallbackQuery(EventBuilder):
|
|||
since the message object is normally not present.
|
||||
"""
|
||||
self._client.loop.create_task(self.answer())
|
||||
if isinstance(self.query.msg_id, types.InputBotInlineMessageID):
|
||||
if isinstance(self.query.msg_id, _tl.InputBotInlineMessageID):
|
||||
return await self._client.edit_message(
|
||||
self.query.msg_id, *args, **kwargs
|
||||
)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from .. import utils
|
||||
from ..tl import types
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
@ -36,23 +35,23 @@ class ChatAction(EventBuilder):
|
|||
# Rely on specific pin updates for unpins, but otherwise ignore them
|
||||
# for new pins (we'd rather handle the new service message with pin,
|
||||
# so that we can act on that message').
|
||||
if isinstance(update, types.UpdatePinnedChannelMessages) and not update.pinned:
|
||||
return cls.Event(types.PeerChannel(update.channel_id),
|
||||
if isinstance(update, _tl.UpdatePinnedChannelMessages) and not update.pinned:
|
||||
return cls.Event(_tl.PeerChannel(update.channel_id),
|
||||
pin_ids=update.messages,
|
||||
pin=update.pinned)
|
||||
|
||||
elif isinstance(update, types.UpdatePinnedMessages) and not update.pinned:
|
||||
elif isinstance(update, _tl.UpdatePinnedMessages) and not update.pinned:
|
||||
return cls.Event(update.peer,
|
||||
pin_ids=update.messages,
|
||||
pin=update.pinned)
|
||||
|
||||
elif isinstance(update, types.UpdateChatParticipantAdd):
|
||||
return cls.Event(types.PeerChat(update.chat_id),
|
||||
elif isinstance(update, _tl.UpdateChatParticipantAdd):
|
||||
return cls.Event(_tl.PeerChat(update.chat_id),
|
||||
added_by=update.inviter_id or True,
|
||||
users=update.user_id)
|
||||
|
||||
elif isinstance(update, types.UpdateChatParticipantDelete):
|
||||
return cls.Event(types.PeerChat(update.chat_id),
|
||||
elif isinstance(update, _tl.UpdateChatParticipantDelete):
|
||||
return cls.Event(_tl.PeerChat(update.chat_id),
|
||||
kicked_by=True,
|
||||
users=update.user_id)
|
||||
|
||||
|
@ -61,50 +60,50 @@ class ChatAction(EventBuilder):
|
|||
# better not to rely on this. Rely only in MessageActionChatDeleteUser.
|
||||
|
||||
elif (isinstance(update, (
|
||||
types.UpdateNewMessage, types.UpdateNewChannelMessage))
|
||||
and isinstance(update.message, types.MessageService)):
|
||||
_tl.UpdateNewMessage, _tl.UpdateNewChannelMessage))
|
||||
and isinstance(update.message, _tl.MessageService)):
|
||||
msg = update.message
|
||||
action = update.message.action
|
||||
if isinstance(action, types.MessageActionChatJoinedByLink):
|
||||
if isinstance(action, _tl.MessageActionChatJoinedByLink):
|
||||
return cls.Event(msg,
|
||||
added_by=True,
|
||||
users=msg.from_id)
|
||||
elif isinstance(action, types.MessageActionChatAddUser):
|
||||
elif isinstance(action, _tl.MessageActionChatAddUser):
|
||||
# If a user adds itself, it means they joined via the public chat username
|
||||
added_by = ([msg.sender_id] == action.users) or msg.from_id
|
||||
return cls.Event(msg,
|
||||
added_by=added_by,
|
||||
users=action.users)
|
||||
elif isinstance(action, types.MessageActionChatDeleteUser):
|
||||
elif isinstance(action, _tl.MessageActionChatDeleteUser):
|
||||
return cls.Event(msg,
|
||||
kicked_by=utils.get_peer_id(msg.from_id) if msg.from_id else True,
|
||||
users=action.user_id)
|
||||
elif isinstance(action, types.MessageActionChatCreate):
|
||||
elif isinstance(action, _tl.MessageActionChatCreate):
|
||||
return cls.Event(msg,
|
||||
users=action.users,
|
||||
created=True,
|
||||
new_title=action.title)
|
||||
elif isinstance(action, types.MessageActionChannelCreate):
|
||||
elif isinstance(action, _tl.MessageActionChannelCreate):
|
||||
return cls.Event(msg,
|
||||
created=True,
|
||||
users=msg.from_id,
|
||||
new_title=action.title)
|
||||
elif isinstance(action, types.MessageActionChatEditTitle):
|
||||
elif isinstance(action, _tl.MessageActionChatEditTitle):
|
||||
return cls.Event(msg,
|
||||
users=msg.from_id,
|
||||
new_title=action.title)
|
||||
elif isinstance(action, types.MessageActionChatEditPhoto):
|
||||
elif isinstance(action, _tl.MessageActionChatEditPhoto):
|
||||
return cls.Event(msg,
|
||||
users=msg.from_id,
|
||||
new_photo=action.photo)
|
||||
elif isinstance(action, types.MessageActionChatDeletePhoto):
|
||||
elif isinstance(action, _tl.MessageActionChatDeletePhoto):
|
||||
return cls.Event(msg,
|
||||
users=msg.from_id,
|
||||
new_photo=True)
|
||||
elif isinstance(action, types.MessageActionPinMessage) and msg.reply_to:
|
||||
elif isinstance(action, _tl.MessageActionPinMessage) and msg.reply_to:
|
||||
return cls.Event(msg,
|
||||
pin_ids=[msg.reply_to_msg_id])
|
||||
elif isinstance(action, types.MessageActionGameScore):
|
||||
elif isinstance(action, _tl.MessageActionGameScore):
|
||||
return cls.Event(msg,
|
||||
new_score=action.score)
|
||||
|
||||
|
@ -142,7 +141,7 @@ class ChatAction(EventBuilder):
|
|||
|
||||
new_title (`str`, optional):
|
||||
The new title string for the chat, if applicable.
|
||||
|
||||
|
||||
new_score (`str`, optional):
|
||||
The new score string for the game, if applicable.
|
||||
|
||||
|
@ -153,7 +152,7 @@ class ChatAction(EventBuilder):
|
|||
def __init__(self, where, new_photo=None,
|
||||
added_by=None, kicked_by=None, created=None,
|
||||
users=None, new_title=None, pin_ids=None, pin=None, new_score=None):
|
||||
if isinstance(where, types.MessageService):
|
||||
if isinstance(where, _tl.MessageService):
|
||||
self.action_message = where
|
||||
where = where.peer_id
|
||||
else:
|
||||
|
@ -169,7 +168,7 @@ class ChatAction(EventBuilder):
|
|||
|
||||
self.new_photo = new_photo is not None
|
||||
self.photo = \
|
||||
new_photo if isinstance(new_photo, types.Photo) else None
|
||||
new_photo if isinstance(new_photo, _tl.Photo) else None
|
||||
|
||||
self._added_by = None
|
||||
self._kicked_by = None
|
||||
|
@ -283,7 +282,7 @@ class ChatAction(EventBuilder):
|
|||
"""
|
||||
The user who added ``users``, if applicable (`None` otherwise).
|
||||
"""
|
||||
if self._added_by and not isinstance(self._added_by, types.User):
|
||||
if self._added_by and not isinstance(self._added_by, _tl.User):
|
||||
aby = self._entities.get(utils.get_peer_id(self._added_by))
|
||||
if aby:
|
||||
self._added_by = aby
|
||||
|
@ -304,7 +303,7 @@ class ChatAction(EventBuilder):
|
|||
"""
|
||||
The user who kicked ``users``, if applicable (`None` otherwise).
|
||||
"""
|
||||
if self._kicked_by and not isinstance(self._kicked_by, types.User):
|
||||
if self._kicked_by and not isinstance(self._kicked_by, _tl.User):
|
||||
kby = self._entities.get(utils.get_peer_id(self._kicked_by))
|
||||
if kby:
|
||||
self._kicked_by = kby
|
||||
|
@ -393,7 +392,7 @@ class ChatAction(EventBuilder):
|
|||
await self.action_message._reload_message()
|
||||
self._users = [
|
||||
u for u in self.action_message.action_entities
|
||||
if isinstance(u, (types.User, types.UserEmpty))]
|
||||
if isinstance(u, (_tl.User, _tl.UserEmpty))]
|
||||
|
||||
return self._users
|
||||
|
||||
|
@ -433,7 +432,7 @@ class ChatAction(EventBuilder):
|
|||
self._input_users = [
|
||||
utils.get_input_peer(u)
|
||||
for u in self.action_message.action_entities
|
||||
if isinstance(u, (types.User, types.UserEmpty))]
|
||||
if isinstance(u, (_tl.User, _tl.UserEmpty))]
|
||||
|
||||
return self._input_users or []
|
||||
|
||||
|
|
|
@ -2,9 +2,7 @@ import abc
|
|||
import asyncio
|
||||
import warnings
|
||||
|
||||
from .. import utils
|
||||
from ..tl import TLObject, types
|
||||
from ..tl.custom.chatgetter import ChatGetter
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
async def _into_id_set(client, chats):
|
||||
|
@ -22,16 +20,16 @@ async def _into_id_set(client, chats):
|
|||
result.add(chat) # Explicitly marked IDs are negative
|
||||
else:
|
||||
result.update({ # Support all valid types of peers
|
||||
utils.get_peer_id(types.PeerUser(chat)),
|
||||
utils.get_peer_id(types.PeerChat(chat)),
|
||||
utils.get_peer_id(types.PeerChannel(chat)),
|
||||
utils.get_peer_id(_tl.PeerUser(chat)),
|
||||
utils.get_peer_id(_tl.PeerChat(chat)),
|
||||
utils.get_peer_id(_tl.PeerChannel(chat)),
|
||||
})
|
||||
elif isinstance(chat, TLObject) and chat.SUBCLASS_OF_ID == 0x2d45687:
|
||||
elif isinstance(chat, _tl.TLObject) and chat.SUBCLASS_OF_ID == 0x2d45687:
|
||||
# 0x2d45687 == crc32(b'Peer')
|
||||
result.add(utils.get_peer_id(chat))
|
||||
else:
|
||||
chat = await client.get_input_entity(chat)
|
||||
if isinstance(chat, types.InputPeerSelf):
|
||||
if isinstance(chat, _tl.InputPeerSelf):
|
||||
chat = await client.get_me(input_peer=True)
|
||||
result.add(utils.get_peer_id(chat))
|
||||
|
||||
|
@ -166,10 +164,10 @@ class EventCommon(ChatGetter, abc.ABC):
|
|||
return self._client
|
||||
|
||||
def __str__(self):
|
||||
return TLObject.pretty_format(self.to_dict())
|
||||
return _tl.TLObject.pretty_format(self.to_dict())
|
||||
|
||||
def stringify(self):
|
||||
return TLObject.pretty_format(self.to_dict(), indent=0)
|
||||
return _tl.TLObject.pretty_format(self.to_dict(), indent=0)
|
||||
|
||||
def to_dict(self):
|
||||
d = {k: v for k, v in self.__dict__.items() if k[0] != '_'}
|
||||
|
|
|
@ -4,9 +4,7 @@ import re
|
|||
import asyncio
|
||||
|
||||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from .. import utils
|
||||
from ..tl import types, functions, custom
|
||||
from ..tl.custom.sendergetter import SenderGetter
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
@ -62,7 +60,7 @@ class InlineQuery(EventBuilder):
|
|||
|
||||
@classmethod
|
||||
def build(cls, update, others=None, self_id=None):
|
||||
if isinstance(update, types.UpdateBotInlineQuery):
|
||||
if isinstance(update, _tl.UpdateBotInlineQuery):
|
||||
return cls.Event(update)
|
||||
|
||||
def filter(self, event):
|
||||
|
@ -74,7 +72,7 @@ class InlineQuery(EventBuilder):
|
|||
|
||||
return super().filter(event)
|
||||
|
||||
class Event(EventCommon, SenderGetter):
|
||||
class Event(EventCommon, _tl.custom.sendergetter.SenderGetter):
|
||||
"""
|
||||
Represents the event of a new callback query.
|
||||
|
||||
|
@ -90,8 +88,8 @@ class InlineQuery(EventBuilder):
|
|||
function, which is ``re.compile(...).match`` by default.
|
||||
"""
|
||||
def __init__(self, query):
|
||||
super().__init__(chat_peer=types.PeerUser(query.user_id))
|
||||
SenderGetter.__init__(self, query.user_id)
|
||||
super().__init__(chat_peer=_tl.PeerUser(query.user_id))
|
||||
_tl.custom.sendergetter.SenderGetter.__init__(self, query.user_id)
|
||||
self.query = query
|
||||
self.pattern_match = None
|
||||
self._answered = False
|
||||
|
@ -223,10 +221,10 @@ class InlineQuery(EventBuilder):
|
|||
results = []
|
||||
|
||||
if switch_pm:
|
||||
switch_pm = types.InlineBotSwitchPM(switch_pm, switch_pm_param)
|
||||
switch_pm = _tl.InlineBotSwitchPM(switch_pm, switch_pm_param)
|
||||
|
||||
return await self._client(
|
||||
functions.messages.SetInlineBotResultsRequest(
|
||||
_tl.fn.messages.SetInlineBotResults(
|
||||
query_id=self.query.query_id,
|
||||
results=results,
|
||||
cache_time=cache_time,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from ..tl import types
|
||||
from .. import _tl
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
@ -37,15 +37,15 @@ class MessageDeleted(EventBuilder):
|
|||
"""
|
||||
@classmethod
|
||||
def build(cls, update, others=None, self_id=None):
|
||||
if isinstance(update, types.UpdateDeleteMessages):
|
||||
if isinstance(update, _tl.UpdateDeleteMessages):
|
||||
return cls.Event(
|
||||
deleted_ids=update.messages,
|
||||
peer=None
|
||||
)
|
||||
elif isinstance(update, types.UpdateDeleteChannelMessages):
|
||||
elif isinstance(update, _tl.UpdateDeleteChannelMessages):
|
||||
return cls.Event(
|
||||
deleted_ids=update.messages,
|
||||
peer=types.PeerChannel(update.channel_id)
|
||||
peer=_tl.PeerChannel(update.channel_id)
|
||||
)
|
||||
|
||||
class Event(EventCommon):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from .common import name_inner_event
|
||||
from .newmessage import NewMessage
|
||||
from ..tl import types
|
||||
from .. import _tl
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
@ -44,8 +44,8 @@ class MessageEdited(NewMessage):
|
|||
"""
|
||||
@classmethod
|
||||
def build(cls, update, others=None, self_id=None):
|
||||
if isinstance(update, (types.UpdateEditMessage,
|
||||
types.UpdateEditChannelMessage)):
|
||||
if isinstance(update, (_tl.UpdateEditMessage,
|
||||
_tl.UpdateEditChannelMessage)):
|
||||
return cls.Event(update.message)
|
||||
|
||||
class Event(NewMessage.Event):
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from .. import utils
|
||||
from ..tl import types
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
@ -36,21 +35,21 @@ class MessageRead(EventBuilder):
|
|||
|
||||
@classmethod
|
||||
def build(cls, update, others=None, self_id=None):
|
||||
if isinstance(update, types.UpdateReadHistoryInbox):
|
||||
if isinstance(update, _tl.UpdateReadHistoryInbox):
|
||||
return cls.Event(update.peer, update.max_id, False)
|
||||
elif isinstance(update, types.UpdateReadHistoryOutbox):
|
||||
elif isinstance(update, _tl.UpdateReadHistoryOutbox):
|
||||
return cls.Event(update.peer, update.max_id, True)
|
||||
elif isinstance(update, types.UpdateReadChannelInbox):
|
||||
return cls.Event(types.PeerChannel(update.channel_id),
|
||||
elif isinstance(update, _tl.UpdateReadChannelInbox):
|
||||
return cls.Event(_tl.PeerChannel(update.channel_id),
|
||||
update.max_id, False)
|
||||
elif isinstance(update, types.UpdateReadChannelOutbox):
|
||||
return cls.Event(types.PeerChannel(update.channel_id),
|
||||
elif isinstance(update, _tl.UpdateReadChannelOutbox):
|
||||
return cls.Event(_tl.PeerChannel(update.channel_id),
|
||||
update.max_id, True)
|
||||
elif isinstance(update, types.UpdateReadMessagesContents):
|
||||
elif isinstance(update, _tl.UpdateReadMessagesContents):
|
||||
return cls.Event(message_ids=update.messages,
|
||||
contents=True)
|
||||
elif isinstance(update, types.UpdateChannelReadMessagesContents):
|
||||
return cls.Event(types.PeerChannel(update.channel_id),
|
||||
elif isinstance(update, _tl.UpdateChannelReadMessagesContents):
|
||||
return cls.Event(_tl.PeerChannel(update.channel_id),
|
||||
message_ids=update.messages,
|
||||
contents=True)
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import re
|
||||
|
||||
from .common import EventBuilder, EventCommon, name_inner_event, _into_id_set
|
||||
from .. import utils
|
||||
from ..tl import types
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
@name_inner_event
|
||||
|
@ -96,19 +95,19 @@ class NewMessage(EventBuilder):
|
|||
@classmethod
|
||||
def build(cls, update, others=None, self_id=None):
|
||||
if isinstance(update,
|
||||
(types.UpdateNewMessage, types.UpdateNewChannelMessage)):
|
||||
if not isinstance(update.message, types.Message):
|
||||
(_tl.UpdateNewMessage, _tl.UpdateNewChannelMessage)):
|
||||
if not isinstance(update.message, _tl.Message):
|
||||
return # We don't care about MessageService's here
|
||||
event = cls.Event(update.message)
|
||||
elif isinstance(update, types.UpdateShortMessage):
|
||||
event = cls.Event(types.Message(
|
||||
elif isinstance(update, _tl.UpdateShortMessage):
|
||||
event = cls.Event(_tl.Message(
|
||||
out=update.out,
|
||||
mentioned=update.mentioned,
|
||||
media_unread=update.media_unread,
|
||||
silent=update.silent,
|
||||
id=update.id,
|
||||
peer_id=types.PeerUser(update.user_id),
|
||||
from_id=types.PeerUser(self_id if update.out else update.user_id),
|
||||
peer_id=_tl.PeerUser(update.user_id),
|
||||
from_id=_tl.PeerUser(self_id if update.out else update.user_id),
|
||||
message=update.message,
|
||||
date=update.date,
|
||||
fwd_from=update.fwd_from,
|
||||
|
@ -117,15 +116,15 @@ class NewMessage(EventBuilder):
|
|||
entities=update.entities,
|
||||
ttl_period=update.ttl_period
|
||||
))
|
||||
elif isinstance(update, types.UpdateShortChatMessage):
|
||||
event = cls.Event(types.Message(
|
||||
elif isinstance(update, _tl.UpdateShortChatMessage):
|
||||
event = cls.Event(_tl.Message(
|
||||
out=update.out,
|
||||
mentioned=update.mentioned,
|
||||
media_unread=update.media_unread,
|
||||
silent=update.silent,
|
||||
id=update.id,
|
||||
from_id=types.PeerUser(self_id if update.out else update.from_id),
|
||||
peer_id=types.PeerChat(update.chat_id),
|
||||
from_id=_tl.PeerUser(self_id if update.out else update.from_id),
|
||||
peer_id=_tl.PeerChat(update.chat_id),
|
||||
message=update.message,
|
||||
date=update.date,
|
||||
fwd_from=update.fwd_from,
|
||||
|
|
|
@ -2,9 +2,7 @@ import datetime
|
|||
import functools
|
||||
|
||||
from .common import EventBuilder, EventCommon, name_inner_event
|
||||
from .. import utils
|
||||
from ..tl import types
|
||||
from ..tl.custom.sendergetter import SenderGetter
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
# TODO Either the properties are poorly named or they should be
|
||||
|
@ -50,22 +48,22 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
@classmethod
|
||||
def build(cls, update, others=None, self_id=None):
|
||||
if isinstance(update, types.UpdateUserStatus):
|
||||
return cls.Event(types.PeerUser(update.user_id),
|
||||
if isinstance(update, _tl.UpdateUserStatus):
|
||||
return cls.Event(_tl.PeerUser(update.user_id),
|
||||
status=update.status)
|
||||
elif isinstance(update, types.UpdateChannelUserTyping):
|
||||
elif isinstance(update, _tl.UpdateChannelUserTyping):
|
||||
return cls.Event(update.from_id,
|
||||
chat_peer=types.PeerChannel(update.channel_id),
|
||||
chat_peer=_tl.PeerChannel(update.channel_id),
|
||||
typing=update.action)
|
||||
elif isinstance(update, types.UpdateChatUserTyping):
|
||||
elif isinstance(update, _tl.UpdateChatUserTyping):
|
||||
return cls.Event(update.from_id,
|
||||
chat_peer=types.PeerChat(update.chat_id),
|
||||
chat_peer=_tl.PeerChat(update.chat_id),
|
||||
typing=update.action)
|
||||
elif isinstance(update, types.UpdateUserTyping):
|
||||
elif isinstance(update, _tl.UpdateUserTyping):
|
||||
return cls.Event(update.user_id,
|
||||
typing=update.action)
|
||||
|
||||
class Event(EventCommon, SenderGetter):
|
||||
class Event(EventCommon, _tl.custom.sendergetter.SenderGetter):
|
||||
"""
|
||||
Represents the event of a user update
|
||||
such as gone online, started typing, etc.
|
||||
|
@ -87,7 +85,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
def __init__(self, peer, *, status=None, chat_peer=None, typing=None):
|
||||
super().__init__(chat_peer or peer)
|
||||
SenderGetter.__init__(self, utils.get_peer_id(peer))
|
||||
_tl.custom.sendergetter.SenderGetter.__init__(self, utils.get_peer_id(peer))
|
||||
|
||||
self.status = status
|
||||
self.action = typing
|
||||
|
@ -126,7 +124,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if the action is typing a message.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageTypingAction)
|
||||
return isinstance(self.action, _tl.SendMessageTypingAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -135,13 +133,13 @@ class UserUpdate(EventBuilder):
|
|||
`True` if the action is uploading something.
|
||||
"""
|
||||
return isinstance(self.action, (
|
||||
types.SendMessageChooseContactAction,
|
||||
types.SendMessageChooseStickerAction,
|
||||
types.SendMessageUploadAudioAction,
|
||||
types.SendMessageUploadDocumentAction,
|
||||
types.SendMessageUploadPhotoAction,
|
||||
types.SendMessageUploadRoundAction,
|
||||
types.SendMessageUploadVideoAction
|
||||
_tl.SendMessageChooseContactAction,
|
||||
_tl.SendMessageChooseStickerAction,
|
||||
_tl.SendMessageUploadAudioAction,
|
||||
_tl.SendMessageUploadDocumentAction,
|
||||
_tl.SendMessageUploadPhotoAction,
|
||||
_tl.SendMessageUploadRoundAction,
|
||||
_tl.SendMessageUploadVideoAction
|
||||
))
|
||||
|
||||
@property
|
||||
|
@ -151,9 +149,9 @@ class UserUpdate(EventBuilder):
|
|||
`True` if the action is recording something.
|
||||
"""
|
||||
return isinstance(self.action, (
|
||||
types.SendMessageRecordAudioAction,
|
||||
types.SendMessageRecordRoundAction,
|
||||
types.SendMessageRecordVideoAction
|
||||
_tl.SendMessageRecordAudioAction,
|
||||
_tl.SendMessageRecordRoundAction,
|
||||
_tl.SendMessageRecordVideoAction
|
||||
))
|
||||
|
||||
@property
|
||||
|
@ -162,7 +160,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if the action is playing a game.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageGamePlayAction)
|
||||
return isinstance(self.action, _tl.SendMessageGamePlayAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -170,7 +168,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if the action was cancelling other actions.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageCancelAction)
|
||||
return isinstance(self.action, _tl.SendMessageCancelAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -178,7 +176,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if what's being uploaded is a geo.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageGeoLocationAction)
|
||||
return isinstance(self.action, _tl.SendMessageGeoLocationAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -187,8 +185,8 @@ class UserUpdate(EventBuilder):
|
|||
`True` if what's being recorded/uploaded is an audio.
|
||||
"""
|
||||
return isinstance(self.action, (
|
||||
types.SendMessageRecordAudioAction,
|
||||
types.SendMessageUploadAudioAction
|
||||
_tl.SendMessageRecordAudioAction,
|
||||
_tl.SendMessageUploadAudioAction
|
||||
))
|
||||
|
||||
@property
|
||||
|
@ -198,8 +196,8 @@ class UserUpdate(EventBuilder):
|
|||
`True` if what's being recorded/uploaded is a round video.
|
||||
"""
|
||||
return isinstance(self.action, (
|
||||
types.SendMessageRecordRoundAction,
|
||||
types.SendMessageUploadRoundAction
|
||||
_tl.SendMessageRecordRoundAction,
|
||||
_tl.SendMessageUploadRoundAction
|
||||
))
|
||||
|
||||
@property
|
||||
|
@ -209,8 +207,8 @@ class UserUpdate(EventBuilder):
|
|||
`True` if what's being recorded/uploaded is an video.
|
||||
"""
|
||||
return isinstance(self.action, (
|
||||
types.SendMessageRecordVideoAction,
|
||||
types.SendMessageUploadVideoAction
|
||||
_tl.SendMessageRecordVideoAction,
|
||||
_tl.SendMessageUploadVideoAction
|
||||
))
|
||||
|
||||
@property
|
||||
|
@ -219,7 +217,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if what's being uploaded (selected) is a contact.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageChooseContactAction)
|
||||
return isinstance(self.action, _tl.SendMessageChooseContactAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -227,7 +225,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if what's being uploaded is document.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageUploadDocumentAction)
|
||||
return isinstance(self.action, _tl.SendMessageUploadDocumentAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -235,7 +233,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if what's being uploaded is a sticker.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageChooseStickerAction)
|
||||
return isinstance(self.action, _tl.SendMessageChooseStickerAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -243,7 +241,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
`True` if what's being uploaded is a photo.
|
||||
"""
|
||||
return isinstance(self.action, types.SendMessageUploadPhotoAction)
|
||||
return isinstance(self.action, _tl.SendMessageUploadPhotoAction)
|
||||
|
||||
@property
|
||||
@_requires_action
|
||||
|
@ -251,7 +249,7 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
Exact `datetime.datetime` when the user was last seen if known.
|
||||
"""
|
||||
if isinstance(self.status, types.UserStatusOffline):
|
||||
if isinstance(self.status, _tl.UserStatusOffline):
|
||||
return self.status.was_online
|
||||
|
||||
@property
|
||||
|
@ -260,19 +258,19 @@ class UserUpdate(EventBuilder):
|
|||
"""
|
||||
The `datetime.datetime` until when the user should appear online.
|
||||
"""
|
||||
if isinstance(self.status, types.UserStatusOnline):
|
||||
if isinstance(self.status, _tl.UserStatusOnline):
|
||||
return self.status.expires
|
||||
|
||||
def _last_seen_delta(self):
|
||||
if isinstance(self.status, types.UserStatusOffline):
|
||||
if isinstance(self.status, _tl.UserStatusOffline):
|
||||
return datetime.datetime.now(tz=datetime.timezone.utc) - self.status.was_online
|
||||
elif isinstance(self.status, types.UserStatusOnline):
|
||||
elif isinstance(self.status, _tl.UserStatusOnline):
|
||||
return datetime.timedelta(days=0)
|
||||
elif isinstance(self.status, types.UserStatusRecently):
|
||||
elif isinstance(self.status, _tl.UserStatusRecently):
|
||||
return datetime.timedelta(days=1)
|
||||
elif isinstance(self.status, types.UserStatusLastWeek):
|
||||
elif isinstance(self.status, _tl.UserStatusLastWeek):
|
||||
return datetime.timedelta(days=7)
|
||||
elif isinstance(self.status, types.UserStatusLastMonth):
|
||||
elif isinstance(self.status, _tl.UserStatusLastMonth):
|
||||
return datetime.timedelta(days=30)
|
||||
else:
|
||||
return datetime.timedelta(days=365)
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
from enum import Enum
|
||||
|
||||
from .abstract import Session
|
||||
from .. import utils
|
||||
from ..tl import TLObject
|
||||
from ..tl.types import (
|
||||
PeerUser, PeerChat, PeerChannel,
|
||||
InputPeerUser, InputPeerChat, InputPeerChannel,
|
||||
InputPhoto, InputDocument
|
||||
)
|
||||
from .. import utils, _tl
|
||||
|
||||
|
||||
class _SentFileType(Enum):
|
||||
|
@ -16,9 +10,9 @@ class _SentFileType(Enum):
|
|||
|
||||
@staticmethod
|
||||
def from_type(cls):
|
||||
if cls == InputDocument:
|
||||
if cls == _tl.InputDocument:
|
||||
return _SentFileType.DOCUMENT
|
||||
elif cls == InputPhoto:
|
||||
elif cls == _tl.InputPhoto:
|
||||
return _SentFileType.PHOTO
|
||||
else:
|
||||
raise ValueError('The cls must be either InputDocument/InputPhoto')
|
||||
|
@ -94,7 +88,7 @@ class MemorySession(Session):
|
|||
return id, hash, username, phone, name
|
||||
|
||||
def _entity_to_row(self, e):
|
||||
if not isinstance(e, TLObject):
|
||||
if not isinstance(e, _tl.TLObject):
|
||||
return
|
||||
try:
|
||||
p = utils.get_input_peer(e, allow_self=False)
|
||||
|
@ -106,9 +100,9 @@ class MemorySession(Session):
|
|||
# anywhere (since layer 102, there are two access hashes).
|
||||
return
|
||||
|
||||
if isinstance(p, (InputPeerUser, InputPeerChannel)):
|
||||
if isinstance(p, (_tl.InputPeerUser, _tl.InputPeerChannel)):
|
||||
p_hash = p.access_hash
|
||||
elif isinstance(p, InputPeerChat):
|
||||
elif isinstance(p, _tl.InputPeerChat):
|
||||
p_hash = 0
|
||||
else:
|
||||
return
|
||||
|
@ -123,7 +117,7 @@ class MemorySession(Session):
|
|||
)
|
||||
|
||||
def _entities_to_rows(self, tlo):
|
||||
if not isinstance(tlo, TLObject) and utils.is_list_like(tlo):
|
||||
if not isinstance(tlo, _tl.TLObject) and utils.is_list_like(tlo):
|
||||
# This may be a list of users already for instance
|
||||
entities = tlo
|
||||
else:
|
||||
|
@ -175,9 +169,9 @@ class MemorySession(Session):
|
|||
in self._entities if found_id == id)
|
||||
else:
|
||||
ids = (
|
||||
utils.get_peer_id(PeerUser(id)),
|
||||
utils.get_peer_id(PeerChat(id)),
|
||||
utils.get_peer_id(PeerChannel(id))
|
||||
utils.get_peer_id(_tl.PeerUser(id)),
|
||||
utils.get_peer_id(_tl.PeerChat(id)),
|
||||
utils.get_peer_id(_tl.PeerChannel(id))
|
||||
)
|
||||
return next((id, hash) for found_id, hash, _, _, _
|
||||
in self._entities if found_id in ids)
|
||||
|
@ -194,7 +188,7 @@ class MemorySession(Session):
|
|||
return utils.get_input_peer(key)
|
||||
except (AttributeError, TypeError):
|
||||
# Not a TLObject or can't be cast into InputPeer
|
||||
if isinstance(key, TLObject):
|
||||
if isinstance(key, _tl.TLObject):
|
||||
key = utils.get_peer_id(key)
|
||||
exact = True
|
||||
else:
|
||||
|
@ -224,17 +218,17 @@ class MemorySession(Session):
|
|||
entity_id, entity_hash = result # unpack resulting tuple
|
||||
entity_id, kind = utils.resolve_id(entity_id)
|
||||
# removes the mark and returns type of entity
|
||||
if kind == PeerUser:
|
||||
return InputPeerUser(entity_id, entity_hash)
|
||||
elif kind == PeerChat:
|
||||
return InputPeerChat(entity_id)
|
||||
elif kind == PeerChannel:
|
||||
return InputPeerChannel(entity_id, entity_hash)
|
||||
if kind == _tl.PeerUser:
|
||||
return _tl.InputPeerUser(entity_id, entity_hash)
|
||||
elif kind == _tl.PeerChat:
|
||||
return _tl.InputPeerChat(entity_id)
|
||||
elif kind == _tl.PeerChannel:
|
||||
return _tl.InputPeerChannel(entity_id, entity_hash)
|
||||
else:
|
||||
raise ValueError('Could not find input entity with key ', key)
|
||||
|
||||
def cache_file(self, md5_digest, file_size, instance):
|
||||
if not isinstance(instance, (InputDocument, InputPhoto)):
|
||||
if not isinstance(instance, (_tl.InputDocument, _tl.InputPhoto)):
|
||||
raise TypeError('Cannot cache %s instance' % type(instance))
|
||||
key = (md5_digest, file_size, _SentFileType.from_type(type(instance)))
|
||||
value = (instance.id, instance.access_hash)
|
||||
|
|
|
@ -2,13 +2,9 @@ import datetime
|
|||
import os
|
||||
import time
|
||||
|
||||
from telethon.tl import types
|
||||
from .memory import MemorySession, _SentFileType
|
||||
from .. import utils
|
||||
from .. import utils, _tl
|
||||
from ..crypto import AuthKey
|
||||
from ..tl.types import (
|
||||
InputPhoto, InputDocument, PeerUser, PeerChat, PeerChannel
|
||||
)
|
||||
|
||||
try:
|
||||
import sqlite3
|
||||
|
@ -208,7 +204,7 @@ class SQLiteSession(MemorySession):
|
|||
pts, qts, date, seq = row
|
||||
date = datetime.datetime.fromtimestamp(
|
||||
date, tz=datetime.timezone.utc)
|
||||
return types.updates.State(pts, qts, date, seq, unread_count=0)
|
||||
return _tl.updates.State(pts, qts, date, seq, unread_count=0)
|
||||
|
||||
def set_update_state(self, entity_id, state):
|
||||
self._execute('insert or replace into update_state values (?,?,?,?,?)',
|
||||
|
@ -325,9 +321,9 @@ class SQLiteSession(MemorySession):
|
|||
else:
|
||||
return self._execute(
|
||||
'select id, hash from entities where id in (?,?,?)',
|
||||
utils.get_peer_id(PeerUser(id)),
|
||||
utils.get_peer_id(PeerChat(id)),
|
||||
utils.get_peer_id(PeerChannel(id))
|
||||
utils.get_peer_id(_tl.PeerUser(id)),
|
||||
utils.get_peer_id(_tl.PeerChat(id)),
|
||||
utils.get_peer_id(_tl.PeerChannel(id))
|
||||
)
|
||||
|
||||
# File processing
|
||||
|
@ -343,7 +339,7 @@ class SQLiteSession(MemorySession):
|
|||
return cls(row[0], row[1])
|
||||
|
||||
def cache_file(self, md5_digest, file_size, instance):
|
||||
if not isinstance(instance, (InputDocument, InputPhoto)):
|
||||
if not isinstance(instance, (_tl.InputDocument, _tl.InputPhoto)):
|
||||
raise TypeError('Cannot cache %s instance' % type(instance))
|
||||
|
||||
self._execute(
|
||||
|
|
|
@ -695,9 +695,9 @@ def generate_tlobjects(tlobjects, layer, import_depth, output_dir):
|
|||
namespace_types[tlobject.namespace].append(tlobject)
|
||||
type_constructors[tlobject.result].append(tlobject)
|
||||
|
||||
_write_modules(output_dir / 'functions', import_depth, 'TLRequest',
|
||||
_write_modules(output_dir / 'fn', import_depth, 'TLRequest',
|
||||
namespace_functions, type_constructors)
|
||||
_write_modules(output_dir / 'types', import_depth, 'TLObject',
|
||||
_write_modules(output_dir, import_depth - 1, 'TLObject',
|
||||
namespace_types, type_constructors)
|
||||
|
||||
filename = output_dir / 'alltlobjects.py'
|
||||
|
|
|
@ -52,8 +52,7 @@ class TLObject:
|
|||
assert self.id == self.infer_id(),\
|
||||
'Invalid inferred ID for ' + repr(self)
|
||||
|
||||
self.class_name = snake_to_camel_case(
|
||||
self.name, suffix='Request' if self.is_function else '')
|
||||
self.class_name = snake_to_camel_case(self.name)
|
||||
|
||||
self.real_args = list(a for a in self.sorted_args() if not
|
||||
(a.flag_indicator or a.generic_definition))
|
||||
|
|
|
@ -5,7 +5,7 @@ from telethon.tl import types, functions
|
|||
|
||||
def test_nested_invalid_serialization():
|
||||
large_long = 2**62
|
||||
request = functions.account.SetPrivacyRequest(
|
||||
request = _tl.fn.account.SetPrivacy(
|
||||
key=types.InputPrivacyKeyChatInvite(),
|
||||
rules=[types.InputPrivacyValueDisallowUsers(users=[large_long])]
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user