Add a new .get_input_entity method and use it on .get_entity

This commit is contained in:
Lonami Exo 2017-10-01 14:19:04 +02:00
parent 9bccd17881
commit 5b6f9b6542

View File

@ -28,19 +28,22 @@ from .tl.functions.contacts import (
) )
from .tl.functions.messages import ( from .tl.functions.messages import (
GetDialogsRequest, GetHistoryRequest, ReadHistoryRequest, SendMediaRequest, GetDialogsRequest, GetHistoryRequest, ReadHistoryRequest, SendMediaRequest,
SendMessageRequest SendMessageRequest, GetChatsRequest
) )
from .tl.functions.users import ( from .tl.functions.users import (
GetUsersRequest GetUsersRequest
) )
from .tl.functions.channels import (
GetChannelsRequest
)
from .tl.types import ( from .tl.types import (
DocumentAttributeAudio, DocumentAttributeFilename, DocumentAttributeAudio, DocumentAttributeFilename,
InputDocumentFileLocation, InputFileLocation, InputDocumentFileLocation, InputFileLocation,
InputMediaUploadedDocument, InputMediaUploadedPhoto, InputPeerEmpty, InputMediaUploadedDocument, InputMediaUploadedPhoto, InputPeerEmpty,
Message, MessageMediaContact, MessageMediaDocument, MessageMediaPhoto, Message, MessageMediaContact, MessageMediaDocument, MessageMediaPhoto,
InputUserSelf, UserProfilePhoto, ChatPhoto, UpdateMessageID, InputUserSelf, UserProfilePhoto, ChatPhoto, UpdateMessageID,
UpdateNewMessage, UpdateShortSentMessage UpdateNewMessage, UpdateShortSentMessage,
) PeerUser, InputPeerUser, InputPeerChat, InputPeerChannel)
from .tl.types.messages import DialogsSlice from .tl.types.messages import DialogsSlice
from .utils import find_user_or_chat, get_extension from .utils import find_user_or_chat, get_extension
@ -811,28 +814,45 @@ class TelegramClient(TelegramBareClient):
@lru_cache() @lru_cache()
def get_entity(self, entity): def get_entity(self, entity):
"""Turns an entity into a valid Telegram user or chat. """Turns an entity into a valid Telegram user or chat.
If "entity" is a string, and starts with '+', or if If "entity" is a string which can be converted to an integer,
it is an integer value, it will be resolved as if it or if it starts with '+' it will be resolved as if it
were a phone number. were a phone number.
If "entity" is a string and doesn't start with '+', or If "entity" is a string and doesn't start with '+', or
it starts with '@', it will be resolved from the username. it starts with '@', it will be resolved from the username.
If no exact match is returned, an error will be raised. If no exact match is returned, an error will be raised.
If "entity" is an integer or a "Peer", its information will
be returned through a call to self.get_input_peer(entity).
If the entity is neither, and it's not a TLObject, an If the entity is neither, and it's not a TLObject, an
error will be raised. error will be raised.
""" """
# TODO Maybe cache both the contacts and the entities. # TODO Maybe cache both the contacts and the entities.
# If an user cannot be found, force a cache update through # If an user cannot be found, force a cache update through
# a public method (since users may change their username) # a public method (since users may change their username)
input_entity = None
if isinstance(entity, TLObject): if isinstance(entity, TLObject):
return entity # crc32(b'InputPeer') and crc32(b'Peer')
if type(entity).SUBCLASS_OF_ID in (0xc91c90b6, 0x2d45687):
input_entity = self.get_input_entity(entity)
else:
# TODO Don't assume it's a valid entity
return entity
if isinstance(entity, int): elif isinstance(entity, int):
entity = '+{}'.format(entity) # Turn it into a phone-like str input_entity = self.get_input_entity(entity)
if input_entity:
if isinstance(input_entity, InputPeerUser):
return self(GetUsersRequest([input_entity]))[0]
elif isinstance(input_entity, InputPeerChat):
return self(GetChatsRequest([input_entity.chat_id]))[0]
elif isinstance(input_entity, InputPeerChannel):
return self(GetChannelsRequest([input_entity]))[0]
if isinstance(entity, str): if isinstance(entity, str):
if entity.startswith('+'): if entity.startswith('+') or entity.isdigit():
contacts = self(GetContactsRequest(0)) contacts = self(GetContactsRequest(0))
try: try:
stripped_phone = entity.strip('+') stripped_phone = entity.strip('+')
@ -863,4 +883,47 @@ class TelegramClient(TelegramBareClient):
'Cannot turn "{}" into any entity (user or chat)'.format(entity) 'Cannot turn "{}" into any entity (user or chat)'.format(entity)
) )
def get_input_entity(self, peer):
"""Gets the input entity given its PeerUser, PeerChat, PeerChannel.
If no Peer class is used, peer is assumed to be the integer ID
of an User.
If this Peer hasn't been seen before by the library, all dialogs
will loaded, and their entities saved to the session file.
If even after
"""
is_peer = False
if isinstance(peer, int):
peer = PeerUser(peer)
is_peer = True
elif isinstance(peer, TLObject):
if type(peer).SUBCLASS_OF_ID == 0xc91c90b6: # crc32(b'InputPeer')
return peer
is_peer = type(peer).SUBCLASS_OF_ID == 0x2d45687 # crc32(b'Peer')
if not is_peer:
raise ValueError(
'Cannot turn "{}" into an input entity.'.format(peer)
)
try:
return self.session.get_input_entity(peer)
except KeyError:
pass
if self.session.save_entities:
# Not found, look in the dialogs (this will save the users)
self.get_dialogs(limit=None)
try:
return self.session.get_input_entity(peer)
except KeyError:
pass
raise ValueError(
'Could not find the input entity corresponding to "{}".'
'Make sure you have encountered this peer before.'.format(peer)
)
# endregion # endregion