Remove Messages type

This commit is contained in:
Dan 2019-06-08 15:13:52 +02:00
parent 797de058e8
commit cfbc5298df
13 changed files with 100 additions and 221 deletions

View File

@ -40,7 +40,6 @@ Messages & Media
:columns: 5 :columns: 5
- :class:`Message` - :class:`Message`
- :class:`Messages`
- :class:`MessageEntity` - :class:`MessageEntity`
- :class:`Photo` - :class:`Photo`
- :class:`Thumbnail` - :class:`Thumbnail`
@ -125,7 +124,6 @@ Details
.. Messages & Media .. Messages & Media
.. autoclass:: Message() .. autoclass:: Message()
.. autoclass:: Messages()
.. autoclass:: MessageEntity() .. autoclass:: MessageEntity()
.. autoclass:: Photo() .. autoclass:: Photo()
.. autoclass:: Thumbnail() .. autoclass:: Thumbnail()

View File

@ -21,6 +21,7 @@ import threading
from collections import OrderedDict from collections import OrderedDict
from queue import Queue from queue import Queue
from threading import Thread from threading import Thread
from . import utils
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api import types
@ -68,7 +69,7 @@ class Dispatcher:
lambda upd, usr, cht: (pyrogram.Message._parse(self.client, upd.message, usr, cht), MessageHandler), lambda upd, usr, cht: (pyrogram.Message._parse(self.client, upd.message, usr, cht), MessageHandler),
Dispatcher.DELETE_MESSAGES_UPDATES: Dispatcher.DELETE_MESSAGES_UPDATES:
lambda upd, usr, cht: (pyrogram.Messages._parse_deleted(self.client, upd), DeletedMessagesHandler), lambda upd, usr, cht: (utils.parse_deleted_messages(self.client, upd), DeletedMessagesHandler),
Dispatcher.CALLBACK_QUERY_UPDATES: Dispatcher.CALLBACK_QUERY_UPDATES:
lambda upd, usr, cht: (pyrogram.CallbackQuery._parse(self.client, upd, usr), CallbackQueryHandler), lambda upd, usr, cht: (pyrogram.CallbackQuery._parse(self.client, upd, usr), CallbackQueryHandler),

View File

@ -18,8 +18,9 @@
import struct import struct
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from typing import Union from typing import Union, List
import pyrogram
from . import BaseClient from . import BaseClient
from ...api import types from ...api import types
@ -135,3 +136,58 @@ def get_input_media_from_file_id(
) )
raise ValueError("Unknown media type: {}".format(file_id_str)) raise ValueError("Unknown media type: {}".format(file_id_str))
def parse_messages(client, messages: types.messages.Messages, replies: int = 1) -> List["pyrogram.Message"]:
users = {i.id: i for i in messages.users}
chats = {i.id: i for i in messages.chats}
if not messages.messages:
return pyrogram.List()
parsed_messages = [
pyrogram.Message._parse(client, message, users, chats, replies=0)
for message in messages.messages
]
if replies:
messages_with_replies = {i.id: getattr(i, "reply_to_msg_id", None) for i in messages.messages}
reply_message_ids = [i[0] for i in filter(lambda x: x[1] is not None, messages_with_replies.items())]
if reply_message_ids:
reply_messages = client.get_messages(
parsed_messages[0].chat.id,
reply_to_message_ids=reply_message_ids,
replies=replies - 1
)
for message in parsed_messages:
reply_id = messages_with_replies[message.message_id]
for reply in reply_messages:
if reply.message_id == reply_id:
message.reply_to_message = reply
return pyrogram.List(parsed_messages)
def parse_deleted_messages(client, update) -> List["pyrogram.Message"]:
messages = update.messages
channel_id = getattr(update, "channel_id", None)
parsed_messages = []
for message in messages:
parsed_messages.append(
pyrogram.Message(
message_id=message,
chat=pyrogram.Chat(
id=int("-100" + str(channel_id)),
type="channel",
client=client
) if channel_id is not None else None,
client=client
)
)
return pyrogram.List(parsed_messages)

View File

