Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/__init__.py
#	pyrogram/client/client.py
#	pyrogram/client/methods/bots/answer_callback_query.py
#	pyrogram/client/methods/bots/get_game_high_scores.py
#	pyrogram/client/methods/bots/get_inline_bot_results.py
#	pyrogram/client/methods/bots/request_callback_answer.py
#	pyrogram/client/methods/bots/send_game.py
#	pyrogram/client/methods/bots/send_inline_bot_result.py
#	pyrogram/client/methods/bots/set_game_score.py
#	pyrogram/client/methods/chats/delete_chat_photo.py
#	pyrogram/client/methods/chats/export_chat_invite_link.py
#	pyrogram/client/methods/chats/get_chat.py
#	pyrogram/client/methods/chats/get_chat_member.py
#	pyrogram/client/methods/chats/get_chat_members.py
#	pyrogram/client/methods/chats/get_chat_members_count.py
#	pyrogram/client/methods/chats/get_dialogs.py
#	pyrogram/client/methods/chats/iter_chat_members.py
#	pyrogram/client/methods/chats/iter_dialogs.py
#	pyrogram/client/methods/chats/join_chat.py
#	pyrogram/client/methods/chats/kick_chat_member.py
#	pyrogram/client/methods/chats/leave_chat.py
#	pyrogram/client/methods/chats/pin_chat_message.py
#	pyrogram/client/methods/chats/promote_chat_member.py
#	pyrogram/client/methods/chats/restrict_chat_member.py
#	pyrogram/client/methods/chats/set_chat_description.py
#	pyrogram/client/methods/chats/set_chat_photo.py
#	pyrogram/client/methods/chats/set_chat_title.py
#	pyrogram/client/methods/chats/unban_chat_member.py
#	pyrogram/client/methods/chats/unpin_chat_message.py
#	pyrogram/client/methods/contacts/add_contacts.py
#	pyrogram/client/methods/contacts/delete_contacts.py
#	pyrogram/client/methods/contacts/get_contacts.py
#	pyrogram/client/methods/messages/delete_messages.py
#	pyrogram/client/methods/messages/download_media.py
#	pyrogram/client/methods/messages/edit_message_caption.py
#	pyrogram/client/methods/messages/edit_message_media.py
#	pyrogram/client/methods/messages/edit_message_reply_markup.py
#	pyrogram/client/methods/messages/edit_message_text.py
#	pyrogram/client/methods/messages/forward_messages.py
#	pyrogram/client/methods/messages/get_history.py
#	pyrogram/client/methods/messages/get_messages.py
#	pyrogram/client/methods/messages/iter_history.py
#	pyrogram/client/methods/messages/send_animation.py
#	pyrogram/client/methods/messages/send_audio.py
#	pyrogram/client/methods/messages/send_cached_media.py
#	pyrogram/client/methods/messages/send_chat_action.py
#	pyrogram/client/methods/messages/send_contact.py
#	pyrogram/client/methods/messages/send_document.py
#	pyrogram/client/methods/messages/send_location.py
#	pyrogram/client/methods/messages/send_media_group.py
#	pyrogram/client/methods/messages/send_message.py
#	pyrogram/client/methods/messages/send_photo.py
#	pyrogram/client/methods/messages/send_sticker.py
#	pyrogram/client/methods/messages/send_venue.py
#	pyrogram/client/methods/messages/send_video.py
#	pyrogram/client/methods/messages/send_video_note.py
#	pyrogram/client/methods/messages/send_voice.py
#	pyrogram/client/methods/password/change_cloud_password.py
#	pyrogram/client/methods/password/enable_cloud_password.py
#	pyrogram/client/methods/password/remove_cloud_password.py
#	pyrogram/client/methods/users/delete_user_profile_photos.py
#	pyrogram/client/methods/users/get_user_profile_photos.py
#	pyrogram/client/methods/users/get_users.py
#	pyrogram/session/auth.py
#	pyrogram/session/session.py
This commit is contained in:
Dan 2019-03-16 19:49:01 +01:00
commit 84fb959c8c
145 changed files with 1639 additions and 1058 deletions

View File

@ -32,7 +32,7 @@ Features
- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C. - **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C.
- **Documented**: Pyrogram API methods, types and public interfaces are well documented. - **Documented**: Pyrogram API methods, types and public interfaces are well documented.
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. - **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
- **Updated**, to the latest Telegram API version, currently Layer 91 on top of `MTProto 2.0`_. - **Updated**, to the latest Telegram API version, currently Layer 95 on top of `MTProto 2.0`_.
- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code. - **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code.
- **Comprehensive**: Execute any advanced action an official client is able to do, and even more. - **Comprehensive**: Execute any advanced action an official client is able to do, and even more.
@ -107,7 +107,7 @@ Copyright & License
</a> </a>
<br> <br>
<a href="compiler/api/source/main_api.tl"> <a href="compiler/api/source/main_api.tl">
<img src="https://img.shields.io/badge/schema-layer%2091-eda738.svg?longCache=true&colorA=262b30" <img src="https://img.shields.io/badge/schema-layer%2095-eda738.svg?longCache=true&colorA=262b30"
alt="Schema Layer"> alt="Schema Layer">
</a> </a>
<a href="https://github.com/pyrogram/tgcrypto"> <a href="https://github.com/pyrogram/tgcrypto">
@ -122,7 +122,7 @@ Copyright & License
.. |description| replace:: **Telegram MTProto API Framework for Python** .. |description| replace:: **Telegram MTProto API Framework for Python**
.. |schema| image:: https://img.shields.io/badge/schema-layer%2091-eda738.svg?longCache=true&colorA=262b30 .. |schema| image:: https://img.shields.io/badge/schema-layer%2095-eda738.svg?longCache=true&colorA=262b30
:target: compiler/api/source/main_api.tl :target: compiler/api/source/main_api.tl
:alt: Schema Layer :alt: Schema Layer

View File

@ -287,9 +287,11 @@ def start():
sorted_args = sort_args(c.args) sorted_args = sort_args(c.args)
arguments = ", " + ", ".join( arguments = (
[get_argument_type(i) for i in sorted_args if i != ("flags", "#")] ", "
) if c.args else "" + ("*, " if c.args else "")
+ (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "")
)
fields = "\n ".join( fields = "\n ".join(
["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args if i != ("flags", "#")] ["self.{0} = {0} # {1}".format(i[0], i[1]) for i in c.args if i != ("flags", "#")]
@ -456,7 +458,11 @@ def start():
fields=fields, fields=fields,
read_types=read_types, read_types=read_types,
write_types=write_types, write_types=write_types,
return_arguments=", ".join([i[0] for i in sorted_args if i != ("flags", "#")]) return_arguments=", ".join(
["{0}={0}".format(i[0]) for i in sorted_args if i != ("flags", "#")]
),
slots=", ".join(['"{}"'.format(i[0]) for i in sorted_args if i != ("flags", "#")]),
qualname="{}{}".format("{}.".format(c.namespace) if c.namespace else "", c.name)
) )
) )

View File

@ -9,7 +9,10 @@ class {class_name}(Object):
"""{docstring_args} """{docstring_args}
""" """
__slots__ = [{slots}]
ID = {object_id} ID = {object_id}
QUALNAME = "{qualname}"
def __init__(self{arguments}): def __init__(self{arguments}):
{fields} {fields}

View File

@ -93,3 +93,4 @@ CALL_ALREADY_ACCEPTED The call is already accepted
CALL_ALREADY_DECLINED The call is already declined CALL_ALREADY_DECLINED The call is already declined
PHOTO_EXT_INVALID The photo extension is invalid PHOTO_EXT_INVALID The photo extension is invalid
EXTERNAL_URL_INVALID The external media URL is invalid EXTERNAL_URL_INVALID The external media URL is invalid
CHAT_NOT_MODIFIED The chat settings were not modified
1 id message
93 CALL_ALREADY_DECLINED The call is already declined
94 PHOTO_EXT_INVALID The photo extension is invalid
95 EXTERNAL_URL_INVALID The external media URL is invalid
96 CHAT_NOT_MODIFIED The chat settings were not modified

View File

@ -26,7 +26,7 @@ Welcome to Pyrogram
</a> </a>
<br> <br>
<a href="compiler/api/source/main_api.tl"> <a href="compiler/api/source/main_api.tl">
<img src="https://img.shields.io/badge/schema-layer%2091-eda738.svg?longCache=true&colorA=262b30" <img src="https://img.shields.io/badge/schema-layer%2095-eda738.svg?longCache=true&colorA=262b30"
alt="Schema Layer"> alt="Schema Layer">
</a> </a>
<a href="https://github.com/pyrogram/tgcrypto"> <a href="https://github.com/pyrogram/tgcrypto">
@ -67,7 +67,7 @@ Features
- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C. - **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C.
- **Documented**: Pyrogram API methods, types and public interfaces are well documented. - **Documented**: Pyrogram API methods, types and public interfaces are well documented.
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted. - **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
- **Updated**, to the latest Telegram API version, currently Layer 91 on top of `MTProto 2.0`_. - **Updated**, to the latest Telegram API version, currently Layer 95 on top of `MTProto 2.0`_.
- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code. - **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code.
- **Comprehensive**: Execute any advanced action an official client is able to do, and even more. - **Comprehensive**: Execute any advanced action an official client is able to do, and even more.

View File

@ -82,7 +82,7 @@ If no error shows up you are good to go.
>>> import pyrogram >>> import pyrogram
>>> pyrogram.__version__ >>> pyrogram.__version__
'0.11.0' '0.12.0'
.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto .. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto
.. _develop: http://github.com/pyrogram/pyrogram .. _develop: http://github.com/pyrogram/pyrogram

View File

