Merge develop -> asyncio-dev

This commit is contained in:
Dan 2020-05-16 01:33:42 +02:00
commit d50322a3f5
5 changed files with 66 additions and 37 deletions

View File

@ -20,6 +20,7 @@ import re
from typing import Callable from typing import Callable
from .filter import Filter from .filter import Filter
from ..types import Message, CallbackQuery, InlineQuery
from ..types.bots_and_keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup from ..types.bots_and_keyboards import InlineKeyboardMarkup, ReplyKeyboardMarkup
CUSTOM_FILTER_NAME = "CustomFilter" CUSTOM_FILTER_NAME = "CustomFilter"
@ -288,26 +289,39 @@ class Filters:
) )
@staticmethod @staticmethod
def regex(pattern, flags: int = 0): def regex(pattern: str, flags: int = 0):
"""Filter message texts or captions that match a given regular expression pattern. """Filter updates that match a given regular expression pattern.
Can be applied to handlers that receive one of the following updates:
- :obj:`Message`: The filter will match ``text`` or ``caption``.
- :obj:`CallbackQuery`: The filter will match ``data``.
- :obj:`InlineQuery`: The filter will match ``query``.
When a pattern matches, all the `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ are
stored in the ``matches`` field of the update object itself.
Parameters: Parameters:
pattern (``str``): pattern (``str``):
The RegEx pattern as string, it will be applied to the text or the caption of a message. When a pattern The regex pattern as string.
matches, all the `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ are stored
in the *matches* field of the :obj:`Message` itself.
flags (``int``, *optional*): flags (``int``, *optional*):
RegEx flags. Regex flags.
""" """
def func(flt, message): def func(flt, update):
text = message.text or message.caption if isinstance(update, Message):
value = update.text or update.caption
elif isinstance(update, CallbackQuery):
value = update.data
elif isinstance(update, InlineQuery):
value = update.query
else:
raise ValueError("Regex filter doesn't work with {}".format(type(update)))
if text: update.matches = list(flt.p.finditer(value)) or None
message.matches = list(flt.p.finditer(text)) or None
return bool(message.matches) return bool(update.matches)
return create(func, "RegexFilter", p=re.compile(pattern, flags)) return create(func, "RegexFilter", p=re.compile(pattern, flags))
@ -375,15 +389,4 @@ class Filters:
and message.from_user.is_self and message.from_user.is_self
and not message.outgoing))) and not message.outgoing)))
@staticmethod
def callback_data(data: str or bytes):
"""Filter callback queries for their data.
Parameters:
data (``str`` | ``bytes``):
Pass the data you want to filter for.
"""
return create(lambda flt, cb: cb.data == flt.data, "CallbackDataFilter", data=data)
dan = create(lambda _, m: bool(m.from_user and m.from_user.id == 23122162), "DanFilter") dan = create(lambda _, m: bool(m.from_user and m.from_user.id == 23122162), "DanFilter")

View File

