Merge develop -> asyncio-dev

This commit is contained in:
Dan 2020-05-25 16:32:04 +02:00
commit c0b38ff010
9 changed files with 133 additions and 23 deletions

View File

@ -176,6 +176,7 @@ def pyrogram_api():
retract_vote retract_vote
send_dice send_dice
search_messages search_messages
search_global
download_media download_media
""", """,
chats=""" chats="""

View File

@ -85,7 +85,7 @@ Requests against the official bot API endpoint are made via JSON/HTTP, but are h
application that implements the MTProto protocol -- just like Pyrogram -- and uses its own API key, which is always application that implements the MTProto protocol -- just like Pyrogram -- and uses its own API key, which is always
required, but hidden to the public. required, but hidden to the public.
.. figure:: https://i.imgur.com/C108qkX.png .. figure:: https://i.imgur.com/WvwBoZo.png
:align: center :align: center
Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to

View File

@ -35,7 +35,7 @@ accounts that are authorized via tokens instead of phone numbers. The Bot API is
Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram servers Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram servers
using MTProto. using MTProto.
.. figure:: https://i.imgur.com/C108qkX.png .. figure:: https://i.imgur.com/WvwBoZo.png
:align: center :align: center
.. _Bot API: https://core.telegram.org/bots/api .. _Bot API: https://core.telegram.org/bots/api

View File

@ -36,20 +36,20 @@ class AnswerCallbackQuery(BaseClient):
callback_query_id (``str``): callback_query_id (``str``):
Unique identifier for the query to be answered. Unique identifier for the query to be answered.
text (``str``): text (``str`` *optional*):
Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters. Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters.
show_alert (``bool``): show_alert (``bool``, *optional*):
If true, an alert will be shown by the client instead of a notification at the top of the chat screen. If true, an alert will be shown by the client instead of a notification at the top of the chat screen.
Defaults to False. Defaults to False.
url (``str``): url (``str``, *optional*):
URL that will be opened by the user's client. URL that will be opened by the user's client.
If you have created a Game and accepted the conditions via @Botfather, specify the URL that opens your If you have created a Game and accepted the conditions via @Botfather, specify the URL that opens your
game note that this will only work if the query comes from a callback_game button. game note that this will only work if the query comes from a callback_game button.
Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter.
cache_time (``int``): cache_time (``int``, *optional*):
The maximum amount of time in seconds that the result of the callback query may be cached client-side. The maximum amount of time in seconds that the result of the callback query may be cached client-side.
Telegram apps will support caching starting in version 3.14. Defaults to 0. Telegram apps will support caching starting in version 3.14. Defaults to 0.
@ -59,6 +59,9 @@ class AnswerCallbackQuery(BaseClient):
Example: Example:
.. code-block:: python .. code-block:: python
# Answer only (remove the spinning circles)
app.answer_callback_query(query_id)
# Answer without alert # Answer without alert
app.answer_callback_query(query_id, text=text) app.answer_callback_query(query_id, text=text)
@ -70,7 +73,7 @@ class AnswerCallbackQuery(BaseClient):
query_id=int(callback_query_id), query_id=int(callback_query_id),
cache_time=cache_time, cache_time=cache_time,
alert=show_alert or None, alert=show_alert or None,
message=text, message=text or None,
url=url url=url or None
) )
) )

View File