@ -37,7 +37,7 @@ __copyright__ = "Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance
"e" if sys.getfilesystemencoding() != "utf-8" else "\xe8" "e" if sys.getfilesystemencoding() != "utf-8" else "\xe8"
) )
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
__version__ = "0.11.1.asyncio" __version__ = "0.12.0.asyncio"
from .api.errors import Error from .api.errors import Error
from .client.types import ( from .client.types import (

View File

@ -19,14 +19,16 @@
from collections import OrderedDict from collections import OrderedDict
from datetime import datetime from datetime import datetime
from io import BytesIO from io import BytesIO
from json import JSONEncoder, dumps from json import dumps
from ..all import objects
class Object: class Object:
all = {} all = {}
__slots__ = []
QUALNAME = "Base"
@staticmethod @staticmethod
def read(b: BytesIO, *args): def read(b: BytesIO, *args):
return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args) return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args)
@ -35,7 +37,7 @@ class Object:
pass pass
def __str__(self) -> str: def __str__(self) -> str:
return dumps(self, cls=Encoder, indent=4) return dumps(self, indent=4, default=default, ensure_ascii=False)
def __bool__(self) -> bool: def __bool__(self) -> bool:
return True return True
@ -62,29 +64,18 @@ def remove_none(obj):
return obj return obj
class Encoder(JSONEncoder): def default(o: "Object"):
def default(self, o: Object):
try: try:
content = o.__dict__ content = {i: getattr(o, i) for i in o.__slots__}
return remove_none(
OrderedDict(
[("_", o.QUALNAME)]
+ [i for i in content.items()]
)
)
except AttributeError: except AttributeError:
if isinstance(o, datetime): if isinstance(o, datetime):
return o.strftime("%d-%b-%Y %H:%M:%S") return o.strftime("%d-%b-%Y %H:%M:%S")
else: else:
return repr(o) return repr(o)
name = o.__class__.__name__
o = objects.get(getattr(o, "ID", None), None)
if o is not None:
if o.startswith("pyrogram.client"):
r = remove_none(OrderedDict([("_", "pyrogram:" + name)] + [i for i in content.items()]))
r.pop("_client", None)
return r
else:
return OrderedDict(
[("_", o.replace("pyrogram.api.types.", "telegram:"))]
+ [i for i in content.items()]
)
else:
return None

View File

@ -16,5 +16,5 @@
# 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 .exceptions import *
from .error import UnknownError from .error import UnknownError
from .exceptions import *

View File

@ -632,9 +632,9 @@ class Client(Methods, BaseClient):
try: try:
r = await self.send( r = await self.send(
functions.auth.SignIn( functions.auth.SignIn(
self.phone_number, phone_number=self.phone_number,
phone_code_hash, phone_code_hash=phone_code_hash,
self.phone_code phone_code=self.phone_code
) )
) )
except PhoneNumberUnoccupied: except PhoneNumberUnoccupied:
@ -645,11 +645,11 @@ class Client(Methods, BaseClient):
try: try:
r = await self.send( r = await self.send(
functions.auth.SignUp( functions.auth.SignUp(
self.phone_number, phone_number=self.phone_number,
phone_code_hash, phone_code_hash=phone_code_hash,
self.phone_code, phone_code=self.phone_code,
self.first_name, first_name=self.first_name,
self.last_name last_name=self.last_name
) )
) )
except PhoneNumberOccupied: except PhoneNumberOccupied:
@ -743,7 +743,11 @@ class Client(Methods, BaseClient):
break break
if terms_of_service: if terms_of_service:
assert await self.send(functions.help.AcceptTermsOfService(terms_of_service.id)) assert await self.send(
functions.help.AcceptTermsOfService(
id=terms_of_service.id
)
)
self.password = None self.password = None
self.user_id = r.user.id self.user_id = r.user.id
@ -1035,10 +1039,10 @@ class Client(Methods, BaseClient):
raise ConnectionError("Client has not been started") raise ConnectionError("Client has not been started")
if self.no_updates: if self.no_updates:
data = functions.InvokeWithoutUpdates(data) data = functions.InvokeWithoutUpdates(query=data)
if self.takeout_id: if self.takeout_id:
data = functions.InvokeWithTakeout(self.takeout_id, data) data = functions.InvokeWithTakeout(takeout_id=self.takeout_id, query=data)
r = await self.session.send(data, retries, timeout) r = await self.session.send(data, retries, timeout)
@ -1350,7 +1354,7 @@ class Client(Methods, BaseClient):
self.fetch_peers( self.fetch_peers(
self.send( self.send(
functions.users.GetUsers( functions.users.GetUsers(
id=[types.InputUser(peer_id, 0)] id=[types.InputUser(user_id=peer_id, access_hash=0)]
) )
) )
) )
@ -1358,7 +1362,7 @@ class Client(Methods, BaseClient):
if str(peer_id).startswith("-100"): if str(peer_id).startswith("-100"):
self.send( self.send(
functions.channels.GetChannels( functions.channels.GetChannels(
id=[types.InputChannel(int(str(peer_id)[4:]), 0)] id=[types.InputChannel(channel_id=int(str(peer_id)[4:]), access_hash=0)]
) )
) )
else: else:
@ -1686,8 +1690,8 @@ class Client(Methods, BaseClient):
hashes = await session.send( hashes = await session.send(
functions.upload.GetCdnFileHashes( functions.upload.GetCdnFileHashes(
r.file_token, file_token=r.file_token,
offset offset=offset
) )
) )

View File

@ -79,10 +79,10 @@ def get_peer_id(input_peer) -> int:
def get_input_peer(peer_id: int, access_hash: int): def get_input_peer(peer_id: int, access_hash: int):
return ( return (
types.InputPeerUser(peer_id, access_hash) if peer_id > 0 types.InputPeerUser(user_id=peer_id, access_hash=access_hash) if peer_id > 0
else types.InputPeerChannel(int(str(peer_id)[4:]), access_hash) else types.InputPeerChannel(channel_id=int(str(peer_id)[4:]), access_hash=access_hash)
if (str(peer_id).startswith("-100") and access_hash) if (str(peer_id).startswith("-100") and access_hash)
else types.InputPeerChat(-peer_id) else types.InputPeerChat(chat_id=-peer_id)
) )

View File

@ -21,12 +21,14 @@ from pyrogram.client.ext import BaseClient
class AnswerCallbackQuery(BaseClient): class AnswerCallbackQuery(BaseClient):
async def answer_callback_query(self, async def answer_callback_query(
self,
callback_query_id: str, callback_query_id: str,
text: str = None, text: str = None,
show_alert: bool = None, show_alert: bool = None,
url: str = None, url: str = None,
cache_time: int = 0): cache_time: int = 0
):
"""Use this method to send answers to callback queries sent from inline keyboards. """Use this method to send answers to callback queries sent from inline keyboards.
The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.

View File

@ -24,10 +24,12 @@ from pyrogram.client.ext import BaseClient
class GetGameHighScores(BaseClient): class GetGameHighScores(BaseClient):
async def get_game_high_scores(self, async def get_game_high_scores(
self,
user_id: Union[int, str], user_id: Union[int, str],
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int = None): message_id: int = None
):
"""Use this method to get data for high score tables. """Use this method to get data for high score tables.
Args: Args:

View File

@ -24,12 +24,14 @@ from pyrogram.client.ext import BaseClient
class GetInlineBotResults(BaseClient): class GetInlineBotResults(BaseClient):
async def get_inline_bot_results(self, async def get_inline_bot_results(
self,
bot: Union[int, str], bot: Union[int, str],
query: str, query: str,
offset: str = "", offset: str = "",
latitude: float = None, latitude: float = None,
longitude: float = None): longitude: float = None
):
"""Use this method to get bot results via inline queries. """Use this method to get bot results via inline queries.
You can then send a result using :obj:`send_inline_bot_result <pyrogram.Client.send_inline_bot_result>` You can then send a result using :obj:`send_inline_bot_result <pyrogram.Client.send_inline_bot_result>`

View File

@ -23,10 +23,12 @@ from pyrogram.client.ext import BaseClient
class RequestCallbackAnswer(BaseClient): class RequestCallbackAnswer(BaseClient):
async def request_callback_answer(self, async def request_callback_answer(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int, message_id: int,
callback_data: bytes): callback_data: bytes
):
"""Use this method to request a callback answer from bots. This is the equivalent of clicking an """Use this method to request a callback answer from bots. This is the equivalent of clicking an
inline button containing callback data. inline button containing callback data.

View File

@ -24,15 +24,19 @@ from pyrogram.client.ext import BaseClient
class SendGame(BaseClient): class SendGame(BaseClient):
async def send_game(self, async def send_game(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
game_short_name: str, game_short_name: str,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message": "pyrogram.ForceReply"
] = None
) -> "pyrogram.Message":
"""Use this method to send a game. """Use this method to send a game.
Args: Args:

View File

@ -23,13 +23,15 @@ from pyrogram.client.ext import BaseClient
class SendInlineBotResult(BaseClient): class SendInlineBotResult(BaseClient):
async def send_inline_bot_result(self, async def send_inline_bot_result(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
query_id: int, query_id: int,
result_id: str, result_id: str,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
hide_via: bool = None): hide_via: bool = None
):
"""Use this method to send an inline bot result. """Use this method to send an inline bot result.
Bot results can be retrieved using :obj:`get_inline_bot_results <pyrogram.Client.get_inline_bot_results>` Bot results can be retrieved using :obj:`get_inline_bot_results <pyrogram.Client.get_inline_bot_results>`

View File

@ -24,13 +24,15 @@ from pyrogram.client.ext import BaseClient
class SetGameScore(BaseClient): class SetGameScore(BaseClient):
async def set_game_score(self, async def set_game_score(
self,
user_id: Union[int, str], user_id: Union[int, str],
score: int, score: int,
force: bool = None, force: bool = None,
disable_edit_message: bool = None, disable_edit_message: bool = None,
chat_id: Union[int, str] = None, chat_id: Union[int, str] = None,
message_id: int = None): message_id: int = None
):
# inline_message_id: str = None): TODO Add inline_message_id # inline_message_id: str = None): TODO Add inline_message_id
"""Use this method to set the score of the specified user in a game. """Use this method to set the score of the specified user in a game.

View File

