Adapt the rest of the library to layer 119

This commit is contained in:
Lonami Exo 2020-10-01 12:22:55 +02:00
parent 62737c1caf
commit d5e4398ace
14 changed files with 78 additions and 98 deletions

View File

@ -60,7 +60,7 @@ class _DialogsIter(RequestIter):
messages = {}
for m in r.messages:
m._finish_init(self.client, entities, None)
messages[_dialog_message_key(m.to_id, m.id)] = m
messages[_dialog_message_key(m.peer_id, m.id)] = m
for d in r.dialogs:
# We check the offset date here because Telegram may ignore it

View File

@ -157,7 +157,7 @@ class MessageParseMethods:
elif (isinstance(update, types.UpdateEditChannelMessage)
and utils.get_peer_id(request.peer) ==
utils.get_peer_id(update.message.to_id)):
utils.get_peer_id(update.message.peer_id)):
if request.id == update.message.id:
update.message._finish_init(self, entities, input_chat)
return update.message
@ -170,7 +170,7 @@ class MessageParseMethods:
if request.media.poll.id == update.poll_id:
m = types.Message(
id=request.id,
to_id=utils.get_peer(request.peer),
peer_id=utils.get_peer(request.peer),
media=types.MessageMediaPoll(
poll=update.poll,
results=update.results

View File

@ -1,6 +1,7 @@
import inspect
import itertools
import typing
import warnings
from .. import helpers, utils, errors, hints
from ..requestiter import RequestIter
@ -62,7 +63,7 @@ class _MessagesIter(RequestIter):
from_user = None # Ignore from_user unless it's a user
if from_user:
self.from_id = await self.client.get_peer_id(from_user)
self.from_id = utils.get_peer(from_user)
else:
self.from_id = None
@ -76,7 +77,9 @@ class _MessagesIter(RequestIter):
if not self.entity:
self.request = functions.messages.SearchGlobalRequest(
q=search or '',
offset_rate=offset_date,
min_date=None,
max_date=offset_date,
offset_rate=None,
offset_peer=types.InputPeerEmpty(),
offset_id=offset_id,
limit=1
@ -270,7 +273,7 @@ class _IDsIter(RequestIter):
else:
r = await self.client(functions.messages.GetMessagesRequest(ids))
if self._entity:
from_id = await self.client.get_peer_id(self._entity)
from_id = utils.get_peer(self._entity)
if isinstance(r, types.messages.MessagesNotModified):
self.buffer.extend(None for _ in ids)
@ -289,7 +292,7 @@ class _IDsIter(RequestIter):
# arbitrary chats. Validate these unless ``from_id is None``.
for message in r.messages:
if isinstance(message, types.MessageEmpty) or (
from_id and message.chat_id != from_id):
from_id and message.peer_id != from_id):
self.buffer.append(None)
else:
message._finish_init(self.client, entities, self._entity)
@ -753,7 +756,7 @@ class MessageMethods:
if isinstance(result, types.UpdateShortSentMessage):
message = types.Message(
id=result.id,
to_id=utils.get_peer(entity),
peer_id=utils.get_peer(entity),
message=message,
date=result.date,
out=result.out,
@ -805,15 +808,7 @@ class MessageMethods:
this behaviour.
as_album (`bool`, optional):
Whether several image messages should be forwarded as an
album (grouped) or not. The default behaviour is to treat
albums specially and send outgoing requests with
``as_album=True`` only for the albums if message objects
are used. If IDs are used it will group by default.
In short, the default should do what you expect,
`True` will group always (even converting separate
images into albums), and `False` will never group.
This flag no longer has any effect.
schedule (`hints.DateLike`, optional):
If set, the message(s) won't forward immediately, and
@ -846,6 +841,9 @@ class MessageMethods:
# Forwarding as a copy
await client.send_message(chat, message)
"""
if as_album is not None:
warnings.warn('the as_album argument is deprecated and no longer has any effect')
single = not utils.is_list_like(messages)
if single:
messages = (messages,)
@ -858,44 +856,24 @@ class MessageMethods:
else:
from_peer_id = None
def _get_key(m):
def get_key(m):
if isinstance(m, int):
if from_peer_id is not None:
return from_peer_id, None
return from_peer_id
raise ValueError('from_peer must be given if integer IDs are used')
elif isinstance(m, types.Message):
return m.chat_id, m.grouped_id
return m.chat_id
else:
raise TypeError('Cannot forward messages of type {}'.format(type(m)))
# We want to group outgoing chunks differently if we are "smart"
# about sending as album.
#
# Why? We need separate requests for ``as_album=True/False``, so
# if we want that behaviour, when we group messages to create the
# chunks, we need to consider the grouped ID too. But if we don't
# care about that, we don't need to consider it for creating the
# chunks, so we can make less requests.
if as_album is None:
get_key = _get_key
else:
def get_key(m):
return _get_key(m)[0] # Ignore grouped_id
sent = []
for chat_id, chunk in itertools.groupby(messages, key=get_key):
for _chat_id, chunk in itertools.groupby(messages, key=get_key):
chunk = list(chunk)
if isinstance(chunk[0], int):
chat = from_peer
grouped = True if as_album is None else as_album
else:
chat = await chunk[0].get_input_chat()
if as_album is None:
grouped = any(m.grouped_id is not None for m in chunk)
else:
grouped = as_album
chunk = [m.id for m in chunk]
req = functions.messages.ForwardMessagesRequest(
@ -903,10 +881,6 @@ class MessageMethods:
id=chunk,
to_peer=entity,
silent=silent,
# Trying to send a single message as grouped will cause
# GROUPED_MEDIA_INVALID. If more than one message is forwarded
# (even without media...), this error goes away.
grouped=len(chunk) > 1 and grouped,
schedule_date=schedule
)
result = await self(req)
@ -1018,7 +992,7 @@ class MessageMethods:
elif isinstance(entity, types.Message):
text = message # Shift the parameters to the right
message = entity
entity = entity.to_id
entity = entity.peer_id
text, msg_entities = await self._parse_message_text(text, parse_mode)
file_handle, media, image = await self._file_to_media(file,

View File

@ -127,12 +127,12 @@ class EntityCache:
if cid in has_message:
x = update.message
y = getattr(x, 'to_id', None) # handle MessageEmpty
y = getattr(x, 'peer_id', None) # handle MessageEmpty
if y and utils.get_peer_id(y) not in dct:
return False
y = getattr(x, 'from_id', None)
if y and y not in dct:
if y and utils.get_peer_id(y) not in dct:
return False
# We don't quite worry about entities anywhere else.

View File

@ -150,12 +150,12 @@ class Album(EventBuilder):
"""
def __init__(self, messages):
message = messages[0]
if not message.out and isinstance(message.to_id, types.PeerUser):
# Incoming message (e.g. from a bot) has to_id=us, and
if not message.out and isinstance(message.peer_id, types.PeerUser):
# Incoming message (e.g. from a bot) has peer_id=us, and
# from_id=bot (the actual "chat" from a user's perspective).
chat_peer = types.PeerUser(message.from_id)
chat_peer = message.from_id
else:
chat_peer = message.to_id
chat_peer = message.peer_id
super().__init__(chat_peer=chat_peer,
msg_id=message.id, broadcast=bool(message.post))

View File

@ -78,7 +78,7 @@ class ChatAction(EventBuilder):
users=msg.from_id)
elif isinstance(action, types.MessageActionChatAddUser):
# If a user adds itself, it means they joined
added_by = ([msg.from_id] == action.users) or msg.from_id
added_by = ([utils.get_peer_id(msg.from_id)] == action.users) or msg.from_id
return cls.Event(msg,
added_by=added_by,
users=action.users)
@ -108,12 +108,12 @@ class ChatAction(EventBuilder):
return cls.Event(msg,
users=msg.from_id,
new_photo=True)
elif isinstance(action, types.MessageActionPinMessage) and msg.reply_to_msg_id:
elif isinstance(action, types.MessageActionPinMessage) and msg.reply_to:
# Seems to not be reliable on unpins, but when pinning
# we prefer this because we know who caused it.
return cls.Event(msg,
users=msg.from_id,
new_pin=msg.reply_to_msg_id)
new_pin=msg.reply_to.reply_to_msg_id)
class Event(EventCommon):
"""
@ -158,7 +158,7 @@ class ChatAction(EventBuilder):
users=None, new_title=None, unpin=None):
if isinstance(where, types.MessageService):
self.action_message = where
where = where.to_id
where = where.peer_id
else:
self.action_message = None
@ -193,9 +193,9 @@ class ChatAction(EventBuilder):
self.created = bool(created)
if isinstance(users, list):
self._user_ids = users
self._user_ids = [utils.get_peer_id(u) for u in users]
elif users:
self._user_ids = [users]
self._user_ids = [utils.get_peer_id(users)]
else:
self._user_ids = []

View File

@ -1,6 +1,7 @@
import re
from .common import EventBuilder, EventCommon, name_inner_event, _into_id_set
from .. import utils
from ..tl import types
@ -106,15 +107,15 @@ class NewMessage(EventBuilder):
media_unread=update.media_unread,
silent=update.silent,
id=update.id,
# Note that to_id/from_id complement each other in private
# Note that peer_id/from_id complement each other in private
# messages, depending on whether the message was outgoing.
to_id=types.PeerUser(update.user_id if update.out else self_id),
from_id=self_id if update.out else update.user_id,
peer_id=types.PeerUser(update.user_id if update.out else self_id),
from_id=types.PeerUser(self_id if update.out else update.user_id),
message=update.message,
date=update.date,
fwd_from=update.fwd_from,
via_bot_id=update.via_bot_id,
reply_to_msg_id=update.reply_to_msg_id,
reply_to=update.reply_to,
entities=update.entities
))
elif isinstance(update, types.UpdateShortChatMessage):
@ -124,13 +125,13 @@ class NewMessage(EventBuilder):
media_unread=update.media_unread,
silent=update.silent,
id=update.id,
from_id=update.from_id,
to_id=types.PeerChat(update.chat_id),
from_id=types.PeerUser(update.from_id),
peer_id=types.PeerChat(update.chat_id),
message=update.message,
date=update.date,
fwd_from=update.fwd_from,
via_bot_id=update.via_bot_id,
reply_to_msg_id=update.reply_to_msg_id,
reply_to=update.reply_to,
entities=update.entities
))
else:
@ -139,8 +140,8 @@ class NewMessage(EventBuilder):
# Make messages sent to ourselves outgoing unless they're forwarded.
# This makes it consistent with official client's appearance.
ori = event.message
if isinstance(ori.to_id, types.PeerUser):
if ori.from_id == ori.to_id.user_id and not ori.fwd_from:
if isinstance(ori.peer_id, types.PeerUser):
if ori.from_id == ori.peer_id and not ori.fwd_from:
event.message.out = True
return event
@ -158,7 +159,7 @@ class NewMessage(EventBuilder):
return
if self.from_users is not None:
if event.message.from_id not in self.from_users:
if utils.get_peer_id(event.message.from_id) not in self.from_users:
return
if self.pattern:
@ -204,12 +205,12 @@ class NewMessage(EventBuilder):
"""
def __init__(self, message):
self.__dict__['_init'] = False
if not message.out and isinstance(message.to_id, types.PeerUser):
# Incoming message (e.g. from a bot) has to_id=us, and
if not message.out and isinstance(message.peer_id, types.PeerUser):
# Incoming message (e.g. from a bot) has peer_id=us, and
# from_id=bot (the actual "chat" from a user's perspective).
chat_peer = types.PeerUser(message.from_id)
chat_peer = message.from_id
else:
chat_peer = message.to_id
chat_peer = message.peer_id
super().__init__(chat_peer=chat_peer,
msg_id=message.id, broadcast=bool(message.post))

View File

@ -134,10 +134,10 @@ class StateCache:
if cid in has_channel_id:
return update.channel_id
elif cid in has_message:
if update.message.to_id is None:
self._logger.info('Update has None to_id %s', update)
if update.message.peer_id is None:
self._logger.info('Update has None peer_id %s', update)
else:
return update.message.to_id.channel_id
return update.message.peer_id.channel_id
return None

View File

@ -95,7 +95,7 @@ class ChatGetter(abc.ABC):
def chat_id(self):
"""
Returns the marked chat integer ID. Note that this value **will
be different** from ``to_id`` for incoming private messages, since
be different** from ``peer_id`` for incoming private messages, since
the chat *to* which the messages go is to your own person, but
the *chat* itself is with the one who sent the message.

View File

@ -165,7 +165,7 @@ class Conversation(ChatGetter):
"""
return self._get_message(
message, self._reply_indices, self._pending_replies, timeout,
lambda x, y: x.reply_to_msg_id == y
lambda x, y: x.reply_to and x.reply_to.reply_to_msg_id == y
)
def _get_message(
@ -374,7 +374,7 @@ class Conversation(ChatGetter):
del self._pending_responses[msg_id]
for msg_id, future in list(self._pending_replies.items()):
if msg_id == response.reply_to_msg_id:
if response.reply_to and msg_id == response.reply_to.reply_to_msg_id:
self._reply_indices[msg_id] = len(self._incoming)
future.set_result(response)
del self._pending_replies[msg_id]

View File

@ -1,6 +1,6 @@
from .chatgetter import ChatGetter
from .sendergetter import SenderGetter
from ... import utils
from ... import utils, helpers
from ...tl import types
@ -30,19 +30,24 @@ class Forward(ChatGetter, SenderGetter):
self.__dict__.update(original.__dict__)
self.original_fwd = original
sender, input_sender = utils._get_entity_pair(
original.from_id, entities, client._entity_cache)
if not original.channel_id:
peer = chat = input_chat = None
sender_id = sender = input_sender = peer = chat = input_chat = None
if not original.from_id:
pass
else:
peer = types.PeerChannel(original.channel_id)
ty = helpers._entity_type(original.from_id)
if ty == helpers._EntityType.USER:
sender_id = utils.get_peer_id(original.from_id)
sender, input_sender = utils._get_entity_pair(
sender_id, entities, client._entity_cache)
elif ty in (helpers._EntityType.CHAT, helpers._EntityType.CHANNEL):
peer = original.from_id
chat, input_chat = utils._get_entity_pair(
utils.get_peer_id(peer), entities, client._entity_cache)
# This call resets the client
ChatGetter.__init__(self, peer, chat=chat, input_chat=input_chat)
SenderGetter.__init__(self, original.from_id, sender=sender, input_sender=input_sender)
SenderGetter.__init__(self, sender_id, sender=sender, input_sender=input_sender)
self._client = client
# TODO We could reload the message

View File

@ -85,7 +85,7 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
The peer who sent this message, which is either
:tl:`PeerUser`, :tl:`PeerChat` or :tl:`PeerChannel`.
reply_to (`int`):
reply_to (:tl:`MessageReplyHeader`):
The original reply header if this message is replying to another.
fwd_from (:tl:`MessageFwdHeader`):
@ -210,15 +210,15 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
self._action_entities = None
if not out and isinstance(peer_id, types.PeerUser):
chat_peer = types.PeerUser(from_id)
if from_id == peer_id.user_id:
chat_peer = from_id
if from_id == peer_id:
self.out = not self.fwd_from # Patch out in our chat
else:
chat_peer = peer_id
# Note that these calls would reset the client
ChatGetter.__init__(self, chat_peer, broadcast=post)
SenderGetter.__init__(self, from_id)
SenderGetter.__init__(self, utils.get_peer_id(from_id) if from_id else None)
if post and not from_id and chat_peer:
# If the message comes from a Channel, let the sender be it
@ -329,10 +329,10 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
`True` if the message is a reply to some other message.
Remember that you can access the ID of the message
this one is replying to through `reply_to_msg_id`,
this one is replying to through `reply_to.reply_to_msg_id`,
and the `Message` object with `get_reply_message()`.
"""
return bool(self.reply_to_msg_id)
return self.reply_to is not None
@property
def forward(self):
@ -647,7 +647,7 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
The result will be cached after its first use.
"""
if self._reply_message is None and self._client:
if not self.reply_to_msg_id:
if not self.reply_to:
return None
# Bots cannot access other bots' messages by their ID.
@ -663,7 +663,7 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
# directly by its ID.
self._reply_message = await self._client.get_messages(
self._input_chat if self.is_channel else None,
ids=self.reply_to_msg_id
ids=self.reply_to.reply_to_msg_id
)
return self._reply_message

View File

@ -76,7 +76,7 @@ async def handler(event):
# If we sent the message, we are replying to someone,
# and we said "save pic" in the message
if event.out and event.reply_to_msg_id and 'save pic' in event.raw_text:
if event.out and event.is_reply and 'save pic' in event.raw_text:
reply_msg = await event.get_reply_message()
replied_to_user = await reply_msg.get_input_sender()

View File

@ -156,7 +156,7 @@ class TLArg:
# treated as a "date" object. Note that this is not a valid
# Telegram object, but it's easier to work with
if self.type == 'int' and (
re.search(r'(\b|_)([dr]ate|until|since)(\b|_)', name) or
re.search(r'(\b|_)(date|until|since)(\b|_)', name) or
name in ('expires', 'expires_at', 'was_online')):
self.type = 'date'