mirror of
https://github.com/pyrogram/pyrogram
synced 2025-09-02 07:15:23 +00:00
Merge branch 'develop' into asyncio
# Conflicts: # pyrogram/client/client.py # pyrogram/client/methods/chats/get_chat.py # pyrogram/client/methods/messages/get_messages.py # pyrogram/client/types/messages_and_media/messages.py
This commit is contained in:
@@ -40,7 +40,7 @@ from .client.types import (
|
||||
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus,
|
||||
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
|
||||
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove,
|
||||
Poll, PollOption
|
||||
Poll, PollOption, ChatPreview
|
||||
)
|
||||
from .client import (
|
||||
Client, ChatAction, ParseMode, Emoji,
|
||||
|
@@ -919,9 +919,9 @@ class Client(Methods, BaseClient):
|
||||
log.info("UpdatesWorkerTask stopped")
|
||||
|
||||
async def send(self,
|
||||
data: Object,
|
||||
retries: int = Session.MAX_RETRIES,
|
||||
timeout: float = Session.WAIT_TIMEOUT):
|
||||
data: Object,
|
||||
retries: int = Session.MAX_RETRIES,
|
||||
timeout: float = Session.WAIT_TIMEOUT):
|
||||
"""Use this method to send Raw Function queries.
|
||||
|
||||
This method makes possible to manually call every single Telegram API method in a low-level manner.
|
||||
@@ -1081,7 +1081,7 @@ class Client(Methods, BaseClient):
|
||||
)
|
||||
|
||||
async def get_initial_dialogs_chunk(self,
|
||||
offset_date: int = 0):
|
||||
offset_date: int = 0):
|
||||
while True:
|
||||
try:
|
||||
r = await self.send(
|
||||
@@ -1114,12 +1114,12 @@ class Client(Methods, BaseClient):
|
||||
await self.get_initial_dialogs_chunk()
|
||||
|
||||
async def resolve_peer(self,
|
||||
peer_id: Union[int, str]):
|
||||
peer_id: Union[int, str]):
|
||||
"""Use this method to get the InputPeer of a known peer_id.
|
||||
|
||||
This is a utility method intended to be used only when working with Raw Functions (i.e: a Telegram API method
|
||||
you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an InputPeer
|
||||
type is required.
|
||||
This is a utility method intended to be used **only** when working with Raw Functions (i.e: a Telegram API
|
||||
method you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an
|
||||
InputPeer type is required.
|
||||
|
||||
Args:
|
||||
peer_id (``int`` | ``str``):
|
||||
@@ -1147,8 +1147,8 @@ class Client(Methods, BaseClient):
|
||||
except ValueError:
|
||||
if peer_id not in self.peers_by_username:
|
||||
await self.send(functions.contacts.ResolveUsername(username=peer_id
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
return self.peers_by_username[peer_id]
|
||||
else:
|
||||
@@ -1190,6 +1190,52 @@ class Client(Methods, BaseClient):
|
||||
file_part: int = 0,
|
||||
progress: callable = None,
|
||||
progress_args: tuple = ()):
|
||||
"""Use this method to upload a file onto Telegram servers, without actually sending the message to anyone.
|
||||
|
||||
This is a utility method intended to be used **only** when working with Raw Functions (i.e: a Telegram API
|
||||
method you wish to use which is not available yet in the Client class as an easy-to-use method), whenever an
|
||||
InputFile type is required.
|
||||
|
||||
Args:
|
||||
path (``str``):
|
||||
The path of the file you want to upload that exists on your local machine.
|
||||
|
||||
file_id (``int``, *optional*):
|
||||
In case a file part expired, pass the file_id and the file_part to retry uploading that specific chunk.
|
||||
|
||||
file_part (``int``, *optional*):
|
||||
In case a file part expired, pass the file_id and the file_part to retry uploading that specific chunk.
|
||||
|
||||
progress (``callable``, *optional*):
|
||||
Pass a callback function to view the upload progress.
|
||||
The function must take *(client, current, total, \*args)* as positional arguments (look at the section
|
||||
below for a detailed description).
|
||||
|
||||
progress_args (``tuple``, *optional*):
|
||||
Extra custom arguments for the progress callback function. Useful, for example, if you want to pass
|
||||
a chat_id and a message_id in order to edit a message with the updated progress.
|
||||
|
||||
Other Parameters:
|
||||
client (:obj:`Client <pyrogram.Client>`):
|
||||
The Client itself, useful when you want to call other API methods inside the callback function.
|
||||
|
||||
current (``int``):
|
||||
The amount of bytes uploaded so far.
|
||||
|
||||
total (``int``):
|
||||
The size of the file.
|
||||
|
||||
*args (``tuple``, *optional*):
|
||||
Extra custom arguments as defined in the *progress_args* parameter.
|
||||
You can either keep *\*args* or add every single extra argument in your function signature.
|
||||
|
||||
Returns:
|
||||
On success, the uploaded file is returned in form of an InputFile object.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
|
||||
"""
|
||||
|
||||
async def worker(session):
|
||||
while True:
|
||||
data = await queue.get()
|
||||
|
@@ -23,7 +23,6 @@ from .decorators import Decorators
|
||||
from .messages import Messages
|
||||
from .password import Password
|
||||
from .users import Users
|
||||
from .utilities import Utilities
|
||||
|
||||
|
||||
class Methods(
|
||||
@@ -32,7 +31,6 @@ class Methods(
|
||||
Password,
|
||||
Chats,
|
||||
Users,
|
||||
Utilities,
|
||||
Messages,
|
||||
Decorators
|
||||
):
|
||||
|
@@ -22,6 +22,7 @@ from .get_chat import GetChat
|
||||
from .get_chat_member import GetChatMember
|
||||
from .get_chat_members import GetChatMembers
|
||||
from .get_chat_members_count import GetChatMembersCount
|
||||
from .get_chat_preview import GetChatPreview
|
||||
from .get_dialogs import GetDialogs
|
||||
from .join_chat import JoinChat
|
||||
from .kick_chat_member import KickChatMember
|
||||
@@ -54,6 +55,7 @@ class Chats(
|
||||
PinChatMessage,
|
||||
UnpinChatMessage,
|
||||
GetDialogs,
|
||||
GetChatMembersCount
|
||||
GetChatMembersCount,
|
||||
GetChatPreview
|
||||
):
|
||||
pass
|
||||
|
@@ -32,13 +32,36 @@ class GetChat(BaseClient):
|
||||
Args:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
Unique identifier for the target chat in form of a *t.me/joinchat/* link, identifier (int) or username
|
||||
of the target channel/supergroup (in the format @username).
|
||||
|
||||
Returns:
|
||||
On success, a :obj:`Chat <pyrogram.Chat>` object is returned.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
|
||||
``ValueError`` in case the chat invite link refers to a chat you haven't joined yet.
|
||||
"""
|
||||
match = self.INVITE_LINK_RE.match(str(chat_id))
|
||||
|
||||
if match:
|
||||
h = match.group(1)
|
||||
|
||||
r = await self.send(
|
||||
functions.messages.CheckChatInvite(
|
||||
hash=h
|
||||
)
|
||||
)
|
||||
|
||||
if isinstance(r, types.ChatInvite):
|
||||
raise ValueError("You haven't joined \"t.me/joinchat/{}\" yet".format(h))
|
||||
|
||||
if isinstance(r.chat, types.Chat):
|
||||
chat_id = -r.chat.id
|
||||
|
||||
if isinstance(r.chat, types.Channel):
|
||||
chat_id = int("-100" + str(r.chat.id))
|
||||
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
|
||||
if isinstance(peer, types.InputPeerChannel):
|
||||
|
63
pyrogram/client/methods/chats/get_chat_preview.py
Normal file
63
pyrogram/client/methods/chats/get_chat_preview.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# 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/>.
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import functions, types
|
||||
from ...ext import BaseClient
|
||||
|
||||
|
||||
class GetChatPreview(BaseClient):
|
||||
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`
|
||||
|
||||
Args:
|
||||
invite_link (``str``):
|
||||
Unique identifier for the target chat in form of *t.me/joinchat/* links.
|
||||
|
||||
Returns:
|
||||
Either :obj:`Chat` or :obj:`ChatPreview`, depending on whether you already joined the chat or not.
|
||||
|
||||
Raises:
|
||||
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
|
||||
``ValueError`` in case of an invalid invite_link.
|
||||
"""
|
||||
match = self.INVITE_LINK_RE.match(invite_link)
|
||||
|
||||
if match:
|
||||
r = self.send(
|
||||
functions.messages.CheckChatInvite(
|
||||
hash=match.group(1)
|
||||
)
|
||||
)
|
||||
|
||||
if isinstance(r, types.ChatInvite):
|
||||
return pyrogram.ChatPreview._parse(self, r)
|
||||
|
||||
if isinstance(r, types.ChatInviteAlready):
|
||||
chat = r.chat
|
||||
|
||||
if isinstance(chat, types.Chat):
|
||||
return pyrogram.Chat._parse_chat_chat(self, chat)
|
||||
|
||||
if isinstance(chat, types.Channel):
|
||||
return pyrogram.Chat._parse_channel_chat(self, chat)
|
||||
else:
|
||||
raise ValueError("The invite_link is invalid")
|
@@ -27,7 +27,7 @@ class JoinChat(BaseClient):
|
||||
|
||||
Args:
|
||||
chat_id (``str``):
|
||||
Unique identifier for the target chat in form of *t.me/joinchat/* links or username of the target
|
||||
Unique identifier for the target chat in form of a *t.me/joinchat/* link or username of the target
|
||||
channel/supergroup (in the format @username).
|
||||
|
||||
Raises:
|
||||
|
@@ -17,6 +17,7 @@
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .delete_messages import DeleteMessages
|
||||
from .download_media import DownloadMedia
|
||||
from .edit_message_caption import EditMessageCaption
|
||||
from .edit_message_media import EditMessageMedia
|
||||
from .edit_message_reply_markup import EditMessageReplyMarkup
|
||||
@@ -68,6 +69,7 @@ class Messages(
|
||||
SendVoice,
|
||||
SendPoll,
|
||||
VotePoll,
|
||||
RetractVote
|
||||
RetractVote,
|
||||
DownloadMedia
|
||||
):
|
||||
pass
|
||||
|
@@ -20,7 +20,7 @@ import asyncio
|
||||
from typing import Union
|
||||
|
||||
import pyrogram
|
||||
from ...ext import BaseClient
|
||||
from pyrogram.client.ext import BaseClient
|
||||
|
||||
|
||||
class DownloadMedia(BaseClient):
|
@@ -78,6 +78,6 @@ class GetMessages(BaseClient):
|
||||
else:
|
||||
rpc = functions.messages.GetMessages(id=ids)
|
||||
|
||||
messages = await pyrogram.Messages._parse(self, await self.send(rpc))
|
||||
messages = await pyrogram.Messages._parse(self, await self.send(rpc), replies)
|
||||
|
||||
return messages if is_iterable else messages.messages[0]
|
||||
|
@@ -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 .download_media import DownloadMedia
|
||||
|
||||
|
||||
class Utilities(
|
||||
DownloadMedia
|
||||
):
|
||||
pass
|
@@ -35,5 +35,5 @@ from .messages_and_media import (
|
||||
)
|
||||
from .user_and_chats import (
|
||||
Chat, ChatMember, ChatMembers, ChatPhoto,
|
||||
Dialog, Dialogs, User, UserStatus
|
||||
Dialog, Dialogs, User, UserStatus, ChatPreview
|
||||
)
|
||||
|
@@ -47,7 +47,7 @@ class Messages(PyrogramType):
|
||||
self.messages = messages
|
||||
|
||||
@staticmethod
|
||||
async def _parse(client, messages: types.messages.Messages) -> "Messages":
|
||||
async def _parse(client, messages: types.messages.Messages, replies: int = 1) -> "Messages":
|
||||
users = {i.id: i for i in messages.users}
|
||||
chats = {i.id: i for i in messages.chats}
|
||||
|
||||
@@ -55,7 +55,7 @@ class Messages(PyrogramType):
|
||||
parsed_messages = []
|
||||
|
||||
for message in messages.messages:
|
||||
parsed_messages.append(await Message._parse(client, message, users, chats))
|
||||
parsed_messages.append(await Message._parse(client, message, users, chats, replies))
|
||||
|
||||
return Messages(
|
||||
total_count=getattr(messages, "count", len(messages.messages)),
|
||||
|
@@ -20,6 +20,7 @@ from .chat import Chat
|
||||
from .chat_member import ChatMember
|
||||
from .chat_members import ChatMembers
|
||||
from .chat_photo import ChatPhoto
|
||||
from .chat_preview import ChatPreview
|
||||
from .dialog import Dialog
|
||||
from .dialogs import Dialogs
|
||||
from .user import User
|
||||
|
78
pyrogram/client/types/user_and_chats/chat_preview.py
Normal file
78
pyrogram/client/types/user_and_chats/chat_preview.py
Normal file
@@ -0,0 +1,78 @@
|
||||
# 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 List
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .chat_photo import ChatPhoto
|
||||
from ..pyrogram_type import PyrogramType
|
||||
from ..user_and_chats.user import User
|
||||
|
||||
|
||||
class ChatPreview(PyrogramType):
|
||||
"""This object represents a chat preview.
|
||||
|
||||
Args:
|
||||
title (``str``):
|
||||
Title of the chat.
|
||||
|
||||
photo (:obj:`ChatPhoto`):
|
||||
Chat photo. Suitable for downloads only.
|
||||
|
||||
type (``str``):
|
||||
Type of chat, can be either, "group", "supergroup" or "channel".
|
||||
|
||||
members_count (``int``):
|
||||
Chat members count.
|
||||
|
||||
members (List of :obj:`User`, *optional*):
|
||||
Preview of some of the chat members.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client: "pyrogram.client.ext.BaseClient",
|
||||
title: str,
|
||||
photo: ChatPhoto,
|
||||
type: str,
|
||||
members_count: int,
|
||||
members: List[User] = None):
|
||||
super().__init__(client)
|
||||
|
||||
self.title = title
|
||||
self.photo = photo
|
||||
self.type = type
|
||||
self.members_count = members_count
|
||||
self.members = members
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, chat_invite: types.ChatInvite) -> "ChatPreview":
|
||||
return ChatPreview(
|
||||
title=chat_invite.title,
|
||||
photo=ChatPhoto._parse(client, chat_invite.photo),
|
||||
type=("group" if not chat_invite.channel else
|
||||
"channel" if chat_invite.broadcast else
|
||||
"supergroup"),
|
||||
members_count=chat_invite.participants_count,
|
||||
members=[User._parse(client, user) for user in chat_invite.participants] or None,
|
||||
client=client
|
||||
)
|
||||
|
||||
# TODO: Maybe just merge this object into Chat itself by adding the "members" field.
|
||||
# get_chat can be used as well instead of get_chat_preview
|
Reference in New Issue
Block a user