diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index aa5714ec..3b6dbae7 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -506,6 +506,7 @@ def start(): f.write("\n 0xb0700027: \"pyrogram.client.types.Photo\",") f.write("\n 0xb0700028: \"pyrogram.client.types.Dialog\",") f.write("\n 0xb0700029: \"pyrogram.client.types.Dialogs\",") + f.write("\n 0xb0700030: \"pyrogram.client.types.ChatMembers\",") f.write("\n}\n") diff --git a/compiler/error/source/400_BAD_REQUEST.tsv b/compiler/error/source/400_BAD_REQUEST.tsv index cd196077..e00c10c5 100644 --- a/compiler/error/source/400_BAD_REQUEST.tsv +++ b/compiler/error/source/400_BAD_REQUEST.tsv @@ -62,4 +62,7 @@ USER_IS_BOT A bot cannot send messages to other bots or to itself WEBPAGE_CURL_FAILED Telegram could not fetch the provided URL STICKERSET_INVALID The requested sticker set is invalid PEER_FLOOD The method can't be used because your account is limited -MEDIA_CAPTION_TOO_LONG The media caption is longer than 200 characters \ No newline at end of file +MEDIA_CAPTION_TOO_LONG The media caption is longer than 200 characters +USER_NOT_MUTUAL_CONTACT The user is not a mutual contact +USER_CHANNELS_TOO_MUCH The user is already in too many channels or supergroups +API_ID_PUBLISHED_FLOOD You are using an API key that is limited on the server side \ No newline at end of file diff --git a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv index abb58495..60d1b51a 100644 --- a/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv +++ b/compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv @@ -3,4 +3,5 @@ AUTH_RESTART User authorization has restarted RPC_CALL_FAIL Telegram is having internal problems. Please try again later RPC_MCGET_FAIL Telegram is having internal problems. Please try again later PERSISTENT_TIMESTAMP_OUTDATED Telegram is having internal problems. Please try again later -HISTORY_GET_FAILED Telegram is having internal problems. Please try again later \ No newline at end of file +HISTORY_GET_FAILED Telegram is having internal problems. Please try again later +REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later \ No newline at end of file diff --git a/docs/source/pyrogram/Client.rst b/docs/source/pyrogram/Client.rst index 2fbd5879..bf9ac2ca 100644 --- a/docs/source/pyrogram/Client.rst +++ b/docs/source/pyrogram/Client.rst @@ -67,4 +67,10 @@ Client get_users get_chat get_messages - get_history \ No newline at end of file + get_history + set_chat_photo + delete_chat_photo + set_chat_title + set_chat_description + pin_chat_message + unpin_chat_message \ No newline at end of file diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 764afb4e..3d220237 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -35,14 +35,12 @@ __version__ = "0.8.0dev1" from .api.errors import Error from .client.types import ( - Audio, Chat, ChatMember, ChatPhoto, Contact, Document, InputMediaPhoto, + Audio, Chat, ChatMember, ChatMembers, ChatPhoto, Contact, Document, InputMediaPhoto, InputMediaVideo, InputPhoneContact, Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, UserProfilePhotos, - Venue, GIF, Video, VideoNote, Voice, CallbackQuery, Messages -) -from .client.types.reply_markup import ( - ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, - KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove + Venue, GIF, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply, + InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, + ReplyKeyboardRemove ) from .client import ( Client, ChatAction, ParseMode, Emoji, diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 833b9d2e..a53c1784 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -1259,8 +1259,6 @@ class Client(Methods, BaseClient): break f.write(chunk) - f.flush() - os.fsync(f.fileno()) offset += limit @@ -1343,8 +1341,6 @@ class Client(Methods, BaseClient): assert h.hash == sha256(cdn_chunk).digest(), "Invalid CDN hash part {}".format(i) f.write(decrypted_chunk) - f.flush() - os.fsync(f.fileno()) offset += limit diff --git a/pyrogram/client/ext/utils.py b/pyrogram/client/ext/utils.py index f300136f..c4b84528 100644 --- a/pyrogram/client/ext/utils.py +++ b/pyrogram/client/ext/utils.py @@ -72,6 +72,7 @@ async def ainput(prompt: str = ""): ENTITIES = { types.MessageEntityMention.ID: "mention", types.MessageEntityHashtag.ID: "hashtag", + types.MessageEntityCashtag.ID: "cashtag", types.MessageEntityBotCommand.ID: "bot_command", types.MessageEntityUrl.ID: "url", types.MessageEntityEmail.ID: "email", @@ -140,6 +141,10 @@ def parse_chat_photo(photo): def parse_user(user: types.User) -> pyrogram_types.User or None: return pyrogram_types.User( id=user.id, + is_self=user.is_self, + is_contact=user.contact, + is_mutual_contact=user.mutual_contact, + is_deleted=user.deleted, is_bot=user.bot, first_name=user.first_name, last_name=user.last_name, @@ -371,6 +376,7 @@ async def parse_messages( phone_number=media.phone_number, first_name=media.first_name, last_name=media.last_name or None, + vcard=media.vcard or None, user_id=media.user_id or None ) elif isinstance(media, types.MessageMediaVenue): @@ -412,8 +418,7 @@ async def parse_messages( duration=audio_attributes.duration, mime_type=doc.mime_type, file_size=doc.size, - thumb=parse_thumb(doc.thumb), - file_name=file_name, + waveform=audio_attributes.waveform, date=doc.date ) else: @@ -476,7 +481,6 @@ async def parse_messages( duration=video_attributes.duration, thumb=parse_thumb(doc.thumb), file_size=doc.size, - file_name=file_name, mime_type=doc.mime_type, date=doc.date ) @@ -938,3 +942,103 @@ def parse_dialog_chat(peer, users: dict, chats: dict): return parse_chat_chat(chats[peer.chat_id]) else: return parse_channel_chat(chats[peer.channel_id]) + + +def parse_chat_members(members: types.channels.ChannelParticipants or types.messages.ChatFull): + users = {i.id: i for i in members.users} + parsed_members = [] + + if isinstance(members, types.channels.ChannelParticipants): + members = members.participants + + for member in members: + user = parse_user(users[member.user_id]) + + if isinstance(member, (types.ChannelParticipant, types.ChannelParticipantSelf)): + parsed_members.append( + pyrogram_types.ChatMember( + user=user, + status="member" + ) + ) + elif isinstance(member, types.ChannelParticipantCreator): + parsed_members.append( + pyrogram_types.ChatMember( + user=user, + status="creator" + ) + ) + elif isinstance(member, types.ChannelParticipantAdmin): + rights = member.admin_rights # type: types.ChannelAdminRights + + parsed_members.append( + pyrogram_types.ChatMember( + user=user, + status="administrator", + can_be_edited=member.can_edit, + can_change_info=rights.change_info, + can_post_messages=rights.post_messages, + can_edit_messages=rights.edit_messages, + can_delete_messages=rights.delete_messages, + can_invite_users=rights.invite_users or rights.invite_link, + can_restrict_members=rights.ban_users, + can_pin_messages=rights.pin_messages, + can_promote_members=rights.add_admins + ) + ) + elif isinstance(member, types.ChannelParticipantBanned): + rights = member.banned_rights # type: types.ChannelBannedRights + + chat_member = pyrogram_types.ChatMember( + user=user, + status="kicked" if rights.view_messages else "restricted", + until_date=0 if rights.until_date == (1 << 31) - 1 else rights.until_date + ) + + if chat_member.status == "restricted": + chat_member.can_send_messages = not rights.send_messages + chat_member.can_send_media_messages = not rights.send_media + chat_member.can_send_other_messages = ( + not rights.send_stickers or not rights.send_gifs or + not rights.send_games or not rights.send_inline + ) + chat_member.can_add_web_page_previews = not rights.embed_links + + parsed_members.append(chat_member) + + return pyrogram_types.ChatMembers( + total_count=members.count, + chat_members=parsed_members + ) + else: + members = members.full_chat.participants.participants + + for member in members: + user = parse_user(users[member.user_id]) + + if isinstance(member, types.ChatParticipant): + parsed_members.append( + pyrogram_types.ChatMember( + user=user, + status="member" + ) + ) + elif isinstance(member, types.ChatParticipantCreator): + parsed_members.append( + pyrogram_types.ChatMember( + user=user, + status="creator" + ) + ) + elif isinstance(member, types.ChatParticipantAdmin): + parsed_members.append( + pyrogram_types.ChatMember( + user=user, + status="administrator" + ) + ) + + return pyrogram_types.ChatMembers( + total_count=len(members), + chat_members=parsed_members + ) diff --git a/pyrogram/client/methods/chats/__init__.py b/pyrogram/client/methods/chats/__init__.py index 9c887ef5..038440f6 100644 --- a/pyrogram/client/methods/chats/__init__.py +++ b/pyrogram/client/methods/chats/__init__.py @@ -16,14 +16,21 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from .delete_chat_photo import DeleteChatPhoto from .export_chat_invite_link import ExportChatInviteLink from .get_chat import GetChat +from .get_chat_members import GetChatMembers from .join_chat import JoinChat from .kick_chat_member import KickChatMember from .leave_chat import LeaveChat +from .pin_chat_message import PinChatMessage from .promote_chat_member import PromoteChatMember from .restrict_chat_member import RestrictChatMember +from .set_chat_description import SetChatDescription +from .set_chat_photo import SetChatPhoto +from .set_chat_title import SetChatTitle from .unban_chat_member import UnbanChatMember +from .unpin_chat_message import UnpinChatMessage class Chats( @@ -34,6 +41,13 @@ class Chats( KickChatMember, UnbanChatMember, RestrictChatMember, - PromoteChatMember + PromoteChatMember, + GetChatMembers, + SetChatPhoto, + DeleteChatPhoto, + SetChatTitle, + SetChatDescription, + PinChatMessage, + UnpinChatMessage ): pass diff --git a/pyrogram/client/methods/chats/delete_chat_photo.py b/pyrogram/client/methods/chats/delete_chat_photo.py new file mode 100644 index 00000000..57d90b11 --- /dev/null +++ b/pyrogram/client/methods/chats/delete_chat_photo.py @@ -0,0 +1,64 @@ +# 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 pyrogram.api import functions, types +from ...ext import BaseClient + + +class DeleteChatPhoto(BaseClient): + def delete_chat_photo(self, chat_id: int or str): + """Use this method to delete a chat photo. + Photos can't be changed for private chats. + You must be an administrator in the chat for this to work and must have the appropriate admin rights. + + Note: + In regular groups (non-supergroups), this method will only work if the "All Members Are Admins" + setting is off. + + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For a private channel/supergroup you can use its *t.me/joinchat/* link. + + Returns: + True on success. + + Raises: + :class:`Error ` + ``ValueError``: If a chat_id belongs to user. + """ + peer = self.resolve_peer(chat_id) + + if isinstance(peer, types.InputPeerChat): + self.send( + functions.messages.EditChatPhoto( + chat_id=peer.chat_id, + photo=types.InputChatPhotoEmpty() + ) + ) + elif isinstance(peer, types.InputPeerChannel): + self.send( + functions.channels.EditPhoto( + channel=peer, + photo=types.InputChatPhotoEmpty() + ) + ) + else: + raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) + + return True diff --git a/pyrogram/client/methods/chats/get_chat.py b/pyrogram/client/methods/chats/get_chat.py index 9b5a5fe8..050b8118 100644 --- a/pyrogram/client/methods/chats/get_chat.py +++ b/pyrogram/client/methods/chats/get_chat.py @@ -25,6 +25,11 @@ class GetChat(BaseClient): """Use this method to get up to date information about the chat (current name of the user for one-on-one conversations, current username of a user, group or channel, etc.) + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For a private channel/supergroup you can use its *t.me/joinchat/* link. + Returns: On success, a :obj:`Chat ` object is returned. diff --git a/pyrogram/client/methods/chats/get_chat_members.py b/pyrogram/client/methods/chats/get_chat_members.py new file mode 100644 index 00000000..a851ef58 --- /dev/null +++ b/pyrogram/client/methods/chats/get_chat_members.py @@ -0,0 +1,79 @@ +# 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 pyrogram.api import functions, types +from ...ext import BaseClient, utils + + +class Filters: + ALL = "all" + KICKED = "kicked" + RESTRICTED = "restricted" + BOTS = "bots" + RECENT = "recent" + ADMINISTRATORS = "administrators" + + +class GetChatMembers(BaseClient): + def get_chat_members(self, + chat_id: int or str, + offset: int = 0, + limit: int = 200, + query: str = "", + filter: str = Filters.ALL): + peer = self.resolve_peer(chat_id) + + if isinstance(peer, types.InputPeerChat): + return utils.parse_chat_members( + self.send( + functions.messages.GetFullChat( + peer.chat_id + ) + ) + ) + elif isinstance(peer, types.InputPeerChannel): + filter = filter.lower() + + if filter == Filters.ALL: + filter = types.ChannelParticipantsSearch(q=query) + elif filter == Filters.KICKED: + filter = types.ChannelParticipantsKicked(q=query) + elif filter == Filters.RESTRICTED: + filter = types.ChannelParticipantsBanned(q=query) + elif filter == Filters.BOTS: + filter = types.ChannelParticipantsBots() + elif filter == Filters.RECENT: + filter = types.ChannelParticipantsRecent() + elif filter == Filters.ADMINISTRATORS: + filter = types.ChannelParticipantsAdmins() + else: + raise ValueError("Invalid filter \"{}\"".format(filter)) + + return utils.parse_chat_members( + self.send( + functions.channels.GetParticipants( + channel=peer, + filter=filter, + offset=offset, + limit=limit, + hash=0 + ) + ) + ) + else: + raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) diff --git a/pyrogram/client/methods/chats/pin_chat_message.py b/pyrogram/client/methods/chats/pin_chat_message.py new file mode 100644 index 00000000..e9bc533e --- /dev/null +++ b/pyrogram/client/methods/chats/pin_chat_message.py @@ -0,0 +1,63 @@ +# 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 pyrogram.api import functions, types +from ...ext import BaseClient + + +class PinChatMessage(BaseClient): + def pin_chat_message(self, chat_id: int or str, message_id: int, disable_notification: bool = None): + """Use this method to pin a message in a supergroup or a channel. + You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin right in + the supergroup or "can_edit_messages" admin right in the channel. + + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For a private channel/supergroup you can use its *t.me/joinchat/* link. + + message_id (``int``): + Identifier of a message to pin. + + disable_notification (``bool``): + Pass True, if it is not necessary to send a notification to all chat members about the new pinned + message. Notifications are always disabled in channels. + + Returns: + True on success. + + Raises: + :class:`Error ` + ``ValueError``: If a chat_id doesn't belong to a supergroup or a channel. + """ + peer = self.resolve_peer(chat_id) + + if isinstance(peer, types.InputPeerChannel): + self.send( + functions.channels.UpdatePinnedMessage( + channel=peer, + id=message_id, + silent=disable_notification or None + ) + ) + elif isinstance(peer, types.InputPeerChat): + raise ValueError("The chat_id \"{}\" belongs to a basic group".format(chat_id)) + else: + raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) + + return True diff --git a/pyrogram/client/methods/chats/set_chat_description.py b/pyrogram/client/methods/chats/set_chat_description.py new file mode 100644 index 00000000..c9597a62 --- /dev/null +++ b/pyrogram/client/methods/chats/set_chat_description.py @@ -0,0 +1,57 @@ +# 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 pyrogram.api import functions, types +from ...ext import BaseClient + + +class SetChatDescription(BaseClient): + def set_chat_description(self, chat_id: int or str, description: str): + """Use this method to change the description of a supergroup or a channel. + You must be an administrator in the chat for this to work and must have the appropriate admin rights. + + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For a private channel/supergroup you can use its *t.me/joinchat/* link. + + description (``str``): + New chat description, 0-255 characters. + + Returns: + True on success. + + Raises: + :class:`Error ` + ``ValueError``: If a chat_id doesn't belong to a supergroup or a channel. + """ + peer = self.resolve_peer(chat_id) + + if isinstance(peer, types.InputPeerChannel): + self.send( + functions.channels.EditAbout( + channel=peer, + about=description + ) + ) + elif isinstance(peer, types.InputPeerChat): + raise ValueError("The chat_id \"{}\" belongs to a basic group".format(chat_id)) + else: + raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) + + return True diff --git a/pyrogram/client/methods/chats/set_chat_photo.py b/pyrogram/client/methods/chats/set_chat_photo.py new file mode 100644 index 00000000..d98fefde --- /dev/null +++ b/pyrogram/client/methods/chats/set_chat_photo.py @@ -0,0 +1,83 @@ +# 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 . + +import os +from base64 import b64decode +from struct import unpack + +from pyrogram.api import functions, types +from ...ext import BaseClient + + +class SetChatPhoto(BaseClient): + def set_chat_photo(self, chat_id: int or str, photo: str): + """Use this method to set a new profile photo for the chat. + Photos can't be changed for private chats. + You must be an administrator in the chat for this to work and must have the appropriate admin rights. + + Note: + In regular groups (non-supergroups), this method will only work if the "All Members Are Admins" + setting is off. + + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For a private channel/supergroup you can use its *t.me/joinchat/* link. + + photo (``str``): + New chat photo. You can pass a :class:`Photo` id or a file path to upload a new photo. + + Returns: + True on success. + + Raises: + :class:`Error ` + ``ValueError``: If a chat_id belongs to user. + """ + peer = self.resolve_peer(chat_id) + + if os.path.exists(photo): + photo = types.InputChatUploadedPhoto(file=self.save_file(photo)) + else: + s = unpack(" +# +# 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 pyrogram.api import functions, types +from ...ext import BaseClient + + +class SetChatTitle(BaseClient): + def set_chat_title(self, chat_id: int or str, title: str): + """Use this method to change the title of a chat. + Titles can't be changed for private chats. + You must be an administrator in the chat for this to work and must have the appropriate admin rights. + + Note: + In regular groups (non-supergroups), this method will only work if the "All Members Are Admins" + setting is off. + + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For a private channel/supergroup you can use its *t.me/joinchat/* link. + + title (``str``): + New chat title, 1-255 characters. + + Returns: + True on success. + + Raises: + :class:`Error ` + ``ValueError``: If a chat_id belongs to user. + """ + peer = self.resolve_peer(chat_id) + + if isinstance(peer, types.InputPeerChat): + self.send( + functions.messages.EditChatTitle( + chat_id=peer.chat_id, + title=title + ) + ) + elif isinstance(peer, types.InputPeerChannel): + self.send( + functions.channels.EditTitle( + channel=peer, + title=title + ) + ) + else: + raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) + + return True diff --git a/pyrogram/client/methods/chats/unpin_chat_message.py b/pyrogram/client/methods/chats/unpin_chat_message.py new file mode 100644 index 00000000..b1eeec79 --- /dev/null +++ b/pyrogram/client/methods/chats/unpin_chat_message.py @@ -0,0 +1,55 @@ +# 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 pyrogram.api import functions, types +from ...ext import BaseClient + + +class UnpinChatMessage(BaseClient): + def unpin_chat_message(self, chat_id: int or str): + """Use this method to unpin a message in a supergroup or a channel. + You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin + right in the supergroup or "can_edit_messages" admin right in the channel. + + Args: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For a private channel/supergroup you can use its *t.me/joinchat/* link. + + Returns: + True on success. + + Raises: + :class:`Error ` + ``ValueError``: If a chat_id doesn't belong to a supergroup or a channel. + """ + peer = self.resolve_peer(chat_id) + + if isinstance(peer, types.InputPeerChannel): + self.send( + functions.channels.UpdatePinnedMessage( + channel=peer, + id=0 + ) + ) + elif isinstance(peer, types.InputPeerChat): + raise ValueError("The chat_id \"{}\" belongs to a basic group".format(chat_id)) + else: + raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) + + return True diff --git a/pyrogram/client/methods/download_media.py b/pyrogram/client/methods/download_media.py index 485684b9..b379dbf7 100644 --- a/pyrogram/client/methods/download_media.py +++ b/pyrogram/client/methods/download_media.py @@ -74,7 +74,10 @@ class DownloadMedia(BaseClient): Raises: :class:`Error ` + ``ValueError``: If the message doesn't contain any downloadable media """ + error_message = "This message doesn't contain any downloadable media" + if isinstance(message, pyrogram_types.Message): if message.photo: media = pyrogram_types.Document( @@ -98,7 +101,7 @@ class DownloadMedia(BaseClient): elif message.gif: media = message.gif else: - return + raise ValueError(error_message) elif isinstance(message, ( pyrogram_types.Photo, pyrogram_types.PhotoSize, @@ -126,7 +129,7 @@ class DownloadMedia(BaseClient): mime_type="" ) else: - return + raise ValueError(error_message) done = asyncio.Event() path = [None] diff --git a/pyrogram/client/methods/messages/send_contact.py b/pyrogram/client/methods/messages/send_contact.py index 7b7b3368..e15bc501 100644 --- a/pyrogram/client/methods/messages/send_contact.py +++ b/pyrogram/client/methods/messages/send_contact.py @@ -26,7 +26,7 @@ class SendContact(BaseClient): phone_number: str, first_name: str, last_name: str = "", - disable_notification: bool = None, + vcard: str = "", disable_notification: bool = None, reply_to_message_id: int = None, reply_markup=None): """Use this method to send phone contacts. @@ -47,6 +47,9 @@ class SendContact(BaseClient): last_name (``str``, *optional*): Contact's last name. + vcard (``str``, *optional*): + Contact's vCard information. + disable_notification (``bool``, *optional*): Sends the message silently. Users will receive a notification with no sound. @@ -68,9 +71,10 @@ class SendContact(BaseClient): functions.messages.SendMedia( peer=await self.resolve_peer(chat_id), media=types.InputMediaContact( - phone_number, - first_name, - last_name + phone_number=phone_number, + first_name=first_name, + last_name=last_name, + vcard=vcard ), message="", silent=disable_notification or None, diff --git a/pyrogram/client/types/__init__.py b/pyrogram/client/types/__init__.py index 3c569324..e6fcc8aa 100644 --- a/pyrogram/client/types/__init__.py +++ b/pyrogram/client/types/__init__.py @@ -16,34 +16,26 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from .audio import Audio from .callback_query import CallbackQuery from .chat import Chat from .chat_member import ChatMember +from .chat_members import ChatMembers from .chat_photo import ChatPhoto -from .contact import Contact from .dialog import Dialog from .dialogs import Dialogs -from .document import Document -from .gif import GIF from .input_media_photo import InputMediaPhoto from .input_media_video import InputMediaVideo from .input_phone_contact import InputPhoneContact -from .location import Location +from .media import ( + Audio, Contact, Document, GIF, Location, Photo, PhotoSize, + Sticker, Venue, Video, VideoNote, Voice, UserProfilePhotos +) from .message import Message from .message_entity import MessageEntity from .messages import Messages -from .photo import Photo -from .photo_size import PhotoSize from .reply_markup import ( ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove ) -from .sticker import Sticker from .update import Update from .user import User -from .user_profile_photos import UserProfilePhotos -from .venue import Venue -from .video import Video -from .video_note import VideoNote -from .voice import Voice diff --git a/pyrogram/client/types/chat.py b/pyrogram/client/types/chat.py index 9cd7aec7..afed1ca4 100644 --- a/pyrogram/client/types/chat.py +++ b/pyrogram/client/types/chat.py @@ -24,15 +24,13 @@ class Chat(Object): Args: id (``int``): - Unique identifier for this chat. This number may be greater than 32 bits and some programming - languages may have difficulty/silent defects in interpreting it. But it is smaller than 52 bits, - so a signed 64 bit integer or double-precision float type are safe for storing this identifier. + Unique identifier for this chat. type (``str``): Type of chat, can be either "private", "group", "supergroup" or "channel". title (``str``, *optional*): - Title, for supergroups, channels and group chats. + Title, for supergroups, channels and basic group chats. username (``str``, *optional*): Username, for private chats, supergroups and channels if available. @@ -44,25 +42,33 @@ class Chat(Object): Last name of the other party in a private chat. all_members_are_administrators (``bool``, *optional*): - True if a group has 'All Members Are Admins' enabled. + True if a basic group has "All Members Are Admins" enabled. photo (:obj:`ChatPhoto `, *optional*): - Chat photo. Returned only in getChat. + Chat photo. Suitable for downloads only. description (``str``, *optional*): - Description, for supergroups and channel chats. Returned only in getChat. + Description, for supergroups and channel chats. + Returned only in :meth:`get_chat() `. invite_link (``str``, *optional*): - Chat invite link, for supergroups and channel chats. Returned only in getChat. + Chat invite link, for supergroups and channel chats. + Returned only in :meth:`get_chat() `. pinned_message (:obj:`Message `, *optional*): - Pinned message, for supergroups and channel chats. Returned only in getChat. + Pinned message, for supergroups and channel chats. + Returned only in :meth:`get_chat() `. sticker_set_name (``str``, *optional*): - For supergroups, name of group sticker set. Returned only in getChat. + For supergroups, name of group sticker set. + Returned only in :meth:`get_chat() `. can_set_sticker_set (``bool``, *optional*): - True, if the bot can change the group sticker set. Returned only in getChat. + True, if the group sticker set can be changed by you. + Returned only in :meth:`get_chat() `. + + members_count (``int``, *optional*): + Chat members count, for groups and channels only. """ ID = 0xb0700002 diff --git a/pyrogram/client/types/chat_members.py b/pyrogram/client/types/chat_members.py new file mode 100644 index 00000000..658a3086 --- /dev/null +++ b/pyrogram/client/types/chat_members.py @@ -0,0 +1,29 @@ +# 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 pyrogram.api.core import Object + + +class ChatMembers(Object): + # TODO: Docstrings + + ID = 0xb0700030 + + def __init__(self, total_count: int, chat_members: list): + self.total_count = total_count + self.chat_members = chat_members diff --git a/pyrogram/client/types/dialog.py b/pyrogram/client/types/dialog.py index 5ad99477..60ffb76c 100644 --- a/pyrogram/client/types/dialog.py +++ b/pyrogram/client/types/dialog.py @@ -20,6 +20,24 @@ from pyrogram.api.core import Object class Dialog(Object): + """This object represents a dialog + + Args: + chat (:obj:`Chat `): + Conversation the dialog belongs to. + + top_message (:obj:`Message `): + The last message sent in the dialog at this time. + + unread_messages_count (``int``): + Amount of unread messages in this dialogs. + + unread_mentions_count (``int``): + Amount of unread messages containing a mention in this dialog. + + unread_mark (``bool``): + True, if the dialog has the unread mark set. + """ ID = 0xb0700028 def __init__(self, @@ -28,7 +46,6 @@ class Dialog(Object): unread_messages_count: int, unread_mentions_count: int, unread_mark: bool): - # TODO docstrings self.chat = chat self.top_message = top_message self.unread_messages_count = unread_messages_count diff --git a/pyrogram/client/types/dialogs.py b/pyrogram/client/types/dialogs.py index 1e1b0cb2..cdf1d951 100644 --- a/pyrogram/client/types/dialogs.py +++ b/pyrogram/client/types/dialogs.py @@ -20,9 +20,17 @@ from pyrogram.api.core import Object class Dialogs(Object): + """This object represents a user's dialogs chunk + + Args: + total_count (``int``): + Total number of dialogs the user has. + + dialogs (List of :obj:`Dialog `): + Requested dialogs. + """ ID = 0xb0700029 def __init__(self, total_count: int, dialogs: list): - # TODO docstrings self.total_count = total_count self.dialogs = dialogs diff --git a/pyrogram/client/types/media/__init__.py b/pyrogram/client/types/media/__init__.py new file mode 100644 index 00000000..5b09d832 --- /dev/null +++ b/pyrogram/client/types/media/__init__.py @@ -0,0 +1,31 @@ +# 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 .audio import Audio +from .contact import Contact +from .document import Document +from .gif import GIF +from .location import Location +from .photo import Photo +from .photo_size import PhotoSize +from .sticker import Sticker +from .user_profile_photos import UserProfilePhotos +from .venue import Venue +from .video import Video +from .video_note import VideoNote +from .voice import Voice diff --git a/pyrogram/client/types/audio.py b/pyrogram/client/types/media/audio.py similarity index 83% rename from pyrogram/client/types/audio.py rename to pyrogram/client/types/media/audio.py index 51cec257..57731266 100644 --- a/pyrogram/client/types/audio.py +++ b/pyrogram/client/types/media/audio.py @@ -65,12 +65,12 @@ class Audio(Object): performer: str = None, title: str = None ): - self.file_id = file_id # string - self.thumb = thumb # flags.0?PhotoSize - self.file_name = file_name # flags.1?string - self.mime_type = mime_type # flags.2?string - self.file_size = file_size # flags.3?int - self.date = date # flags.4?int - self.duration = duration # int - self.performer = performer # flags.5?string - self.title = title # flags.6?string + self.file_id = file_id + self.thumb = thumb + self.file_name = file_name + self.mime_type = mime_type + self.file_size = file_size + self.date = date + self.duration = duration + self.performer = performer + self.title = title diff --git a/pyrogram/client/types/contact.py b/pyrogram/client/types/media/contact.py similarity index 74% rename from pyrogram/client/types/contact.py rename to pyrogram/client/types/media/contact.py index f625120c..a59e2047 100644 --- a/pyrogram/client/types/contact.py +++ b/pyrogram/client/types/media/contact.py @@ -32,14 +32,25 @@ class Contact(Object): last_name (``str``, *optional*): Contact's last name. + vcard (``str``, *optional*): + Contact's vCard. + user_id (``int``, *optional*): Contact's user identifier in Telegram. """ ID = 0xb0700011 - def __init__(self, phone_number: str, first_name: str, last_name: str = None, user_id=None): - self.phone_number = phone_number # string - self.first_name = first_name # string - self.last_name = last_name # flags.0?string - self.user_id = user_id # flags.1?int + def __init__( + self, + phone_number: str, + first_name: str, + last_name: str = None, + vcard: str = None, + user_id: int = None + ): + self.phone_number = phone_number + self.first_name = first_name + self.last_name = last_name + self.vcard = vcard + self.user_id = user_id diff --git a/pyrogram/client/types/document.py b/pyrogram/client/types/media/document.py similarity index 84% rename from pyrogram/client/types/document.py rename to pyrogram/client/types/media/document.py index 076c1934..d87fa666 100644 --- a/pyrogram/client/types/document.py +++ b/pyrogram/client/types/media/document.py @@ -20,7 +20,7 @@ from pyrogram.api.core import Object class Document(Object): - """This object represents a general file (as opposed to photos, voice messages and audio files). + """This object represents a general file (as opposed to photos, voice messages, audio files, ...). Args: file_id (``str``): @@ -53,9 +53,9 @@ class Document(Object): file_size: int = None, date: int = None ): - self.file_id = file_id # string - self.thumb = thumb # flags.0?PhotoSize - self.file_name = file_name # flags.1?string - self.mime_type = mime_type # flags.2?string - self.file_size = file_size # flags.3?int - self.date = date # flags.3?int + self.file_id = file_id + self.thumb = thumb + self.file_name = file_name + self.mime_type = mime_type + self.file_size = file_size + self.date = date diff --git a/pyrogram/client/types/gif.py b/pyrogram/client/types/media/gif.py similarity index 83% rename from pyrogram/client/types/gif.py rename to pyrogram/client/types/media/gif.py index 71e975f5..5172aae2 100644 --- a/pyrogram/client/types/gif.py +++ b/pyrogram/client/types/media/gif.py @@ -65,12 +65,12 @@ class GIF(Object): file_size: int = None, date: int = None ): - self.file_id = file_id # string - self.thumb = thumb # flags.0?PhotoSize - self.file_name = file_name # flags.1?string - self.mime_type = mime_type # flags.2?string - self.file_size = file_size # flags.3?int - self.date = date # flags.4?int - self.width = width # int - self.height = height # int - self.duration = duration # int + self.file_id = file_id + self.thumb = thumb + self.file_name = file_name + self.mime_type = mime_type + self.file_size = file_size + self.date = date + self.width = width + self.height = height + self.duration = duration diff --git a/pyrogram/client/types/location.py b/pyrogram/client/types/media/location.py similarity index 93% rename from pyrogram/client/types/location.py rename to pyrogram/client/types/media/location.py index 1f5feb00..be8c839f 100644 --- a/pyrogram/client/types/location.py +++ b/pyrogram/client/types/media/location.py @@ -33,5 +33,5 @@ class Location(Object): ID = 0xb0700012 def __init__(self, longitude: float, latitude: float): - self.longitude = longitude # double - self.latitude = latitude # double + self.longitude = longitude + self.latitude = latitude diff --git a/pyrogram/client/types/photo.py b/pyrogram/client/types/media/photo.py similarity index 92% rename from pyrogram/client/types/photo.py rename to pyrogram/client/types/media/photo.py index f5494f13..d9deed76 100644 --- a/pyrogram/client/types/photo.py +++ b/pyrogram/client/types/media/photo.py @@ -27,10 +27,10 @@ class Photo(Object): Unique identifier for this photo. date (``int``): - Date the photo was sent in Unix time + Date the photo was sent in Unix time. sizes (List of :obj:`PhotoSize `): - Available sizes of this photo + Available sizes of this photo. """ ID = 0xb0700027 diff --git a/pyrogram/client/types/photo_size.py b/pyrogram/client/types/media/photo_size.py similarity index 94% rename from pyrogram/client/types/photo_size.py rename to pyrogram/client/types/media/photo_size.py index 65691de0..764b046b 100644 --- a/pyrogram/client/types/photo_size.py +++ b/pyrogram/client/types/media/photo_size.py @@ -20,7 +20,7 @@ from pyrogram.api.core import Object class PhotoSize(Object): - """This object represents one size of a photo or a file / sticker thumbnail. + """This object represents one size of a photo or a file/sticker thumbnail. Args: file_id (``str``): diff --git a/pyrogram/client/types/sticker.py b/pyrogram/client/types/media/sticker.py similarity index 81% rename from pyrogram/client/types/sticker.py rename to pyrogram/client/types/media/sticker.py index a5ed9085..2e7ac901 100644 --- a/pyrogram/client/types/sticker.py +++ b/pyrogram/client/types/media/sticker.py @@ -73,14 +73,14 @@ class Sticker(Object): set_name: str = None, mask_position=None ): - self.file_id = file_id # string - self.thumb = thumb # flags.0?PhotoSize - self.file_name = file_name # flags.1?string - self.mime_type = mime_type # flags.2?string - self.file_size = file_size # flags.3?int - self.date = date # flags.4?int - self.width = width # int - self.height = height # int - self.emoji = emoji # flags.5?string - self.set_name = set_name # flags.6?string - self.mask_position = mask_position # flags.7?MaskPosition + self.file_id = file_id + self.thumb = thumb + self.file_name = file_name + self.mime_type = mime_type + self.file_size = file_size + self.date = date + self.width = width + self.height = height + self.emoji = emoji + self.set_name = set_name + self.mask_position = mask_position diff --git a/pyrogram/client/types/user_profile_photos.py b/pyrogram/client/types/media/user_profile_photos.py similarity index 100% rename from pyrogram/client/types/user_profile_photos.py rename to pyrogram/client/types/media/user_profile_photos.py diff --git a/pyrogram/client/types/venue.py b/pyrogram/client/types/media/venue.py similarity index 87% rename from pyrogram/client/types/venue.py rename to pyrogram/client/types/media/venue.py index 653f0dd3..5d9e387f 100644 --- a/pyrogram/client/types/venue.py +++ b/pyrogram/client/types/media/venue.py @@ -40,7 +40,7 @@ class Venue(Object): ID = 0xb0700013 def __init__(self, location, title: str, address: str, foursquare_id: str = None): - self.location = location # Location - self.title = title # string - self.address = address # string - self.foursquare_id = foursquare_id # flags.0?string + self.location = location + self.title = title + self.address = address + self.foursquare_id = foursquare_id diff --git a/pyrogram/client/types/video.py b/pyrogram/client/types/media/video.py similarity index 83% rename from pyrogram/client/types/video.py rename to pyrogram/client/types/media/video.py index b4ffff2b..8b272a2d 100644 --- a/pyrogram/client/types/video.py +++ b/pyrogram/client/types/media/video.py @@ -65,12 +65,12 @@ class Video(Object): file_size: int = None, date: int = None ): - self.file_id = file_id # string - self.thumb = thumb # flags.0?PhotoSize - self.file_name = file_name # flags.1?string - self.mime_type = mime_type # flags.2?string - self.file_size = file_size # flags.3?int - self.date = date # flags.4?int - self.width = width # int - self.height = height # int - self.duration = duration # int + self.file_id = file_id + self.thumb = thumb + self.file_name = file_name + self.mime_type = mime_type + self.file_size = file_size + self.date = date + self.width = width + self.height = height + self.duration = duration diff --git a/pyrogram/client/types/video_note.py b/pyrogram/client/types/media/video_note.py similarity index 79% rename from pyrogram/client/types/video_note.py rename to pyrogram/client/types/media/video_note.py index 7f0b6736..642eb5aa 100644 --- a/pyrogram/client/types/video_note.py +++ b/pyrogram/client/types/media/video_note.py @@ -35,9 +35,6 @@ class VideoNote(Object): thumb (:obj:`PhotoSize `, *optional*): Video thumbnail. - file_name (``str``, *optional*): - Video note file name. - mime_type (``str``, *optional*): MIME type of the file as defined by sender. @@ -56,16 +53,14 @@ class VideoNote(Object): length: int, duration: int, thumb=None, - file_name: str = None, mime_type: str = None, file_size: int = None, date: int = None ): - self.file_id = file_id # string - self.thumb = thumb # flags.0?PhotoSize - self.file_name = file_name # flags.1?string - self.mime_type = mime_type # flags.2?string - self.file_size = file_size # flags.3?int - self.date = date # flags.4?int - self.length = length # int - self.duration = duration # int + self.file_id = file_id + self.thumb = thumb + self.mime_type = mime_type + self.file_size = file_size + self.date = date + self.length = length + self.duration = duration diff --git a/pyrogram/client/types/voice.py b/pyrogram/client/types/media/voice.py similarity index 73% rename from pyrogram/client/types/voice.py rename to pyrogram/client/types/media/voice.py index 414d2267..d838cf59 100644 --- a/pyrogram/client/types/voice.py +++ b/pyrogram/client/types/media/voice.py @@ -29,11 +29,8 @@ class Voice(Object): duration (``int``): Duration of the audio in seconds as defined by sender. - thumb (:obj:`PhotoSize `, *optional*): - Voice thumbnail. - - file_name (``str``, *optional*): - Voice file name. + waveform (``bytes``, *optional*): + Voice waveform. mime_type (``str``, *optional*): MIME type of the file as defined by sender. @@ -51,15 +48,13 @@ class Voice(Object): self, file_id: str, duration: int, - thumb=None, - file_name: str = None, + waveform: bytes = None, mime_type: str = None, file_size: int = None, date: int = None): - self.file_id = file_id # string - self.thumb = thumb # flags.0?PhotoSize - self.file_name = file_name # flags.1?string - self.mime_type = mime_type # flags.2?string - self.file_size = file_size # flags.3?int - self.date = date # flags.4?int - self.duration = duration # int + self.file_id = file_id + self.duration = duration + self.waveform = waveform + self.mime_type = mime_type + self.file_size = file_size + self.date = date diff --git a/pyrogram/client/types/message.py b/pyrogram/client/types/message.py index 86c40f75..c9137328 100644 --- a/pyrogram/client/types/message.py +++ b/pyrogram/client/types/message.py @@ -26,9 +26,6 @@ class Message(Object): Args: message_id (``int``): Unique message identifier inside this chat. - - client (:obj:`Client `, *optional*): - The client instance this message is bound to. date (``int``, *optional*): Date the message was sent in Unix time. @@ -574,3 +571,39 @@ class Message(Object): raise ValueError("This button is not supported yet") else: raise ValueError("The message doesn't contain any keyboard") + + def download(self, file_name: str = "", block: bool = True): + """Use this method as a shortcut for: + + .. code-block:: python + + client.download_media(message) + + Example: + .. code-block:: python + + message.download() + + Args: + file_name (``str``, *optional*): + A custom *file_name* to be used instead of the one provided by Telegram. + By default, all files are downloaded in the *downloads* folder in your working directory. + You can also specify a path for downloading files in a custom location: paths that end with "/" + are considered directories. All non-existent folders will be created automatically. + + block (``bool``, *optional*): + Blocks the code execution until the file has been downloaded. + Defaults to True. + + Returns: + On success, the absolute path of the downloaded file as string is returned, None otherwise. + + Raises: + :class:`Error ` + ``ValueError``: If the message doesn't contain any downloadable media + """ + return self._client.download_media( + message=self, + file_name=file_name, + block=block + ) diff --git a/pyrogram/client/types/message_entity.py b/pyrogram/client/types/message_entity.py index 460da6e7..db2eee3e 100644 --- a/pyrogram/client/types/message_entity.py +++ b/pyrogram/client/types/message_entity.py @@ -26,9 +26,9 @@ class MessageEntity(Object): Args: type (``str``): Type of the entity. - Can be mention (@username), hashtag, bot_command, url, email, bold (bold text), italic (italic text), - code (monowidth string), pre (monowidth block), text_link (for clickable text URLs), - text_mention (for users without usernames). + Can be "mention" (@username), "hashtag", "cashtag", "bot_command", "url", "email", "bold" (bold text), + italic (italic text), "code" (monowidth string), "pre" (monowidth block), "text_link" (for clickable text + URLs), "text_mention" (for users without usernames). offset (``int``): Offset in UTF-16 code units to the start of the entity. @@ -45,9 +45,16 @@ class MessageEntity(Object): ID = 0xb0700004 - def __init__(self, type: str, offset: int, length: int, url: str = None, user=None): - self.type = type # string - self.offset = offset # int - self.length = length # int - self.url = url # flags.0?string - self.user = user # flags.1?User + def __init__( + self, + type: str, + offset: int, + length: int, + url: str = None, + user=None + ): + self.type = type + self.offset = offset + self.length = length + self.url = url + self.user = user diff --git a/pyrogram/client/types/messages.py b/pyrogram/client/types/messages.py index 0d5d0a36..7a2546a9 100644 --- a/pyrogram/client/types/messages.py +++ b/pyrogram/client/types/messages.py @@ -33,5 +33,5 @@ class Messages(Object): ID = 0xb0700026 def __init__(self, total_count: int, messages: list): - self.total_count = total_count # int - self.messages = messages # Vector> + self.total_count = total_count + self.messages = messages diff --git a/pyrogram/client/types/user.py b/pyrogram/client/types/user.py index 62e79e19..9ae5dab2 100644 --- a/pyrogram/client/types/user.py +++ b/pyrogram/client/types/user.py @@ -26,6 +26,18 @@ class User(Object): id (``int``): Unique identifier for this user or bot. + is_self(``bool``): + True, if this user is you yourself. + + is_contact(``bool``): + True, if this user is in your contacts. + + is_mutual_contact(``bool``): + True, if you both have each other's contact. + + is_deleted(``bool``): + True, if this user is deleted. + is_bot (``bool``): True, if this user is a bot. @@ -42,10 +54,10 @@ class User(Object): IETF language tag of the user's language. phone_number (``str``, *optional*): - User's or bot's phone number. + User's phone number. photo (:obj:`ChatPhoto `, *optional*): - User's or bot's current profile photo. + User's or bot's current profile photo. Suitable for downloads only. """ ID = 0xb0700001 @@ -53,6 +65,10 @@ class User(Object): def __init__( self, id: int, + is_self: bool, + is_contact: bool, + is_mutual_contact: bool, + is_deleted: bool, is_bot: bool, first_name: str, last_name: str = None, @@ -62,6 +78,10 @@ class User(Object): photo=None ): self.id = id + self.is_self = is_self + self.is_contact = is_contact + self.is_mutual_contact = is_mutual_contact + self.is_deleted = is_deleted self.is_bot = is_bot self.first_name = first_name self.last_name = last_name