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.
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
- **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.
- **Comprehensive**: Execute any advanced action an official client is able to do, and even more.
@ -107,7 +107,7 @@ Copyright & License
</a>
<br>
<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">
</a>
<a href="https://github.com/pyrogram/tgcrypto">
@ -122,7 +122,7 @@ Copyright & License
.. |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
:alt: Schema Layer

View File

@ -287,9 +287,11 @@ def start():
sorted_args = sort_args(c.args)
arguments = ", " + ", ".join(
[get_argument_type(i) for i in sorted_args if i != ("flags", "#")]
) if c.args else ""
arguments = (
", "
+ ("*, " if c.args else "")
+ (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "")
)
fields = "\n ".join(
["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,
read_types=read_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}
"""
__slots__ = [{slots}]
ID = {object_id}
QUALNAME = "{qualname}"
def __init__(self{arguments}):
{fields}

View File

@ -93,3 +93,4 @@ CALL_ALREADY_ACCEPTED The call is already accepted
CALL_ALREADY_DECLINED The call is already declined
PHOTO_EXT_INVALID The photo extension 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>
<br>
<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">
</a>
<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.
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
- **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.
- **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
>>> pyrogram.__version__
'0.11.0'
'0.12.0'
.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto
.. _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"
)
__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 .client.types import (

View File

@ -19,14 +19,16 @@
from collections import OrderedDict
from datetime import datetime
from io import BytesIO
from json import JSONEncoder, dumps
from ..all import objects
from json import dumps
class Object:
all = {}
__slots__ = []
QUALNAME = "Base"
@staticmethod
def read(b: BytesIO, *args):
return Object.all[int.from_bytes(b.read(4), "little")].read(b, *args)
@ -35,7 +37,7 @@ class Object:
pass
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:
return True
@ -62,29 +64,18 @@ def remove_none(obj):
return obj
class Encoder(JSONEncoder):
def default(self, o: Object):
def default(o: "Object"):
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:
if isinstance(o, datetime):
return o.strftime("%d-%b-%Y %H:%M:%S")
else:
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
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .exceptions import *
from .error import UnknownError
from .exceptions import *

View File

@ -632,9 +632,9 @@ class Client(Methods, BaseClient):
try:
r = await self.send(
functions.auth.SignIn(
self.phone_number,
phone_code_hash,
self.phone_code
phone_number=self.phone_number,
phone_code_hash=phone_code_hash,
phone_code=self.phone_code
)
)
except PhoneNumberUnoccupied:
@ -645,11 +645,11 @@ class Client(Methods, BaseClient):
try:
r = await self.send(
functions.auth.SignUp(
self.phone_number,
phone_code_hash,
self.phone_code,
self.first_name,
self.last_name
phone_number=self.phone_number,
phone_code_hash=phone_code_hash,
phone_code=self.phone_code,
first_name=self.first_name,
last_name=self.last_name
)
)
except PhoneNumberOccupied:
@ -743,7 +743,11 @@ class Client(Methods, BaseClient):
break
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.user_id = r.user.id
@ -1035,10 +1039,10 @@ class Client(Methods, BaseClient):
raise ConnectionError("Client has not been started")
if self.no_updates:
data = functions.InvokeWithoutUpdates(data)
data = functions.InvokeWithoutUpdates(query=data)
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)
@ -1350,7 +1354,7 @@ class Client(Methods, BaseClient):
self.fetch_peers(
self.send(
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"):
self.send(
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:
@ -1686,8 +1690,8 @@ class Client(Methods, BaseClient):
hashes = await session.send(
functions.upload.GetCdnFileHashes(
r.file_token,
offset
file_token=r.file_token,
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):
return (
types.InputPeerUser(peer_id, access_hash) if peer_id > 0
else types.InputPeerChannel(int(str(peer_id)[4:]), access_hash)
types.InputPeerUser(user_id=peer_id, access_hash=access_hash) if peer_id > 0
else types.InputPeerChannel(channel_id=int(str(peer_id)[4:]), access_hash=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):
async def answer_callback_query(self,
async def answer_callback_query(
self,
callback_query_id: str,
text: str = None,
show_alert: bool = 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.
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):
async def get_game_high_scores(self,
async def get_game_high_scores(
self,
user_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.
Args:

View File

@ -24,12 +24,14 @@ from pyrogram.client.ext import BaseClient
class GetInlineBotResults(BaseClient):
async def get_inline_bot_results(self,
async def get_inline_bot_results(
self,
bot: Union[int, str],
query: str,
offset: str = "",
latitude: float = None,
longitude: float = None):
longitude: float = None
):
"""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>`

View File

@ -23,10 +23,12 @@ from pyrogram.client.ext import BaseClient
class RequestCallbackAnswer(BaseClient):
async def request_callback_answer(self,
async def request_callback_answer(
self,
chat_id: Union[int, str],
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
inline button containing callback data.

View File

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

View File

@ -23,13 +23,15 @@ from pyrogram.client.ext import BaseClient
class SendInlineBotResult(BaseClient):
async def send_inline_bot_result(self,
async def send_inline_bot_result(
self,
chat_id: Union[int, str],
query_id: int,
result_id: str,
disable_notification: bool = None,
reply_to_message_id: int = None,
hide_via: bool = None):
hide_via: bool = None
):
"""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>`

View File

@ -24,13 +24,15 @@ from pyrogram.client.ext import BaseClient
class SetGameScore(BaseClient):
async def set_game_score(self,
async def set_game_score(
self,
user_id: Union[int, str],
score: int,
force: bool = None,
disable_edit_message: bool = 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
"""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 .pin_chat_message import PinChatMessage
from .promote_chat_member import PromoteChatMember
from .restrict_chat import RestrictChat
from .restrict_chat_member import RestrictChatMember
from .set_chat_description import SetChatDescription
from .set_chat_photo import SetChatPhoto
@ -62,6 +63,7 @@ class Chats(
GetChatPreview,
IterDialogs,
IterChatMembers,
UpdateChatUsername
UpdateChatUsername,
RestrictChat
):
pass

View File

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

View File

@ -23,8 +23,10 @@ from ...ext import BaseClient
class ExportChatInviteLink(BaseClient):
async def export_chat_invite_link(self,
chat_id: Union[int, str]) -> str:
async def export_chat_invite_link(
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.
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):
return await self.send(
functions.messages.ExportChatInvite(
chat_id=peer.chat_id
peer=peer.chat_id
)
).link
elif isinstance(peer, types.InputPeerChannel):

View File

@ -24,8 +24,10 @@ from ...ext import BaseClient
class GetChat(BaseClient):
async def get_chat(self,
chat_id: Union[int, str]) -> "pyrogram.Chat":
async def get_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
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)
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)):
r = await self.send(functions.users.GetFullUser(peer))
r = await self.send(functions.users.GetFullUser(id=peer))
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)

View File

@ -24,9 +24,11 @@ from ...ext import BaseClient
class GetChatMember(BaseClient):
async def get_chat_member(self,
async def get_chat_member(
self,
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.
Args:

View File

@ -33,12 +33,14 @@ class Filters:
class GetChatMembers(BaseClient):
async def get_chat_members(self,
async def get_chat_members(
self,
chat_id: Union[int, str],
offset: int = 0,
limit: int = 200,
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.
You can get up to 200 chat members at once.
@ -92,7 +94,7 @@ class GetChatMembers(BaseClient):
self,
await self.send(
functions.messages.GetFullChat(
peer.chat_id
chat_id=peer.chat_id
)
)
)

View File

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

View File

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

View File

@ -28,10 +28,12 @@ log = logging.getLogger(__name__)
class GetDialogs(BaseClient):
async def get_dialogs(self,
async def get_dialogs(
self,
offset_date: int = 0,
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
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):
@async_generator
async def iter_chat_members(self,
async def iter_chat_members(
self,
chat_id: Union[int, str],
limit: int = 0,
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.
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):
@async_generator
async def iter_dialogs(self,
async def iter_dialogs(
self,
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.
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):
async def join_chat(self,
chat_id: str):
async def join_chat(
self,
chat_id: str
):
"""Use this method to join a group chat or channel.
Args:

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class KickChatMember(BaseClient):
async def kick_chat_member(self,
async def kick_chat_member(
self,
chat_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.
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

View File

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

View File

@ -23,10 +23,12 @@ from ...ext import BaseClient
class PinChatMessage(BaseClient):
async def pin_chat_message(self,
async def pin_chat_message(
self,
chat_id: Union[int, str],
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.
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.
@ -55,3 +57,5 @@ class PinChatMessage(BaseClient):
silent=disable_notification or None
)
)
return True

View File

@ -23,7 +23,8 @@ from ...ext import BaseClient
class PromoteChatMember(BaseClient):
async def promote_chat_member(self,
async def promote_chat_member(
self,
chat_id: Union[int, str],
user_id: Union[int, str],
can_change_info: bool = True,
@ -33,7 +34,8 @@ class PromoteChatMember(BaseClient):
can_restrict_members: bool = True,
can_invite_users: bool = True,
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.
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 ...ext import BaseClient
from ...types.user_and_chats import Chat
class RestrictChatMember(BaseClient):
async def restrict_chat_member(self,
async def restrict_chat_member(
self,
chat_id: Union[int, str],
user_id: Union[int, str],
until_date: int = 0,
can_send_messages: bool = False,
can_send_media_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
this to work and must have the appropriate admin rights. Pass True for all boolean parameters to lift
restrictions from a user.
@ -60,10 +67,22 @@ class RestrictChatMember(BaseClient):
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
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:
True on success.
On success, a :obj:`Chat <pyrogram.Chat>` object is returned.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
@ -75,6 +94,10 @@ class RestrictChatMember(BaseClient):
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
@ -84,6 +107,7 @@ class RestrictChatMember(BaseClient):
send_media = None
if can_send_other_messages:
send_messages = None
send_media = None
send_stickers = None
send_gifs = None
@ -91,10 +115,24 @@ class RestrictChatMember(BaseClient):
send_inline = None
if can_add_web_page_previews:
send_messages = None
send_media = 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(
channel=await self.resolve_peer(chat_id),
user_id=await self.resolve_peer(user_id),
@ -106,9 +144,13 @@ class RestrictChatMember(BaseClient):
send_gifs=send_gifs,
send_games=send_games,
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):
async def set_chat_description(self,
async def set_chat_description(
self,
chat_id: Union[int, str],
description: str) -> bool:
description: str
) -> bool:
"""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.

View File

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

View File

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

View File

@ -23,9 +23,11 @@ from ...ext import BaseClient
class UnbanChatMember(BaseClient):
async def unban_chat_member(self,
async def unban_chat_member(
self,
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.
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.

View File

@ -23,8 +23,10 @@ from ...ext import BaseClient
class UnpinChatMessage(BaseClient):
async def unpin_chat_message(self,
chat_id: Union[int, str]) -> bool:
async def unpin_chat_message(
self,
chat_id: Union[int, str]
) -> bool:
"""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
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):
def update_chat_username(self,
def update_chat_username(
self,
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.
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):
async def add_contacts(self,
contacts: List["pyrogram.InputPhoneContact"]):
async def add_contacts(
self,
contacts: List["pyrogram.InputPhoneContact"]
):
"""Use this method to add contacts to your Telegram address book.
Args:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,9 +23,11 @@ from pyrogram.client.ext import BaseClient
class ClosePoll(BaseClient):
def close_poll(self,
def close_poll(
self,
chat_id: Union[int, str],
message_id: id) -> bool:
message_id: id
) -> bool:
"""Use this method to close (stop) a poll.
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):
async def delete_messages(self,
async def delete_messages(
self,
chat_id: Union[int, str],
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:
- 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):
async def download_media(self,
async def download_media(
self,
message: Union["pyrogram.Message", str],
file_name: str = "",
block: bool = True,
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.
Args:

View File

@ -24,12 +24,14 @@ from pyrogram.client.ext import BaseClient
class EditMessageCaption(BaseClient):
async def edit_message_caption(self,
async def edit_message_caption(
self,
chat_id: Union[int, str],
message_id: int,
caption: 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.
Args:

View File

@ -33,11 +33,13 @@ from pyrogram.client.types.input_media import InputMedia
class EditMessageMedia(BaseClient):
async def edit_message_media(self,
async def edit_message_media(
self,
chat_id: Union[int, str],
message_id: int,
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.
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,
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,
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,
h=media.height
),
types.DocumentAttributeFilename(os.path.basename(media.media)),
types.DocumentAttributeFilename(
file_name=os.path.basename(media.media)
),
types.DocumentAttributeAnimated()
]
)
@ -296,7 +304,9 @@ class EditMessageMedia(BaseClient):
thumb=None if media.thumb is None else self.save_file(media.thumb),
file=await self.save_file(media.media),
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):
async def edit_message_reply_markup(self,
async def edit_message_reply_markup(
self,
chat_id: Union[int, str],
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).
Args:

View File

@ -24,13 +24,15 @@ from pyrogram.client.ext import BaseClient
class EditMessageText(BaseClient):
async def edit_message_text(self,
async def edit_message_text(
self,
chat_id: Union[int, str],
message_id: int,
text: str,
parse_mode: str = "",
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.
Args:

View File

@ -24,11 +24,13 @@ from ...ext import BaseClient
class ForwardMessages(BaseClient):
async def forward_messages(self,
async def forward_messages(
self,
chat_id: Union[int, str],
from_chat_id: Union[int, str],
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.
Args:

View File

@ -29,13 +29,15 @@ log = logging.getLogger(__name__)
class GetHistory(BaseClient):
async def get_history(self,
async def get_history(
self,
chat_id: Union[int, str],
limit: int = 100,
offset: int = 0,
offset_id: 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.
You can get up to 100 messages at once.

View File

@ -29,11 +29,13 @@ log = logging.getLogger(__name__)
class GetMessages(BaseClient):
async def get_messages(self,
async def get_messages(
self,
chat_id: Union[int, str],
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.
You can retrieve up to 200 messages at once.
@ -76,7 +78,7 @@ class GetMessages(BaseClient):
is_iterable = not isinstance(ids, int)
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):
rpc = functions.channels.GetMessages(channel=peer, id=ids)

View File

@ -26,13 +26,15 @@ from ...ext import BaseClient
class IterHistory(BaseClient):
@async_generator
async def iter_history(self,
async def iter_history(
self,
chat_id: Union[int, str],
limit: int = 0,
offset: int = 0,
offset_id: 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.
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):
def retract_vote(self,
def retract_vote(
self,
chat_id: Union[int, str],
message_id: id) -> bool:
message_id: id
) -> bool:
"""Use this method to retract your vote in a poll.
Args:

View File

@ -28,7 +28,8 @@ from pyrogram.client.ext import BaseClient, utils
class SendAnimation(BaseClient):
async def send_animation(self,
async def send_animation(
self,
chat_id: Union[int, str],
animation: str,
caption: str = "",
@ -39,12 +40,15 @@ class SendAnimation(BaseClient):
thumb: str = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup",
reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None,
"pyrogram.ForceReply"
] = 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).
Args:
@ -141,7 +145,7 @@ class SendAnimation(BaseClient):
w=width,
h=height
),
types.DocumentAttributeFilename(os.path.basename(animation)),
types.DocumentAttributeFilename(file_name=os.path.basename(animation)),
types.DocumentAttributeAnimated()
]
)

View File

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

View File

@ -23,10 +23,12 @@ from pyrogram.client.ext import BaseClient, ChatAction
class SendChatAction(BaseClient):
async def send_chat_action(self,
async def send_chat_action(
self,
chat_id: Union[int, 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.
Args:

View File

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

View File

@ -28,19 +28,23 @@ from pyrogram.client.ext import BaseClient, utils
class SendDocument(BaseClient):
async def send_document(self,
async def send_document(
self,
chat_id: Union[int, str],
document: str,
thumb: str = None, caption: str = "",
parse_mode: str = "",
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup",
reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None,
"pyrogram.ForceReply"
] = 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.
Args:
@ -122,7 +126,7 @@ class SendDocument(BaseClient):
file=file,
thumb=thumb,
attributes=[
types.DocumentAttributeFilename(os.path.basename(document))
types.DocumentAttributeFilename(file_name=os.path.basename(document))
]
)
elif document.startswith("http"):

View File

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

View File

@ -34,11 +34,13 @@ log = logging.getLogger(__name__)
class SendMediaGroup(BaseClient):
# TODO: Add progress parameter
# 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],
media: List[Union["pyrogram.InputMediaPhoto", "pyrogram.InputMediaVideo"]],
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.
Args:
@ -137,7 +139,7 @@ class SendMediaGroup(BaseClient):
w=i.width,
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):
async def send_message(self,
async def send_message(
self,
chat_id: Union[int, str],
text: str,
parse_mode: str = "",
disable_web_page_preview: bool = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup",
reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message":
"pyrogram.ForceReply"
] = None
) -> "pyrogram.Message":
"""Use this method to send text messages.
Args:

View File

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

View File

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

View File

@ -28,17 +28,21 @@ from pyrogram.client.ext import BaseClient, utils
class SendSticker(BaseClient):
async def send_sticker(self,
async def send_sticker(
self,
chat_id: Union[int, str],
sticker: str,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup",
reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None,
"pyrogram.ForceReply"
] = 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.
Args:
@ -103,7 +107,7 @@ class SendSticker(BaseClient):
mime_type="image/webp",
file=file,
attributes=[
types.DocumentAttributeFilename(os.path.basename(sticker))
types.DocumentAttributeFilename(file_name=os.path.basename(sticker))
]
)
elif sticker.startswith("http"):

View File

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

View File

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

View File

@ -28,19 +28,24 @@ from pyrogram.client.ext import BaseClient, utils
class SendVideoNote(BaseClient):
async def send_video_note(self,
async def send_video_note(
self,
chat_id: Union[int, str],
video_note: str,
duration: int = 0,
length: int = 1,
thumb: str = None, disable_notification: bool = None,
thumb: str = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup",
reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None,
"pyrogram.ForceReply"
] = 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.
Args:

View File

@ -28,7 +28,8 @@ from pyrogram.client.ext import BaseClient, utils
class SendVoice(BaseClient):
async def send_voice(self,
async def send_voice(
self,
chat_id: Union[int, str],
voice: str,
caption: str = "",
@ -36,12 +37,15 @@ class SendVoice(BaseClient):
duration: int = 0,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup",
reply_markup: Union[
"pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None,
"pyrogram.ForceReply"
] = 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.
Args:

View File

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

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class ChangeCloudPassword(BaseClient):
async def change_cloud_password(self,
async def change_cloud_password(
self,
current_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.
Args:

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class EnableCloudPassword(BaseClient):
async def enable_cloud_password(self,
async def enable_cloud_password(
self,
password: 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.
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):
async def remove_cloud_password(self,
password: str) -> bool:
async def remove_cloud_password(
self,
password: str
) -> bool:
"""Use this method to turn off the Two-Step Verification security feature (Cloud Password) on your account.
Args:

View File

@ -101,4 +101,4 @@ def compute_check(r: types.account.Password, password: str) -> types.InputCheckP
+ 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):
async def delete_user_profile_photos(self,
id: Union[str, List[str]]) -> bool:
async def delete_user_profile_photos(
self,
id: Union[str, List[str]]
) -> bool:
"""Use this method to delete your own profile photos
Args:

View File

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

View File

@ -24,10 +24,12 @@ from ...ext import BaseClient
class GetUserProfilePhotos(BaseClient):
async def get_user_profile_photos(self,
async def get_user_profile_photos(
self,
user_id: Union[int, str],
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.
Args:

View File

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

View File

@ -21,8 +21,10 @@ from ...ext import BaseClient
class SetUserProfilePhoto(BaseClient):
def set_user_profile_photo(self,
photo: str) -> bool:
def set_user_profile_photo(
self,
photo: str
) -> bool:
"""Use this method to set a new profile photo.
This method only works for Users.
@ -43,7 +45,7 @@ class SetUserProfilePhoto(BaseClient):
return bool(
self.send(
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):
def update_username(self,
username: Union[str, None]) -> bool:
def update_username(
self,
username: Union[str, None]
) -> bool:
"""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

View File

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

View File

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

View File

@ -25,5 +25,7 @@ class CallbackGame(PyrogramType):
Use BotFather to set up your game.
"""
__slots__ = []
def __init__(self):
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",
id: str,
@ -67,7 +70,8 @@ class CallbackQuery(PyrogramType, Update):
message: "pyrogram.Message" = None,
inline_message_id: str = None,
data: bytes = None,
game_short_name: str = None):
game_short_name: str = None
):
super().__init__(client)
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.
"""
def __init__(self,
selective: bool = None):
__slots__ = ["selective"]
def __init__(
self,
selective: bool = None
):
super().__init__(None)
self.selective = selective

View File

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

View File

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

View File

@ -54,13 +54,19 @@ class InlineKeyboardButton(PyrogramType):
# 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,
callback_data: bytes = None,
url: str = None,
switch_inline_query: str = None,
switch_inline_query_current_chat: str = None,
callback_game: CallbackGame = None):
callback_game: CallbackGame = None
):
super().__init__(None)
self.text = str(text)
@ -105,16 +111,20 @@ class InlineKeyboardButton(PyrogramType):
def write(self):
if self.callback_data:
return KeyboardButtonCallback(self.text, self.callback_data)
return KeyboardButtonCallback(text=self.text, data=self.callback_data)
if self.url:
return KeyboardButtonUrl(self.text, self.url)
return KeyboardButtonUrl(text=self.text, url=self.url)
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:
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:
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.
"""
def __init__(self,
inline_keyboard: List[List[InlineKeyboardButton]]):
__slots__ = ["inline_keyboard"]
def __init__(
self,
inline_keyboard: List[List[InlineKeyboardButton]]
):
super().__init__(None)
self.inline_keyboard = inline_keyboard
@ -55,7 +59,7 @@ class InlineKeyboardMarkup(PyrogramType):
def write(self):
return ReplyInlineMarkup(
[KeyboardButtonRow(
[j.write() for j in i]
rows=[KeyboardButtonRow(
buttons=[j.write() for j in i]
) for i in self.inline_keyboard]
)

View File

@ -40,10 +40,14 @@ class KeyboardButton(PyrogramType):
Available in private chats only.
"""
def __init__(self,
__slots__ = ["text", "request_contact", "request_location"]
def __init__(
self,
text: str,
request_contact: bool = None,
request_location: bool = None):
request_location: bool = None
):
super().__init__(None)
self.text = str(text)
@ -71,8 +75,8 @@ class KeyboardButton(PyrogramType):
# TODO: Enforce optional args mutual exclusiveness
if self.request_contact:
return KeyboardButtonRequestPhone(self.text)
return KeyboardButtonRequestPhone(text=self.text)
elif self.request_location:
return KeyboardButtonRequestGeoLocation(self.text)
return KeyboardButtonRequestGeoLocation(text=self.text)
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.
"""
def __init__(self,
__slots__ = ["keyboard", "resize_keyboard", "one_time_keyboard", "selective"]
def __init__(
self,
keyboard: List[List[Union[KeyboardButton, str]]],
resize_keyboard: bool = None,
one_time_keyboard: bool = None,
selective: bool = None):
selective: bool = None
):
super().__init__(None)
self.keyboard = keyboard
@ -83,9 +87,11 @@ class ReplyKeyboardMarkup(PyrogramType):
def write(self):
return RawReplyKeyboardMarkup(
rows=[KeyboardButtonRow(
[KeyboardButton(j).write()
buttons=[
KeyboardButton(j).write()
if isinstance(j, str) else j.write()
for j in i]
for j in i
]
) for i in self.keyboard],
resize=self.resize_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.
"""
def __init__(self,
selective: bool = None):
__slots__ = ["selective"]
def __init__(
self,
selective: bool = None
):
super().__init__(None)
self.selective = selective

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