@ -31,6 +31,7 @@ from .kick_chat_member import KickChatMember
from .leave_chat import LeaveChat from .leave_chat import LeaveChat
from .pin_chat_message import PinChatMessage from .pin_chat_message import PinChatMessage
from .promote_chat_member import PromoteChatMember from .promote_chat_member import PromoteChatMember
from .restrict_chat import RestrictChat
from .restrict_chat_member import RestrictChatMember from .restrict_chat_member import RestrictChatMember
from .set_chat_description import SetChatDescription from .set_chat_description import SetChatDescription
from .set_chat_photo import SetChatPhoto from .set_chat_photo import SetChatPhoto
@ -62,6 +63,7 @@ class Chats(
GetChatPreview, GetChatPreview,
IterDialogs, IterDialogs,
IterChatMembers, IterChatMembers,
UpdateChatUsername UpdateChatUsername,
RestrictChat
): ):
pass pass

View File

@ -23,8 +23,10 @@ from ...ext import BaseClient
class DeleteChatPhoto(BaseClient): class DeleteChatPhoto(BaseClient):
async def delete_chat_photo(self, async def delete_chat_photo(
chat_id: Union[int, str]) -> bool: self,
chat_id: Union[int, str]
) -> bool:
"""Use this method to delete a chat photo. """Use this method to delete a chat photo.
Photos can't be changed for private chats. 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. You must be an administrator in the chat for this to work and must have the appropriate admin rights.

View File

@ -23,8 +23,10 @@ from ...ext import BaseClient
class ExportChatInviteLink(BaseClient): class ExportChatInviteLink(BaseClient):
async def export_chat_invite_link(self, async def export_chat_invite_link(
chat_id: Union[int, str]) -> str: self,
chat_id: Union[int, str]
) -> str:
"""Use this method to generate a new invite link for a chat; any previously generated link is revoked. """Use this method to generate a new invite link for a chat; any previously generated link is revoked.
You must be an administrator in the chat for this to work and have the appropriate admin rights. You must be an administrator in the chat for this to work and have the appropriate admin rights.
@ -45,7 +47,7 @@ class ExportChatInviteLink(BaseClient):
if isinstance(peer, types.InputPeerChat): if isinstance(peer, types.InputPeerChat):
return await self.send( return await self.send(
functions.messages.ExportChatInvite( functions.messages.ExportChatInvite(
chat_id=peer.chat_id peer=peer.chat_id
) )
).link ).link
elif isinstance(peer, types.InputPeerChannel): elif isinstance(peer, types.InputPeerChannel):

View File

@ -24,8 +24,10 @@ from ...ext import BaseClient
class GetChat(BaseClient): class GetChat(BaseClient):
async def get_chat(self, async def get_chat(
chat_id: Union[int, str]) -> "pyrogram.Chat": self,
chat_id: Union[int, str]
) -> "pyrogram.Chat":
"""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.)
@ -67,10 +69,10 @@ class GetChat(BaseClient):
peer = await self.resolve_peer(chat_id) peer = await self.resolve_peer(chat_id)
if isinstance(peer, types.InputPeerChannel): if isinstance(peer, types.InputPeerChannel):
r = await self.send(functions.channels.GetFullChannel(peer)) r = await self.send(functions.channels.GetFullChannel(channel=peer))
elif isinstance(peer, (types.InputPeerUser, types.InputPeerSelf)): elif isinstance(peer, (types.InputPeerUser, types.InputPeerSelf)):
r = await self.send(functions.users.GetFullUser(peer)) r = await self.send(functions.users.GetFullUser(id=peer))
else: else:
r = await self.send(functions.messages.GetFullChat(peer.chat_id)) r = await self.send(functions.messages.GetFullChat(chat_id=peer.chat_id))
return await pyrogram.Chat._parse_full(self, r) return await pyrogram.Chat._parse_full(self, r)

View File

@ -24,9 +24,11 @@ from ...ext import BaseClient
class GetChatMember(BaseClient): class GetChatMember(BaseClient):
async def get_chat_member(self, async def get_chat_member(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
user_id: Union[int, str]) -> "pyrogram.ChatMember": user_id: Union[int, str]
) -> "pyrogram.ChatMember":
"""Use this method to get information about one member of a chat. """Use this method to get information about one member of a chat.
Args: Args:

View File

@ -33,12 +33,14 @@ class Filters:
class GetChatMembers(BaseClient): class GetChatMembers(BaseClient):
async def get_chat_members(self, async def get_chat_members(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
offset: int = 0, offset: int = 0,
limit: int = 200, limit: int = 200,
query: str = "", query: str = "",
filter: str = Filters.ALL) -> "pyrogram.ChatMembers": filter: str = Filters.ALL
) -> "pyrogram.ChatMembers":
"""Use this method to get a chunk of the members list of a chat. """Use this method to get a chunk of the members list of a chat.
You can get up to 200 chat members at once. You can get up to 200 chat members at once.
@ -92,7 +94,7 @@ class GetChatMembers(BaseClient):
self, self,
await self.send( await self.send(
functions.messages.GetFullChat( functions.messages.GetFullChat(
peer.chat_id chat_id=peer.chat_id
) )
) )
) )

View File

@ -23,8 +23,10 @@ from ...ext import BaseClient
class GetChatMembersCount(BaseClient): class GetChatMembersCount(BaseClient):
async def get_chat_members_count(self, async def get_chat_members_count(
chat_id: Union[int, str]) -> int: self,
chat_id: Union[int, str]
) -> int:
"""Use this method to get the number of members in a chat. """Use this method to get the number of members in a chat.
Args: Args:

View File

@ -22,8 +22,10 @@ from ...ext import BaseClient
class GetChatPreview(BaseClient): class GetChatPreview(BaseClient):
def get_chat_preview(self, def get_chat_preview(
invite_link: str): self,
invite_link: str
):
"""Use this method to get the preview of a chat using the invite link. """Use this method to get the preview of a chat using the invite link.
This method only returns a chat preview, if you want to join a chat use :meth:`join_chat` This method only returns a chat preview, if you want to join a chat use :meth:`join_chat`

View File

@ -28,10 +28,12 @@ log = logging.getLogger(__name__)
class GetDialogs(BaseClient): class GetDialogs(BaseClient):
async def get_dialogs(self, async def get_dialogs(
self,
offset_date: int = 0, offset_date: int = 0,
limit: int = 100, limit: int = 100,
pinned_only: bool = False) -> "pyrogram.Dialogs": pinned_only: bool = False
) -> "pyrogram.Dialogs":
"""Use this method to get a chunk of the user's dialogs """Use this method to get a chunk of the user's dialogs
You can get up to 100 dialogs at once. You can get up to 100 dialogs at once.

View File

@ -41,11 +41,13 @@ QUERYABLE_FILTERS = (Filters.ALL, Filters.KICKED, Filters.RESTRICTED)
class IterChatMembers(BaseClient): class IterChatMembers(BaseClient):
@async_generator @async_generator
async def iter_chat_members(self, async def iter_chat_members(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
limit: int = 0, limit: int = 0,
query: str = "", query: str = "",
filter: str = Filters.ALL) -> Optional[AsyncGenerator["pyrogram.ChatMember", None]]: filter: str = Filters.ALL
) -> Optional[AsyncGenerator["pyrogram.ChatMember", None]]:
"""Use this method to iterate through the members of a chat sequentially. """Use this method to iterate through the members of a chat sequentially.
This convenience method does the same as repeatedly calling :meth:`get_chat_members` in a loop, thus saving you This convenience method does the same as repeatedly calling :meth:`get_chat_members` in a loop, thus saving you

View File

@ -26,9 +26,11 @@ from ...ext import BaseClient
class IterDialogs(BaseClient): class IterDialogs(BaseClient):
@async_generator @async_generator
async def iter_dialogs(self, async def iter_dialogs(
self,
limit: int = 0, limit: int = 0,
offset_date: int = 0) -> Optional[AsyncGenerator["pyrogram.Dialog", None]]: offset_date: int = 0
) -> Optional[AsyncGenerator["pyrogram.Dialog", None]]:
"""Use this method to iterate through a user's dialogs sequentially. """Use this method to iterate through a user's dialogs sequentially.
This convenience method does the same as repeatedly calling :meth:`get_dialogs` in a loop, thus saving you from This convenience method does the same as repeatedly calling :meth:`get_dialogs` in a loop, thus saving you from

View File

@ -22,8 +22,10 @@ from ...ext import BaseClient
class JoinChat(BaseClient): class JoinChat(BaseClient):
async def join_chat(self, async def join_chat(
chat_id: str): self,
chat_id: str
):
"""Use this method to join a group chat or channel. """Use this method to join a group chat or channel.
Args: Args:

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class KickChatMember(BaseClient): class KickChatMember(BaseClient):
async def kick_chat_member(self, async def kick_chat_member(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
user_id: Union[int, str], user_id: Union[int, str],
until_date: int = 0) -> Union["pyrogram.Message", bool]: until_date: int = 0
) -> Union["pyrogram.Message", bool]:
"""Use this method to kick a user from a group, a supergroup or a channel. """Use this method to kick a user from a group, a supergroup or a channel.
In the case of supergroups and channels, the user will not be able to return to the group on their own using In the case of supergroups and channels, the user will not be able to return to the group on their own using
invite links, etc., unless unbanned first. You must be an administrator in the chat for this to work and must invite links, etc., unless unbanned first. You must be an administrator in the chat for this to work and must

View File

@ -23,9 +23,11 @@ from ...ext import BaseClient
class LeaveChat(BaseClient): class LeaveChat(BaseClient):
async def leave_chat(self, async def leave_chat(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
delete: bool = False): delete: bool = False
):
"""Use this method to leave a group chat or channel. """Use this method to leave a group chat or channel.
Args: Args:

View File

@ -23,10 +23,12 @@ from ...ext import BaseClient
class PinChatMessage(BaseClient): class PinChatMessage(BaseClient):
async def pin_chat_message(self, async def pin_chat_message(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int, message_id: int,
disable_notification: bool = None) -> bool: disable_notification: bool = None
) -> bool:
"""Use this method to pin a message in a group, channel or your own chat. """Use this method to pin a message in a group, channel or your own chat.
You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin right in 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. the supergroup or "can_edit_messages" admin right in the channel.
@ -55,3 +57,5 @@ class PinChatMessage(BaseClient):
silent=disable_notification or None silent=disable_notification or None
) )
) )
return True