@ -20,16 +20,15 @@ from .handler import Handler
class DeletedMessagesHandler(Handler): class DeletedMessagesHandler(Handler):
"""The deleted Messages handler class. Used to handle deleted messages coming from any chat """The deleted messages handler class. Used to handle deleted messages coming from any chat
(private, group, channel). It is intended to be used with (private, group, channel). It is intended to be used with :meth:`~Client.add_handler`
:meth:`~Client.add_handler`
For a nicer way to register this handler, have a look at the For a nicer way to register this handler, have a look at the
:meth:`~Client.on_deleted_messages` decorator. :meth:`~Client.on_deleted_messages` decorator.
Parameters: Parameters:
callback (``callable``): callback (``callable``):
Pass a function that will be called when one or more Messages have been deleted. Pass a function that will be called when one or more messages have been deleted.
It takes *(client, messages)* as positional arguments (look at the section below for a detailed description). It takes *(client, messages)* as positional arguments (look at the section below for a detailed description).
filters (:obj:`Filters`): filters (:obj:`Filters`):
@ -40,12 +39,12 @@ class DeletedMessagesHandler(Handler):
client (:obj:`Client`): client (:obj:`Client`):
The Client itself, useful when you want to call other API methods inside the message handler. The Client itself, useful when you want to call other API methods inside the message handler.
messages (:obj:`Messages`): messages (List of :obj:`Message`):
The deleted messages. The deleted messages, as list.
""" """
def __init__(self, callback: callable, filters=None): def __init__(self, callback: callable, filters=None):
super().__init__(callback, filters) super().__init__(callback, filters)
def check(self, messages): def check(self, messages):
return super().check(messages.messages[0]) return super().check(messages[0])

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union, Iterable from typing import Union, Iterable, List
import pyrogram import pyrogram
from pyrogram.api import functions, types from pyrogram.api import functions, types
@ -32,7 +32,7 @@ class ForwardMessages(BaseClient):
disable_notification: bool = None, disable_notification: bool = None,
as_copy: bool = False, as_copy: bool = False,
remove_caption: bool = False remove_caption: bool = False
) -> "pyrogram.Messages": ) -> List["pyrogram.Message"]:
"""Forward messages of any kind. """Forward messages of any kind.
Parameters: Parameters:
@ -64,9 +64,9 @@ class ForwardMessages(BaseClient):
Defaults to False. Defaults to False.
Returns: Returns:
:obj:`Message` | :obj:`Messages`: In case *message_ids* was an integer, the single forwarded message is :obj:`Message` | List of :obj:`Message`: In case *message_ids* was an integer, the single forwarded message
returned, otherwise, in case *message_ids* was an iterable, the returned value will be an object containing is returned, otherwise, in case *message_ids* was an iterable, the returned value will be a list of
a list of messages, even if such iterable contained just a single element. messages, even if such iterable contained just a single element.
Raises: Raises:
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
@ -79,9 +79,9 @@ class ForwardMessages(BaseClient):
forwarded_messages = [] forwarded_messages = []
for chunk in [message_ids[i:i + 200] for i in range(0, len(message_ids), 200)]: for chunk in [message_ids[i:i + 200] for i in range(0, len(message_ids), 200)]:
messages = self.get_messages(chat_id=from_chat_id, message_ids=chunk) # type: pyrogram.Messages messages = self.get_messages(chat_id=from_chat_id, message_ids=chunk)
for message in messages.messages: for message in messages:
forwarded_messages.append( forwarded_messages.append(
message.forward( message.forward(
chat_id, chat_id,
@ -91,11 +91,7 @@ class ForwardMessages(BaseClient):
) )
) )
return pyrogram.Messages( return pyrogram.List(forwarded_messages) if is_iterable else forwarded_messages[0]
client=self,
total_count=len(forwarded_messages),
messages=forwarded_messages
) if is_iterable else forwarded_messages[0]
else: else:
r = self.send( r = self.send(
functions.messages.ForwardMessages( functions.messages.ForwardMessages(
@ -121,8 +117,4 @@ class ForwardMessages(BaseClient):
) )
) )
return pyrogram.Messages( return pyrogram.List(forwarded_messages) if is_iterable else forwarded_messages[0]
client=self,
total_count=len(forwarded_messages),
messages=forwarded_messages
) if is_iterable else forwarded_messages[0]

View File