@ -16,6 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram import pyrogram
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ...ext import BaseClient from ...ext import BaseClient
@ -24,14 +26,14 @@ from ...ext import BaseClient
class JoinChat(BaseClient): class JoinChat(BaseClient):
async def join_chat( async def join_chat(
self, self,
chat_id: str chat_id: Union[int, str]
): ):
"""Join a group chat or channel. """Join a group chat or channel.
Parameters: Parameters:
chat_id (``str``): chat_id (``int`` | ``str``):
Unique identifier for the target chat in form of a *t.me/joinchat/* link or username of the target Unique identifier for the target chat in form of a *t.me/joinchat/* link, a username of the target
channel/supergroup (in the format @username). channel/supergroup (in the format @username) or a chat id of a linked chat (channel or supergroup).
Returns: Returns:
:obj:`Chat`: On success, a chat object is returned. :obj:`Chat`: On success, a chat object is returned.
@ -44,8 +46,11 @@ class JoinChat(BaseClient):
# Join chat via invite link # Join chat via invite link
app.join_chat("https://t.me/joinchat/AAAAAE0QmSW3IUmm3UFR7A") app.join_chat("https://t.me/joinchat/AAAAAE0QmSW3IUmm3UFR7A")
# Join a linked chat
app.join_chat(app.get_chat("pyrogram").linked_chat.id)
""" """
match = self.INVITE_LINK_RE.match(chat_id) match = self.INVITE_LINK_RE.match(str(chat_id))
if match: if match:
chat = await self.send( chat = await self.send(

View File

@ -18,7 +18,7 @@
from base64 import b64encode from base64 import b64encode
from struct import pack from struct import pack
from typing import Union from typing import Union, List, Match
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api import types
@ -59,6 +59,9 @@ class CallbackQuery(Object, Update):
game_short_name (``str``, *optional*): game_short_name (``str``, *optional*):
Short name of a Game to be returned, serves as the unique identifier for the game. Short name of a Game to be returned, serves as the unique identifier for the game.
matches (List of regex Matches, *optional*):
A list containing all `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ that match
the data of this callback query. Only applicable when using :obj:`Filters.regex <pyrogram.Filters.regex>`.
""" """
def __init__( def __init__(
@ -71,7 +74,8 @@ class CallbackQuery(Object, Update):
message: "pyrogram.Message" = None, message: "pyrogram.Message" = None,
inline_message_id: str = None, inline_message_id: str = None,
data: Union[str, bytes] = None, data: Union[str, bytes] = None,
game_short_name: str = None game_short_name: str = None,
matches: List[Match] = None
): ):
super().__init__(client) super().__init__(client)
@ -82,6 +86,7 @@ class CallbackQuery(Object, Update):
self.inline_message_id = inline_message_id self.inline_message_id = inline_message_id
self.data = data self.data = data
self.game_short_name = game_short_name self.game_short_name = game_short_name
self.matches = matches
@staticmethod @staticmethod
async def _parse(client, callback_query, users) -> "CallbackQuery": async def _parse(client, callback_query, users) -> "CallbackQuery":

View File

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import List from typing import List, Match
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api import types
@ -47,6 +47,10 @@ class InlineQuery(Object, Update):
location (:obj:`Location`. *optional*): location (:obj:`Location`. *optional*):
Sender location, only for bots that request user location. Sender location, only for bots that request user location.
matches (List of regex Matches, *optional*):
A list containing all `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ that match
the query of this inline query. Only applicable when using :obj:`Filters.regex <pyrogram.Filters.regex>`.
""" """
def __init__( def __init__(
@ -57,7 +61,8 @@ class InlineQuery(Object, Update):
from_user: User, from_user: User,
query: str, query: str,
offset: str, offset: str,
location: Location = None location: Location = None,
matches: List[Match] = None
): ):
super().__init__(client) super().__init__(client)
@ -66,6 +71,7 @@ class InlineQuery(Object, Update):
self.query = query self.query = query
self.offset = offset self.offset = offset
self.location = location self.location = location
self.matches = matches
@staticmethod @staticmethod
def _parse(client, inline_query: types.UpdateBotInlineQuery, users: dict) -> "InlineQuery": def _parse(client, inline_query: types.UpdateBotInlineQuery, users: dict) -> "InlineQuery":

View File

@ -101,6 +101,9 @@ class Chat(Object):
distance (``int``, *optional*): distance (``int``, *optional*):
Distance in meters of this group chat from your location. Distance in meters of this group chat from your location.
Returned only in :meth:`~Client.get_nearby_chats`. Returned only in :meth:`~Client.get_nearby_chats`.
linked_chat (:obj:`Chat`, *optional*):
The linked discussion group (in case of channels) or the linked channel (in case of supergroups).
""" """
def __init__( def __init__(
@ -127,7 +130,8 @@ class Chat(Object):
members_count: int = None, members_count: int = None,
restrictions: List[Restriction] = None, restrictions: List[Restriction] = None,
permissions: "pyrogram.ChatPermissions" = None, permissions: "pyrogram.ChatPermissions" = None,
distance: int = None distance: int = None,
linked_chat: "pyrogram.Chat" = None
): ):
super().__init__(client) super().__init__(client)
@ -152,6 +156,7 @@ class Chat(Object):
self.restrictions = restrictions self.restrictions = restrictions
self.permissions = permissions self.permissions = permissions
self.distance = distance self.distance = distance
self.linked_chat = linked_chat
@staticmethod @staticmethod
def _parse_user_chat(client, user: types.User) -> "Chat": def _parse_user_chat(client, user: types.User) -> "Chat":
@ -241,10 +246,14 @@ class Chat(Object):
else: else:
full_chat = chat_full.full_chat full_chat = chat_full.full_chat
chat = None chat = None
linked_chat = None
for i in chat_full.chats: for c in chat_full.chats:
if full_chat.id == i.id: if full_chat.id == c.id:
chat = i 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)
@ -259,6 +268,7 @@ 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 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(
@ -665,7 +675,7 @@ class Chat(Object):
chat.join() chat.join()
Note: Note:
This only works for public groups and channels that have set a username. This only works for public groups, channels that have set a username or linked chats.
Returns: Returns:
:obj:`Chat`: On success, a chat object is returned. :obj:`Chat`: On success, a chat object is returned.
@ -674,7 +684,7 @@ class Chat(Object):
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
""" """
return await self._client.join_chat(self.username) return await self._client.join_chat(self.username or self.id)
async def leave(self): async def leave(self):
"""Bound method *leave* of :obj:`Chat`. """Bound method *leave* of :obj:`Chat`.