View File

@ -23,7 +23,8 @@ from ...ext import BaseClient
class PromoteChatMember(BaseClient): class PromoteChatMember(BaseClient):
async def promote_chat_member(self, async def promote_chat_member(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
user_id: Union[int, str], user_id: Union[int, str],
can_change_info: bool = True, can_change_info: bool = True,
@ -33,7 +34,8 @@ class PromoteChatMember(BaseClient):
can_restrict_members: bool = True, can_restrict_members: bool = True,
can_invite_users: bool = True, can_invite_users: bool = True,
can_pin_messages: bool = False, can_pin_messages: bool = False,
can_promote_members: bool = False) -> bool: can_promote_members: bool = False
) -> bool:
"""Use this method to promote or demote a user in a supergroup or a channel. """Use this method to promote or demote a user in a supergroup or a channel.
You must be an administrator in the chat for this to work and must have the appropriate admin rights. You must be an administrator in the chat for this to work and must have the appropriate admin rights.

View File

@ -0,0 +1,143 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
from pyrogram.api import functions, types
from ...ext import BaseClient
from ...types.user_and_chats import Chat
class RestrictChat(BaseClient):
def restrict_chat(
self,
chat_id: Union[int, str],
can_send_messages: bool = False,
can_send_media_messages: bool = False,
can_send_other_messages: bool = False,
can_add_web_page_previews: bool = False,
can_send_polls: bool = False,
can_change_info: bool = False,
can_invite_users: bool = False,
can_pin_messages: bool = False
) -> Chat:
"""Use this method to restrict a chat.
Pass True for all boolean parameters to lift restrictions from a chat.
Args:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
can_send_messages (``bool``, *optional*):
Pass True, if the user can send text messages, contacts, locations and venues.
can_send_media_messages (``bool``, *optional*):
Pass True, if the user can send audios, documents, photos, videos, video notes and voice notes,
implies can_send_messages.
can_send_other_messages (``bool``, *optional*):
Pass True, if the user can send animations, games, stickers and use inline bots,
implies can_send_media_messages.
can_add_web_page_previews (``bool``, *optional*):
Pass True, if the user may add web page previews to their messages, implies can_send_media_messages.
can_send_polls (``bool``, *optional*):
Pass True, if the user can send polls, implies can_send_media_messages.
can_change_info (``bool``, *optional*):
Pass True, if the user can change the chat title, photo and other settings.
can_invite_users (``bool``, *optional*):
Pass True, if the user can invite new users to the chat.
can_pin_messages (``bool``, *optional*):
Pass True, if the user can pin messages.
Returns:
On success, a :obj:`Chat <pyrogram.Chat>` object is returned.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
"""
send_messages = True
send_media = True
send_stickers = True
send_gifs = True
send_games = True
send_inline = True
embed_links = True
send_polls = True
change_info = True
invite_users = True
pin_messages = True
if can_send_messages:
send_messages = None
if can_send_media_messages:
send_messages = None
send_media = None
if can_send_other_messages:
send_messages = None
send_media = None
send_stickers = None
send_gifs = None
send_games = None
send_inline = None
if can_add_web_page_previews:
send_messages = None
send_media = None
embed_links = None
if can_send_polls:
send_messages = None
send_polls = None
if can_change_info:
change_info = None
if can_invite_users:
invite_users = None
if can_pin_messages:
pin_messages = None
r = self.send(
functions.messages.EditChatDefaultBannedRights(
peer=self.resolve_peer(chat_id),
banned_rights=types.ChatBannedRights(
until_date=0,
send_messages=send_messages,
send_media=send_media,
send_stickers=send_stickers,
send_gifs=send_gifs,
send_games=send_games,
send_inline=send_inline,
embed_links=embed_links,
send_polls=send_polls,
change_info=change_info,
invite_users=invite_users,
pin_messages=pin_messages
)
)
)
return Chat._parse_chat(self, r.chats[0])

View File

@ -20,17 +20,24 @@ from typing import Union
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ...ext import BaseClient from ...ext import BaseClient
from ...types.user_and_chats import Chat
class RestrictChatMember(BaseClient): class RestrictChatMember(BaseClient):
async def restrict_chat_member(self, async def restrict_chat_member(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
user_id: Union[int, str], user_id: Union[int, str],
until_date: int = 0, until_date: int = 0,
can_send_messages: bool = False, can_send_messages: bool = False,
can_send_media_messages: bool = False, can_send_media_messages: bool = False,
can_send_other_messages: bool = False, can_send_other_messages: bool = False,
can_add_web_page_previews: bool = False) -> bool: can_add_web_page_previews: bool = False,
can_send_polls: bool = False,
can_change_info: bool = False,
can_invite_users: bool = False,
can_pin_messages: bool = False
) -> Chat:
"""Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for """Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for
this to work and must have the appropriate admin rights. Pass True for all boolean parameters to lift this to work and must have the appropriate admin rights. Pass True for all boolean parameters to lift
restrictions from a user. restrictions from a user.
@ -60,10 +67,22 @@ class RestrictChatMember(BaseClient):
implies can_send_media_messages. implies can_send_media_messages.
can_add_web_page_previews (``bool``, *optional*): can_add_web_page_previews (``bool``, *optional*):
Pass True, if the user may add web page previews to their messages, implies can_send_media_messages Pass True, if the user may add web page previews to their messages, implies can_send_media_messages.
can_send_polls (``bool``, *optional*):
Pass True, if the user can send polls, implies can_send_media_messages.
can_change_info (``bool``, *optional*):
Pass True, if the user can change the chat title, photo and other settings.
can_invite_users (``bool``, *optional*):
Pass True, if the user can invite new users to the chat.
can_pin_messages (``bool``, *optional*):
Pass True, if the user can pin messages.
Returns: Returns:
True on success. On success, a :obj:`Chat <pyrogram.Chat>` object is returned.
Raises: Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error. :class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
@ -75,6 +94,10 @@ class RestrictChatMember(BaseClient):
send_games = True send_games = True
send_inline = True send_inline = True
embed_links = True embed_links = True
send_polls = True
change_info = True
invite_users = True
pin_messages = True
if can_send_messages: if can_send_messages:
send_messages = None send_messages = None
@ -84,6 +107,7 @@ class RestrictChatMember(BaseClient):
send_media = None send_media = None
if can_send_other_messages: if can_send_other_messages:
send_messages = None
send_media = None send_media = None
send_stickers = None send_stickers = None
send_gifs = None send_gifs = None
@ -91,10 +115,24 @@ class RestrictChatMember(BaseClient):
send_inline = None send_inline = None
if can_add_web_page_previews: if can_add_web_page_previews:
send_messages = None
send_media = None send_media = None
embed_links = None embed_links = None
await self.send( if can_send_polls:
send_messages = None
send_polls = None
if can_change_info:
change_info = None
if can_invite_users:
invite_users = None
if can_pin_messages:
pin_messages = None
r = await self.send(
functions.channels.EditBanned( functions.channels.EditBanned(
channel=await self.resolve_peer(chat_id), channel=await self.resolve_peer(chat_id),
user_id=await self.resolve_peer(user_id), user_id=await self.resolve_peer(user_id),
@ -106,9 +144,13 @@ class RestrictChatMember(BaseClient):
send_gifs=send_gifs, send_gifs=send_gifs,
send_games=send_games, send_games=send_games,
send_inline=send_inline, send_inline=send_inline,
embed_links=embed_links embed_links=embed_links,
send_polls=send_polls,
change_info=change_info,
invite_users=invite_users,
pin_messages=pin_messages
) )
) )
) )
return True return Chat._parse_chat(self, r.chats[0])

View File

@ -23,9 +23,11 @@ from ...ext import BaseClient
class SetChatDescription(BaseClient): class SetChatDescription(BaseClient):
async def set_chat_description(self, async def set_chat_description(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
description: str) -> bool: description: str
) -> bool:
"""Use this method to change the description of a supergroup or a channel. """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. You must be an administrator in the chat for this to work and must have the appropriate admin rights.

View File

@ -26,9 +26,11 @@ from ...ext import BaseClient
class SetChatPhoto(BaseClient): class SetChatPhoto(BaseClient):
async def set_chat_photo(self, async def set_chat_photo(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
photo: str) -> bool: photo: str
) -> bool:
"""Use this method to set a new profile photo for the chat. """Use this method to set a new profile photo for the chat.
Photos can't be changed for private chats. 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. You must be an administrator in the chat for this to work and must have the appropriate admin rights.

View File

@ -23,9 +23,11 @@ from ...ext import BaseClient
class SetChatTitle(BaseClient): class SetChatTitle(BaseClient):
async def set_chat_title(self, async def set_chat_title(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
title: str) -> bool: title: str
) -> bool:
"""Use this method to change the title of a chat. """Use this method to change the title of a chat.
Titles can't be changed for private chats. 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. You must be an administrator in the chat for this to work and must have the appropriate admin rights.

View File

@ -23,9 +23,11 @@ from ...ext import BaseClient
class UnbanChatMember(BaseClient): class UnbanChatMember(BaseClient):
async def unban_chat_member(self, async def unban_chat_member(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
user_id: Union[int, str]) -> bool: user_id: Union[int, str]
) -> bool:
"""Use this method to unban a previously kicked user in a supergroup or channel. """Use this method to unban a previously kicked user in a supergroup or channel.
The user will **not** return to the group or channel automatically, but will be able to join via link, etc. The user will **not** return to the group or channel automatically, but will be able to join via link, etc.
You must be an administrator for this to work. You must be an administrator for this to work.

View File

