2
0
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:
Dan
2018-12-31 12:06:15 +01:00
29 changed files with 390 additions and 146 deletions

View File

@@ -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,

View File

@@ -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()

View File

@@ -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
):

View File

@@ -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

View File

@@ -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):

View 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")

View File

@@ -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:

View File

@@ -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

View File

@@ -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):

View File

@@ -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]

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 .download_media import DownloadMedia
class Utilities(
DownloadMedia
):
pass

View File

@@ -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
)

View File

@@ -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)),

View File

@@ -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

View 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