@ -18,10 +18,11 @@
import logging import logging
import time import time
from typing import Union from typing import Union, List
import pyrogram import pyrogram
from pyrogram.api import functions from pyrogram.api import functions
from pyrogram.client.ext import utils
from pyrogram.errors import FloodWait from pyrogram.errors import FloodWait
from ...ext import BaseClient from ...ext import BaseClient
@ -37,7 +38,7 @@ class GetHistory(BaseClient):
offset_id: int = 0, offset_id: int = 0,
offset_date: int = 0, offset_date: int = 0,
reverse: bool = False reverse: bool = False
) -> "pyrogram.Messages": ) -> List["pyrogram.Message"]:
"""Retrieve a chunk of the history of a chat. """Retrieve a chunk of the history of a chat.
You can get up to 100 messages at once. You can get up to 100 messages at once.
@ -67,15 +68,17 @@ class GetHistory(BaseClient):
Pass True to retrieve the messages in reversed order (from older to most recent). Pass True to retrieve the messages in reversed order (from older to most recent).
Returns: Returns:
:obj:`Messages` - On success, an object containing a list of the retrieved messages. List of :obj:`Message` - On success, a list of the retrieved messages is returned.
Raises: Raises:
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
""" """
offset_id = offset_id or (1 if reverse else 0)
while True: while True:
try: try:
messages = pyrogram.Messages._parse( messages = utils.parse_messages(
self, self,
self.send( self.send(
functions.messages.GetHistory( functions.messages.GetHistory(
@ -97,6 +100,6 @@ class GetHistory(BaseClient):
break break
if reverse: if reverse:
messages.messages.reverse() messages.reverse()
return messages return messages

View File

@ -18,12 +18,12 @@
import logging import logging
import time import time
from typing import Union, Iterable from typing import Union, Iterable, List
import pyrogram import pyrogram
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.errors import FloodWait from pyrogram.errors import FloodWait
from ...ext import BaseClient from ...ext import BaseClient, utils
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -35,7 +35,7 @@ class GetMessages(BaseClient):
message_ids: Union[int, Iterable[int]] = None, message_ids: Union[int, Iterable[int]] = None,
reply_to_message_ids: Union[int, Iterable[int]] = None, reply_to_message_ids: Union[int, Iterable[int]] = None,
replies: int = 1 replies: int = 1
) -> Union["pyrogram.Message", "pyrogram.Messages"]: ) -> Union["pyrogram.Message", List["pyrogram.Message"]]:
"""Get one or more messages that belong to a specific chat. """Get one or more messages that belong to a specific chat.
You can retrieve up to 200 messages at once. You can retrieve up to 200 messages at once.
@ -60,9 +60,9 @@ class GetMessages(BaseClient):
Defaults to 1. Defaults to 1.
Returns: Returns:
:obj:`Message` | :obj:`Messages`: In case *message_ids* was an integer, the single requested message is :obj:`Message` | List of :obj:`Message`: In case *message_ids* was an integer, the single requested message is
returned, otherwise, in case *message_ids* was an iterable, the returned value will be an object containing returned, otherwise, in case *message_ids* was an iterable, the returned value will be a list of messages,
a list of messages, even if such iterable contained just a single element. even if such iterable contained just a single element.
Raises: Raises:
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
@ -99,6 +99,6 @@ class GetMessages(BaseClient):
else: else:
break break
messages = pyrogram.Messages._parse(self, r, replies=replies) messages = utils.parse_messages(self, r, replies=replies)
return messages if is_iterable else messages.messages[0] return messages if is_iterable else messages[0]

View File

@ -80,7 +80,7 @@ class IterHistory(BaseClient):
offset_id=offset_id, offset_id=offset_id,
offset_date=offset_date, offset_date=offset_date,
reverse=reverse reverse=reverse
).messages )
if not messages: if not messages:
return return

View File

@ -38,7 +38,7 @@ class SendMediaGroup(BaseClient):
media: List[Union["pyrogram.InputMediaPhoto", "pyrogram.InputMediaVideo"]], media: List[Union["pyrogram.InputMediaPhoto", "pyrogram.InputMediaVideo"]],
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None reply_to_message_id: int = None
): ) -> List["pyrogram.Message"]:
"""Send a group of photos or videos as an album. """Send a group of photos or videos as an album.
Parameters: Parameters:
@ -58,7 +58,7 @@ class SendMediaGroup(BaseClient):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
Returns: Returns:
:obj:`Messages`: On success, an object is returned containing all the single messages sent. List of :obj:`Message`: On success, a list of the sent messages is returned.
Raises: Raises:
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
@ -158,7 +158,7 @@ class SendMediaGroup(BaseClient):
else: else:
break break
return pyrogram.Messages._parse( return utils.parse_messages(
self, self,
types.messages.Messages( types.messages.Messages(
messages=[m.message for m in filter( messages=[m.message for m in filter(

View File

@ -20,6 +20,7 @@ from typing import Union, List
import pyrogram import pyrogram
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.client.ext import utils
from ...ext import BaseClient from ...ext import BaseClient
@ -66,7 +67,7 @@ class GetProfilePhotos(BaseClient):
return pyrogram.List(pyrogram.Photo._parse(self, photo) for photo in r.photos) return pyrogram.List(pyrogram.Photo._parse(self, photo) for photo in r.photos)
else: else:
new_chat_photos = pyrogram.Messages._parse( r = utils.parse_messages(
self, self,
self.send( self.send(
functions.messages.Search( functions.messages.Search(
@ -85,4 +86,4 @@ class GetProfilePhotos(BaseClient):
) )
) )
return pyrogram.List([m.new_chat_photo for m in new_chat_photos.messages][:limit]) return pyrogram.List([message.new_chat_photo for message in r][:limit])

View File

@ -24,7 +24,6 @@ from .game import Game
from .location import Location from .location import Location
from .message import Message from .message import Message
from .message_entity import MessageEntity from .message_entity import MessageEntity
from .messages import Messages
from .photo import Photo from .photo import Photo
from .poll import Poll from .poll import Poll
from .poll_option import PollOption from .poll_option import PollOption
@ -37,6 +36,6 @@ from .video_note import VideoNote
from .voice import Voice from .voice import Voice
__all__ = [ __all__ = [
"Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Messages", "Photo", "Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Photo", "Thumbnail",
"Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice" "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice"
] ]

View File

@ -2617,7 +2617,7 @@ class Message(Object, Update):
) )
if self.photo: if self.photo:
file_id = self.photo.sizes[-1].file_id file_id = self.photo.file_id
elif self.audio: elif self.audio:
file_id = self.audio.file_id file_id = self.audio.file_id
elif self.document: elif self.document:

View File

@ -1,170 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import List, Union
import pyrogram
from pyrogram.api import types
from .message import Message
from ..object import Object
from ..update import Update
from ..user_and_chats import Chat
class Messages(Object, Update):
"""Contains a chat's messages.
Parameters:
total_count (``int``):
Total number of messages the target chat has.
messages (List of :obj:`Message`):
Requested messages.
"""
__slots__ = ["total_count", "messages"]
def __init__(
self,
*,
client: "pyrogram.BaseClient" = None,
total_count: int,
messages: List[Message]
):
super().__init__(client)
self.total_count = total_count
self.messages = messages
@staticmethod
def _parse(client, messages: types.messages.Messages, replies: int = 1) -> "Messages":
users = {i.id: i for i in messages.users}
chats = {i.id: i for i in messages.chats}
total_count = getattr(messages, "count", len(messages.messages))
if not messages.messages:
return Messages(
total_count=total_count,
messages=[],
client=client
)
parsed_messages = [Message._parse(client, message, users, chats, replies=0) for message in messages.messages]
if replies:
messages_with_replies = {i.id: getattr(i, "reply_to_msg_id", None) for i in messages.messages}
reply_message_ids = [i[0] for i in filter(lambda x: x[1] is not None, messages_with_replies.items())]
if reply_message_ids:
reply_messages = client.get_messages(
parsed_messages[0].chat.id,
reply_to_message_ids=reply_message_ids,
replies=replies - 1
).messages
for message in parsed_messages:
reply_id = messages_with_replies[message.message_id]
for reply in reply_messages:
if reply.message_id == reply_id:
message.reply_to_message = reply
return Messages(
total_count=total_count,
messages=parsed_messages,
client=client
)
@staticmethod
def _parse_deleted(client, update) -> "Messages":
messages = update.messages
channel_id = getattr(update, "channel_id", None)
parsed_messages = []
for message in messages:
parsed_messages.append(
Message(
message_id=message,
chat=Chat(
id=int("-100" + str(channel_id)),
type="channel",
client=client
) if channel_id is not None else None,
client=client
)
)
return Messages(
total_count=len(parsed_messages),
messages=parsed_messages,
client=client
)
def forward(
self,
chat_id: Union[int, str],
disable_notification: bool = None,
as_copy: bool = False,
remove_caption: bool = False
):
"""Bound method *forward* of :obj:`Message`.
Parameters:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
disable_notification (``bool``, *optional*):
Sends messages silently.
Users will receive a notification with no sound.
as_copy (``bool``, *optional*):
Pass True to forward messages without the forward header (i.e.: send a copy of the message content).
Defaults to False.
remove_caption (``bool``, *optional*):
If set to True and *as_copy* is enabled as well, media captions are not preserved when copying the
message. Has no effect if *as_copy* is not enabled.
Defaults to False.
Returns:
On success, a :obj:`Messages` containing forwarded messages is returned.
Raises:
RPCError: In case of a Telegram RPC error.
"""
forwarded_messages = []
for message in self.messages:
forwarded_messages.append(
message.forward(
chat_id=chat_id,
as_copy=as_copy,
disable_notification=disable_notification,
remove_caption=remove_caption
)
)
return Messages(
total_count=len(forwarded_messages),
messages=forwarded_messages,
client=self._client
)