Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/client/types/message.py
This commit is contained in:
Dan 2018-06-23 14:30:27 +02:00
commit 811e67c229
32 changed files with 245 additions and 202 deletions

View File

@ -12,12 +12,10 @@ Pyrogram |twitter|
@app.on_message(Filters.private)
def hello(client, message):
client.send_message(
message.chat.id, "Hello {}".format(message.from_user.first_name))
message.reply("Hello {}".format(message.from_user.first_name))
app.start()
app.idle()
app.run()
**Pyrogram** is a brand new Telegram_ Client Library written from the ground up in Python and C. It can be used for building
custom Telegram applications that interact with the MTProto API as both User and Bot.

View File

@ -44,8 +44,7 @@ Welcome to Pyrogram
@app.on_message(Filters.private)
def hello(client, message):
message.reply_text(
"Hello {}".format(message.from_user.first_name))
message.reply("Hello {}".format(message.from_user.first_name))
app.run()

View File

@ -19,6 +19,7 @@
import re
from .filter import Filter
from ..types.reply_markup import InlineKeyboardMarkup, ReplyKeyboardMarkup
def build(name: str, func: callable, **kwargs) -> type:
@ -131,7 +132,11 @@ class Filters:
pinned_message = build("PinnedMessage", lambda _, m: bool(m.pinned_message))
"""Filter service messages for pinned messages."""
# TODO: Add filters for reply markups
reply_keyboard = build("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup))
"""Filter messages containing reply keyboard markups"""
inline_keyboard = build("InlineKeyboard", lambda _, m: isinstance(m.reply_markup, InlineKeyboardMarkup))
"""Filter messages containing inline keyboard markups"""
@staticmethod
def command(command: str or list,

View File

@ -16,12 +16,16 @@
# 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 .callback_query import CallbackQuery
from .inline import Inline
from .answer_callback_query import AnswerCallbackQuery
from .get_inline_bot_results import GetInlineBotResults
from .request_callback_answer import RequestCallbackAnswer
from .send_inline_bot_result import SendInlineBotResult
class Bots(
CallbackQuery,
Inline
AnswerCallbackQuery,
GetInlineBotResults,
RequestCallbackAnswer,
SendInlineBotResult
):
pass

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions
from ....ext import BaseClient
from pyrogram.client.ext import BaseClient
class AnswerCallbackQuery(BaseClient):

View File

@ -1,25 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .answer_callback_query import AnswerCallbackQuery
class CallbackQuery(
AnswerCallbackQuery
):
pass

View File

@ -18,7 +18,7 @@
from pyrogram.api import functions, types
from pyrogram.api.errors import UnknownError
from ....ext import BaseClient
from pyrogram.client.ext import BaseClient
class GetInlineBotResults(BaseClient):

View File

@ -1,27 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .get_inline_bot_results import GetInlineBotResults
from .send_inline_bot_result import SendInlineBotResult
class Inline(
SendInlineBotResult,
GetInlineBotResults
):
pass

View File

@ -0,0 +1,51 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions
from pyrogram.client.ext import BaseClient
class RequestCallbackAnswer(BaseClient):
def request_callback_answer(self,
chat_id: int or str,
message_id: int,
callback_data: str):
"""Use this method to request a callback answer from bots. This is the equivalent of clicking an inline button
containing callback data. The answer contains info useful for clients to display a notification at the top of
the chat screen or as an alert.
Args:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
For a private channel/supergroup you can use its *t.me/joinchat/* link.
message_id (``int``):
The message id the inline keyboard is attached on.
callback_data (``str``):
Callback data associated with the inline button you want to get the answer from.
"""
return self.send(
functions.messages.GetBotCallbackAnswer(
peer=self.resolve_peer(chat_id),
msg_id=message_id,
data=callback_data.encode()
)
)

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions
from ....ext import BaseClient
from pyrogram.client.ext import BaseClient
class SendInlineBotResult(BaseClient):

View File

@ -16,22 +16,50 @@
# 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 .action import Action
from .delete_messages import DeleteMessages
from .edit_message_caption import EditMessageCaption
from .edit_message_reply_markup import EditMessageReplyMarkup
from .edit_message_text import EditMessageText
from .forward_messages import ForwardMessages
from .get_history import GetHistory
from .get_messages import GetMessages
from .media import Media
from .send_audio import SendAudio
from .send_chat_action import SendChatAction
from .send_contact import SendContact
from .send_document import SendDocument
from .send_gif import SendGIF
from .send_location import SendLocation
from .send_media_group import SendMediaGroup
from .send_message import SendMessage
from .update import Update
from .send_photo import SendPhoto
from .send_sticker import SendSticker
from .send_venue import SendVenue
from .send_video import SendVideo
from .send_video_note import SendVideoNote
from .send_voice import SendVoice
class Messages(
DeleteMessages,
EditMessageCaption,
EditMessageReplyMarkup,
EditMessageText,
ForwardMessages,
GetHistory,
GetMessages,
Action,
Media,
Update,
ForwardMessages,
SendMessage
SendAudio,
SendChatAction,
SendContact,
SendDocument,
SendGIF,
SendLocation,
SendMediaGroup,
SendMessage,
SendPhoto,
SendSticker,
SendVenue,
SendVideo,
SendVideoNote,
SendVoice
):
pass

View File

@ -1,25 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .send_chat_action import SendChatAction
class Action(
SendChatAction
):
pass

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types
from ....ext import BaseClient
from pyrogram.client.ext import BaseClient
class DeleteMessages(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class EditMessageCaption(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class EditMessageReplyMarkup(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class EditMessageText(BaseClient):

View File

@ -1,47 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .send_audio import SendAudio
from .send_contact import SendContact
from .send_document import SendDocument
from .send_gif import SendGIF
from .send_location import SendLocation
from .send_media_group import SendMediaGroup
from .send_photo import SendPhoto
from .send_sticker import SendSticker
from .send_venue import SendVenue
from .send_video import SendVideo
from .send_video_note import SendVideoNote
from .send_voice import SendVoice
class Media(
SendContact,
SendVenue,
SendLocation,
SendMediaGroup,
SendVideoNote,
SendVoice,
SendVideo,
SendGIF,
SendSticker,
SendDocument,
SendAudio,
SendPhoto
):
pass

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendAudio(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions
from ....ext import BaseClient, ChatAction
from pyrogram.client.ext import BaseClient, ChatAction
class SendChatAction(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendContact(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendDocument(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendGIF(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendLocation(BaseClient):

View File

@ -24,7 +24,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid
from pyrogram.client import types as pyrogram_types
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendMediaGroup(BaseClient):

View File

@ -22,7 +22,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendPhoto(BaseClient):

View File

@ -22,7 +22,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendSticker(BaseClient):

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api import functions, types
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendVenue(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendVideo(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendVideoNote(BaseClient):

View File

@ -23,7 +23,7 @@ import struct
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid, FilePartMissing
from ....ext import BaseClient, utils
from pyrogram.client.ext import BaseClient, utils
class SendVoice(BaseClient):

View File

@ -1,31 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .delete_messages import DeleteMessages
from .edit_message_caption import EditMessageCaption
from .edit_message_reply_markup import EditMessageReplyMarkup
from .edit_message_text import EditMessageText
class Update(
DeleteMessages,
EditMessageReplyMarkup,
EditMessageCaption,
EditMessageText
):
pass

View File

@ -17,6 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from pyrogram.api.core import Object
from .reply_markup import InlineKeyboardMarkup, ReplyKeyboardMarkup
class Message(Object):
@ -310,14 +311,14 @@ class Message(Object):
self.command = command
self.reply_markup = reply_markup
async def reply_text(self,
text: str,
quote: bool = None,
parse_mode: str = "",
disable_web_page_preview: bool = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup=None):
async def reply(self,
text: str,
quote: bool = None,
parse_mode: str = "",
disable_web_page_preview: bool = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup=None):
"""Use this method as a shortcut for:
.. code-block:: python
@ -460,3 +461,115 @@ class Message(Object):
)
return True
async def click(self, x: int or str, y: int = None, quote: bool = None):
"""Use this method to click a button attached to the message.
It's a shortcut for:
- Clicking inline buttons:
.. code-block:: python
client.request_callback_answer(
chat_id=message.chat.id,
message_id=message.message_id,
callback_data=message.reply_markup[i][j].callback_data
)
- Clicking normal buttons:
.. code-block:: python
client.send_message(
chat_id=message.chat.id,
text=message.reply_markup[i][j].text
)
This method can be used in three different ways:
1. Pass one integer argument only (e.g.: ``.click(2)``, to click a button at index 2).
Buttons are counted left to right, starting from the top.
2. Pass two integer arguments (e.g.: ``.click(1, 0)``, to click a button at position (1, 0)).
The origin (0, 0) is top-left.
3. Pass one string argument only (e.g.: ``.click("Settings")``, to click a button by using its label).
Only the first matching button will be pressed.
Args:
x (``int`` | ``str``):
Used as integer index, integer abscissa (in pair with y) or as string label.
y (``int``, *optional*):
Used as ordinate only (in pair with x).
quote (``bool``, *optional*):
Useful for normal buttons only, where pressing it will result in a new message sent.
If ``True``, the message will be sent as a reply to this message.
Defaults to ``True`` in group chats and ``False`` in private chats.
Returns:
- The result of *request_callback_answer()* in case of inline callback button clicks.
- The result of *reply()* in case of normal button clicks.
- A string in case the inline button is an URL, switch_inline_query or switch_inline_query_current_chat
button.
Raises:
:class:`Error <pyrogram.Error>`
``ValueError``: If the provided index or position is out of range or the button label was not found.
"""
if isinstance(self.reply_markup, ReplyKeyboardMarkup):
if quote is None:
quote = self.chat.type != "private"
return await self.reply(x, quote=quote)
elif isinstance(self.reply_markup, InlineKeyboardMarkup):
if isinstance(x, int) and y is None:
try:
button = [
button
for row in self.reply_markup.inline_keyboard
for button in row
][x]
except IndexError:
raise ValueError("The button at index {} doesn't exist".format(x)) from None
elif isinstance(x, int) and isinstance(y, int):
try:
button = self.reply_markup.inline_keyboard[y][x]
except IndexError:
raise ValueError("The button at position ({}, {}) doesn't exist".format(x, y)) from None
elif isinstance(x, str):
x = x.encode("utf-16", "surrogatepass").decode("utf-16")
try:
button = [
button
for row in self.reply_markup.inline_keyboard
for button in row
if x == button.text
][0]
except IndexError:
raise ValueError(
"The button with label '{}' doesn't exists".format(
x.encode("unicode_escape").decode()
)
) from None
else:
raise ValueError("Invalid arguments")
if button.callback_data:
return await self._client.request_callback_answer(
chat_id=self.chat.id,
message_id=self.message_id,
data=button.callback_data
)
elif button.url:
return button.url
elif button.switch_inline_query:
return button.switch_inline_query
elif button.switch_inline_query_current_chat:
return button.switch_inline_query_current_chat
else:
raise ValueError("This button is not supported yet")
else:
raise ValueError("The message doesn't contain any keyboard")