Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/client/methods/messages/send_contact.py
This commit is contained in:
Dan 2018-07-16 17:39:54 +02:00
commit 8a69c2d74e
41 changed files with 897 additions and 150 deletions

View File

@ -506,6 +506,7 @@ def start():
f.write("\n 0xb0700027: \"pyrogram.client.types.Photo\",") f.write("\n 0xb0700027: \"pyrogram.client.types.Photo\",")
f.write("\n 0xb0700028: \"pyrogram.client.types.Dialog\",") f.write("\n 0xb0700028: \"pyrogram.client.types.Dialog\",")
f.write("\n 0xb0700029: \"pyrogram.client.types.Dialogs\",") f.write("\n 0xb0700029: \"pyrogram.client.types.Dialogs\",")
f.write("\n 0xb0700030: \"pyrogram.client.types.ChatMembers\",")
f.write("\n}\n") f.write("\n}\n")

View File

@ -63,3 +63,6 @@ WEBPAGE_CURL_FAILED Telegram could not fetch the provided URL
STICKERSET_INVALID The requested sticker set is invalid STICKERSET_INVALID The requested sticker set is invalid
PEER_FLOOD The method can't be used because your account is limited 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 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
1 id message
63 STICKERSET_INVALID The requested sticker set is invalid
64 PEER_FLOOD The method can't be used because your account is limited
65 MEDIA_CAPTION_TOO_LONG The media caption is longer than 200 characters
66 USER_NOT_MUTUAL_CONTACT The user is not a mutual contact
67 USER_CHANNELS_TOO_MUCH The user is already in too many channels or supergroups
68 API_ID_PUBLISHED_FLOOD You are using an API key that is limited on the server side

View File

@ -4,3 +4,4 @@ RPC_CALL_FAIL Telegram is having internal problems. Please try again later
RPC_MCGET_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 PERSISTENT_TIMESTAMP_OUTDATED Telegram is having internal problems. Please try again later
HISTORY_GET_FAILED Telegram is having internal problems. Please try again later 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
1 id message
4 RPC_MCGET_FAIL Telegram is having internal problems. Please try again later
5 PERSISTENT_TIMESTAMP_OUTDATED Telegram is having internal problems. Please try again later
6 HISTORY_GET_FAILED Telegram is having internal problems. Please try again later
7 REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later

View File

@ -68,3 +68,9 @@ Client
get_chat get_chat
get_messages get_messages
get_history get_history
set_chat_photo
delete_chat_photo
set_chat_title
set_chat_description
pin_chat_message
unpin_chat_message

View File

