From efc9f4c4146cb914b46e401fae25f6d3971f2a34 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Mon, 25 Jun 2018 11:03:20 +0200 Subject: [PATCH] Get rid of all remaining async properties --- telethon/events/chataction.py | 89 ++++++++++++++++++++++++++-------- telethon/events/messageread.py | 5 +- telethon/events/userupdate.py | 24 ++++++--- telethon/tl/custom/dialog.py | 2 +- telethon/tl/custom/draft.py | 58 +++++++++++++++++----- 5 files changed, 134 insertions(+), 44 deletions(-) diff --git a/telethon/events/chataction.py b/telethon/events/chataction.py index ca34289a..582e3dd2 100644 --- a/telethon/events/chataction.py +++ b/telethon/events/chataction.py @@ -204,8 +204,7 @@ class ChatAction(EventBuilder): return await self._client.delete_messages( await self.input_chat, [self.action_message], *args, **kwargs) - @property - async def pinned_message(self): + async def get_pinned_message(self): """ If ``new_pin`` is ``True``, this returns the `telethon.tl.custom.message.Message` object that was pinned. @@ -230,48 +229,77 @@ class ChatAction(EventBuilder): return self._pinned_message @property - async def added_by(self): + def added_by(self): """ The user who added ``users``, if applicable (``None`` otherwise). """ if self._added_by and not isinstance(self._added_by, types.User): aby = self._entities.get(utils.get_peer_id(self._added_by)) - if not aby: - aby = await self._client.get_entity(self._added_by) - self._added_by = aby + if aby: + self._added_by = aby + + return self._added_by + + async def get_added_by(self): + """ + Returns `added_by` but will make an API call if necessary. + """ + if not self.added_by and self._added_by: + self._added_by = await self._client.get_entity(self._added_by) return self._added_by @property - async def kicked_by(self): + def kicked_by(self): """ The user who kicked ``users``, if applicable (``None`` otherwise). """ if self._kicked_by and not isinstance(self._kicked_by, types.User): kby = self._entities.get(utils.get_peer_id(self._kicked_by)) if kby: - kby = await self._client.get_entity(self._kicked_by) - self._kicked_by = kby + self._kicked_by = kby + + return self._kicked_by + + async def get_kicked_by(self): + """ + Returns `kicked_by` but will make an API call if necessary. + """ + if not self.kicked_by and self._kicked_by: + self._kicked_by = await self._client.get_entity(self._kicked_by) return self._kicked_by @property - async def user(self): + def user(self): """ The first user that takes part in this action (e.g. joined). Might be ``None`` if the information can't be retrieved or there is no user taking part. """ - if await self.users: + if self.users: return self._users[0] - @property - async def input_user(self): + async def get_user(self): + """ + Returns `user` but will make an API call if necessary. + """ + if self.users or await self.get_users(): + return self._users[0] + + def input_user(self): """ Input version of the ``self.user`` property. """ - if await self.input_users: + if self.input_users: + return self._input_users[0] + + async def get_input_user(self): + """ + Returns `input_user` but will make an API call if necessary. + """ + if self.input_users or await self.get_input_users(): return self._input_users[0] @property @@ -283,7 +311,7 @@ class ChatAction(EventBuilder): return utils.get_peer_id(self._user_peers[0]) @property - async def users(self): + def users(self): """ A list of users that take part in this action (e.g. joined). @@ -294,6 +322,22 @@ class ChatAction(EventBuilder): return [] if self._users is None: + self._users = [ + self._entities[utils.get_peer_id(peer)] + for peer in self._user_peers + if utils.get_peer_id(peer) in self._entities + ] + + return self._users + + async def get_users(self): + """ + Returns `users` but will make an API call if necessary. + """ + if not self._user_peers: + return [] + + if self._users is None or len(self._users) != len(self._user_peers): have, missing = [], [] for peer in self._user_peers: user = self._entities.get(utils.get_peer_id(peer)) @@ -312,7 +356,7 @@ class ChatAction(EventBuilder): return self._users @property - async def input_users(self): + def input_users(self): """ Input version of the ``self.users`` property. """ @@ -321,11 +365,18 @@ class ChatAction(EventBuilder): for peer in self._user_peers: try: self._input_users.append( - await self._client.get_input_entity(peer) + self._client.session.get_input_entity(peer) ) - except (TypeError, ValueError): + except ValueError: pass - return self._input_users + return self._input_users or [] + + async def get_input_users(self): + """ + Returns `input_users` but will make an API call if necessary. + """ + # TODO Maybe we could re-fetch the message + return self.input_users @property def user_ids(self): diff --git a/telethon/events/messageread.py b/telethon/events/messageread.py index 48425fa9..ac729681 100644 --- a/telethon/events/messageread.py +++ b/telethon/events/messageread.py @@ -88,10 +88,9 @@ class MessageRead(EventBuilder): """ return self._message_ids - @property - async def messages(self): + async def get_messages(self): """ - The list of `telethon.tl.custom.message.Message` + Returns the list of `telethon.tl.custom.message.Message` **which contents'** were read. Use :meth:`is_read` if you need to check whether a message diff --git a/telethon/events/userupdate.py b/telethon/events/userupdate.py index d67dfe4f..518edd9a 100644 --- a/telethon/events/userupdate.py +++ b/telethon/events/userupdate.py @@ -148,16 +148,24 @@ class UserUpdate(EventBuilder): self.uploading = self.video = True @property - async def user(self): - """Alias around the chat (conversation).""" - return await self.chat + def user(self): + """Alias for `chat` (conversation).""" + return self.chat + + async def get_user(self): + """Alias for `get_chat` (conversation).""" + return await self.get_chat() @property - async def input_user(self): - """Alias around the input chat.""" - return await self.input_chat + def input_user(self): + """Alias for `input_chat`.""" + return self.input_chat + + async def get_input_user(self): + """Alias for `get_input_chat`.""" + return await self.get_input_chat() @property - async def user_id(self): - """Alias around `chat_id`.""" + def user_id(self): + """Alias for `chat_id`.""" return self.chat_id diff --git a/telethon/tl/custom/dialog.py b/telethon/tl/custom/dialog.py index 5287926a..fd2becdc 100644 --- a/telethon/tl/custom/dialog.py +++ b/telethon/tl/custom/dialog.py @@ -79,7 +79,7 @@ class Dialog: self.unread_count = dialog.unread_count self.unread_mentions_count = dialog.unread_mentions_count - self.draft = Draft(client, dialog.peer, dialog.draft) + self.draft = Draft._from_dialog(client, dialog) self.is_user = isinstance(self.entity, types.User) self.is_group = ( diff --git a/telethon/tl/custom/draft.py b/telethon/tl/custom/draft.py index 7941e750..334b6f26 100644 --- a/telethon/tl/custom/draft.py +++ b/telethon/tl/custom/draft.py @@ -5,7 +5,7 @@ from ..functions.messages import SaveDraftRequest from ..types import UpdateDraftMessage, DraftMessage from ...errors import RPCError from ...extensions import markdown -from ...utils import Default +from ...utils import Default, get_peer_id, get_input_peer class Draft: @@ -24,9 +24,12 @@ class Draft: reply_to_msg_id (`int`): The message ID that the draft will reply to. """ - def __init__(self, client, peer, draft): + def __init__(self, client, peer, draft, entity): self._client = client self._peer = peer + 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) @@ -37,28 +40,57 @@ class Draft: self.reply_to_msg_id = draft.reply_to_msg_id @classmethod - def _from_update(cls, client, update): - if not isinstance(update, UpdateDraftMessage): - raise TypeError( - 'You can only create a new `Draft` from a corresponding ' - '`UpdateDraftMessage` object.' - ) + def _from_dialog(cls, client, dialog): + return cls(client=client, peer=dialog.dialog.peer, + draft=dialog.dialog.draft, entity=dialog.entity) - return cls(client=client, peer=update.peer, draft=update.draft) + @classmethod + def _from_update(cls, client, update, entities=None): + assert isinstance(update, UpdateDraftMessage) + return cls(client=client, peer=update.peer, draft=update.draft, + entity=(entities or {}).get(get_peer_id(update.peer))) @property - async def entity(self): + def entity(self): """ The entity that belongs to this dialog (user, chat or channel). """ - return await self._client.get_entity(self._peer) + return self._entity @property - async def input_entity(self): + def input_entity(self): """ Input version of the entity. """ - return await self._client.get_input_entity(self._peer) + if not self._input_entity: + try: + self._input_entity =\ + self._client.session.get_input_entity(self._peer) + except ValueError: + pass + + return self._input_entity + + async def get_entity(self): + """ + Returns `entity` but will make an API call if necessary. + """ + if not self.entity and await self.get_input_entity(): + try: + self._entity =\ + self._client.get_entity(self._input_entity) + except ValueError: + pass + + return self._entity + + async def get_input_entity(self): + """ + Returns `input_entity` but will make an API call if necessary. + """ + # We don't actually have an API call we can make yet + # to get more info, but keep this method for consistency. + return self.input_entity @property def text(self):