Merge pull request #251 from pyrogram/types-revamp

Types revamp
This commit is contained in:
Dan 2019-06-12 10:48:10 +02:00 committed by GitHub
commit a21858a262
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 206 additions and 579 deletions

View File

@ -8,4 +8,5 @@ REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again la
RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later
WORKER_BUSY_TOO_LONG_RETRY Telegram is having internal problems. Please try again later
INTERDC_X_CALL_ERROR Telegram is having internal problems. Please try again later
INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems. Please try again later
INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems. Please try again later
FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later
1 id message
8 RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later
9 WORKER_BUSY_TOO_LONG_RETRY Telegram is having internal problems. Please try again later
10 INTERDC_X_CALL_ERROR Telegram is having internal problems. Please try again later
11 INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems. Please try again later
12 FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later

View File

@ -30,10 +30,8 @@ Users & Chats
- :class:`ChatPreview`
- :class:`ChatPhoto`
- :class:`ChatMember`
- :class:`ChatMembers`
- :class:`ChatPermissions`
- :class:`Dialog`
- :class:`Dialogs`
Messages & Media
^^^^^^^^^^^^^^^^
@ -42,10 +40,8 @@ Messages & Media
:columns: 5
- :class:`Message`
- :class:`Messages`
- :class:`MessageEntity`
- :class:`Photo`
- :class:`ProfilePhotos`
- :class:`Thumbnail`
- :class:`Audio`
- :class:`Document`
@ -61,8 +57,8 @@ Messages & Media
- :class:`Poll`
- :class:`PollOption`
Keyboards
^^^^^^^^^
Bots & Keyboards
^^^^^^^^^^^^^^^^
.. hlist::
:columns: 4
@ -75,7 +71,6 @@ Keyboards
- :class:`ForceReply`
- :class:`CallbackQuery`
- :class:`GameHighScore`
- :class:`GameHighScores`
- :class:`CallbackGame`
Input Media
@ -123,17 +118,13 @@ Details
.. autoclass:: ChatPreview()
.. autoclass:: ChatPhoto()
.. autoclass:: ChatMember()
.. autoclass:: ChatMembers()
.. autoclass:: ChatPermissions()
.. autoclass:: Dialog()
.. autoclass:: Dialogs()
.. Messages & Media
.. autoclass:: Message()
.. autoclass:: Messages()
.. autoclass:: MessageEntity()
.. autoclass:: Photo()
.. autoclass:: ProfilePhotos()
.. autoclass:: Thumbnail()
.. autoclass:: Audio()
.. autoclass:: Document()
@ -149,7 +140,7 @@ Details
.. autoclass:: Poll()
.. autoclass:: PollOption()
.. Keyboards
.. Bots & Keyboards
.. autoclass:: ReplyKeyboardMarkup()
.. autoclass:: KeyboardButton()
.. autoclass:: ReplyKeyboardRemove()
@ -158,7 +149,6 @@ Details
.. autoclass:: ForceReply()
.. autoclass:: CallbackQuery()
.. autoclass:: GameHighScore()
.. autoclass:: GameHighScores()
.. autoclass:: CallbackGame()
.. Input Media

View File

@ -19,6 +19,5 @@
from .base_client import BaseClient
from .dispatcher import Dispatcher
from .emoji import Emoji
from .syncer import Syncer
from .file_data import FileData
from .syncer import Syncer

View File

