Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/client/client.py
#	pyrogram/client/methods/chats/get_chat.py
#	pyrogram/client/methods/messages/get_messages.py
#	pyrogram/client/types/messages_and_media/messages.py
This commit is contained in:
Dan 2018-12-31 12:06:15 +01:00
commit 2ea1f0f323
29 changed files with 390 additions and 146 deletions

View file

@ -1,5 +1,5 @@
Bad Request 400 - Bad Request
=========== =================
.. module:: pyrogram.api.errors.BadRequest .. module:: pyrogram.api.errors.BadRequest

View file

@ -1,5 +1,5 @@
Flood 420 - Flood
===== ===========
.. module:: pyrogram.api.errors.Flood .. module:: pyrogram.api.errors.Flood

View file

@ -1,5 +1,5 @@
Forbidden 403 - Forbidden
========= ===============
.. module:: pyrogram.api.errors.Forbidden .. module:: pyrogram.api.errors.Forbidden

View file

@ -1,5 +1,5 @@
Internal Server Error 500 - Internal Server Error
===================== ===========================
.. module:: pyrogram.api.errors.InternalServerError .. module:: pyrogram.api.errors.InternalServerError

View file

@ -1,5 +1,5 @@
Not Acceptable 406 - Not Acceptable
============== ====================
.. module:: pyrogram.api.errors.NotAcceptable .. module:: pyrogram.api.errors.NotAcceptable

View file

@ -1,5 +1,5 @@
See Other 303 - See Other
========= ===============
.. module:: pyrogram.api.errors.SeeOther .. module:: pyrogram.api.errors.SeeOther

View file

@ -1,5 +1,5 @@
Unauthorized 401 - Unauthorized
============ ==================
.. module:: pyrogram.api.errors.Unauthorized .. module:: pyrogram.api.errors.Unauthorized

View file

@ -1,5 +1,5 @@
Unknown Error 520 - Unknown Error
============= ===================
.. module:: pyrogram.api.errors.UnknownError .. module:: pyrogram.api.errors.UnknownError

View file

@ -93,6 +93,7 @@ To get started, press the Next button.
resources/BotsInteraction resources/BotsInteraction
resources/ErrorHandling resources/ErrorHandling
resources/TestServers resources/TestServers
resources/AdvancedUsage
resources/Changelog resources/Changelog
.. toctree:: .. toctree::

View file

@ -19,7 +19,7 @@ Utilities
remove_handler remove_handler
send send
resolve_peer resolve_peer
download_media save_file
Decorators Decorators
---------- ----------
@ -65,6 +65,7 @@ Messages
send_poll send_poll
vote_poll vote_poll
retract_vote retract_vote
download_media
Chats Chats
----- -----
@ -86,6 +87,7 @@ Chats
pin_chat_message pin_chat_message
unpin_chat_message unpin_chat_message
get_chat get_chat
get_chat_preview
get_chat_member get_chat_member
get_chat_members get_chat_members
get_chat_members_count get_chat_members_count

View file

@ -12,6 +12,7 @@ Users & Chats
User User
UserStatus UserStatus
Chat Chat
ChatPreview
ChatPhoto ChatPhoto
ChatMember ChatMember
ChatMembers ChatMembers
@ -82,6 +83,9 @@ Input Media
.. autoclass:: Chat .. autoclass:: Chat
:members: :members:
.. autoclass:: ChatPreview
:members:
.. autoclass:: ChatPhoto .. autoclass:: ChatPhoto
:members: :members:

View file

