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
- :class:`Message`
- :class:`Messages`
- :class:`MessageEntity`
- :class:`Photo`
- :class:`Thumbnail`
@ -125,7 +124,6 @@ Details
.. Messages & Media
.. autoclass:: Message()
.. autoclass:: Messages()
.. autoclass:: MessageEntity()
.. autoclass:: Photo()
.. autoclass:: Thumbnail()

View File

@ -21,6 +21,7 @@ import threading
from collections import OrderedDict
from queue import Queue
from threading import Thread
from . import utils
import pyrogram
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),
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:
lambda upd, usr, cht: (pyrogram.CallbackQuery._parse(self.client, upd, usr), CallbackQueryHandler),

View File

@ -18,8 +18,9 @@
import struct
from base64 import b64decode, b64encode
from typing import Union
from typing import Union, List
import pyrogram
from . import BaseClient
from ...api import types
@ -135,3 +136,58 @@ def get_input_media_from_file_id(
)
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):
"""The deleted Messages handler class. Used to handle deleted messages coming from any chat
(private, group, channel). It is intended to be used with
:meth:`~Client.add_handler`
"""The deleted messages handler class. Used to handle deleted messages coming from any chat
(private, group, channel). It is intended to be used with :meth:`~Client.add_handler`
For a nicer way to register this handler, have a look at the
:meth:`~Client.on_deleted_messages` decorator.
Parameters:
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).
filters (:obj:`Filters`):
@ -40,12 +39,12 @@ class DeletedMessagesHandler(Handler):
client (:obj:`Client`):
The Client itself, useful when you want to call other API methods inside the message handler.
messages (:obj:`Messages`):
The deleted messages.
messages (List of :obj:`Message`):
The deleted messages, as list.
"""
def __init__(self, callback: callable, filters=None):
super().__init__(callback, filters)
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
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union, Iterable
from typing import Union, Iterable, List
import pyrogram
from pyrogram.api import functions, types
@ -32,7 +32,7 @@ class ForwardMessages(BaseClient):
disable_notification: bool = None,
as_copy: bool = False,
remove_caption: bool = False
) -> "pyrogram.Messages":
) -> List["pyrogram.Message"]:
"""Forward messages of any kind.
Parameters:
@ -64,9 +64,9 @@ class ForwardMessages(BaseClient):
Defaults to False.
Returns:
:obj:`Message` | :obj:`Messages`: In case *message_ids* was an integer, the single forwarded message is
returned, otherwise, in case *message_ids* was an iterable, the returned value will be an object containing
a list of messages, even if such iterable contained just a single element.
:obj:`Message` | List of :obj:`Message`: In case *message_ids* was an integer, the single forwarded message
is returned, otherwise, in case *message_ids* was an iterable, the returned value will be a list of
messages, even if such iterable contained just a single element.
Raises:
RPCError: In case of a Telegram RPC error.
@ -79,9 +79,9 @@ class ForwardMessages(BaseClient):
forwarded_messages = []
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(
message.forward(
chat_id,
@ -91,11 +91,7 @@ class ForwardMessages(BaseClient):
)
)
return pyrogram.Messages(
client=self,
total_count=len(forwarded_messages),
messages=forwarded_messages
) if is_iterable else forwarded_messages[0]
return pyrogram.List(forwarded_messages) if is_iterable else forwarded_messages[0]
else:
r = self.send(
functions.messages.ForwardMessages(
@ -121,8 +117,4 @@ class ForwardMessages(BaseClient):
)
)
return pyrogram.Messages(
client=self,
total_count=len(forwarded_messages),
messages=forwarded_messages
) if is_iterable else forwarded_messages[0]
return pyrogram.List(forwarded_messages) if is_iterable else forwarded_messages[0]

View File

@ -18,10 +18,11 @@
import logging
import time
from typing import Union
from typing import Union, List
import pyrogram
from pyrogram.api import functions
from pyrogram.client.ext import utils
from pyrogram.errors import FloodWait
from ...ext import BaseClient
@ -37,7 +38,7 @@ class GetHistory(BaseClient):
offset_id: int = 0,
offset_date: int = 0,
reverse: bool = False
) -> "pyrogram.Messages":
) -> List["pyrogram.Message"]:
"""Retrieve a chunk of the history of a chat.
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).
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:
RPCError: In case of a Telegram RPC error.
"""
offset_id = offset_id or (1 if reverse else 0)
while True:
try:
messages = pyrogram.Messages._parse(
messages = utils.parse_messages(
self,
self.send(
functions.messages.GetHistory(
@ -97,6 +100,6 @@ class GetHistory(BaseClient):
break
if reverse:
messages.messages.reverse()
messages.reverse()
return messages

View File

@ -18,12 +18,12 @@
import logging
import time
from typing import Union, Iterable
from typing import Union, Iterable, List
import pyrogram
from pyrogram.api import functions, types
from pyrogram.errors import FloodWait
from ...ext import BaseClient
from ...ext import BaseClient, utils
log = logging.getLogger(__name__)
@ -35,7 +35,7 @@ class GetMessages(BaseClient):
message_ids: Union[int, Iterable[int]] = None,
reply_to_message_ids: Union[int, Iterable[int]] = None,
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.
You can retrieve up to 200 messages at once.
@ -60,9 +60,9 @@ class GetMessages(BaseClient):
Defaults to 1.
Returns:
:obj:`Message` | :obj:`Messages`: 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
a list of messages, even if such iterable contained just a single element.
: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 a list of messages,
even if such iterable contained just a single element.
Raises:
RPCError: In case of a Telegram RPC error.
@ -99,6 +99,6 @@ class GetMessages(BaseClient):
else:
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_date=offset_date,
reverse=reverse
).messages
)
if not messages:
return

View File

@ -38,7 +38,7 @@ class SendMediaGroup(BaseClient):
media: List[Union["pyrogram.InputMediaPhoto", "pyrogram.InputMediaVideo"]],
disable_notification: bool = None,
reply_to_message_id: int = None
):
) -> List["pyrogram.Message"]:
"""Send a group of photos or videos as an album.
Parameters:
@ -58,7 +58,7 @@ class SendMediaGroup(BaseClient):
If the message is a reply, ID of the original message.
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:
RPCError: In case of a Telegram RPC error.
@ -158,7 +158,7 @@ class SendMediaGroup(BaseClient):
else:
break
return pyrogram.Messages._parse(
return utils.parse_messages(
self,
types.messages.Messages(
messages=[m.message for m in filter(

View File

@ -20,6 +20,7 @@ from typing import Union, List
import pyrogram
from pyrogram.api import functions, types
from pyrogram.client.ext import utils
from ...ext import BaseClient
@ -66,7 +67,7 @@ class GetProfilePhotos(BaseClient):
return pyrogram.List(pyrogram.Photo._parse(self, photo) for photo in r.photos)
else:
new_chat_photos = pyrogram.Messages._parse(
r = utils.parse_messages(
self,
self.send(
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 .message import Message
from .message_entity import MessageEntity
from .messages import Messages
from .photo import Photo
from .poll import Poll
from .poll_option import PollOption
@ -37,6 +36,6 @@ from .video_note import VideoNote
from .voice import Voice
__all__ = [
"Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Messages", "Photo",
"Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice"
"Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Photo", "Thumbnail",
"StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice"
]

View File

@ -2617,7 +2617,7 @@ class Message(Object, Update):
)
if self.photo:
file_id = self.photo.sizes[-1].file_id
file_id = self.photo.file_id
elif self.audio:
file_id = self.audio.file_id
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
)