@ -24,6 +24,7 @@ from threading import Thread
import pyrogram
from pyrogram.api import types
from . import utils
from ..handlers import (
CallbackQueryHandler, MessageHandler, DeletedMessagesHandler,
UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler
@ -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

@ -19,7 +19,7 @@
import re
from .filter import Filter
from ..types.keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup
from ..types.bots_and_keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup
def create(name: str, func: callable, **kwargs) -> type:

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
from typing import Union, List
import pyrogram
from pyrogram.api import functions
@ -29,7 +29,7 @@ class GetGameHighScores(BaseClient):
user_id: Union[int, str],
chat_id: Union[int, str],
message_id: int = None
) -> "pyrogram.GameHighScores":
) -> List["pyrogram.GameHighScore"]:
"""Get data for high score tables.
Parameters:
@ -49,20 +49,19 @@ class GetGameHighScores(BaseClient):
Required if inline_message_id is not specified.
Returns:
:obj:`GameHighScores`: On success.
List of :obj:`GameHighScore`: On success.
Raises:
RPCError: In case of a Telegram RPC error.
"""
# TODO: inline_message_id
return pyrogram.GameHighScores._parse(
self,
self.send(
functions.messages.GetGameHighScores(
peer=self.resolve_peer(chat_id),
id=message_id,
user_id=self.resolve_peer(user_id)
)
r = self.send(
functions.messages.GetGameHighScores(
peer=self.resolve_peer(chat_id),
id=message_id,
user_id=self.resolve_peer(user_id)
)
)
return pyrogram.List(pyrogram.GameHighScore._parse(self, score, r.users) for score in r.scores)

View File

@ -51,13 +51,18 @@ class GetChatMember(BaseClient):
user = self.resolve_peer(user_id)
if isinstance(chat, types.InputPeerChat):
full_chat = self.send(
r = self.send(
functions.messages.GetFullChat(
chat_id=chat.chat_id
)
)
for member in pyrogram.ChatMembers._parse(self, full_chat).chat_members:
members = r.full_chat.participants.participants
users = {i.id: i for i in r.users}
for member in members:
member = pyrogram.ChatMember._parse(self, member, users)
if isinstance(user, types.InputPeerSelf):
if member.user.is_self:
return member

View File

@ -18,7 +18,7 @@
import logging
import time
from typing import Union
from typing import Union, List
import pyrogram
from pyrogram.api import functions, types
@ -45,7 +45,7 @@ class GetChatMembers(BaseClient):
limit: int = 200,
query: str = "",
filter: str = Filters.ALL
) -> "pyrogram.ChatMembers":
) -> List["pyrogram.ChatMember"]:
"""Get a chunk of the members list of a chat.
You can get up to 200 chat members at once.
@ -59,15 +59,16 @@ class GetChatMembers(BaseClient):
offset (``int``, *optional*):
Sequential number of the first member to be returned.
Defaults to 0 [1]_.
Only applicable to supergroups and channels. Defaults to 0 [1]_.
limit (``int``, *optional*):
Limits the number of members to be retrieved.
Only applicable to supergroups and channels.
Defaults to 200, which is also the maximum server limit allowed per method call.
query (``str``, *optional*):
Query string to filter members based on their display names and usernames.
Defaults to "" (empty string) [2]_.
Only applicable to supergroups and channels. Defaults to "" (empty string) [2]_.
filter (``str``, *optional*):
Filter used to select the kind of members you want to retrieve. Only applicable for supergroups
@ -78,6 +79,7 @@ class GetChatMembers(BaseClient):
*"bots"* - bots only,
*"recent"* - recent members only,
*"administrators"* - chat administrators only.
Only applicable to supergroups and channels.
Defaults to *"all"*.
.. [1] Server limit: on supergroups, you can get up to 10,000 members for a single query and up to 200 members
@ -86,7 +88,7 @@ class GetChatMembers(BaseClient):
.. [2] A query string is applicable only for *"all"*, *"kicked"* and *"restricted"* filters only.
Returns:
:obj:`ChatMembers`: On success, an object containing a list of chat members is returned.
List of :obj:`ChatMember`: On success, a list of chat members is returned.
Raises:
RPCError: In case of a Telegram RPC error.
@ -95,14 +97,16 @@ class GetChatMembers(BaseClient):
peer = self.resolve_peer(chat_id)
if isinstance(peer, types.InputPeerChat):
return pyrogram.ChatMembers._parse(
self,
self.send(
functions.messages.GetFullChat(
chat_id=peer.chat_id
)
r = self.send(
functions.messages.GetFullChat(
chat_id=peer.chat_id
)
)
members = r.full_chat.participants.participants
users = {i.id: i for i in r.users}
return pyrogram.List(pyrogram.ChatMember._parse(self, member, users) for member in members)
elif isinstance(peer, types.InputPeerChannel):
filter = filter.lower()
@ -123,18 +127,20 @@ class GetChatMembers(BaseClient):
while True:
try:
return pyrogram.ChatMembers._parse(
self,
self.send(
functions.channels.GetParticipants(
channel=peer,
filter=filter,
offset=offset,
limit=limit,
hash=0
)
r = self.send(
functions.channels.GetParticipants(
channel=peer,
filter=filter,
offset=offset,
limit=limit,
hash=0
)
)
members = r.participants
users = {i.id: i for i in r.users}
return pyrogram.List(pyrogram.ChatMember._parse(self, member, users) for member in members)
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
time.sleep(e.x)

View File

@ -18,6 +18,7 @@
import logging
import time
from typing import List
import pyrogram
from pyrogram.api import functions, types
@ -33,7 +34,7 @@ class GetDialogs(BaseClient):
offset_date: int = 0,
limit: int = 100,
pinned_only: bool = False
) -> "pyrogram.Dialogs":
) -> List["pyrogram.Dialog"]:
"""Get a chunk of the user's dialogs.
You can get up to 100 dialogs at once.
@ -53,7 +54,7 @@ class GetDialogs(BaseClient):
Defaults to False.
Returns:
:obj:`Dialogs`: On success, an object containing a list of dialogs is returned.
List of :obj:`Dialog`: On success, a list of dialogs is returned.
Raises:
RPCError: In case of a Telegram RPC error.
@ -80,4 +81,32 @@ class GetDialogs(BaseClient):
else:
break
return pyrogram.Dialogs._parse(self, r)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
messages = {}
for message in r.messages:
to_id = message.to_id
if isinstance(to_id, types.PeerUser):
if message.out:
chat_id = to_id.user_id
else:
chat_id = message.from_id
elif isinstance(to_id, types.PeerChat):
chat_id = -to_id.chat_id
else:
chat_id = int("-100" + str(to_id.channel_id))
messages[chat_id] = pyrogram.Message._parse(self, message, users, chats)
parsed_dialogs = []
for dialog in r.dialogs:
if not isinstance(dialog, types.Dialog):
continue
parsed_dialogs.append(pyrogram.Dialog._parse(self, dialog, messages, users, chats))
return pyrogram.List(parsed_dialogs)

View File

@ -106,7 +106,7 @@ class IterChatMembers(BaseClient):
limit=limit,
query=q,
filter=filter
).chat_members
)
if not chat_members:
break