@ -0,0 +1,121 @@
Advanced Usage
==============
In this section, you'll be shown the alternative way of communicating with Telegram using Pyrogram: the main Telegram
API with its raw functions and types.
Telegram Raw API
----------------
If you can't find a high-level method for your needs or if you want complete, low-level access to the whole
Telegram API, you have to use the raw :mod:`functions <pyrogram.api.functions>` and :mod:`types <pyrogram.api.types>`
exposed by the ``pyrogram.api`` package and call any Telegram API method you wish using the
:meth:`send() <pyrogram.Client.send>` method provided by the Client class.
.. hint::
Every available high-level method mentioned in the previous page is built on top of these raw functions.
Nothing stops you from using the raw functions only, but they are rather complex and `plenty of them`_ are already
re-implemented by providing a much simpler and cleaner interface which is very similar to the Bot API.
If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_!
Caveats
-------
As hinted before, raw functions and types can be confusing, mainly because people don't realize they must accept
*exactly* the right values, but also because most of them don't have enough Python experience to fully grasp how things
work.
This section will therefore explain some pitfalls to take into consideration when working with the raw API.
Chat IDs
^^^^^^^^
The way Telegram works makes it impossible to directly send a message to a user or a chat by using their IDs only.
Instead, a pair of ``id`` and ``access_hash`` wrapped in a so called ``InputPeer`` is always needed.
There are three different InputPeer types, one for each kind of Telegram entity.
Whenever an InputPeer is needed you must pass one of these:
- `InputPeerUser <https://docs.pyrogram.ml/types/InputPeerUser>`_ - Users
- `InputPeerChat <https://docs.pyrogram.ml/types/InputPeerChat>`_ - Basic Chats
- `InputPeerChannel <https://docs.pyrogram.ml/types/InputPeerChannel>`_ - Either Channels or Supergroups
But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides
:meth:`resolve_peer() <pyrogram.Client.resolve_peer>` as a convenience utility method that returns the correct InputPeer
by accepting a peer ID only.
Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and
all positive within their respective raw types.
Things are different when working with Pyrogram's API because having them in the same space can theoretically lead to
collisions, and that's why Pyrogram (as well as the official Bot API) uses a slightly different representation for each
kind of ID.
For example, given the ID *123456789*, here's how Pyrogram can tell entities apart:
- ``+ID`` - User: *123456789*
- ``-ID`` - Chat: *-123456789*
- ``-100ID`` - Channel (and Supergroup): *-100123456789*
So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an
high-level method.
Examples
--------
- Update first name, last name and bio:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions
with Client("my_account") as app:
app.send(
functions.account.UpdateProfile(
first_name="Dan", last_name="Tès",
about="Bio written from Pyrogram"
)
)
- Share your Last Seen time only with your contacts:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions, types
with Client("my_account") as app:
app.send(
functions.account.SetPrivacy(
key=types.InputPrivacyKeyStatusTimestamp(),
rules=[types.InputPrivacyValueAllowContacts()]
)
)
- Invite users to your channel/supergroup:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions, types
with Client("my_account") as app:
app.send(
functions.channels.InviteToChannel(
channel=app.resolve_peer(123456789), # ID or Username
users=[ # The users you want to invite
app.resolve_peer(23456789), # By ID
app.resolve_peer("username"), # By username
app.resolve_peer("393281234567"), # By phone number
]
)
)
.. _plenty of them: ../pyrogram/Client.html#messages
.. _Raw Functions: Usage.html#using-raw-functions
.. _Community: https://t.me/PyrogramChat

View file

@ -6,13 +6,13 @@ Errors are inevitable when working with the API, and they must be correctly hand
There are many errors that Telegram could return, but they all fall in one of these categories There are many errors that Telegram could return, but they all fall in one of these categories
(which are in turn children of the :obj:`pyrogram.Error` superclass) (which are in turn children of the :obj:`pyrogram.Error` superclass)
- :obj:`303 See Other <pyrogram.api.errors.SeeOther>` - :obj:`303 - See Other <pyrogram.api.errors.SeeOther>`
- :obj:`400 Bad Request <pyrogram.api.errors.BadRequest>` - :obj:`400 - Bad Request <pyrogram.api.errors.BadRequest>`
- :obj:`401 Unauthorized <pyrogram.api.errors.Unauthorized>` - :obj:`401 - Unauthorized <pyrogram.api.errors.Unauthorized>`
- :obj:`403 Forbidden <pyrogram.api.errors.Forbidden>` - :obj:`403 - Forbidden <pyrogram.api.errors.Forbidden>`
- :obj:`406 Not Acceptable <pyrogram.api.errors.NotAcceptable>` - :obj:`406 - Not Acceptable <pyrogram.api.errors.NotAcceptable>`
- :obj:`420 Flood <pyrogram.api.errors.Flood>` - :obj:`420 - Flood <pyrogram.api.errors.Flood>`
- :obj:`500 Internal Server Error <pyrogram.api.errors.InternalServerError>` - :obj:`500 - Internal Server Error <pyrogram.api.errors.InternalServerError>`
As stated above, there are really many (too many) errors, and in case Pyrogram does not know anything yet about a As stated above, there are really many (too many) errors, and in case Pyrogram does not know anything yet about a
specific one, it raises a special :obj:`520 Unknown Error <pyrogram.api.errors.UnknownError>` exception and logs it specific one, it raises a special :obj:`520 Unknown Error <pyrogram.api.errors.UnknownError>` exception and logs it

