Add async/await on tl.custom

This commit is contained in:
Lonami Exo 2018-06-10 20:29:57 +02:00
parent 1bde72d375
commit d462b04a9c
4 changed files with 78 additions and 68 deletions

View File

@ -88,12 +88,13 @@ class Dialog:
) )
self.is_channel = isinstance(self.entity, types.Channel) self.is_channel = isinstance(self.entity, types.Channel)
def send_message(self, *args, **kwargs): async def send_message(self, *args, **kwargs):
""" """
Sends a message to this dialog. This is just a wrapper around Sends a message to this dialog. This is just a wrapper around
``client.send_message(dialog.input_entity, *args, **kwargs)``. ``client.send_message(dialog.input_entity, *args, **kwargs)``.
""" """
return self._client.send_message(self.input_entity, *args, **kwargs) return await self._client.send_message(
self.input_entity, *args, **kwargs)
def to_dict(self): def to_dict(self):
return { return {

View File

@ -47,18 +47,18 @@ class Draft:
return cls(client=client, peer=update.peer, draft=update.draft) return cls(client=client, peer=update.peer, draft=update.draft)
@property @property
def entity(self): async def entity(self):
""" """
The entity that belongs to this dialog (user, chat or channel). The entity that belongs to this dialog (user, chat or channel).
""" """
return self._client.get_entity(self._peer) return await self._client.get_entity(self._peer)
@property @property
def input_entity(self): async def input_entity(self):
""" """
Input version of the entity. Input version of the entity.
""" """
return self._client.get_input_entity(self._peer) return await self._client.get_input_entity(self._peer)
@property @property
def text(self): def text(self):
@ -83,8 +83,9 @@ class Draft:
""" """
return not self._text return not self._text
def set_message(self, text=None, reply_to=0, parse_mode=Default, async def set_message(
link_preview=None): self, text=None, reply_to=0, parse_mode=Default,
link_preview=None):
""" """
Changes the draft message on the Telegram servers. The changes are Changes the draft message on the Telegram servers. The changes are
reflected in this object. reflected in this object.
@ -110,8 +111,10 @@ class Draft:
if link_preview is None: if link_preview is None:
link_preview = self.link_preview link_preview = self.link_preview
raw_text, entities = self._client._parse_message_text(text, parse_mode) raw_text, entities =\
result = self._client(SaveDraftRequest( await self._client._parse_message_text(text, parse_mode)
result = await self._client(SaveDraftRequest(
peer=self._peer, peer=self._peer,
message=raw_text, message=raw_text,
no_webpage=not link_preview, no_webpage=not link_preview,
@ -128,22 +131,22 @@ class Draft:
return result return result
def send(self, clear=True, parse_mode=Default): async def send(self, clear=True, parse_mode=Default):
""" """
Sends the contents of this draft to the dialog. This is just a Sends the contents of this draft to the dialog. This is just a
wrapper around ``send_message(dialog.input_entity, *args, **kwargs)``. wrapper around ``send_message(dialog.input_entity, *args, **kwargs)``.
""" """
self._client.send_message(self._peer, self.text, await self._client.send_message(
reply_to=self.reply_to_msg_id, self._peer, self.text, reply_to=self.reply_to_msg_id,
link_preview=self.link_preview, link_preview=self.link_preview, parse_mode=parse_mode,
parse_mode=parse_mode, clear_draft=clear
clear_draft=clear) )
def delete(self): async def delete(self):
""" """
Deletes this draft, and returns ``True`` on success. Deletes this draft, and returns ``True`` on success.
""" """
return self.set_message(text='') return await self.set_message(text='')
def to_dict(self): def to_dict(self):
try: try:

View File

@ -134,14 +134,15 @@ class Message:
if isinstance(self.original_message, types.MessageService): if isinstance(self.original_message, types.MessageService):
return self.original_message.action return self.original_message.action
def _reload_message(self): async def _reload_message(self):
""" """
Re-fetches this message to reload the sender and chat entities, Re-fetches this message to reload the sender and chat entities,
along with their input versions. along with their input versions.
""" """
try: try:
chat = self.input_chat if self.is_channel else None chat = await self.input_chat if self.is_channel else None
msg = self._client.get_messages(chat, ids=self.original_message.id) msg = await self._client.get_messages(
chat, ids=self.original_message.id)
except ValueError: except ValueError:
return # We may not have the input chat/get message failed return # We may not have the input chat/get message failed
if not msg: if not msg:
@ -153,7 +154,7 @@ class Message:
self._input_chat = msg._input_chat self._input_chat = msg._input_chat
@property @property
def sender(self): async def sender(self):
""" """
This (:tl:`User`) may make an API call the first time to get This (:tl:`User`) may make an API call the first time to get
the most up to date version of the sender (mostly when the event the most up to date version of the sender (mostly when the event
@ -163,22 +164,24 @@ class Message:
""" """
if self._sender is None: if self._sender is None:
try: try:
self._sender = self._client.get_entity(self.input_sender) self._sender =\
await self._client.get_entity(await self.input_sender)
except ValueError: except ValueError:
self._reload_message() await self._reload_message()
return self._sender return self._sender
@property @property
def chat(self): async def chat(self):
if self._chat is None: if self._chat is None:
try: try:
self._chat = self._client.get_entity(self.input_chat) self._chat =\
await self._client.get_entity(await self.input_chat)
except ValueError: except ValueError:
self._reload_message() await self._reload_message()
return self._chat return self._chat
@property @property
def input_sender(self): async def input_sender(self):
""" """
This (:tl:`InputPeer`) is the input version of the user who This (:tl:`InputPeer`) is the input version of the user who
sent the message. Similarly to `input_chat`, this doesn't have sent the message. Similarly to `input_chat`, this doesn't have
@ -194,14 +197,14 @@ class Message:
self._input_sender = get_input_peer(self._sender) self._input_sender = get_input_peer(self._sender)
else: else:
try: try:
self._input_sender = self._client.get_input_entity( self._input_sender = await self._client.get_input_entity(
self.original_message.from_id) self.original_message.from_id)
except ValueError: except ValueError:
self._reload_message() await self._reload_message()
return self._input_sender return self._input_sender
@property @property
def input_chat(self): async def input_chat(self):
""" """
This (:tl:`InputPeer`) is the input version of the chat where the This (:tl:`InputPeer`) is the input version of the chat where the
message was sent. Similarly to `input_sender`, this doesn't have message was sent. Similarly to `input_sender`, this doesn't have
@ -214,14 +217,14 @@ class Message:
if self._input_chat is None: if self._input_chat is None:
if self._chat is None: if self._chat is None:
try: try:
self._chat = self._client.get_input_entity( self._chat = await self._client.get_input_entity(
self.original_message.to_id) self.original_message.to_id)
except ValueError: except ValueError:
# There's a chance that the chat is a recent new dialog. # There's a chance that the chat is a recent new dialog.
# The input chat cannot rely on ._reload_message() because # The input chat cannot rely on ._reload_message() because
# said method may need the input chat. # said method may need the input chat.
target = self.chat_id target = self.chat_id
for d in self._client.iter_dialogs(100): async for d in self._client.iter_dialogs(100):
if d.id == target: if d.id == target:
self._chat = d.entity self._chat = d.entity
break break
@ -383,7 +386,7 @@ class Message:
return self.original_message.out return self.original_message.out
@property @property
def reply_message(self): async def reply_message(self):
""" """
The `telethon.tl.custom.message.Message` that this message is replying The `telethon.tl.custom.message.Message` that this message is replying
to, or ``None``. to, or ``None``.
@ -394,7 +397,7 @@ class Message:
if self._reply_message is None: if self._reply_message is None:
if not self.original_message.reply_to_msg_id: if not self.original_message.reply_to_msg_id:
return None return None
self._reply_message = self._client.get_messages( self._reply_message = await self._client.get_messages(
self.input_chat if self.is_channel else None, self.input_chat if self.is_channel else None,
ids=self.original_message.reply_to_msg_id ids=self.original_message.reply_to_msg_id
) )
@ -402,7 +405,7 @@ class Message:
return self._reply_message return self._reply_message
@property @property
def fwd_from_entity(self): async def fwd_from_entity(self):
""" """
If the :tl:`Message` is a forwarded message, returns the :tl:`User` If the :tl:`Message` is a forwarded message, returns the :tl:`User`
or :tl:`Channel` who originally sent the message, or ``None``. or :tl:`Channel` who originally sent the message, or ``None``.
@ -411,32 +414,33 @@ class Message:
if getattr(self.original_message, 'fwd_from', None): if getattr(self.original_message, 'fwd_from', None):
fwd = self.original_message.fwd_from fwd = self.original_message.fwd_from
if fwd.from_id: if fwd.from_id:
self._fwd_from_entity = self._client.get_entity( self._fwd_from_entity =\
fwd.from_id) await self._client.get_entity(fwd.from_id)
elif fwd.channel_id: elif fwd.channel_id:
self._fwd_from_entity = self._client.get_entity( self._fwd_from_entity = await self._client.get_entity(
get_peer_id(types.PeerChannel(fwd.channel_id))) get_peer_id(types.PeerChannel(fwd.channel_id)))
return self._fwd_from_entity return self._fwd_from_entity
def respond(self, *args, **kwargs): async def respond(self, *args, **kwargs):
""" """
Responds to the message (not as a reply). Shorthand for Responds to the message (not as a reply). Shorthand for
`telethon.telegram_client.TelegramClient.send_message` with `telethon.telegram_client.TelegramClient.send_message` with
``entity`` already set. ``entity`` already set.
""" """
return self._client.send_message(self.input_chat, *args, **kwargs) return await self._client.send_message(
await self.input_chat, *args, **kwargs)
def reply(self, *args, **kwargs): async def reply(self, *args, **kwargs):
""" """
Replies to the message (as a reply). Shorthand for Replies to the message (as a reply). Shorthand for
`telethon.telegram_client.TelegramClient.send_message` with `telethon.telegram_client.TelegramClient.send_message` with
both ``entity`` and ``reply_to`` already set. both ``entity`` and ``reply_to`` already set.
""" """
kwargs['reply_to'] = self.original_message.id kwargs['reply_to'] = self.original_message.id
return self._client.send_message(self.original_message.to_id, return await self._client.send_message(
*args, **kwargs) await self.input_chat, *args, **kwargs)
def forward_to(self, *args, **kwargs): async def forward_to(self, *args, **kwargs):
""" """
Forwards the message. Shorthand for Forwards the message. Shorthand for
`telethon.telegram_client.TelegramClient.forward_messages` with `telethon.telegram_client.TelegramClient.forward_messages` with
@ -447,10 +451,10 @@ class Message:
`telethon.telegram_client.TelegramClient` instance directly. `telethon.telegram_client.TelegramClient` instance directly.
""" """
kwargs['messages'] = self.original_message.id kwargs['messages'] = self.original_message.id
kwargs['from_peer'] = self.input_chat kwargs['from_peer'] = await self.input_chat
return self._client.forward_messages(*args, **kwargs) return await self._client.forward_messages(*args, **kwargs)
def edit(self, *args, **kwargs): async def edit(self, *args, **kwargs):
""" """
Edits the message iff it's outgoing. Shorthand for Edits the message iff it's outgoing. Shorthand for
`telethon.telegram_client.TelegramClient.edit_message` with `telethon.telegram_client.TelegramClient.edit_message` with
@ -468,10 +472,10 @@ class Message:
if self.original_message.to_id.user_id != me.user_id: if self.original_message.to_id.user_id != me.user_id:
return None return None
return self._client.edit_message( return await self._client.edit_message(
self.input_chat, self.original_message, *args, **kwargs) await self.input_chat, self.original_message, *args, **kwargs)
def delete(self, *args, **kwargs): async def delete(self, *args, **kwargs):
""" """
Deletes the message. You're responsible for checking whether you Deletes the message. You're responsible for checking whether you
have the permission to do so, or to except the error otherwise. have the permission to do so, or to except the error otherwise.
@ -483,17 +487,17 @@ class Message:
this `delete` method. Use a this `delete` method. Use a
`telethon.telegram_client.TelegramClient` instance directly. `telethon.telegram_client.TelegramClient` instance directly.
""" """
return self._client.delete_messages( return await self._client.delete_messages(
self.input_chat, [self.original_message], *args, **kwargs) await self.input_chat, [self.original_message], *args, **kwargs)
def download_media(self, *args, **kwargs): async def download_media(self, *args, **kwargs):
""" """
Downloads the media contained in the message, if any. Downloads the media contained in the message, if any.
`telethon.telegram_client.TelegramClient.download_media` with `telethon.telegram_client.TelegramClient.download_media` with
the ``message`` already set. the ``message`` already set.
""" """
return self._client.download_media(self.original_message, return await self._client.download_media(
*args, **kwargs) self.original_message, *args, **kwargs)
def get_entities_text(self): def get_entities_text(self):
""" """
@ -504,7 +508,7 @@ class Message:
self.original_message.entities) self.original_message.entities)
return list(zip(self.original_message.entities, texts)) return list(zip(self.original_message.entities, texts))
def click(self, i=None, j=None, *, text=None, filter=None): async def click(self, i=None, j=None, *, text=None, filter=None):
""" """
Clicks the inline keyboard button of the message, if any. Clicks the inline keyboard button of the message, if any.
@ -557,25 +561,25 @@ class Message:
if callable(text): if callable(text):
for button in self._buttons_flat: for button in self._buttons_flat:
if text(button.text): if text(button.text):
return button.click() return await button.click()
else: else:
for button in self._buttons_flat: for button in self._buttons_flat:
if button.text == text: if button.text == text:
return button.click() return await button.click()
return return
if filter is not None: if filter is not None:
for button in self._buttons_flat: for button in self._buttons_flat:
if filter(button): if filter(button):
return button.click() return await button.click()
return return
if i is None: if i is None:
i = 0 i = 0
if j is None: if j is None:
return self._buttons_flat[i].click() return await self._buttons_flat[i].click()
else: else:
return self._buttons[i][j].click() return await self._buttons[i][j].click()
class _CustomMessage(Message, types.Message): class _CustomMessage(Message, types.Message):

View File

@ -51,7 +51,7 @@ class MessageButton:
if isinstance(self.button, types.KeyboardButtonUrl): if isinstance(self.button, types.KeyboardButtonUrl):
return self.button.url return self.button.url
def click(self): async def click(self):
""" """
Clicks the inline keyboard button of the message, if any. Clicks the inline keyboard button of the message, if any.
@ -59,15 +59,17 @@ class MessageButton:
send the message, switch to inline, or open its URL. send the message, switch to inline, or open its URL.
""" """
if isinstance(self.button, types.KeyboardButton): if isinstance(self.button, types.KeyboardButton):
return self._client.send_message( return await self._client.send_message(
self._chat, self.button.text, reply_to=self._msg_id) self._chat, self.button.text, reply_to=self._msg_id)
elif isinstance(self.button, types.KeyboardButtonCallback): elif isinstance(self.button, types.KeyboardButtonCallback):
return self._client(functions.messages.GetBotCallbackAnswerRequest( req = functions.messages.GetBotCallbackAnswerRequest(
peer=self._chat, msg_id=self._msg_id, data=self.button.data peer=self._chat, msg_id=self._msg_id, data=self.button.data
), retries=1) )
return await self._client(req, retries=1)
elif isinstance(self.button, types.KeyboardButtonSwitchInline): elif isinstance(self.button, types.KeyboardButtonSwitchInline):
return self._client(functions.messages.StartBotRequest( req = functions.messages.StartBotRequest(
bot=self._from, peer=self._chat, start_param=self.button.query bot=self._from, peer=self._chat, start_param=self.button.query
), retries=1) )
return await self._client(req, retries=1)
elif isinstance(self.button, types.KeyboardButtonUrl): elif isinstance(self.button, types.KeyboardButtonUrl):
return webbrowser.open(self.button.url) return webbrowser.open(self.button.url)