View File

@ -55,7 +55,7 @@ class IterDialogs(BaseClient):
pinned_dialogs = self.get_dialogs(
pinned_only=True
).dialogs
)
for dialog in pinned_dialogs:
yield dialog
@ -69,7 +69,7 @@ class IterDialogs(BaseClient):
dialogs = self.get_dialogs(
offset_date=offset_date,
limit=limit
).dialogs
)
if not dialogs:
return

View File

@ -47,4 +47,4 @@ class GetContacts(BaseClient):
time.sleep(e.x)
else:
log.info("Total contacts: {}".format(len(self.peers_by_phone)))
return [pyrogram.User._parse(self, user) for user in contacts.users]
return pyrogram.List(pyrogram.User._parse(self, user) for user in contacts.users)

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

@ -16,10 +16,11 @@
# 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
from typing import Union, List
import pyrogram
from pyrogram.api import functions, types
from pyrogram.client.ext import utils
from ...ext import BaseClient
@ -29,7 +30,7 @@ class GetProfilePhotos(BaseClient):
chat_id: Union[int, str],
offset: int = 0,
limit: int = 100
) -> "pyrogram.ProfilePhotos":
) -> List["pyrogram.Photo"]:
"""Get a list of profile pictures for a user or a chat.
Parameters:
@ -47,7 +48,7 @@ class GetProfilePhotos(BaseClient):
Values between 1100 are accepted. Defaults to 100.
Returns:
:obj:`ProfilePhotos`: On success, an object containing a list of the profile photos is returned.
List of :obj:`Photo`: On success, a list of profile photos is returned.
Raises:
RPCError: In case of a Telegram RPC error.
@ -55,19 +56,18 @@ class GetProfilePhotos(BaseClient):
peer_id = self.resolve_peer(chat_id)
if isinstance(peer_id, (types.InputPeerUser, types.InputPeerSelf)):
return pyrogram.ProfilePhotos._parse(
self,
self.send(
functions.photos.GetUserPhotos(
user_id=peer_id,
offset=offset,
max_id=0,
limit=limit
)
r = self.send(
functions.photos.GetUserPhotos(
user_id=peer_id,
offset=offset,
max_id=0,
limit=limit
)
)
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(
@ -86,7 +86,4 @@ class GetProfilePhotos(BaseClient):
)
)
return pyrogram.ProfilePhotos(
total_count=new_chat_photos.total_count,
profile_photos=[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

@ -56,7 +56,7 @@ class GetUsers(BaseClient):
)
)
users = []
users = pyrogram.List()
for i in r:
users.append(pyrogram.User._parse(self, i))

View File

@ -63,7 +63,7 @@ class IterProfilePhotos(BaseClient):
chat_id=chat_id,
offset=offset,
limit=limit
).photos
)
if not photos:
return

View File

@ -16,10 +16,12 @@
# 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 .keyboards import *
from .bots_and_keyboards import *
from .inline_mode import *
from .input_media import *
from .input_message_content import *
from .list import List
from .messages_and_media import *
from .object import Object
from .update import *
from .user_and_chats import *

View File

@ -20,7 +20,6 @@ from .callback_game import CallbackGame
from .callback_query import CallbackQuery
from .force_reply import ForceReply
from .game_high_score import GameHighScore
from .game_high_scores import GameHighScores
from .inline_keyboard_button import InlineKeyboardButton
from .inline_keyboard_markup import InlineKeyboardMarkup
from .keyboard_button import KeyboardButton
@ -28,6 +27,6 @@ from .reply_keyboard_markup import ReplyKeyboardMarkup
from .reply_keyboard_remove import ReplyKeyboardRemove
__all__ = [
"CallbackGame", "CallbackQuery", "ForceReply", "GameHighScore", "GameHighScores", "InlineKeyboardButton",
"InlineKeyboardMarkup", "KeyboardButton", "ReplyKeyboardMarkup", "ReplyKeyboardRemove"
"CallbackGame", "CallbackQuery", "ForceReply", "GameHighScore", "InlineKeyboardButton", "InlineKeyboardMarkup",
"KeyboardButton", "ReplyKeyboardMarkup", "ReplyKeyboardRemove"
]

View File

@ -1,60 +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
import pyrogram
from pyrogram.api import types
from pyrogram.client.types.object import Object
from .game_high_score import GameHighScore
class GameHighScores(Object):
"""The high scores table for a game.
Parameters:
total_count (``int``):
Total number of scores the target game has.
game_high_scores (List of :obj:`GameHighScore`):
Game scores.
"""
__slots__ = ["total_count", "game_high_scores"]
def __init__(
self,
*,
client: "pyrogram.BaseClient" = None,
total_count: int,
game_high_scores: List[GameHighScore]
):
super().__init__(client)
self.total_count = total_count
self.game_high_scores = game_high_scores
@staticmethod
def _parse(client, game_high_scores: types.messages.HighScores) -> "GameHighScores":
return GameHighScores(
total_count=len(game_high_scores.scores),
game_high_scores=[
GameHighScore._parse(client, score, game_high_scores.users)
for score in game_high_scores.scores],
client=client
)

View File

@ -24,11 +24,9 @@ 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
from .profile_photos import ProfilePhotos
from .sticker import Sticker
from .stripped_thumbnail import StrippedThumbnail
from .thumbnail import Thumbnail
@ -38,7 +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", "ProfilePhotos", "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
)

View File

@ -1,57 +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
import pyrogram
from .photo import Photo
from ..object import Object
class ProfilePhotos(Object):
"""Contains a user's profile pictures.
Parameters:
total_count (``int``):
Total number of profile pictures the target user has.
profile_photos (List of :obj:`Photo`):
Requested profile pictures.
"""
__slots__ = ["total_count", "profile_photos"]
def __init__(
self,
*,
client: "pyrogram.BaseClient" = None,
total_count: int,
profile_photos: List[Photo]
):
super().__init__(client)
self.total_count = total_count
self.profile_photos = profile_photos
@staticmethod
def _parse(client, photos) -> "ProfilePhotos":
return ProfilePhotos(
total_count=getattr(photos, "count", len(photos.photos)),
profile_photos=[Photo._parse(client, photo) for photo in photos.photos],
client=client
)

View File

@ -18,16 +18,13 @@
from .chat import Chat
from .chat_member import ChatMember
from .chat_members import ChatMembers
from .chat_permissions import ChatPermissions
from .chat_photo import ChatPhoto
from .chat_preview import ChatPreview
from .dialog import Dialog
from .dialogs import Dialogs
from .user import User
from .user_status import UserStatus
__all__ = [
"Chat", "ChatMember", "ChatMembers", "ChatPermissions", "ChatPhoto", "ChatPreview", "Dialog", "Dialogs", "User",
"UserStatus"
"Chat", "ChatMember", "ChatPermissions", "ChatPhoto", "ChatPreview", "Dialog", "User", "UserStatus"
]

View File

@ -1,71 +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
import pyrogram
from pyrogram.api import types
from .chat_member import ChatMember
from ..object import Object
class ChatMembers(Object):
"""Contains information about the members list of a chat.
Parameters:
total_count (``int``):
Total number of members the chat has.
chat_members (List of :obj:`ChatMember <pyrogram.ChatMember>`):
Requested chat members.
"""
__slots__ = ["total_count", "chat_members"]
def __init__(
self,
*,
client: "pyrogram.BaseClient" = None,
total_count: int,
chat_members: List[ChatMember]
):
super().__init__(client)
self.total_count = total_count
self.chat_members = chat_members
@staticmethod
def _parse(client, members):
users = {i.id: i for i in members.users}
chat_members = []
if isinstance(members, types.channels.ChannelParticipants):
total_count = members.count
members = members.participants
else:
members = members.full_chat.participants.participants
total_count = len(members)
for member in members:
chat_members.append(ChatMember._parse(client, member, users))
return ChatMembers(
total_count=total_count,
chat_members=chat_members,
client=client
)

View File

@ -1,87 +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
import pyrogram
from pyrogram.api import types
from .dialog import Dialog
from ..messages_and_media import Message
from ..object import Object
class Dialogs(Object):
"""Contains a user's dialogs chunk.
Parameters:
total_count (``int``):
Total number of dialogs the user has.
dialogs (List of :obj:`Dialog`):
Requested dialogs.
"""
__slots__ = ["total_count", "dialogs"]
def __init__(
self,
*,
client: "pyrogram.BaseClient" = None,
total_count: int,
dialogs: List[Dialog]
):
super().__init__(client)
self.total_count = total_count
self.dialogs = dialogs
@staticmethod
def _parse(client, dialogs: types.messages.Dialogs) -> "Dialogs":
users = {i.id: i for i in dialogs.users}
chats = {i.id: i for i in dialogs.chats}
messages = {}
for message in dialogs.messages:
to_id = message.to_id
if isinstance(to_id, types.PeerUser):
if message.out:
chat_id = to_id.user_id
else:
chat_id = message.from_id
elif isinstance(to_id, types.PeerChat):
chat_id = -to_id.chat_id
else:
chat_id = int("-100" + str(to_id.channel_id))
messages[chat_id] = Message._parse(client, message, users, chats)
parsed_dialogs = []
for dialog in dialogs.dialogs:
if not isinstance(dialog, types.Dialog):
continue
parsed_dialogs.append(Dialog._parse(client, dialog, messages, users, chats))
return Dialogs(
total_count=getattr(dialogs, "count", len(dialogs.dialogs)),
dialogs=parsed_dialogs,
client=client
)