View file

@ -1,8 +1,7 @@
Usage Usage
===== =====
Having your `project set up`_ and your account authorized_, it's time to play with the API. Having your `project set up`_ and your account authorized_, it's time to play with the API. Let's start!
In this section, you'll be shown two ways of communicating with Telegram using Pyrogram. Let's start!
High-level API High-level API
-------------- --------------
@ -43,79 +42,8 @@ exceptions in your code:
More examples on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_. More examples on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_.
Raw Functions
-------------
If you can't find a high-level method for your needs or if you want complete, low-level access to the whole Telegram API,
you have to use the raw :mod:`functions <pyrogram.api.functions>` and :mod:`types <pyrogram.api.types>` exposed by the
``pyrogram.api`` package and call any Telegram API method you wish using the :meth:`send() <pyrogram.Client.send>`
method provided by the Client class.
.. hint::
Every high-level method mentioned in the section above is built on top of these raw functions.
Nothing stops you from using the raw functions only, but they are rather complex and `plenty of them`_ are already
re-implemented by providing a much simpler and cleaner interface which is very similar to the Bot API.
If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_!
Examples (more on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_):
- Update first name, last name and bio:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions
with Client("my_account") as app:
app.send(
functions.account.UpdateProfile(
first_name="Dan", last_name="Tès",
about="Bio written from Pyrogram"
)
)
- Share your Last Seen time only with your contacts:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions, types
with Client("my_account") as app:
app.send(
functions.account.SetPrivacy(
key=types.InputPrivacyKeyStatusTimestamp(),
rules=[types.InputPrivacyValueAllowContacts()]
)
)
- Invite users to your channel/supergroup:
.. code-block:: python
from pyrogram import Client
from pyrogram.api import functions, types
with Client("my_account") as app:
app.send(
functions.channels.InviteToChannel(
channel=app.resolve_peer(123456789), # ID or Username
users=[ # The users you want to invite
app.resolve_peer(23456789), # By ID
app.resolve_peer("username"), # By username
app.resolve_peer("393281234567"), # By phone number
]
)
)
.. _methods: ../pyrogram/Client.html#messages
.. _plenty of them: ../pyrogram/Client.html#messages
.. _types: ../pyrogram/Types.html
.. _Raw Functions: Usage.html#using-raw-functions
.. _Community: https://t.me/PyrogramChat
.. _project set up: Setup.html .. _project set up: Setup.html
.. _authorized: Setup.html#user-authorization .. _authorized: Setup.html#user-authorization
.. _Telegram Bot API: https://core.telegram.org/bots/api .. _Telegram Bot API: https://core.telegram.org/bots/api
.. _methods: ../pyrogram/Client.html#messages
.. _types: ../pyrogram/Types.html

View file

