Telethon/telethon/tl/custom/sendergetter.py

101 lines
3.7 KiB
Python
Raw Normal View History

2018-07-10 16:15:22 +03:00
import abc
class SenderGetter(abc.ABC):
"""
Helper base class that introduces the `sender`, `input_sender`
and `sender_id` properties and `get_sender` and `get_input_sender`
methods.
"""
2019-05-12 15:00:12 +03:00
def __init__(self, sender_id=None, *, sender=None, input_sender=None):
self._sender_id = sender_id
self._sender = sender
self._input_sender = input_sender
self._client = None
2019-05-03 14:59:17 +03:00
2018-07-10 16:15:22 +03:00
@property
def sender(self):
"""
Returns the :tl:`User` or :tl:`Channel` that sent this object.
It may be `None` if Telegram didn't send the sender.
2018-07-10 16:15:22 +03:00
If you only need the ID, use `sender_id` instead.
If you need to call a method which needs
this chat, use `input_sender` instead.
If you're using `telethon.events`, use `get_sender()` instead.
2018-07-10 16:15:22 +03:00
"""
return self._sender
async def get_sender(self):
"""
Returns `sender`, but will make an API call to find the
sender unless it's already cached.
If you only need the ID, use `sender_id` instead.
If you need to call a method which needs
this sender, use `get_input_sender()` instead.
2018-07-10 16:15:22 +03:00
"""
# ``sender.min`` is present both in :tl:`User` and :tl:`Channel`.
# It's a flag that will be set if only minimal information is
# available (such as display name, but username may be missing),
# in which case we want to force fetch the entire thing because
# the user explicitly called a method. If the user is okay with
# cached information, they may use the property instead.
if (self._sender is None or getattr(self._sender, 'min', None)) \
and await self.get_input_sender():
# self.get_input_sender may refresh in which case the sender may no longer be min
# However it could still incur a cost so the cheap check is done twice instead.
if self._sender is None or getattr(self._sender, 'min', None):
try:
self._sender =\
await self._client.get_entity(self._input_sender)
except ValueError:
await self._refetch_sender()
2018-07-10 16:15:22 +03:00
return self._sender
@property
def input_sender(self):
"""
This :tl:`InputPeer` is the input version of the user/channel who
sent the message. Similarly to `input_chat
<telethon.tl.custom.chatgetter.ChatGetter.input_chat>`, this doesn't
have things like username or similar, but still useful in some cases.
2018-07-10 16:15:22 +03:00
Note that this might not be available if the library can't
find the input chat, or if the message a broadcast on a channel.
"""
if self._input_sender is None and self._sender_id and self._client:
2018-07-10 16:15:22 +03:00
try:
2019-05-02 19:51:10 +03:00
self._input_sender = \
self._client._entity_cache[self._sender_id]
except KeyError:
2018-07-10 16:15:22 +03:00
pass
return self._input_sender
async def get_input_sender(self):
"""
Returns `input_sender`, but will make an API call to find the
input sender unless it's already cached.
"""
if self.input_sender is None and self._sender_id and self._client:
2018-07-10 16:15:22 +03:00
await self._refetch_sender()
return self._input_sender
@property
def sender_id(self):
"""
Returns the marked sender integer ID, if present.
If there is a sender in the object, `sender_id` will *always* be set,
which is why you should use it instead of `sender.id <sender>`.
2018-07-10 16:15:22 +03:00
"""
return self._sender_id
async def _refetch_sender(self):
"""
Re-fetches sender information through other means.
"""