@ -35,14 +35,12 @@ __version__ = "0.8.0dev1"
from .api.errors import Error from .api.errors import Error
from .client.types import ( from .client.types import (
Audio, Chat, ChatMember, ChatPhoto, Contact, Document, InputMediaPhoto, Audio, Chat, ChatMember, ChatMembers, ChatPhoto, Contact, Document, InputMediaPhoto,
InputMediaVideo, InputPhoneContact, Location, Message, MessageEntity, InputMediaVideo, InputPhoneContact, Location, Message, MessageEntity,
Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, UserProfilePhotos, Dialog, Dialogs, Photo, PhotoSize, Sticker, Update, User, UserProfilePhotos,
Venue, GIF, Video, VideoNote, Voice, CallbackQuery, Messages Venue, GIF, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
) InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup,
from .client.types.reply_markup import ( ReplyKeyboardRemove
ForceReply, InlineKeyboardButton, InlineKeyboardMarkup,
KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
) )
from .client import ( from .client import (
Client, ChatAction, ParseMode, Emoji, Client, ChatAction, ParseMode, Emoji,

View File

@ -1259,8 +1259,6 @@ class Client(Methods, BaseClient):
break break
f.write(chunk) f.write(chunk)
f.flush()
os.fsync(f.fileno())
offset += limit offset += limit
@ -1343,8 +1341,6 @@ class Client(Methods, BaseClient):
assert h.hash == sha256(cdn_chunk).digest(), "Invalid CDN hash part {}".format(i) assert h.hash == sha256(cdn_chunk).digest(), "Invalid CDN hash part {}".format(i)
f.write(decrypted_chunk) f.write(decrypted_chunk)
f.flush()
os.fsync(f.fileno())
offset += limit offset += limit

View File

@ -72,6 +72,7 @@ async def ainput(prompt: str = ""):
ENTITIES = { ENTITIES = {
types.MessageEntityMention.ID: "mention", types.MessageEntityMention.ID: "mention",
types.MessageEntityHashtag.ID: "hashtag", types.MessageEntityHashtag.ID: "hashtag",
types.MessageEntityCashtag.ID: "cashtag",
types.MessageEntityBotCommand.ID: "bot_command", types.MessageEntityBotCommand.ID: "bot_command",
types.MessageEntityUrl.ID: "url", types.MessageEntityUrl.ID: "url",
types.MessageEntityEmail.ID: "email", types.MessageEntityEmail.ID: "email",
@ -140,6 +141,10 @@ def parse_chat_photo(photo):
def parse_user(user: types.User) -> pyrogram_types.User or None: def parse_user(user: types.User) -> pyrogram_types.User or None:
return pyrogram_types.User( return pyrogram_types.User(
id=user.id, 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, is_bot=user.bot,
first_name=user.first_name, first_name=user.first_name,
last_name=user.last_name, last_name=user.last_name,
@ -371,6 +376,7 @@ async def parse_messages(
phone_number=media.phone_number, phone_number=media.phone_number,
first_name=media.first_name, first_name=media.first_name,
last_name=media.last_name or None, last_name=media.last_name or None,
vcard=media.vcard or None,
user_id=media.user_id or None user_id=media.user_id or None
) )
elif isinstance(media, types.MessageMediaVenue): elif isinstance(media, types.MessageMediaVenue):
@ -412,8 +418,7 @@ async def parse_messages(
duration=audio_attributes.duration, duration=audio_attributes.duration,
mime_type=doc.mime_type, mime_type=doc.mime_type,
file_size=doc.size, file_size=doc.size,
thumb=parse_thumb(doc.thumb), waveform=audio_attributes.waveform,
file_name=file_name,
date=doc.date date=doc.date
) )
else: else:
@ -476,7 +481,6 @@ async def parse_messages(
duration=video_attributes.duration, duration=video_attributes.duration,
thumb=parse_thumb(doc.thumb), thumb=parse_thumb(doc.thumb),
file_size=doc.size, file_size=doc.size,
file_name=file_name,
mime_type=doc.mime_type, mime_type=doc.mime_type,
date=doc.date date=doc.date
) )
@ -938,3 +942,103 @@ def parse_dialog_chat(peer, users: dict, chats: dict):
return parse_chat_chat(chats[peer.chat_id]) return parse_chat_chat(chats[peer.chat_id])
else: else:
return parse_channel_chat(chats[peer.channel_id]) 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
)

View File

@ -16,14 +16,21 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .delete_chat_photo import DeleteChatPhoto
from .export_chat_invite_link import ExportChatInviteLink from .export_chat_invite_link import ExportChatInviteLink
from .get_chat import GetChat from .get_chat import GetChat
from .get_chat_members import GetChatMembers
from .join_chat import JoinChat from .join_chat import JoinChat
from .kick_chat_member import KickChatMember from .kick_chat_member import KickChatMember
from .leave_chat import LeaveChat from .leave_chat import LeaveChat
from .pin_chat_message import PinChatMessage
from .promote_chat_member import PromoteChatMember from .promote_chat_member import PromoteChatMember
from .restrict_chat_member import RestrictChatMember 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 .unban_chat_member import UnbanChatMember
from .unpin_chat_message import UnpinChatMessage
class Chats( class Chats(
@ -34,6 +41,13 @@ class Chats(
KickChatMember, KickChatMember,
UnbanChatMember, UnbanChatMember,
RestrictChatMember, RestrictChatMember,
PromoteChatMember PromoteChatMember,
GetChatMembers,
SetChatPhoto,
DeleteChatPhoto,
SetChatTitle,
SetChatDescription,
PinChatMessage,
UnpinChatMessage
): ):
pass pass

View File

@ -0,0 +1,64 @@
# 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 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 <pyrogram.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

View File

@ -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 """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.) 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: Returns:
On success, a :obj:`Chat <pyrogram.Chat>` object is returned. On success, a :obj:`Chat <pyrogram.Chat>` object is returned.

View File

@ -0,0 +1,79 @@
# 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 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))

View File

@ -0,0 +1,63 @@
# 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 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 <pyrogram.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

View File

@ -0,0 +1,57 @@
# 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 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 <pyrogram.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

View File

@ -0,0 +1,83 @@
# 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/>.
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 <pyrogram.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("<qq", b64decode(photo + "=" * (-len(photo) % 4), "-_"))
photo = types.InputChatPhoto(
id=types.InputPhoto(
id=s[0],
access_hash=s[1]
)
)
if isinstance(peer, types.InputPeerChat):
self.send(
functions.messages.EditChatPhoto(
chat_id=peer.chat_id,
photo=photo
)
)
elif isinstance(peer, types.InputPeerChannel):
self.send(
functions.channels.EditPhoto(
channel=peer,
photo=photo
)
)
else:
raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id))
return True

View File

@ -0,0 +1,67 @@
# 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 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 <pyrogram.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

View File

@ -0,0 +1,55 @@
# 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 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 <pyrogram.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

View File

@ -74,7 +74,10 @@ class DownloadMedia(BaseClient):
Raises: Raises:
:class:`Error <pyrogram.Error>` :class:`Error <pyrogram.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 isinstance(message, pyrogram_types.Message):
if message.photo: if message.photo:
media = pyrogram_types.Document( media = pyrogram_types.Document(
@ -98,7 +101,7 @@ class DownloadMedia(BaseClient):
elif message.gif: elif message.gif:
media = message.gif media = message.gif
else: else:
return raise ValueError(error_message)
elif isinstance(message, ( elif isinstance(message, (
pyrogram_types.Photo, pyrogram_types.Photo,
pyrogram_types.PhotoSize, pyrogram_types.PhotoSize,
@ -126,7 +129,7 @@ class DownloadMedia(BaseClient):
mime_type="" mime_type=""
) )
else: else:
return raise ValueError(error_message)
done = asyncio.Event() done = asyncio.Event()
path = [None] path = [None]

View File

@ -26,7 +26,7 @@ class SendContact(BaseClient):
phone_number: str, phone_number: str,
first_name: str, first_name: str,
last_name: str = "", last_name: str = "",
disable_notification: bool = None, vcard: str = "", disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup=None): reply_markup=None):
"""Use this method to send phone contacts. """Use this method to send phone contacts.
@ -47,6 +47,9 @@ class SendContact(BaseClient):
last_name (``str``, *optional*): last_name (``str``, *optional*):
Contact's last name. Contact's last name.
vcard (``str``, *optional*):
Contact's vCard information.
disable_notification (``bool``, *optional*): disable_notification (``bool``, *optional*):
Sends the message silently. Sends the message silently.
Users will receive a notification with no sound. Users will receive a notification with no sound.
@ -68,9 +71,10 @@ class SendContact(BaseClient):
functions.messages.SendMedia( functions.messages.SendMedia(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
media=types.InputMediaContact( media=types.InputMediaContact(
phone_number, phone_number=phone_number,
first_name, first_name=first_name,
last_name last_name=last_name,
vcard=vcard
), ),
message="", message="",
silent=disable_notification or None, silent=disable_notification or None,

View File

@ -16,34 +16,26 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .audio import Audio
from .callback_query import CallbackQuery from .callback_query import CallbackQuery
from .chat import Chat from .chat import Chat
from .chat_member import ChatMember from .chat_member import ChatMember
from .chat_members import ChatMembers
from .chat_photo import ChatPhoto from .chat_photo import ChatPhoto
from .contact import Contact
from .dialog import Dialog from .dialog import Dialog
from .dialogs import Dialogs from .dialogs import Dialogs
from .document import Document
from .gif import GIF
from .input_media_photo import InputMediaPhoto from .input_media_photo import InputMediaPhoto
from .input_media_video import InputMediaVideo from .input_media_video import InputMediaVideo
from .input_phone_contact import InputPhoneContact 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 import Message
from .message_entity import MessageEntity from .message_entity import MessageEntity
from .messages import Messages from .messages import Messages
from .photo import Photo
from .photo_size import PhotoSize
from .reply_markup import ( from .reply_markup import (
ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup,
KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
) )
from .sticker import Sticker
from .update import Update from .update import Update
from .user import User 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

View File

@ -24,15 +24,13 @@ class Chat(Object):
Args: Args:
id (``int``): id (``int``):
Unique identifier for this chat. This number may be greater than 32 bits and some programming Unique identifier for this chat.
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.
type (``str``): type (``str``):
Type of chat, can be either "private", "group", "supergroup" or "channel". Type of chat, can be either "private", "group", "supergroup" or "channel".
title (``str``, *optional*): title (``str``, *optional*):
Title, for supergroups, channels and group chats. Title, for supergroups, channels and basic group chats.
username (``str``, *optional*): username (``str``, *optional*):
Username, for private chats, supergroups and channels if available. 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. Last name of the other party in a private chat.
all_members_are_administrators (``bool``, *optional*): 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 <pyrogram.ChatPhoto>`, *optional*): photo (:obj:`ChatPhoto <pyrogram.ChatPhoto>`, *optional*):
Chat photo. Returned only in getChat. Chat photo. Suitable for downloads only.
description (``str``, *optional*): 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() <pyrogram.Client.get_chat>`.
invite_link (``str``, *optional*): 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() <pyrogram.Client.get_chat>`.
pinned_message (:obj:`Message <pyrogram.Message>`, *optional*): pinned_message (:obj:`Message <pyrogram.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() <pyrogram.Client.get_chat>`.
sticker_set_name (``str``, *optional*): 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() <pyrogram.Client.get_chat>`.
can_set_sticker_set (``bool``, *optional*): 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() <pyrogram.Client.get_chat>`.
members_count (``int``, *optional*):
Chat members count, for groups and channels only.
""" """
ID = 0xb0700002 ID = 0xb0700002

View File

@ -0,0 +1,29 @@
# 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 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

View File

@ -20,6 +20,24 @@ from pyrogram.api.core import Object
class Dialog(Object): class Dialog(Object):
"""This object represents a dialog
Args:
chat (:obj:`Chat <pyrogram.Chat>`):
Conversation the dialog belongs to.
top_message (:obj:`Message <pyrogram.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 ID = 0xb0700028
def __init__(self, def __init__(self,
@ -28,7 +46,6 @@ class Dialog(Object):
unread_messages_count: int, unread_messages_count: int,
unread_mentions_count: int, unread_mentions_count: int,
unread_mark: bool): unread_mark: bool):
# TODO docstrings
self.chat = chat self.chat = chat
self.top_message = top_message self.top_message = top_message
self.unread_messages_count = unread_messages_count self.unread_messages_count = unread_messages_count

View File

@ -20,9 +20,17 @@ from pyrogram.api.core import Object
class Dialogs(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 <pyrogram.Dialog>`):
Requested dialogs.
"""
ID = 0xb0700029 ID = 0xb0700029
def __init__(self, total_count: int, dialogs: list): def __init__(self, total_count: int, dialogs: list):
# TODO docstrings
self.total_count = total_count self.total_count = total_count
self.dialogs = dialogs self.dialogs = dialogs

View File

@ -0,0 +1,31 @@
# 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 .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

View File

@ -65,12 +65,12 @@ class Audio(Object):
performer: str = None, performer: str = None,
title: str = None title: str = None
): ):
self.file_id = file_id # string self.file_id = file_id
self.thumb = thumb # flags.0?PhotoSize self.thumb = thumb
self.file_name = file_name # flags.1?string self.file_name = file_name
self.mime_type = mime_type # flags.2?string self.mime_type = mime_type
self.file_size = file_size # flags.3?int self.file_size = file_size
self.date = date # flags.4?int self.date = date
self.duration = duration # int self.duration = duration
self.performer = performer # flags.5?string self.performer = performer
self.title = title # flags.6?string self.title = title

View File

@ -32,14 +32,25 @@ class Contact(Object):
last_name (``str``, *optional*): last_name (``str``, *optional*):
Contact's last name. Contact's last name.
vcard (``str``, *optional*):
Contact's vCard.
user_id (``int``, *optional*): user_id (``int``, *optional*):
Contact's user identifier in Telegram. Contact's user identifier in Telegram.
""" """
ID = 0xb0700011 ID = 0xb0700011
def __init__(self, phone_number: str, first_name: str, last_name: str = None, user_id=None): def __init__(
self.phone_number = phone_number # string self,
self.first_name = first_name # string phone_number: str,
self.last_name = last_name # flags.0?string first_name: str,
self.user_id = user_id # flags.1?int 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

View File

@ -20,7 +20,7 @@ from pyrogram.api.core import Object
class Document(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: Args:
file_id (``str``): file_id (``str``):
@ -53,9 +53,9 @@ class Document(Object):
file_size: int = None, file_size: int = None,
date: int = None date: int = None
): ):
self.file_id = file_id # string self.file_id = file_id
self.thumb = thumb # flags.0?PhotoSize self.thumb = thumb
self.file_name = file_name # flags.1?string self.file_name = file_name
self.mime_type = mime_type # flags.2?string self.mime_type = mime_type
self.file_size = file_size # flags.3?int self.file_size = file_size
self.date = date # flags.3?int self.date = date

View File

@ -65,12 +65,12 @@ class GIF(Object):
file_size: int = None, file_size: int = None,
date: int = None date: int = None
): ):
self.file_id = file_id # string self.file_id = file_id
self.thumb = thumb # flags.0?PhotoSize self.thumb = thumb
self.file_name = file_name # flags.1?string self.file_name = file_name
self.mime_type = mime_type # flags.2?string self.mime_type = mime_type
self.file_size = file_size # flags.3?int self.file_size = file_size
self.date = date # flags.4?int self.date = date
self.width = width # int self.width = width
self.height = height # int self.height = height
self.duration = duration # int self.duration = duration

View File

@ -33,5 +33,5 @@ class Location(Object):
ID = 0xb0700012 ID = 0xb0700012
def __init__(self, longitude: float, latitude: float): def __init__(self, longitude: float, latitude: float):
self.longitude = longitude # double self.longitude = longitude
self.latitude = latitude # double self.latitude = latitude

View File

@ -27,10 +27,10 @@ class Photo(Object):
Unique identifier for this photo. Unique identifier for this photo.
date (``int``): date (``int``):
Date the photo was sent in Unix time Date the photo was sent in Unix time.
sizes (List of :obj:`PhotoSize <pyrogram.PhotoSize>`): sizes (List of :obj:`PhotoSize <pyrogram.PhotoSize>`):
Available sizes of this photo Available sizes of this photo.
""" """
ID = 0xb0700027 ID = 0xb0700027

View File

@ -20,7 +20,7 @@ from pyrogram.api.core import Object
class PhotoSize(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: Args:
file_id (``str``): file_id (``str``):

View File

@ -73,14 +73,14 @@ class Sticker(Object):
set_name: str = None, set_name: str = None,
mask_position=None mask_position=None
): ):
self.file_id = file_id # string self.file_id = file_id
self.thumb = thumb # flags.0?PhotoSize self.thumb = thumb
self.file_name = file_name # flags.1?string self.file_name = file_name
self.mime_type = mime_type # flags.2?string self.mime_type = mime_type
self.file_size = file_size # flags.3?int self.file_size = file_size
self.date = date # flags.4?int self.date = date
self.width = width # int self.width = width
self.height = height # int self.height = height
self.emoji = emoji # flags.5?string self.emoji = emoji
self.set_name = set_name # flags.6?string self.set_name = set_name
self.mask_position = mask_position # flags.7?MaskPosition self.mask_position = mask_position

View File

@ -40,7 +40,7 @@ class Venue(Object):
ID = 0xb0700013 ID = 0xb0700013
def __init__(self, location, title: str, address: str, foursquare_id: str = None): def __init__(self, location, title: str, address: str, foursquare_id: str = None):
self.location = location # Location self.location = location
self.title = title # string self.title = title
self.address = address # string self.address = address
self.foursquare_id = foursquare_id # flags.0?string self.foursquare_id = foursquare_id

View File

@ -65,12 +65,12 @@ class Video(Object):
file_size: int = None, file_size: int = None,
date: int = None date: int = None
): ):
self.file_id = file_id # string self.file_id = file_id
self.thumb = thumb # flags.0?PhotoSize self.thumb = thumb
self.file_name = file_name # flags.1?string self.file_name = file_name
self.mime_type = mime_type # flags.2?string self.mime_type = mime_type
self.file_size = file_size # flags.3?int self.file_size = file_size
self.date = date # flags.4?int self.date = date
self.width = width # int self.width = width
self.height = height # int self.height = height
self.duration = duration # int self.duration = duration

View File

@ -35,9 +35,6 @@ class VideoNote(Object):
thumb (:obj:`PhotoSize <pyrogram.PhotoSize>`, *optional*): thumb (:obj:`PhotoSize <pyrogram.PhotoSize>`, *optional*):
Video thumbnail. Video thumbnail.
file_name (``str``, *optional*):
Video note file name.
mime_type (``str``, *optional*): mime_type (``str``, *optional*):
MIME type of the file as defined by sender. MIME type of the file as defined by sender.
@ -56,16 +53,14 @@ class VideoNote(Object):
length: int, length: int,
duration: int, duration: int,
thumb=None, thumb=None,
file_name: str = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None date: int = None
): ):
self.file_id = file_id # string self.file_id = file_id
self.thumb = thumb # flags.0?PhotoSize self.thumb = thumb
self.file_name = file_name # flags.1?string self.mime_type = mime_type
self.mime_type = mime_type # flags.2?string self.file_size = file_size
self.file_size = file_size # flags.3?int self.date = date
self.date = date # flags.4?int self.length = length
self.length = length # int self.duration = duration
self.duration = duration # int

View File

@ -29,11 +29,8 @@ class Voice(Object):
duration (``int``): duration (``int``):
Duration of the audio in seconds as defined by sender. Duration of the audio in seconds as defined by sender.
thumb (:obj:`PhotoSize <pyrogram.PhotoSize>`, *optional*): waveform (``bytes``, *optional*):
Voice thumbnail. Voice waveform.
file_name (``str``, *optional*):
Voice file name.
mime_type (``str``, *optional*): mime_type (``str``, *optional*):
MIME type of the file as defined by sender. MIME type of the file as defined by sender.
@ -51,15 +48,13 @@ class Voice(Object):
self, self,
file_id: str, file_id: str,
duration: int, duration: int,
thumb=None, waveform: bytes = None,
file_name: str = None,
mime_type: str = None, mime_type: str = None,
file_size: int = None, file_size: int = None,
date: int = None): date: int = None):
self.file_id = file_id # string self.file_id = file_id
self.thumb = thumb # flags.0?PhotoSize self.duration = duration
self.file_name = file_name # flags.1?string self.waveform = waveform
self.mime_type = mime_type # flags.2?string self.mime_type = mime_type
self.file_size = file_size # flags.3?int self.file_size = file_size
self.date = date # flags.4?int self.date = date
self.duration = duration # int

View File

@ -27,9 +27,6 @@ class Message(Object):
message_id (``int``): message_id (``int``):
Unique message identifier inside this chat. Unique message identifier inside this chat.
client (:obj:`Client <pyrogram.Client>`, *optional*):
The client instance this message is bound to.
date (``int``, *optional*): date (``int``, *optional*):
Date the message was sent in Unix time. Date the message was sent in Unix time.
@ -574,3 +571,39 @@ class Message(Object):
raise ValueError("This button is not supported yet") raise ValueError("This button is not supported yet")
else: else:
raise ValueError("The message doesn't contain any keyboard") 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 <pyrogram.Error>`
``ValueError``: If the message doesn't contain any downloadable media
"""
return self._client.download_media(
message=self,
file_name=file_name,
block=block
)

View File

@ -26,9 +26,9 @@ class MessageEntity(Object):
Args: Args:
type (``str``): type (``str``):
Type of the entity. Type of the entity.
Can be mention (@username), hashtag, bot_command, url, email, bold (bold text), italic (italic text), Can be "mention" (@username), "hashtag", "cashtag", "bot_command", "url", "email", "bold" (bold text),
code (monowidth string), pre (monowidth block), text_link (for clickable text URLs), italic (italic text), "code" (monowidth string), "pre" (monowidth block), "text_link" (for clickable text
text_mention (for users without usernames). URLs), "text_mention" (for users without usernames).
offset (``int``): offset (``int``):
Offset in UTF-16 code units to the start of the entity. Offset in UTF-16 code units to the start of the entity.
@ -45,9 +45,16 @@ class MessageEntity(Object):
ID = 0xb0700004 ID = 0xb0700004
def __init__(self, type: str, offset: int, length: int, url: str = None, user=None): def __init__(
self.type = type # string self,
self.offset = offset # int type: str,
self.length = length # int offset: int,
self.url = url # flags.0?string length: int,
self.user = user # flags.1?User url: str = None,
user=None
):
self.type = type
self.offset = offset
self.length = length
self.url = url
self.user = user

View File

@ -33,5 +33,5 @@ class Messages(Object):
ID = 0xb0700026 ID = 0xb0700026
def __init__(self, total_count: int, messages: list): def __init__(self, total_count: int, messages: list):
self.total_count = total_count # int self.total_count = total_count
self.messages = messages # Vector<Vector<PhotoSize>> self.messages = messages

View File

@ -26,6 +26,18 @@ class User(Object):
id (``int``): id (``int``):
Unique identifier for this user or bot. 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``): is_bot (``bool``):
True, if this user is a bot. True, if this user is a bot.
@ -42,10 +54,10 @@ class User(Object):
IETF language tag of the user's language. IETF language tag of the user's language.
phone_number (``str``, *optional*): phone_number (``str``, *optional*):
User's or bot's phone number. User's phone number.
photo (:obj:`ChatPhoto <pyrogram.ChatPhoto>`, *optional*): photo (:obj:`ChatPhoto <pyrogram.ChatPhoto>`, *optional*):
User's or bot's current profile photo. User's or bot's current profile photo. Suitable for downloads only.
""" """
ID = 0xb0700001 ID = 0xb0700001
@ -53,6 +65,10 @@ class User(Object):
def __init__( def __init__(
self, self,
id: int, id: int,
is_self: bool,
is_contact: bool,
is_mutual_contact: bool,
is_deleted: bool,
is_bot: bool, is_bot: bool,
first_name: str, first_name: str,
last_name: str = None, last_name: str = None,
@ -62,6 +78,10 @@ class User(Object):
photo=None photo=None
): ):
self.id = id 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.is_bot = is_bot
self.first_name = first_name self.first_name = first_name
self.last_name = last_name self.last_name = last_name