@ -23,8 +23,10 @@ from ...ext import BaseClient
class UnpinChatMessage(BaseClient): class UnpinChatMessage(BaseClient):
async def unpin_chat_message(self, async def unpin_chat_message(
chat_id: Union[int, str]) -> bool: self,
chat_id: Union[int, str]
) -> bool:
"""Use this method to unpin a message in a group, channel or your own chat. """Use this method to unpin a message in a group, channel or your own chat.
You must be an administrator in the chat for this to work and must have the "can_pin_messages" admin 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. right in the supergroup or "can_edit_messages" admin right in the channel.

View File

@ -23,9 +23,11 @@ from ...ext import BaseClient
class UpdateChatUsername(BaseClient): class UpdateChatUsername(BaseClient):
def update_chat_username(self, def update_chat_username(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
username: Union[str, None]) -> bool: username: Union[str, None]
) -> bool:
"""Use this method to update a channel or a supergroup username. """Use this method to update a channel or a supergroup username.
To update your own username (for users only, not bots) you can use :meth:`update_username`. To update your own username (for users only, not bots) you can use :meth:`update_username`.

View File

@ -24,8 +24,10 @@ from ...ext import BaseClient
class AddContacts(BaseClient): class AddContacts(BaseClient):
async def add_contacts(self, async def add_contacts(
contacts: List["pyrogram.InputPhoneContact"]): self,
contacts: List["pyrogram.InputPhoneContact"]
):
"""Use this method to add contacts to your Telegram address book. """Use this method to add contacts to your Telegram address book.
Args: Args:

View File

@ -24,8 +24,10 @@ from ...ext import BaseClient
class DeleteContacts(BaseClient): class DeleteContacts(BaseClient):
async def delete_contacts(self, async def delete_contacts(
ids: List[int]): self,
ids: List[int]
):
"""Use this method to delete contacts from your Telegram address book """Use this method to delete contacts from your Telegram address book
Args: Args:

View File

@ -39,7 +39,7 @@ class GetContacts(BaseClient):
""" """
while True: while True:
try: try:
contacts = await self.send(functions.contacts.GetContacts(0)) contacts = await self.send(functions.contacts.GetContacts(hash=0))
except FloodWait as e: except FloodWait as e:
log.warning("get_contacts flood: waiting {} seconds".format(e.x)) log.warning("get_contacts flood: waiting {} seconds".format(e.x))
await asyncio.sleep(e.x) await asyncio.sleep(e.x)

View File

@ -25,9 +25,11 @@ from ...ext import BaseClient
class OnCallbackQuery(BaseClient): class OnCallbackQuery(BaseClient):
def on_callback_query(self=None, def on_callback_query(
self=None,
filters=None, filters=None,
group: int = 0) -> callable: group: int = 0
) -> callable:
"""Use this decorator to automatically register a function for handling """Use this decorator to automatically register a function for handling
callback queries. This does the same thing as :meth:`add_handler` using the callback queries. This does the same thing as :meth:`add_handler` using the
:class:`CallbackQueryHandler`. :class:`CallbackQueryHandler`.

View File

@ -25,9 +25,11 @@ from ...ext import BaseClient
class OnDeletedMessages(BaseClient): class OnDeletedMessages(BaseClient):
def on_deleted_messages(self=None, def on_deleted_messages(
self=None,
filters=None, filters=None,
group: int = 0) -> callable: group: int = 0
) -> callable:
"""Use this decorator to automatically register a function for handling """Use this decorator to automatically register a function for handling
deleted messages. This does the same thing as :meth:`add_handler` using the deleted messages. This does the same thing as :meth:`add_handler` using the
:class:`DeletedMessagesHandler`. :class:`DeletedMessagesHandler`.

View File

@ -25,9 +25,11 @@ from ...ext import BaseClient
class OnMessage(BaseClient): class OnMessage(BaseClient):
def on_message(self=None, def on_message(
self=None,
filters=None, filters=None,
group: int = 0) -> callable: group: int = 0
) -> callable:
"""Use this decorator to automatically register a function for handling """Use this decorator to automatically register a function for handling
messages. This does the same thing as :meth:`add_handler` using the messages. This does the same thing as :meth:`add_handler` using the
:class:`MessageHandler`. :class:`MessageHandler`.

View File

@ -24,8 +24,10 @@ from ...ext import BaseClient
class OnRawUpdate(BaseClient): class OnRawUpdate(BaseClient):
def on_raw_update(self=None, def on_raw_update(
group: int = 0) -> callable: self=None,
group: int = 0
) -> callable:
"""Use this decorator to automatically register a function for handling """Use this decorator to automatically register a function for handling
raw updates. This does the same thing as :meth:`add_handler` using the raw updates. This does the same thing as :meth:`add_handler` using the
:class:`RawUpdateHandler`. :class:`RawUpdateHandler`.

View File

@ -25,9 +25,11 @@ from ...ext import BaseClient
class OnUserStatus(BaseClient): class OnUserStatus(BaseClient):
def on_user_status(self=None, def on_user_status(
self=None,
filters=None, filters=None,
group: int = 0) -> callable: group: int = 0
) -> callable:
"""Use this decorator to automatically register a function for handling """Use this decorator to automatically register a function for handling
user status updates. This does the same thing as :meth:`add_handler` using the user status updates. This does the same thing as :meth:`add_handler` using the
:class:`UserStatusHandler`. :class:`UserStatusHandler`.

View File

@ -23,9 +23,11 @@ from pyrogram.client.ext import BaseClient
class ClosePoll(BaseClient): class ClosePoll(BaseClient):
def close_poll(self, def close_poll(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: id) -> bool: message_id: id
) -> bool:
"""Use this method to close (stop) a poll. """Use this method to close (stop) a poll.
Closed polls can't be reopened and nobody will be able to vote in it anymore. Closed polls can't be reopened and nobody will be able to vote in it anymore.

View File

@ -23,10 +23,12 @@ from pyrogram.client.ext import BaseClient
class DeleteMessages(BaseClient): class DeleteMessages(BaseClient):
async def delete_messages(self, async def delete_messages(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_ids: Iterable[int], message_ids: Iterable[int],
revoke: bool = True) -> bool: revoke: bool = True
) -> bool:
"""Use this method to delete messages, including service messages, with the following limitations: """Use this method to delete messages, including service messages, with the following limitations:
- A message can only be deleted if it was sent less than 48 hours ago. - A message can only be deleted if it was sent less than 48 hours ago.

View File

@ -24,12 +24,14 @@ from pyrogram.client.ext import BaseClient
class DownloadMedia(BaseClient): class DownloadMedia(BaseClient):
async def download_media(self, async def download_media(
self,
message: Union["pyrogram.Message", str], message: Union["pyrogram.Message", str],
file_name: str = "", file_name: str = "",
block: bool = True, block: bool = True,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union[str, None]: progress_args: tuple = ()
) -> Union[str, None]:
"""Use this method to download the media from a Message. """Use this method to download the media from a Message.
Args: Args:

View File

@ -24,12 +24,14 @@ from pyrogram.client.ext import BaseClient
class EditMessageCaption(BaseClient): class EditMessageCaption(BaseClient):
async def edit_message_caption(self, async def edit_message_caption(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int, message_id: int,
caption: str, caption: str,
parse_mode: str = "", parse_mode: str = "",
reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "pyrogram.Message": reply_markup: "pyrogram.InlineKeyboardMarkup" = None
) -> "pyrogram.Message":
"""Use this method to edit captions of messages. """Use this method to edit captions of messages.
Args: Args:

View File

@ -33,11 +33,13 @@ from pyrogram.client.types.input_media import InputMedia
class EditMessageMedia(BaseClient): class EditMessageMedia(BaseClient):
async def edit_message_media(self, async def edit_message_media(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int, message_id: int,
media: InputMedia, media: InputMedia,
reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "pyrogram.Message": reply_markup: "pyrogram.InlineKeyboardMarkup" = None
) -> "pyrogram.Message":
"""Use this method to edit audio, document, photo, or video messages. """Use this method to edit audio, document, photo, or video messages.
If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise, If a message is a part of a message album, then it can be edited only to a photo or a video. Otherwise,
@ -131,7 +133,9 @@ class EditMessageMedia(BaseClient):
w=media.width, w=media.width,
h=media.height h=media.height
), ),
types.DocumentAttributeFilename(os.path.basename(media.media)) types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
)
] ]
) )
) )
@ -187,7 +191,9 @@ class EditMessageMedia(BaseClient):
performer=media.performer, performer=media.performer,
title=media.title title=media.title
), ),
types.DocumentAttributeFilename(os.path.basename(media.media)) types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
)
] ]
) )
) )
@ -244,7 +250,9 @@ class EditMessageMedia(BaseClient):
w=media.width, w=media.width,
h=media.height h=media.height
), ),
types.DocumentAttributeFilename(os.path.basename(media.media)), types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
),
types.DocumentAttributeAnimated() types.DocumentAttributeAnimated()
] ]
) )
@ -296,7 +304,9 @@ class EditMessageMedia(BaseClient):
thumb=None if media.thumb is None else self.save_file(media.thumb), thumb=None if media.thumb is None else self.save_file(media.thumb),
file=await self.save_file(media.media), file=await self.save_file(media.media),
attributes=[ attributes=[
types.DocumentAttributeFilename(os.path.basename(media.media)) types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
)
] ]
) )
) )

View File

@ -24,10 +24,12 @@ from pyrogram.client.ext import BaseClient
class EditMessageReplyMarkup(BaseClient): class EditMessageReplyMarkup(BaseClient):
async def edit_message_reply_markup(self, async def edit_message_reply_markup(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int, message_id: int,
reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "pyrogram.Message": reply_markup: "pyrogram.InlineKeyboardMarkup" = None
) -> "pyrogram.Message":
"""Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). """Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots).
Args: Args:

View File

@ -24,13 +24,15 @@ from pyrogram.client.ext import BaseClient
class EditMessageText(BaseClient): class EditMessageText(BaseClient):
async def edit_message_text(self, async def edit_message_text(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int, message_id: int,
text: str, text: str,
parse_mode: str = "", parse_mode: str = "",
disable_web_page_preview: bool = None, disable_web_page_preview: bool = None,
reply_markup: "pyrogram.InlineKeyboardMarkup" = None) -> "pyrogram.Message": reply_markup: "pyrogram.InlineKeyboardMarkup" = None
) -> "pyrogram.Message":
"""Use this method to edit text messages. """Use this method to edit text messages.
Args: Args:

