diff --git a/docs/source/errors/BadRequest.rst b/docs/source/errors/BadRequest.rst index 7ea6cb4b..c51a7d54 100644 --- a/docs/source/errors/BadRequest.rst +++ b/docs/source/errors/BadRequest.rst @@ -1,5 +1,5 @@ -Bad Request -=========== +400 - Bad Request +================= .. module:: pyrogram.api.errors.BadRequest diff --git a/docs/source/errors/Flood.rst b/docs/source/errors/Flood.rst index a83a216c..72f819ea 100644 --- a/docs/source/errors/Flood.rst +++ b/docs/source/errors/Flood.rst @@ -1,5 +1,5 @@ -Flood -===== +420 - Flood +=========== .. module:: pyrogram.api.errors.Flood diff --git a/docs/source/errors/Forbidden.rst b/docs/source/errors/Forbidden.rst index fd2e08ce..aaaceaff 100644 --- a/docs/source/errors/Forbidden.rst +++ b/docs/source/errors/Forbidden.rst @@ -1,5 +1,5 @@ -Forbidden -========= +403 - Forbidden +=============== .. module:: pyrogram.api.errors.Forbidden diff --git a/docs/source/errors/InternalServerError.rst b/docs/source/errors/InternalServerError.rst index 310c5cfc..5e506fc9 100644 --- a/docs/source/errors/InternalServerError.rst +++ b/docs/source/errors/InternalServerError.rst @@ -1,5 +1,5 @@ -Internal Server Error -===================== +500 - Internal Server Error +=========================== .. module:: pyrogram.api.errors.InternalServerError diff --git a/docs/source/errors/NotAcceptable.rst b/docs/source/errors/NotAcceptable.rst index 66ebaf72..e9301396 100644 --- a/docs/source/errors/NotAcceptable.rst +++ b/docs/source/errors/NotAcceptable.rst @@ -1,5 +1,5 @@ -Not Acceptable -============== +406 - Not Acceptable +==================== .. module:: pyrogram.api.errors.NotAcceptable diff --git a/docs/source/errors/SeeOther.rst b/docs/source/errors/SeeOther.rst index 49411379..a916e779 100644 --- a/docs/source/errors/SeeOther.rst +++ b/docs/source/errors/SeeOther.rst @@ -1,5 +1,5 @@ -See Other -========= +303 - See Other +=============== .. module:: pyrogram.api.errors.SeeOther diff --git a/docs/source/errors/Unauthorized.rst b/docs/source/errors/Unauthorized.rst index b3926132..6de3ff67 100644 --- a/docs/source/errors/Unauthorized.rst +++ b/docs/source/errors/Unauthorized.rst @@ -1,5 +1,5 @@ -Unauthorized -============ +401 - Unauthorized +================== .. module:: pyrogram.api.errors.Unauthorized diff --git a/docs/source/errors/UnknownError.rst b/docs/source/errors/UnknownError.rst index 030f3e02..767f19c3 100644 --- a/docs/source/errors/UnknownError.rst +++ b/docs/source/errors/UnknownError.rst @@ -1,5 +1,5 @@ -Unknown Error -============= +520 - Unknown Error +=================== .. module:: pyrogram.api.errors.UnknownError diff --git a/docs/source/index.rst b/docs/source/index.rst index 8234374c..085b38fb 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -93,6 +93,7 @@ To get started, press the Next button. resources/BotsInteraction resources/ErrorHandling resources/TestServers + resources/AdvancedUsage resources/Changelog .. toctree:: diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index a0177a12..14796ef2 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -19,7 +19,7 @@ Utilities remove_handler send resolve_peer - download_media + save_file Decorators ---------- @@ -65,6 +65,7 @@ Messages send_poll vote_poll retract_vote + download_media Chats ----- @@ -86,6 +87,7 @@ Chats pin_chat_message unpin_chat_message get_chat + get_chat_preview get_chat_member get_chat_members get_chat_members_count diff --git a/docs/source/pyrogram/Types.rst b/docs/source/pyrogram/Types.rst index 47c755f9..bf1bf937 100644 --- a/docs/source/pyrogram/Types.rst +++ b/docs/source/pyrogram/Types.rst @@ -12,6 +12,7 @@ Users & Chats User UserStatus Chat + ChatPreview ChatPhoto ChatMember ChatMembers @@ -82,6 +83,9 @@ Input Media .. autoclass:: Chat :members: +.. autoclass:: ChatPreview + :members: + .. autoclass:: ChatPhoto :members: diff --git a/docs/source/resources/AdvancedUsage.rst b/docs/source/resources/AdvancedUsage.rst new file mode 100644 index 00000000..02395f26 --- /dev/null +++ b/docs/source/resources/AdvancedUsage.rst @@ -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 ` and :mod:`types ` +exposed by the ``pyrogram.api`` package and call any Telegram API method you wish using the +:meth:`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 `_ - Users + - `InputPeerChat `_ - Basic Chats + - `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() ` 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 \ No newline at end of file diff --git a/docs/source/resources/ErrorHandling.rst b/docs/source/resources/ErrorHandling.rst index f2a77b7a..1f08c165 100644 --- a/docs/source/resources/ErrorHandling.rst +++ b/docs/source/resources/ErrorHandling.rst @@ -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 (which are in turn children of the :obj:`pyrogram.Error` superclass) -- :obj:`303 See Other ` -- :obj:`400 Bad Request ` -- :obj:`401 Unauthorized ` -- :obj:`403 Forbidden ` -- :obj:`406 Not Acceptable ` -- :obj:`420 Flood ` -- :obj:`500 Internal Server Error ` +- :obj:`303 - See Other ` +- :obj:`400 - Bad Request ` +- :obj:`401 - Unauthorized ` +- :obj:`403 - Forbidden ` +- :obj:`406 - Not Acceptable ` +- :obj:`420 - Flood ` +- :obj:`500 - Internal Server Error ` 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 ` exception and logs it diff --git a/docs/source/start/Usage.rst b/docs/source/start/Usage.rst index 6c1697b9..8bb197ab 100644 --- a/docs/source/start/Usage.rst +++ b/docs/source/start/Usage.rst @@ -1,8 +1,7 @@ Usage ===== -Having your `project set up`_ and your account authorized_, it's time to play with the API. -In this section, you'll be shown two ways of communicating with Telegram using Pyrogram. Let's start! +Having your `project set up`_ and your account authorized_, it's time to play with the API. Let's start! High-level API -------------- @@ -43,79 +42,8 @@ exceptions in your code: More examples on `GitHub `_. -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 ` and :mod:`types ` exposed by the -``pyrogram.api`` package and call any Telegram API method you wish using the :meth:`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 `_): - -- 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 .. _authorized: Setup.html#user-authorization -.. _Telegram Bot API: https://core.telegram.org/bots/api \ No newline at end of file +.. _Telegram Bot API: https://core.telegram.org/bots/api +.. _methods: ../pyrogram/Client.html#messages +.. _types: ../pyrogram/Types.html \ No newline at end of file diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 96249768..f6fbb8e5 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -40,7 +40,7 @@ from .client.types import ( Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus, UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, - Poll, PollOption + Poll, PollOption, ChatPreview ) from .client import ( Client, ChatAction, ParseMode, Emoji, diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index fa69b51d..77c4452c 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -919,9 +919,9 @@ class Client(Methods, BaseClient): log.info("UpdatesWorkerTask stopped") async def send(self, - data: Object, - retries: int = Session.MAX_RETRIES, - timeout: float = Session.WAIT_TIMEOUT): + data: Object, + retries: int = Session.MAX_RETRIES, + timeout: float = Session.WAIT_TIMEOUT): """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. @@ -1081,7 +1081,7 @@ class Client(Methods, BaseClient): ) async def get_initial_dialogs_chunk(self, - offset_date: int = 0): + offset_date: int = 0): while True: try: r = await self.send( @@ -1114,12 +1114,12 @@ class Client(Methods, BaseClient): await self.get_initial_dialogs_chunk() 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. - 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 InputPeer - type is required. + 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 + InputPeer type is required. Args: peer_id (``int`` | ``str``): @@ -1147,8 +1147,8 @@ class Client(Methods, BaseClient): except ValueError: if peer_id not in self.peers_by_username: await self.send(functions.contacts.ResolveUsername(username=peer_id - ) - ) + ) + ) return self.peers_by_username[peer_id] else: @@ -1190,6 +1190,52 @@ class Client(Methods, BaseClient): file_part: int = 0, progress: callable = None, 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 `): + 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 ` in case of a Telegram RPC error. + """ + async def worker(session): while True: data = await queue.get() diff --git a/pyrogram/client/methods/__init__.py b/pyrogram/client/methods/__init__.py index eba768bb..ea249e3f 100644 --- a/pyrogram/client/methods/__init__.py +++ b/pyrogram/client/methods/__init__.py @@ -23,7 +23,6 @@ from .decorators import Decorators from .messages import Messages from .password import Password from .users import Users -from .utilities import Utilities class Methods( @@ -32,7 +31,6 @@ class Methods( Password, Chats, Users, - Utilities, Messages, Decorators ): diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index f9eb25f3..3d928e87 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -22,6 +22,7 @@ from .get_chat import GetChat from .get_chat_member import GetChatMember from .get_chat_members import GetChatMembers from .get_chat_members_count import GetChatMembersCount +from .get_chat_preview import GetChatPreview from .get_dialogs import GetDialogs from .join_chat import JoinChat from .kick_chat_member import KickChatMember @@ -54,6 +55,7 @@ class Chats( PinChatMessage, UnpinChatMessage, GetDialogs, - GetChatMembersCount + GetChatMembersCount, + GetChatPreview ): pass diff --git a/pyrogram/client/methods/chats/get_chat.py b/pyrogram/client/methods/chats/get_chat.py index 8446b29d..7e8fdeb7 100644 --- a/pyrogram/client/methods/chats/get_chat.py +++ b/pyrogram/client/methods/chats/get_chat.py @@ -32,13 +32,36 @@ class GetChat(BaseClient): Args: chat_id (``int`` | ``str``): 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: On success, a :obj:`Chat ` object is returned. Raises: :class:`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) if isinstance(peer, types.InputPeerChannel): diff --git a/pyrogram/client/methods/chats/get_chat_preview.py b/pyrogram/client/methods/chats/get_chat_preview.py new file mode 100644 index 00000000..434c385b --- /dev/null +++ b/pyrogram/client/methods/chats/get_chat_preview.py @@ -0,0 +1,63 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2019 Dan Tès +# +# 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 . + +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 ` 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") diff --git a/pyrogram/client/methods/chats/join_chat.py b/pyrogram/client/methods/chats/join_chat.py index f37368ba..6daaac6e 100644 --- a/pyrogram/client/methods/chats/join_chat.py +++ b/pyrogram/client/methods/chats/join_chat.py @@ -27,7 +27,7 @@ class JoinChat(BaseClient): Args: 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). Raises: diff --git a/pyrogram/client/methods/messages/__init__.py b/pyrogram/client/methods/messages/__init__.py index 66340283..cfb36fd0 100644 --- a/pyrogram/client/methods/messages/__init__.py +++ b/pyrogram/client/methods/messages/__init__.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from .delete_messages import DeleteMessages +from .download_media import DownloadMedia from .edit_message_caption import EditMessageCaption from .edit_message_media import EditMessageMedia from .edit_message_reply_markup import EditMessageReplyMarkup @@ -68,6 +69,7 @@ class Messages( SendVoice, SendPoll, VotePoll, - RetractVote + RetractVote, + DownloadMedia ): pass diff --git a/pyrogram/client/methods/utilities/download_media.py b/pyrogram/client/methods/messages/download_media.py similarity index 99% rename from pyrogram/client/methods/utilities/download_media.py rename to pyrogram/client/methods/messages/download_media.py index d9284d81..2dc0b71e 100644 --- a/pyrogram/client/methods/utilities/download_media.py +++ b/pyrogram/client/methods/messages/download_media.py @@ -20,7 +20,7 @@ import asyncio from typing import Union import pyrogram -from ...ext import BaseClient +from pyrogram.client.ext import BaseClient class DownloadMedia(BaseClient): diff --git a/pyrogram/client/methods/messages/get_messages.py b/pyrogram/client/methods/messages/get_messages.py index b1ee9339..9a47d256 100644 --- a/pyrogram/client/methods/messages/get_messages.py +++ b/pyrogram/client/methods/messages/get_messages.py @@ -78,6 +78,6 @@ class GetMessages(BaseClient): else: 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] diff --git a/pyrogram/client/methods/utilities/__init__.py b/pyrogram/client/methods/utilities/__init__.py deleted file mode 100644 index f8db23e5..00000000 --- a/pyrogram/client/methods/utilities/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# Pyrogram - Telegram MTProto API Client Library for Python -# Copyright (C) 2017-2018 Dan Tès -# -# 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 . - -from .download_media import DownloadMedia - - -class Utilities( - DownloadMedia -): - pass diff --git a/pyrogram/client/types/__init__.py b/pyrogram/client/types/__init__.py index 24de120f..7b30670f 100644 --- a/pyrogram/client/types/__init__.py +++ b/pyrogram/client/types/__init__.py @@ -35,5 +35,5 @@ from .messages_and_media import ( ) from .user_and_chats import ( Chat, ChatMember, ChatMembers, ChatPhoto, - Dialog, Dialogs, User, UserStatus + Dialog, Dialogs, User, UserStatus, ChatPreview ) diff --git a/pyrogram/client/types/messages_and_media/messages.py b/pyrogram/client/types/messages_and_media/messages.py index 31cfb3df..46e3aee2 100644 --- a/pyrogram/client/types/messages_and_media/messages.py +++ b/pyrogram/client/types/messages_and_media/messages.py @@ -47,7 +47,7 @@ class Messages(PyrogramType): self.messages = messages @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} chats = {i.id: i for i in messages.chats} @@ -55,7 +55,7 @@ class Messages(PyrogramType): parsed_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( total_count=getattr(messages, "count", len(messages.messages)), diff --git a/pyrogram/client/types/user_and_chats/__init__.py b/pyrogram/client/types/user_and_chats/__init__.py index 0f814b92..ec082dfe 100644 --- a/pyrogram/client/types/user_and_chats/__init__.py +++ b/pyrogram/client/types/user_and_chats/__init__.py @@ -20,6 +20,7 @@ from .chat import Chat from .chat_member import ChatMember from .chat_members import ChatMembers from .chat_photo import ChatPhoto +from .chat_preview import ChatPreview from .dialog import Dialog from .dialogs import Dialogs from .user import User diff --git a/pyrogram/client/types/user_and_chats/chat_preview.py b/pyrogram/client/types/user_and_chats/chat_preview.py new file mode 100644 index 00000000..45048637 --- /dev/null +++ b/pyrogram/client/types/user_and_chats/chat_preview.py @@ -0,0 +1,78 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-2019 Dan Tès +# +# 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 . + +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