Begin unification of event builders and events

This commit is contained in:
Lonami Exo
2022-01-28 11:34:16 +01:00
parent f2ef0bfceb
commit 9726169a8c
15 changed files with 1142 additions and 1719 deletions

View File

@@ -1,7 +1,7 @@
import datetime
import functools
from .common import EventBuilder, EventCommon, name_inner_event
from .base import EventBuilder
from .._misc import utils
from .. import _tl
from ..types import _custom
@@ -32,11 +32,25 @@ def _requires_status(function):
return wrapped
@name_inner_event
class UserUpdate(EventBuilder):
class UserUpdateEvent(EventBuilder, _custom.chatgetter.ChatGetter, _custom.sendergetter.SenderGetter):
"""
Occurs whenever a user goes online, starts typing, etc.
Members:
status (:tl:`UserStatus`, optional):
The user status if the update is about going online or offline.
You should check this attribute first before checking any
of the seen within properties, since they will all be `None`
if the status is not set.
action (:tl:`SendMessageAction`, optional):
The "typing" action if any the user is performing if any.
You should check this attribute first before checking any
of the typing properties, since they will all be `None`
if the action is not set.
Example
.. code-block:: python
@@ -48,262 +62,242 @@ class UserUpdate(EventBuilder):
if event.uploading:
await client.send_message(event.user_id, 'What are you sending?')
"""
def __init__(self, peer, *, status=None, chat_peer=None, typing=None):
_custom.chatgetter.ChatGetter.__init__(self, chat_peer or peer)
_custom.sendergetter.SenderGetter.__init__(self, utils.get_peer_id(peer))
self.status = status
self.action = typing
@classmethod
def build(cls, update, others=None, self_id=None, *todo, **todo2):
def _build(cls, update, others=None, self_id=None, *todo, **todo2):
if isinstance(update, _tl.UpdateUserStatus):
return cls.Event(_tl.PeerUser(update.user_id),
return UserUpdateEvent(_tl.PeerUser(update.user_id),
status=update.status)
elif isinstance(update, _tl.UpdateChannelUserTyping):
return cls.Event(update.from_id,
return UserUpdateEvent(update.from_id,
chat_peer=_tl.PeerChannel(update.channel_id),
typing=update.action)
elif isinstance(update, _tl.UpdateChatUserTyping):
return cls.Event(update.from_id,
return UserUpdateEvent(update.from_id,
chat_peer=_tl.PeerChat(update.chat_id),
typing=update.action)
elif isinstance(update, _tl.UpdateUserTyping):
return cls.Event(update.user_id,
return UserUpdateEvent(update.user_id,
typing=update.action)
class Event(EventCommon, _custom.sendergetter.SenderGetter):
def _set_client(self, client):
super()._set_client(client)
self._sender, self._input_sender = utils._get_entity_pair(self.sender_id, self._entities)
@property
def user(self):
"""Alias for `sender <telethon.tl.custom.sendergetter.SenderGetter.sender>`."""
return self.sender
async def get_user(self):
"""Alias for `get_sender <telethon.tl.custom.sendergetter.SenderGetter.get_sender>`."""
return await self.get_sender()
@property
def input_user(self):
"""Alias for `input_sender <telethon.tl.custom.sendergetter.SenderGetter.input_sender>`."""
return self.input_sender
async def get_input_user(self):
"""Alias for `get_input_sender <telethon.tl.custom.sendergetter.SenderGetter.get_input_sender>`."""
return await self.get_input_sender()
@property
def user_id(self):
"""Alias for `sender_id <telethon.tl.custom.sendergetter.SenderGetter.sender_id>`."""
return self.sender_id
@property
@_requires_action
def typing(self):
"""
Represents the event of a user update
such as gone online, started typing, etc.
Members:
status (:tl:`UserStatus`, optional):
The user status if the update is about going online or offline.
You should check this attribute first before checking any
of the seen within properties, since they will all be `None`
if the status is not set.
action (:tl:`SendMessageAction`, optional):
The "typing" action if any the user is performing if any.
You should check this attribute first before checking any
of the typing properties, since they will all be `None`
if the action is not set.
`True` if the action is typing a message.
"""
def __init__(self, peer, *, status=None, chat_peer=None, typing=None):
super().__init__(chat_peer or peer)
_custom.sendergetter.SenderGetter.__init__(self, utils.get_peer_id(peer))
return isinstance(self.action, _tl.SendMessageTypingAction)
self.status = status
self.action = typing
@property
@_requires_action
def uploading(self):
"""
`True` if the action is uploading something.
"""
return isinstance(self.action, (
_tl.SendMessageChooseContactAction,
_tl.SendMessageChooseStickerAction,
_tl.SendMessageUploadAudioAction,
_tl.SendMessageUploadDocumentAction,
_tl.SendMessageUploadPhotoAction,
_tl.SendMessageUploadRoundAction,
_tl.SendMessageUploadVideoAction
))
def _set_client(self, client):
super()._set_client(client)
self._sender, self._input_sender = utils._get_entity_pair(self.sender_id, self._entities)
@property
@_requires_action
def recording(self):
"""
`True` if the action is recording something.
"""
return isinstance(self.action, (
_tl.SendMessageRecordAudioAction,
_tl.SendMessageRecordRoundAction,
_tl.SendMessageRecordVideoAction
))
@property
def user(self):
"""Alias for `sender <telethon.tl.custom.sendergetter.SenderGetter.sender>`."""
return self.sender
@property
@_requires_action
def playing(self):
"""
`True` if the action is playing a game.
"""
return isinstance(self.action, _tl.SendMessageGamePlayAction)
async def get_user(self):
"""Alias for `get_sender <telethon.tl.custom.sendergetter.SenderGetter.get_sender>`."""
return await self.get_sender()
@property
@_requires_action
def cancel(self):
"""
`True` if the action was cancelling other actions.
"""
return isinstance(self.action, _tl.SendMessageCancelAction)
@property
def input_user(self):
"""Alias for `input_sender <telethon.tl.custom.sendergetter.SenderGetter.input_sender>`."""
return self.input_sender
@property
@_requires_action
def geo(self):
"""
`True` if what's being uploaded is a geo.
"""
return isinstance(self.action, _tl.SendMessageGeoLocationAction)
async def get_input_user(self):
"""Alias for `get_input_sender <telethon.tl.custom.sendergetter.SenderGetter.get_input_sender>`."""
return await self.get_input_sender()
@property
@_requires_action
def audio(self):
"""
`True` if what's being recorded/uploaded is an audio.
"""
return isinstance(self.action, (
_tl.SendMessageRecordAudioAction,
_tl.SendMessageUploadAudioAction
))
@property
def user_id(self):
"""Alias for `sender_id <telethon.tl.custom.sendergetter.SenderGetter.sender_id>`."""
return self.sender_id
@property
@_requires_action
def round(self):
"""
`True` if what's being recorded/uploaded is a round video.
"""
return isinstance(self.action, (
_tl.SendMessageRecordRoundAction,
_tl.SendMessageUploadRoundAction
))
@property
@_requires_action
def typing(self):
"""
`True` if the action is typing a message.
"""
return isinstance(self.action, _tl.SendMessageTypingAction)
@property
@_requires_action
def video(self):
"""
`True` if what's being recorded/uploaded is an video.
"""
return isinstance(self.action, (
_tl.SendMessageRecordVideoAction,
_tl.SendMessageUploadVideoAction
))
@property
@_requires_action
def uploading(self):
"""
`True` if the action is uploading something.
"""
return isinstance(self.action, (
_tl.SendMessageChooseContactAction,
_tl.SendMessageChooseStickerAction,
_tl.SendMessageUploadAudioAction,
_tl.SendMessageUploadDocumentAction,
_tl.SendMessageUploadPhotoAction,
_tl.SendMessageUploadRoundAction,
_tl.SendMessageUploadVideoAction
))
@property
@_requires_action
def contact(self):
"""
`True` if what's being uploaded (selected) is a contact.
"""
return isinstance(self.action, _tl.SendMessageChooseContactAction)
@property
@_requires_action
def recording(self):
"""
`True` if the action is recording something.
"""
return isinstance(self.action, (
_tl.SendMessageRecordAudioAction,
_tl.SendMessageRecordRoundAction,
_tl.SendMessageRecordVideoAction
))
@property
@_requires_action
def document(self):
"""
`True` if what's being uploaded is document.
"""
return isinstance(self.action, _tl.SendMessageUploadDocumentAction)
@property
@_requires_action
def playing(self):
"""
`True` if the action is playing a game.
"""
return isinstance(self.action, _tl.SendMessageGamePlayAction)
@property
@_requires_action
def sticker(self):
"""
`True` if what's being uploaded is a sticker.
"""
return isinstance(self.action, _tl.SendMessageChooseStickerAction)
@property
@_requires_action
def cancel(self):
"""
`True` if the action was cancelling other actions.
"""
return isinstance(self.action, _tl.SendMessageCancelAction)
@property
@_requires_action
def photo(self):
"""
`True` if what's being uploaded is a photo.
"""
return isinstance(self.action, _tl.SendMessageUploadPhotoAction)
@property
@_requires_action
def geo(self):
"""
`True` if what's being uploaded is a geo.
"""
return isinstance(self.action, _tl.SendMessageGeoLocationAction)
@property
@_requires_action
def last_seen(self):
"""
Exact `datetime.datetime` when the user was last seen if known.
"""
if isinstance(self.status, _tl.UserStatusOffline):
return self.status.was_online
@property
@_requires_action
def audio(self):
"""
`True` if what's being recorded/uploaded is an audio.
"""
return isinstance(self.action, (
_tl.SendMessageRecordAudioAction,
_tl.SendMessageUploadAudioAction
))
@property
@_requires_status
def until(self):
"""
The `datetime.datetime` until when the user should appear online.
"""
if isinstance(self.status, _tl.UserStatusOnline):
return self.status.expires
@property
@_requires_action
def round(self):
"""
`True` if what's being recorded/uploaded is a round video.
"""
return isinstance(self.action, (
_tl.SendMessageRecordRoundAction,
_tl.SendMessageUploadRoundAction
))
def _last_seen_delta(self):
if isinstance(self.status, _tl.UserStatusOffline):
return datetime.datetime.now(tz=datetime.timezone.utc) - self.status.was_online
elif isinstance(self.status, _tl.UserStatusOnline):
return datetime.timedelta(days=0)
elif isinstance(self.status, _tl.UserStatusRecently):
return datetime.timedelta(days=1)
elif isinstance(self.status, _tl.UserStatusLastWeek):
return datetime.timedelta(days=7)
elif isinstance(self.status, _tl.UserStatusLastMonth):
return datetime.timedelta(days=30)
else:
return datetime.timedelta(days=365)
@property
@_requires_action
def video(self):
"""
`True` if what's being recorded/uploaded is an video.
"""
return isinstance(self.action, (
_tl.SendMessageRecordVideoAction,
_tl.SendMessageUploadVideoAction
))
@property
@_requires_status
def online(self):
"""
`True` if the user is currently online,
"""
return self._last_seen_delta() <= datetime.timedelta(days=0)
@property
@_requires_action
def contact(self):
"""
`True` if what's being uploaded (selected) is a contact.
"""
return isinstance(self.action, _tl.SendMessageChooseContactAction)
@property
@_requires_status
def recently(self):
"""
`True` if the user was seen within a day.
"""
return self._last_seen_delta() <= datetime.timedelta(days=1)
@property
@_requires_action
def document(self):
"""
`True` if what's being uploaded is document.
"""
return isinstance(self.action, _tl.SendMessageUploadDocumentAction)
@property
@_requires_status
def within_weeks(self):
"""
`True` if the user was seen within 7 days.
"""
return self._last_seen_delta() <= datetime.timedelta(days=7)
@property
@_requires_action
def sticker(self):
"""
`True` if what's being uploaded is a sticker.
"""
return isinstance(self.action, _tl.SendMessageChooseStickerAction)
@property
@_requires_action
def photo(self):
"""
`True` if what's being uploaded is a photo.
"""
return isinstance(self.action, _tl.SendMessageUploadPhotoAction)
@property
@_requires_action
def last_seen(self):
"""
Exact `datetime.datetime` when the user was last seen if known.
"""
if isinstance(self.status, _tl.UserStatusOffline):
return self.status.was_online
@property
@_requires_status
def until(self):
"""
The `datetime.datetime` until when the user should appear online.
"""
if isinstance(self.status, _tl.UserStatusOnline):
return self.status.expires
def _last_seen_delta(self):
if isinstance(self.status, _tl.UserStatusOffline):
return datetime.datetime.now(tz=datetime.timezone.utc) - self.status.was_online
elif isinstance(self.status, _tl.UserStatusOnline):
return datetime.timedelta(days=0)
elif isinstance(self.status, _tl.UserStatusRecently):
return datetime.timedelta(days=1)
elif isinstance(self.status, _tl.UserStatusLastWeek):
return datetime.timedelta(days=7)
elif isinstance(self.status, _tl.UserStatusLastMonth):
return datetime.timedelta(days=30)
else:
return datetime.timedelta(days=365)
@property
@_requires_status
def online(self):
"""
`True` if the user is currently online,
"""
return self._last_seen_delta() <= datetime.timedelta(days=0)
@property
@_requires_status
def recently(self):
"""
`True` if the user was seen within a day.
"""
return self._last_seen_delta() <= datetime.timedelta(days=1)
@property
@_requires_status
def within_weeks(self):
"""
`True` if the user was seen within 7 days.
"""
return self._last_seen_delta() <= datetime.timedelta(days=7)
@property
@_requires_status
def within_months(self):
"""
`True` if the user was seen within 30 days.
"""
return self._last_seen_delta() <= datetime.timedelta(days=30)
@property
@_requires_status
def within_months(self):
"""
`True` if the user was seen within 30 days.
"""
return self._last_seen_delta() <= datetime.timedelta(days=30)