View File

@ -24,11 +24,13 @@ from ...ext import BaseClient
class ForwardMessages(BaseClient): class ForwardMessages(BaseClient):
async def forward_messages(self, async def forward_messages(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
from_chat_id: Union[int, str], from_chat_id: Union[int, str],
message_ids: Iterable[int], message_ids: Iterable[int],
disable_notification: bool = None) -> "pyrogram.Messages": disable_notification: bool = None
) -> "pyrogram.Messages":
"""Use this method to forward messages of any kind. """Use this method to forward messages of any kind.
Args: Args:

View File

@ -29,13 +29,15 @@ log = logging.getLogger(__name__)
class GetHistory(BaseClient): class GetHistory(BaseClient):
async def get_history(self, async def get_history(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
limit: int = 100, limit: int = 100,
offset: int = 0, offset: int = 0,
offset_id: int = 0, offset_id: int = 0,
offset_date: int = 0, offset_date: int = 0,
reverse: bool = False): reverse: bool = False
):
"""Use this method to retrieve a chunk of the history of a chat. """Use this method to retrieve a chunk of the history of a chat.
You can get up to 100 messages at once. You can get up to 100 messages at once.

View File

@ -29,11 +29,13 @@ log = logging.getLogger(__name__)
class GetMessages(BaseClient): class GetMessages(BaseClient):
async def get_messages(self, async def get_messages(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_ids: Union[int, Iterable[int]] = None, message_ids: Union[int, Iterable[int]] = None,
reply_to_message_ids: Union[int, Iterable[int]] = None, reply_to_message_ids: Union[int, Iterable[int]] = None,
replies: int = 1) -> Union["pyrogram.Message", "pyrogram.Messages"]: replies: int = 1
) -> Union["pyrogram.Message", "pyrogram.Messages"]:
"""Use this method to get one or more messages that belong to a specific chat. """Use this method to get one or more messages that belong to a specific chat.
You can retrieve up to 200 messages at once. You can retrieve up to 200 messages at once.
@ -76,7 +78,7 @@ class GetMessages(BaseClient):
is_iterable = not isinstance(ids, int) is_iterable = not isinstance(ids, int)
ids = list(ids) if is_iterable else [ids] ids = list(ids) if is_iterable else [ids]
ids = [ids_type(i) for i in ids] ids = [ids_type(id=i) for i in ids]
if isinstance(peer, types.InputPeerChannel): if isinstance(peer, types.InputPeerChannel):
rpc = functions.channels.GetMessages(channel=peer, id=ids) rpc = functions.channels.GetMessages(channel=peer, id=ids)

View File

@ -26,13 +26,15 @@ from ...ext import BaseClient
class IterHistory(BaseClient): class IterHistory(BaseClient):
@async_generator @async_generator
async def iter_history(self, async def iter_history(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
limit: int = 0, limit: int = 0,
offset: int = 0, offset: int = 0,
offset_id: int = 0, offset_id: int = 0,
offset_date: int = 0, offset_date: int = 0,
reverse: bool = False) -> Optional[AsyncGenerator["pyrogram.Message", None]]: reverse: bool = False
) -> Optional[AsyncGenerator["pyrogram.Message", None]]:
"""Use this method to iterate through a chat history sequentially. """Use this method to iterate through a chat history sequentially.
This convenience method does the same as repeatedly calling :meth:`get_history` in a loop, thus saving you from This convenience method does the same as repeatedly calling :meth:`get_history` in a loop, thus saving you from

View File

@ -23,9 +23,11 @@ from pyrogram.client.ext import BaseClient
class RetractVote(BaseClient): class RetractVote(BaseClient):
def retract_vote(self, def retract_vote(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: id) -> bool: message_id: id
) -> bool:
"""Use this method to retract your vote in a poll. """Use this method to retract your vote in a poll.
Args: Args:

View File

@ -28,7 +28,8 @@ from pyrogram.client.ext import BaseClient, utils
class SendAnimation(BaseClient): class SendAnimation(BaseClient):
async def send_animation(self, async def send_animation(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
animation: str, animation: str,
caption: str = "", caption: str = "",
@ -39,12 +40,15 @@ class SendAnimation(BaseClient):
thumb: str = None, thumb: str = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send animation files (animation or H.264/MPEG-4 AVC video without sound). """Use this method to send animation files (animation or H.264/MPEG-4 AVC video without sound).
Args: Args:
@ -141,7 +145,7 @@ class SendAnimation(BaseClient):
w=width, w=width,
h=height h=height
), ),
types.DocumentAttributeFilename(os.path.basename(animation)), types.DocumentAttributeFilename(file_name=os.path.basename(animation)),
types.DocumentAttributeAnimated() types.DocumentAttributeAnimated()
] ]
) )

View File

@ -28,7 +28,8 @@ from pyrogram.client.ext import BaseClient, utils
class SendAudio(BaseClient): class SendAudio(BaseClient):
async def send_audio(self, async def send_audio(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
audio: str, audio: str,
caption: str = "", caption: str = "",
@ -38,12 +39,15 @@ class SendAudio(BaseClient):
title: str = None, title: str = None,
thumb: str = None, disable_notification: bool = None, thumb: str = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send audio files. """Use this method to send audio files.
For sending voice messages, use the :obj:`send_voice()` method instead. For sending voice messages, use the :obj:`send_voice()` method instead.
@ -141,7 +145,7 @@ class SendAudio(BaseClient):
performer=performer, performer=performer,
title=title title=title
), ),
types.DocumentAttributeFilename(os.path.basename(audio)) types.DocumentAttributeFilename(file_name=os.path.basename(audio))
] ]
) )
elif audio.startswith("http"): elif audio.startswith("http"):

View File

@ -23,10 +23,12 @@ from pyrogram.client.ext import BaseClient, ChatAction
class SendChatAction(BaseClient): class SendChatAction(BaseClient):
async def send_chat_action(self, async def send_chat_action(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
action: Union[ChatAction, str], action: Union[ChatAction, str],
progress: int = 0): progress: int = 0
):
"""Use this method when you need to tell the other party that something is happening on your side. """Use this method when you need to tell the other party that something is happening on your side.
Args: Args:

View File

@ -24,17 +24,21 @@ from pyrogram.client.ext import BaseClient
class SendContact(BaseClient): class SendContact(BaseClient):
async def send_contact(self, async def send_contact(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
phone_number: str, phone_number: str,
first_name: str, first_name: str,
last_name: str = "", last_name: str = "",
vcard: 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: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message": "pyrogram.ForceReply"
] = None
) -> "pyrogram.Message":
"""Use this method to send phone contacts. """Use this method to send phone contacts.
Args: Args:

View File

@ -28,19 +28,23 @@ from pyrogram.client.ext import BaseClient, utils
class SendDocument(BaseClient): class SendDocument(BaseClient):
async def send_document(self, async def send_document(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
document: str, document: str,
thumb: str = None, caption: str = "", thumb: str = None, caption: str = "",
parse_mode: str = "", parse_mode: str = "",
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send general files. """Use this method to send general files.
Args: Args:
@ -122,7 +126,7 @@ class SendDocument(BaseClient):
file=file, file=file,
thumb=thumb, thumb=thumb,
attributes=[ attributes=[
types.DocumentAttributeFilename(os.path.basename(document)) types.DocumentAttributeFilename(file_name=os.path.basename(document))
] ]
) )
elif document.startswith("http"): elif document.startswith("http"):

View File

@ -24,16 +24,20 @@ from pyrogram.client.ext import BaseClient
class SendLocation(BaseClient): class SendLocation(BaseClient):
async def send_location(self, async def send_location(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
latitude: float, latitude: float,
longitude: float, longitude: float,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message": "pyrogram.ForceReply"
] = None
) -> "pyrogram.Message":
"""Use this method to send points on the map. """Use this method to send points on the map.
Args: Args:
@ -69,9 +73,9 @@ class SendLocation(BaseClient):
functions.messages.SendMedia( functions.messages.SendMedia(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
media=types.InputMediaGeoPoint( media=types.InputMediaGeoPoint(
types.InputGeoPoint( geo_point=types.InputGeoPoint(
latitude, lat=latitude,
longitude long=longitude
) )
), ),
message="", message="",

View File

@ -34,11 +34,13 @@ log = logging.getLogger(__name__)
class SendMediaGroup(BaseClient): class SendMediaGroup(BaseClient):
# TODO: Add progress parameter # TODO: Add progress parameter
# TODO: Figure out how to send albums using URLs # TODO: Figure out how to send albums using URLs
async def send_media_group(self, async def send_media_group(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
media: List[Union["pyrogram.InputMediaPhoto", "pyrogram.InputMediaVideo"]], media: List[Union["pyrogram.InputMediaPhoto", "pyrogram.InputMediaVideo"]],
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None): reply_to_message_id: int = None
):
"""Use this method to send a group of photos or videos as an album. """Use this method to send a group of photos or videos as an album.
Args: Args:
@ -137,7 +139,7 @@ class SendMediaGroup(BaseClient):
w=i.width, w=i.width,
h=i.height h=i.height
), ),
types.DocumentAttributeFilename(os.path.basename(i.media)) types.DocumentAttributeFilename(file_name=os.path.basename(i.media))
] ]
) )
) )

View File

@ -24,17 +24,21 @@ from ...ext import BaseClient
class SendMessage(BaseClient): class SendMessage(BaseClient):
async def send_message(self, async def send_message(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
text: str, text: str,
parse_mode: str = "", parse_mode: str = "",
disable_web_page_preview: bool = None, disable_web_page_preview: bool = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message": "pyrogram.ForceReply"
] = None
) -> "pyrogram.Message":
"""Use this method to send text messages. """Use this method to send text messages.
Args: Args:

View File

@ -28,7 +28,8 @@ from pyrogram.client.ext import BaseClient, utils
class SendPhoto(BaseClient): class SendPhoto(BaseClient):
async def send_photo(self, async def send_photo(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
photo: str, photo: str,
caption: str = "", caption: str = "",
@ -36,12 +37,15 @@ class SendPhoto(BaseClient):
ttl_seconds: int = None, ttl_seconds: int = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send photos. """Use this method to send photos.
Args: Args:

View File

@ -24,16 +24,20 @@ from pyrogram.client.ext import BaseClient
class SendPoll(BaseClient): class SendPoll(BaseClient):
def send_poll(self, def send_poll \
(self,
chat_id: Union[int, str], chat_id: Union[int, str],
question: str, question: str,
options: List[str], options: List[str],
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message": "pyrogram.ForceReply"
] = None
) -> "pyrogram.Message":
"""Use this method to send a new poll. """Use this method to send a new poll.
Args: Args:

View File

@ -28,17 +28,21 @@ from pyrogram.client.ext import BaseClient, utils
class SendSticker(BaseClient): class SendSticker(BaseClient):
async def send_sticker(self, async def send_sticker(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
sticker: str, sticker: str,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send .webp stickers. """Use this method to send .webp stickers.
Args: Args:
@ -103,7 +107,7 @@ class SendSticker(BaseClient):
mime_type="image/webp", mime_type="image/webp",
file=file, file=file,
attributes=[ attributes=[
types.DocumentAttributeFilename(os.path.basename(sticker)) types.DocumentAttributeFilename(file_name=os.path.basename(sticker))
] ]
) )
elif sticker.startswith("http"): elif sticker.startswith("http"):

View File

@ -24,19 +24,24 @@ from pyrogram.client.ext import BaseClient
class SendVenue(BaseClient): class SendVenue(BaseClient):
async def send_venue(self, async def send_venue(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
latitude: float, latitude: float,
longitude: float, longitude: float,
title: str, title: str,
address: str, address: str,
foursquare_id: str = "", foursquare_id: str = "",
foursquare_type: str = "", disable_notification: bool = None, foursquare_type: str = "",
disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message": "pyrogram.ForceReply"
] = None
) -> "pyrogram.Message":
"""Use this method to send information about a venue. """Use this method to send information about a venue.
Args: Args:

View File

@ -28,7 +28,8 @@ from pyrogram.client.ext import BaseClient, utils
class SendVideo(BaseClient): class SendVideo(BaseClient):
async def send_video(self, async def send_video(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
video: str, video: str,
caption: str = "", caption: str = "",
@ -40,12 +41,15 @@ class SendVideo(BaseClient):
supports_streaming: bool = True, supports_streaming: bool = True,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send video files. """Use this method to send video files.
Args: Args:
@ -145,7 +149,7 @@ class SendVideo(BaseClient):
w=width, w=width,
h=height h=height
), ),
types.DocumentAttributeFilename(os.path.basename(video)) types.DocumentAttributeFilename(file_name=os.path.basename(video))
] ]
) )
elif video.startswith("http"): elif video.startswith("http"):