@ -33,11 +33,14 @@ from .get_messages import GetMessages
from .iter_history import IterHistory from .iter_history import IterHistory
from .read_history import ReadHistory from .read_history import ReadHistory
from .retract_vote import RetractVote from .retract_vote import RetractVote
from .search_global import SearchGlobal
from .search_messages import SearchMessages
from .send_animation import SendAnimation from .send_animation import SendAnimation
from .send_audio import SendAudio from .send_audio import SendAudio
from .send_cached_media import SendCachedMedia from .send_cached_media import SendCachedMedia
from .send_chat_action import SendChatAction from .send_chat_action import SendChatAction
from .send_contact import SendContact from .send_contact import SendContact
from .send_dice import SendDice
from .send_document import SendDocument from .send_document import SendDocument
from .send_location import SendLocation from .send_location import SendLocation
from .send_media_group import SendMediaGroup from .send_media_group import SendMediaGroup
@ -51,8 +54,6 @@ from .send_video_note import SendVideoNote
from .send_voice import SendVoice from .send_voice import SendVoice
from .stop_poll import StopPoll from .stop_poll import StopPoll
from .vote_poll import VotePoll from .vote_poll import VotePoll
from .send_dice import SendDice
from .search_messages import SearchMessages
class Messages( class Messages(
@ -92,6 +93,7 @@ class Messages(
EditInlineMedia, EditInlineMedia,
EditInlineReplyMarkup, EditInlineReplyMarkup,
SendDice, SendDice,
SearchMessages SearchMessages,
SearchGlobal
): ):
pass pass

View File

@ -0,0 +1,99 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2020 Dan <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 Generator, Optional
from async_generator import async_generator, yield_
import pyrogram
from pyrogram.api import functions, types
from pyrogram.client.ext import BaseClient, utils
class SearchGlobal(BaseClient):
@async_generator
async def search_global(
self,
query: str,
limit: int = 0,
) -> Optional[Generator["pyrogram.Message", None, None]]:
"""Search messages globally from all of your chats.
.. note::
Due to server-side limitations, you can only get up to around ~10,000 messages and each message
retrieved will not have any *reply_to_message* field.
Parameters:
query (``str``):
Text query string.
limit (``int``, *optional*):
Limits the number of messages to be retrieved.
By default, no limit is applied and all messages are returned.
Returns:
``Generator``: A generator yielding :obj:`Message` objects.
Example:
.. code-block:: python
# Search for "pyrogram". Get the first 420 results
for message in app.search_global("pyrogram", limit=420):
print(message.text)
"""
current = 0
# There seems to be an hard limit of 10k, beyond which Telegram starts spitting one message at a time.
total = abs(limit) or (1 << 31)
limit = min(100, total)
offset_date = 0
offset_peer = types.InputPeerEmpty()
offset_id = 0
while True:
messages = await utils.parse_messages(
self,
await self.send(
functions.messages.SearchGlobal(
q=query,
offset_rate=offset_date,
offset_peer=offset_peer,
offset_id=offset_id,
limit=limit
)
),
replies=0
)
if not messages:
return
last = messages[-1]
offset_date = last.date
offset_peer = await self.resolve_peer(last.chat.id)
offset_id = last.message_id
for message in messages:
await yield_(message)
current += 1
if current >= total:
return

View File

@ -38,7 +38,7 @@ class SendDice(BaseClient):
"pyrogram.ForceReply" "pyrogram.ForceReply"
] = None ] = None
) -> Union["pyrogram.Message", None]: ) -> Union["pyrogram.Message", None]:
"""Send a dice. """Send a dice with a random value from 1 to 6.
Parameters: Parameters:
chat_id (``int`` | ``str``): chat_id (``int`` | ``str``):
@ -47,8 +47,8 @@ class SendDice(BaseClient):
For a contact that exists in your Telegram address book you can use his phone number (str). For a contact that exists in your Telegram address book you can use his phone number (str).
emoji (``str``, *optional*): emoji (``str``, *optional*):
Emoji on which the dice throw animation is based. Currently, must be one of "🎲" or "🎯". Emoji on which the dice throw animation is based. Currently, must be one of "🎲", "🎯" or "🏀".
Defauts to "🎲". Defaults to "🎲".
disable_notification (``bool``, *optional*): disable_notification (``bool``, *optional*):
Sends the message silently. Sends the message silently.
@ -75,6 +75,9 @@ class SendDice(BaseClient):
# Send a dart # Send a dart
app.send_dice("pyrogramlounge", "🎯") app.send_dice("pyrogramlounge", "🎯")
# Send a basketball
app.send_dice("pyrogramlounge", "🏀")
""" """
r = await self.send( r = await self.send(

View File

@ -143,20 +143,20 @@ class CallbackQuery(Object, Update):
callback_query.answer("Hello", show_alert=True) callback_query.answer("Hello", show_alert=True)
Parameters: Parameters:
text (``str``): text (``str``, *optional*):
Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters. Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters.
show_alert (``bool``): show_alert (``bool`` *optional*):
If true, an alert will be shown by the client instead of a notification at the top of the chat screen. If true, an alert will be shown by the client instead of a notification at the top of the chat screen.
Defaults to False. Defaults to False.
url (``str``): url (``str`` *optional*):
URL that will be opened by the user's client. URL that will be opened by the user's client.
If you have created a Game and accepted the conditions via @Botfather, specify the URL that opens your If you have created a Game and accepted the conditions via @Botfather, specify the URL that opens your
game note that this will only work if the query comes from a callback_game button. game note that this will only work if the query comes from a callback_game button.
Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter. Otherwise, you may use links like t.me/your_bot?start=XXXX that open your bot with a parameter.
cache_time (``int``): cache_time (``int`` *optional*):
The maximum amount of time in seconds that the result of the callback query may be cached client-side. The maximum amount of time in seconds that the result of the callback query may be cached client-side.
Telegram apps will support caching starting in version 3.14. Defaults to 0. Telegram apps will support caching starting in version 3.14. Defaults to 0.
""" """

View File

@ -252,8 +252,9 @@ class Chat(Object):
if full_chat.id == c.id: if full_chat.id == c.id:
chat = c chat = c
if full_chat.linked_chat_id == c.id: if isinstance(chat_full, types.ChannelFull):
linked_chat = c if full_chat.linked_chat_id == c.id:
linked_chat = c
if isinstance(full_chat, types.ChatFull): if isinstance(full_chat, types.ChatFull):
parsed_chat = Chat._parse_chat_chat(client, chat) parsed_chat = Chat._parse_chat_chat(client, chat)
@ -268,7 +269,8 @@ class Chat(Object):
# TODO: Add StickerSet type # TODO: Add StickerSet type
parsed_chat.can_set_sticker_set = full_chat.can_set_stickers parsed_chat.can_set_sticker_set = full_chat.can_set_stickers
parsed_chat.sticker_set_name = getattr(full_chat.stickerset, "short_name", None) parsed_chat.sticker_set_name = getattr(full_chat.stickerset, "short_name", None)
parsed_chat.linked_chat = Chat._parse_channel_chat(client, linked_chat) if linked_chat:
parsed_chat.linked_chat = Chat._parse_channel_chat(client, linked_chat)
if full_chat.pinned_msg_id: if full_chat.pinned_msg_id:
parsed_chat.pinned_message = await client.get_messages( parsed_chat.pinned_message = await client.get_messages(
@ -545,13 +547,13 @@ class Chat(Object):
client.restrict_chat_member( client.restrict_chat_member(
chat_id=chat_id, chat_id=chat_id,
user_id=user_id, user_id=user_id,
permissions=ChatPermission() permissions=ChatPermissions()
) )
Example: Example:
.. code-block:: python .. code-block:: python
chat.restrict_member(user_id, ChatPermission()) chat.restrict_member(user_id, ChatPermissions())
Parameters: Parameters:
user_id (``int`` | ``str``): user_id (``int`` | ``str``):