@ -40,7 +40,7 @@ from .client.types import (
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus, Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus,
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply, UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove,
Poll, PollOption Poll, PollOption, ChatPreview
) )
from .client import ( from .client import (
Client, ChatAction, ParseMode, Emoji, Client, ChatAction, ParseMode, Emoji,

View file

@ -919,9 +919,9 @@ class Client(Methods, BaseClient):
log.info("UpdatesWorkerTask stopped") log.info("UpdatesWorkerTask stopped")
async def send(self, async def send(self,
data: Object, data: Object,
retries: int = Session.MAX_RETRIES, retries: int = Session.MAX_RETRIES,
timeout: float = Session.WAIT_TIMEOUT): timeout: float = Session.WAIT_TIMEOUT):
"""Use this method to send Raw Function queries. """Use this method to send Raw Function queries.
This method makes possible to manually call every single Telegram API method in a low-level manner. This method makes possible to manually call every single Telegram API method in a low-level manner.
@ -1081,7 +1081,7 @@ class Client(Methods, BaseClient):
) )
async def get_initial_dialogs_chunk(self, async def get_initial_dialogs_chunk(self,
offset_date: int = 0): offset_date: int = 0):
while True: while True:
try: try:
r = await self.send( r = await self.send(
@ -1114,12 +1114,12 @@ class Client(Methods, BaseClient):
await self.get_initial_dialogs_chunk() await self.get_initial_dialogs_chunk()
async def resolve_peer(self, async def resolve_peer(self,
peer_id: Union[int, str]): peer_id: Union[int, str]):
"""Use this method to get the InputPeer of a known peer_id. """Use this method to get the InputPeer of a known peer_id.
This is a utility method intended to be used only when working with Raw Functions (i.e: a Telegram API method This is a utility method intended to be used **only** when working with Raw Functions (i.e: a Telegram API
you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an InputPeer method you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an
type is required. InputPeer type is required.
Args: Args:
peer_id (``int`` | ``str``): peer_id (``int`` | ``str``):
@ -1147,8 +1147,8 @@ class Client(Methods, BaseClient):
except ValueError: except ValueError:
if peer_id not in self.peers_by_username: if peer_id not in self.peers_by_username:
await self.send(functions.contacts.ResolveUsername(username=peer_id await self.send(functions.contacts.ResolveUsername(username=peer_id
) )
) )
return self.peers_by_username[peer_id] return self.peers_by_username[peer_id]
else: else:
@ -1190,6 +1190,52 @@ class Client(Methods, BaseClient):
file_part: int = 0, file_part: int = 0,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()): progress_args: tuple = ()):
"""Use this method to upload a file onto Telegram servers, without actually sending the message to anyone.
This is a utility method intended to be used **only** when working with Raw Functions (i.e: a Telegram API
method you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an
InputFile type is required.
Args:
path (``str``):
The path of the file you want to upload that exists on your local machine.
file_id (``int``, *optional*):
In case a file part expired, pass the file_id and the file_part to retry uploading that specific chunk.
file_part (``int``, *optional*):
In case a file part expired, pass the file_id and the file_part to retry uploading that specific chunk.
progress (``callable``, *optional*):
Pass a callback function to view the upload progress.
The function must take *(client, current, total, \*args)* as positional arguments (look at the section
below for a detailed description).
progress_args (``tuple``, *optional*):
Extra custom arguments for the progress callback function. Useful, for example, if you want to pass
a chat_id and a message_id in order to edit a message with the updated progress.
Other Parameters:
client (:obj:`Client <pyrogram.Client>`):
The Client itself, useful when you want to call other API methods inside the callback function.
current (``int``):
The amount of bytes uploaded so far.
total (``int``):
The size of the file.
*args (``tuple``, *optional*):
Extra custom arguments as defined in the *progress_args* parameter.
You can either keep *\*args* or add every single extra argument in your function signature.
Returns:
On success, the uploaded file is returned in form of an InputFile object.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
"""
async def worker(session): async def worker(session):
while True: while True:
data = await queue.get() data = await queue.get()

View file

@ -23,7 +23,6 @@ from .decorators import Decorators
from .messages import Messages from .messages import Messages
from .password import Password from .password import Password
from .users import Users from .users import Users
from .utilities import Utilities
class Methods( class Methods(
@ -32,7 +31,6 @@ class Methods(
Password, Password,
Chats, Chats,
Users, Users,
Utilities,
Messages, Messages,
Decorators Decorators
): ):

View file

@ -22,6 +22,7 @@ from .get_chat import GetChat
from .get_chat_member import GetChatMember from .get_chat_member import GetChatMember
from .get_chat_members import GetChatMembers from .get_chat_members import GetChatMembers
from .get_chat_members_count import GetChatMembersCount from .get_chat_members_count import GetChatMembersCount
from .get_chat_preview import GetChatPreview
from .get_dialogs import GetDialogs from .get_dialogs import GetDialogs
from .join_chat import JoinChat from .join_chat import JoinChat
from .kick_chat_member import KickChatMember from .kick_chat_member import KickChatMember
@ -54,6 +55,7 @@ class Chats(
PinChatMessage, PinChatMessage,
UnpinChatMessage, UnpinChatMessage,
GetDialogs, GetDialogs,
GetChatMembersCount GetChatMembersCount,
GetChatPreview
): ):
pass pass

View file

@ -32,13 +32,36 @@ class GetChat(BaseClient):
Args: Args:
chat_id (``int`` | ``str``): chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat. Unique identifier (int) or username (str) of the target chat.
Unique identifier for the target chat in form of a *t.me/joinchat/* link, identifier (int) or username
of the target channel/supergroup (in the format @username).
Returns: Returns:
On success, a :obj:`Chat <pyrogram.Chat>` object is returned. On success, a :obj:`Chat <pyrogram.Chat>` object is returned.
Raises: Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error. :class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
``ValueError`` in case the chat invite link refers to a chat you haven't joined yet.
""" """
match = self.INVITE_LINK_RE.match(str(chat_id))
if match:
h = match.group(1)
r = await self.send(
functions.messages.CheckChatInvite(
hash=h
)
)
if isinstance(r, types.ChatInvite):
raise ValueError("You haven't joined \"t.me/joinchat/{}\" yet".format(h))
if isinstance(r.chat, types.Chat):
chat_id = -r.chat.id
if isinstance(r.chat, types.Channel):
chat_id = int("-100" + str(r.chat.id))
peer = await self.resolve_peer(chat_id) peer = await self.resolve_peer(chat_id)
if isinstance(peer, types.InputPeerChannel): if isinstance(peer, types.InputPeerChannel):

View file

@ -0,0 +1,63 @@
# 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/>.
import pyrogram
from pyrogram.api import functions, types
from ...ext import BaseClient
class GetChatPreview(BaseClient):
def get_chat_preview(self,
invite_link: str):
"""Use this method to get the preview of a chat using the invite link.
This method only returns a chat preview, if you want to join a chat use :meth:`join_chat`
Args:
invite_link (``str``):
Unique identifier for the target chat in form of *t.me/joinchat/* links.
Returns:
Either :obj:`Chat` or :obj:`ChatPreview`, depending on whether you already joined the chat or not.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
``ValueError`` in case of an invalid invite_link.
"""
match = self.INVITE_LINK_RE.match(invite_link)
if match:
r = self.send(
functions.messages.CheckChatInvite(
hash=match.group(1)
)
)
if isinstance(r, types.ChatInvite):
return pyrogram.ChatPreview._parse(self, r)
if isinstance(r, types.ChatInviteAlready):
chat = r.chat
if isinstance(chat, types.Chat):
return pyrogram.Chat._parse_chat_chat(self, chat)
if isinstance(chat, types.Channel):
return pyrogram.Chat._parse_channel_chat(self, chat)
else:
raise ValueError("The invite_link is invalid")

View file

@ -27,7 +27,7 @@ class JoinChat(BaseClient):
Args: Args:
chat_id (``str``): chat_id (``str``):
Unique identifier for the target chat in form of *t.me/joinchat/* links or username of the target Unique identifier for the target chat in form of a *t.me/joinchat/* link or username of the target
channel/supergroup (in the format @username). channel/supergroup (in the format @username).
Raises: Raises:

View file

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .delete_messages import DeleteMessages from .delete_messages import DeleteMessages
from .download_media import DownloadMedia
from .edit_message_caption import EditMessageCaption from .edit_message_caption import EditMessageCaption
from .edit_message_media import EditMessageMedia from .edit_message_media import EditMessageMedia
from .edit_message_reply_markup import EditMessageReplyMarkup from .edit_message_reply_markup import EditMessageReplyMarkup
@ -68,6 +69,7 @@ class Messages(
SendVoice, SendVoice,
SendPoll, SendPoll,
VotePoll, VotePoll,
RetractVote RetractVote,
DownloadMedia
): ):
pass pass

View file

@ -20,7 +20,7 @@ import asyncio
from typing import Union from typing import Union
import pyrogram import pyrogram
from ...ext import BaseClient from pyrogram.client.ext import BaseClient
class DownloadMedia(BaseClient): class DownloadMedia(BaseClient):

View file

@ -78,6 +78,6 @@ class GetMessages(BaseClient):
else: else:
rpc = functions.messages.GetMessages(id=ids) rpc = functions.messages.GetMessages(id=ids)
messages = await pyrogram.Messages._parse(self, await self.send(rpc)) messages = await pyrogram.Messages._parse(self, await self.send(rpc), replies)
return messages if is_iterable else messages.messages[0] return messages if is_iterable else messages.messages[0]

View file

@ -1,25 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 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 .download_media import DownloadMedia
class Utilities(
DownloadMedia
):
pass

View file

@ -35,5 +35,5 @@ from .messages_and_media import (
) )
from .user_and_chats import ( from .user_and_chats import (
Chat, ChatMember, ChatMembers, ChatPhoto, Chat, ChatMember, ChatMembers, ChatPhoto,
Dialog, Dialogs, User, UserStatus Dialog, Dialogs, User, UserStatus, ChatPreview
) )

View file

@ -47,7 +47,7 @@ class Messages(PyrogramType):
self.messages = messages self.messages = messages
@staticmethod @staticmethod
async def _parse(client, messages: types.messages.Messages) -> "Messages": async def _parse(client, messages: types.messages.Messages, replies: int = 1) -> "Messages":
users = {i.id: i for i in messages.users} users = {i.id: i for i in messages.users}
chats = {i.id: i for i in messages.chats} chats = {i.id: i for i in messages.chats}
@ -55,7 +55,7 @@ class Messages(PyrogramType):
parsed_messages = [] parsed_messages = []
for message in messages.messages: for message in messages.messages:
parsed_messages.append(await Message._parse(client, message, users, chats)) parsed_messages.append(await Message._parse(client, message, users, chats, replies))
return Messages( return Messages(
total_count=getattr(messages, "count", len(messages.messages)), total_count=getattr(messages, "count", len(messages.messages)),

View file

@ -20,6 +20,7 @@ from .chat import Chat
from .chat_member import ChatMember from .chat_member import ChatMember
from .chat_members import ChatMembers from .chat_members import ChatMembers
from .chat_photo import ChatPhoto from .chat_photo import ChatPhoto
from .chat_preview import ChatPreview
from .dialog import Dialog from .dialog import Dialog
from .dialogs import Dialogs from .dialogs import Dialogs
from .user import User from .user import User

View file

@ -0,0 +1,78 @@
# 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_photo import ChatPhoto
from ..pyrogram_type import PyrogramType
from ..user_and_chats.user import User
class ChatPreview(PyrogramType):
"""This object represents a chat preview.
Args:
title (``str``):
Title of the chat.
photo (:obj:`ChatPhoto`):
Chat photo. Suitable for downloads only.
type (``str``):
Type of chat, can be either, "group", "supergroup" or "channel".
members_count (``int``):
Chat members count.
members (List of :obj:`User`, *optional*):
Preview of some of the chat members.
"""
def __init__(self,
*,
client: "pyrogram.client.ext.BaseClient",
title: str,
photo: ChatPhoto,
type: str,
members_count: int,
members: List[User] = None):
super().__init__(client)
self.title = title
self.photo = photo
self.type = type
self.members_count = members_count
self.members = members
@staticmethod
def _parse(client, chat_invite: types.ChatInvite) -> "ChatPreview":
return ChatPreview(
title=chat_invite.title,
photo=ChatPhoto._parse(client, chat_invite.photo),
type=("group" if not chat_invite.channel else
"channel" if chat_invite.broadcast else
"supergroup"),
members_count=chat_invite.participants_count,
members=[User._parse(client, user) for user in chat_invite.participants] or None,
client=client
)
# TODO: Maybe just merge this object into Chat itself by adding the "members" field.
# get_chat can be used as well instead of get_chat_preview