View File

@ -28,19 +28,24 @@ from pyrogram.client.ext import BaseClient, utils
class SendVideoNote(BaseClient): class SendVideoNote(BaseClient):
async def send_video_note(self, async def send_video_note(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
video_note: str, video_note: str,
duration: int = 0, duration: int = 0,
length: int = 1, length: int = 1,
thumb: str = None, disable_notification: bool = None, thumb: str = None,
disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send video messages. """Use this method to send video messages.
Args: Args:

View File

@ -28,7 +28,8 @@ from pyrogram.client.ext import BaseClient, utils
class SendVoice(BaseClient): class SendVoice(BaseClient):
async def send_voice(self, async def send_voice(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
voice: str, voice: str,
caption: str = "", caption: str = "",
@ -36,12 +37,15 @@ class SendVoice(BaseClient):
duration: int = 0, duration: int = 0,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup", reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None, "pyrogram.ForceReply"
] = None,
progress: callable = None, progress: callable = None,
progress_args: tuple = ()) -> Union["pyrogram.Message", None]: progress_args: tuple = ()
) -> Union["pyrogram.Message", None]:
"""Use this method to send audio files. """Use this method to send audio files.
Args: Args:

View File

@ -23,10 +23,12 @@ from pyrogram.client.ext import BaseClient
class VotePoll(BaseClient): class VotePoll(BaseClient):
def vote_poll(self, def vote_poll(
self,
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: id, message_id: id,
option: int) -> bool: option: int
) -> bool:
"""Use this method to vote a poll. """Use this method to vote a poll.
Args: Args:

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class ChangeCloudPassword(BaseClient): class ChangeCloudPassword(BaseClient):
async def change_cloud_password(self, async def change_cloud_password(
self,
current_password: str, current_password: str,
new_password: str, new_password: str,
new_hint: str = "") -> bool: new_hint: str = ""
) -> bool:
"""Use this method to change your Two-Step Verification password (Cloud Password) with a new one. """Use this method to change your Two-Step Verification password (Cloud Password) with a new one.
Args: Args:

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class EnableCloudPassword(BaseClient): class EnableCloudPassword(BaseClient):
async def enable_cloud_password(self, async def enable_cloud_password(
self,
password: str, password: str,
hint: str = "", hint: str = "",
email: str = None) -> bool: email: str = None
) -> bool:
"""Use this method to enable the Two-Step Verification security feature (Cloud Password) on your account. """Use this method to enable the Two-Step Verification security feature (Cloud Password) on your account.
This password will be asked when you log-in on a new device in addition to the SMS code. This password will be asked when you log-in on a new device in addition to the SMS code.

View File

@ -22,8 +22,10 @@ from ...ext import BaseClient
class RemoveCloudPassword(BaseClient): class RemoveCloudPassword(BaseClient):
async def remove_cloud_password(self, async def remove_cloud_password(
password: str) -> bool: self,
password: str
) -> bool:
"""Use this method to turn off the Two-Step Verification security feature (Cloud Password) on your account. """Use this method to turn off the Two-Step Verification security feature (Cloud Password) on your account.
Args: Args:

View File

@ -101,4 +101,4 @@ def compute_check(r: types.account.Password, password: str) -> types.InputCheckP
+ K_bytes + K_bytes
) )
return types.InputCheckPasswordSRP(srp_id, A_bytes, M1_bytes) return types.InputCheckPasswordSRP(srp_id=srp_id, A=A_bytes, M1=M1_bytes)

View File

@ -25,8 +25,10 @@ from ...ext import BaseClient
class DeleteUserProfilePhotos(BaseClient): class DeleteUserProfilePhotos(BaseClient):
async def delete_user_profile_photos(self, async def delete_user_profile_photos(
id: Union[str, List[str]]) -> bool: self,
id: Union[str, List[str]]
) -> bool:
"""Use this method to delete your own profile photos """Use this method to delete your own profile photos
Args: Args:

View File

@ -35,7 +35,7 @@ class GetMe(BaseClient):
self, self,
(await self.send( (await self.send(
functions.users.GetFullUser( functions.users.GetFullUser(
types.InputPeerSelf() id=types.InputPeerSelf()
) )
)).user )).user
) )

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class GetUserProfilePhotos(BaseClient): class GetUserProfilePhotos(BaseClient):
async def get_user_profile_photos(self, async def get_user_profile_photos(
self,
user_id: Union[int, str], user_id: Union[int, str],
offset: int = 0, offset: int = 0,
limit: int = 100) -> "pyrogram.UserProfilePhotos": limit: int = 100
) -> "pyrogram.UserProfilePhotos":
"""Use this method to get a list of profile pictures for a user. """Use this method to get a list of profile pictures for a user.
Args: Args:

View File

@ -25,8 +25,10 @@ from ...ext import BaseClient
class GetUsers(BaseClient): class GetUsers(BaseClient):
async def get_users(self, async def get_users(
user_ids: Iterable[Union[int, str]]) -> Union["pyrogram.User", List["pyrogram.User"]]: self,
user_ids: Iterable[Union[int, str]]
) -> Union["pyrogram.User", List["pyrogram.User"]]:
"""Use this method to get information about a user. """Use this method to get information about a user.
You can retrieve up to 200 users at once. You can retrieve up to 200 users at once.

View File

@ -21,8 +21,10 @@ from ...ext import BaseClient
class SetUserProfilePhoto(BaseClient): class SetUserProfilePhoto(BaseClient):
def set_user_profile_photo(self, def set_user_profile_photo(
photo: str) -> bool: self,
photo: str
) -> bool:
"""Use this method to set a new profile photo. """Use this method to set a new profile photo.
This method only works for Users. This method only works for Users.
@ -43,7 +45,7 @@ class SetUserProfilePhoto(BaseClient):
return bool( return bool(
self.send( self.send(
functions.photos.UploadProfilePhoto( functions.photos.UploadProfilePhoto(
self.save_file(photo) file=self.save_file(photo)
) )
) )
) )

View File

@ -23,8 +23,10 @@ from ...ext import BaseClient
class UpdateUsername(BaseClient): class UpdateUsername(BaseClient):
def update_username(self, def update_username(
username: Union[str, None]) -> bool: self,
username: Union[str, None]
) -> bool:
"""Use this method to update your own username. """Use this method to update your own username.
This method only works for users, not bots. Bot usernames must be changed via Bot Support or by recreating This method only works for users, not bots. Bot usernames must be changed via Bot Support or by recreating

View File

@ -55,20 +55,20 @@ class HTML:
input_user = self.peers_by_id.get(user_id, None) input_user = self.peers_by_id.get(user_id, None)
entity = ( entity = (
Mention(start, len(body), input_user) Mention(offset=start, length=len(body), user_id=input_user)
if input_user else MentionInvalid(start, len(body), user_id) if input_user else MentionInvalid(offset=start, length=len(body), user_id=user_id)
) )
else: else:
entity = Url(start, len(body), url) entity = Url(offset=start, length=len(body), url=url)
else: else:
if style == "b" or style == "strong": if style == "b" or style == "strong":
entity = Bold(start, len(body)) entity = Bold(offset=start, length=len(body))
elif style == "i" or style == "em": elif style == "i" or style == "em":
entity = Italic(start, len(body)) entity = Italic(offset=start, length=len(body))
elif style == "code": elif style == "code":
entity = Code(start, len(body)) entity = Code(offset=start, length=len(body))
elif style == "pre": elif style == "pre":
entity = Pre(start, len(body), "") entity = Pre(offset=start, length=len(body), language="")
else: else:
continue continue

View File

@ -72,24 +72,24 @@ class Markdown:
input_user = self.peers_by_id.get(user_id, None) input_user = self.peers_by_id.get(user_id, None)
entity = ( entity = (
Mention(start, len(text), input_user) Mention(offset=start, length=len(text), user_id=input_user)
if input_user if input_user
else MentionInvalid(start, len(text), user_id) else MentionInvalid(offset=start, length=len(text), user_id=user_id)
) )
else: else:
entity = Url(start, len(text), url) entity = Url(offset=start, length=len(text), url=url)
body = text body = text
offset += len(url) + 4 offset += len(url) + 4
else: else:
if style == self.BOLD_DELIMITER: if style == self.BOLD_DELIMITER:
entity = Bold(start, len(body)) entity = Bold(offset=start, length=len(body))
elif style == self.ITALIC_DELIMITER: elif style == self.ITALIC_DELIMITER:
entity = Italic(start, len(body)) entity = Italic(offset=start, length=len(body))
elif style == self.CODE_DELIMITER: elif style == self.CODE_DELIMITER:
entity = Code(start, len(body)) entity = Code(offset=start, length=len(body))
elif style == self.PRE_DELIMITER: elif style == self.PRE_DELIMITER:
entity = Pre(start, len(body), "") entity = Pre(offset=start, length=len(body), language="")
else: else:
continue continue

View File

@ -25,5 +25,7 @@ class CallbackGame(PyrogramType):
Use BotFather to set up your game. Use BotFather to set up your game.
""" """
__slots__ = []
def __init__(self): def __init__(self):
super().__init__(None) super().__init__(None)

View File

@ -58,7 +58,10 @@ class CallbackQuery(PyrogramType, Update):
""" """
def __init__(self, __slots__ = ["id", "from_user", "chat_instance", "message", "inline_message_id", "data", "game_short_name"]
def __init__(
self,
*, *,
client: "pyrogram.client.ext.BaseClient", client: "pyrogram.client.ext.BaseClient",
id: str, id: str,
@ -67,7 +70,8 @@ class CallbackQuery(PyrogramType, Update):
message: "pyrogram.Message" = None, message: "pyrogram.Message" = None,
inline_message_id: str = None, inline_message_id: str = None,
data: bytes = None, data: bytes = None,
game_short_name: str = None): game_short_name: str = None
):
super().__init__(client) super().__init__(client)
self.id = id self.id = id

View File

@ -33,8 +33,12 @@ class ForceReply(PyrogramType):
2) if the bot's message is a reply (has reply_to_message_id), sender of the original message. 2) if the bot's message is a reply (has reply_to_message_id), sender of the original message.
""" """
def __init__(self, __slots__ = ["selective"]
selective: bool = None):
def __init__(
self,
selective: bool = None
):
super().__init__(None) super().__init__(None)
self.selective = selective self.selective = selective

View File

@ -37,12 +37,16 @@ class GameHighScore(PyrogramType):
Position in high score table for the game. Position in high score table for the game.
""" """
def __init__(self, __slots__ = ["user", "score", "position"]
def __init__(
self,
*, *,
client: "pyrogram.client.ext.BaseClient", client: "pyrogram.client.ext.BaseClient",
user: User, user: User,
score: int, score: int,
position: int = None): position: int = None
):
super().__init__(client) super().__init__(client)
self.user = user self.user = user

View File

@ -35,11 +35,15 @@ class GameHighScores(PyrogramType):
Game scores. Game scores.
""" """
def __init__(self, __slots__ = ["total_count", "game_high_scores"]
def __init__(
self,
*, *,
client: "pyrogram.client.ext.BaseClient", client: "pyrogram.client.ext.BaseClient",
total_count: int, total_count: int,
game_high_scores: List[GameHighScore]): game_high_scores: List[GameHighScore]
):
super().__init__(client) super().__init__(client)
self.total_count = total_count self.total_count = total_count

View File

@ -54,13 +54,19 @@ class InlineKeyboardButton(PyrogramType):
# TODO: Add callback_game and pay fields # TODO: Add callback_game and pay fields
def __init__(self, __slots__ = [
"text", "url", "callback_data", "switch_inline_query", "switch_inline_query_current_chat", "callback_game"
]
def __init__(
self,
text: str, text: str,
callback_data: bytes = None, callback_data: bytes = None,
url: str = None, url: str = None,
switch_inline_query: str = None, switch_inline_query: str = None,
switch_inline_query_current_chat: str = None, switch_inline_query_current_chat: str = None,
callback_game: CallbackGame = None): callback_game: CallbackGame = None
):
super().__init__(None) super().__init__(None)
self.text = str(text) self.text = str(text)
@ -105,16 +111,20 @@ class InlineKeyboardButton(PyrogramType):
def write(self): def write(self):
if self.callback_data: if self.callback_data:
return KeyboardButtonCallback(self.text, self.callback_data) return KeyboardButtonCallback(text=self.text, data=self.callback_data)
if self.url: if self.url:
return KeyboardButtonUrl(self.text, self.url) return KeyboardButtonUrl(text=self.text, url=self.url)
if self.switch_inline_query: if self.switch_inline_query:
return KeyboardButtonSwitchInline(self.text, self.switch_inline_query) return KeyboardButtonSwitchInline(text=self.text, query=self.switch_inline_query)
if self.switch_inline_query_current_chat: if self.switch_inline_query_current_chat:
return KeyboardButtonSwitchInline(self.text, self.switch_inline_query_current_chat, same_peer=True) return KeyboardButtonSwitchInline(
text=self.text,
query=self.switch_inline_query_current_chat,
same_peer=True
)
if self.callback_game: if self.callback_game:
return KeyboardButtonGame(self.text) return KeyboardButtonGame(text=self.text)

View File

@ -31,8 +31,12 @@ class InlineKeyboardMarkup(PyrogramType):
List of button rows, each represented by a List of InlineKeyboardButton objects. List of button rows, each represented by a List of InlineKeyboardButton objects.
""" """
def __init__(self, __slots__ = ["inline_keyboard"]
inline_keyboard: List[List[InlineKeyboardButton]]):
def __init__(
self,
inline_keyboard: List[List[InlineKeyboardButton]]
):
super().__init__(None) super().__init__(None)
self.inline_keyboard = inline_keyboard self.inline_keyboard = inline_keyboard
@ -55,7 +59,7 @@ class InlineKeyboardMarkup(PyrogramType):
def write(self): def write(self):
return ReplyInlineMarkup( return ReplyInlineMarkup(
[KeyboardButtonRow( rows=[KeyboardButtonRow(
[j.write() for j in i] buttons=[j.write() for j in i]
) for i in self.inline_keyboard] ) for i in self.inline_keyboard]
) )

View File

@ -40,10 +40,14 @@ class KeyboardButton(PyrogramType):
Available in private chats only. Available in private chats only.
""" """
def __init__(self, __slots__ = ["text", "request_contact", "request_location"]
def __init__(
self,
text: str, text: str,
request_contact: bool = None, request_contact: bool = None,
request_location: bool = None): request_location: bool = None
):
super().__init__(None) super().__init__(None)
self.text = str(text) self.text = str(text)
@ -71,8 +75,8 @@ class KeyboardButton(PyrogramType):
# TODO: Enforce optional args mutual exclusiveness # TODO: Enforce optional args mutual exclusiveness
if self.request_contact: if self.request_contact:
return KeyboardButtonRequestPhone(self.text) return KeyboardButtonRequestPhone(text=self.text)
elif self.request_location: elif self.request_location:
return KeyboardButtonRequestGeoLocation(self.text) return KeyboardButtonRequestGeoLocation(text=self.text)
else: else:
return RawKeyboardButton(self.text) return RawKeyboardButton(text=self.text)

View File

@ -49,11 +49,15 @@ class ReplyKeyboardMarkup(PyrogramType):
select the new language. Other users in the group don't see the keyboard. select the new language. Other users in the group don't see the keyboard.
""" """
def __init__(self, __slots__ = ["keyboard", "resize_keyboard", "one_time_keyboard", "selective"]
def __init__(
self,
keyboard: List[List[Union[KeyboardButton, str]]], keyboard: List[List[Union[KeyboardButton, str]]],
resize_keyboard: bool = None, resize_keyboard: bool = None,
one_time_keyboard: bool = None, one_time_keyboard: bool = None,
selective: bool = None): selective: bool = None
):
super().__init__(None) super().__init__(None)
self.keyboard = keyboard self.keyboard = keyboard
@ -83,9 +87,11 @@ class ReplyKeyboardMarkup(PyrogramType):
def write(self): def write(self):
return RawReplyKeyboardMarkup( return RawReplyKeyboardMarkup(
rows=[KeyboardButtonRow( rows=[KeyboardButtonRow(
[KeyboardButton(j).write() buttons=[
KeyboardButton(j).write()
if isinstance(j, str) else j.write() if isinstance(j, str) else j.write()
for j in i] for j in i
]
) for i in self.keyboard], ) for i in self.keyboard],
resize=self.resize_keyboard or None, resize=self.resize_keyboard or None,
single_use=self.one_time_keyboard or None, single_use=self.one_time_keyboard or None,

View File

@ -35,8 +35,12 @@ class ReplyKeyboardRemove(PyrogramType):
keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet. keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet.
""" """
def __init__(self, __slots__ = ["selective"]
selective: bool = None):
def __init__(
self,
selective: bool = None
):
super().__init__(None) super().__init__(None)
self.selective = selective self.selective = selective

Some files were not shown because too many files have changed in this diff Show More