Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/client/methods/messages/forward_messages.py
#	pyrogram/client/methods/messages/send_contact.py
#	pyrogram/client/types/messages_and_media/message.py
This commit is contained in:
Dan 2019-03-21 14:02:35 +01:00
commit 03707fd312
10 changed files with 2107 additions and 91 deletions

View File

@ -182,6 +182,8 @@ class Client(Methods, BaseClient):
Defaults to False (normal session). Defaults to False (normal session).
""" """
terms_of_service_displayed = False
def __init__(self, def __init__(self,
session_name: str, session_name: str,
api_id: Union[int, str] = None, api_id: Union[int, str] = None,
@ -602,8 +604,9 @@ class Client(Methods, BaseClient):
phone_code_hash = r.phone_code_hash phone_code_hash = r.phone_code_hash
terms_of_service = r.terms_of_service terms_of_service = r.terms_of_service
if terms_of_service: if terms_of_service and not Client.terms_of_service_displayed:
print("\n" + terms_of_service.text + "\n") print("\n" + terms_of_service.text + "\n")
Client.terms_of_service_displayed = True
if self.force_sms: if self.force_sms:
await self.send( await self.send(

View File

@ -29,7 +29,9 @@ class ForwardMessages(BaseClient):
chat_id: Union[int, str], chat_id: Union[int, str],
from_chat_id: Union[int, str], from_chat_id: Union[int, str],
message_ids: Iterable[int], message_ids: Iterable[int],
disable_notification: bool = None disable_notification: bool = None,
as_copy: bool = False,
remove_caption: bool = False
) -> "pyrogram.Messages": ) -> "pyrogram.Messages":
"""Use this method to forward messages of any kind. """Use this method to forward messages of any kind.
@ -52,6 +54,15 @@ class ForwardMessages(BaseClient):
Sends the message silently. Sends the message silently.
Users will receive a notification with no sound. Users will receive a notification with no sound.
as_copy (``bool``, *optional*):
Pass True to forward messages without the forward header (i.e.: send a copy of the message content).
Defaults to False.
remove_caption (``bool``, *optional*):
If set to True and *as_copy* is enabled as well, media captions are not preserved when copying the
message. Has no effect if *as_copy* is not enabled.
Defaults to False.
Returns: Returns:
On success and in case *message_ids* was an iterable, the returned value will be a list of the forwarded On success and in case *message_ids* was an iterable, the returned value will be a list of the forwarded
:obj:`Messages <pyrogram.Message>` even if a list contains just one element, otherwise if :obj:`Messages <pyrogram.Message>` even if a list contains just one element, otherwise if
@ -61,35 +72,55 @@ class ForwardMessages(BaseClient):
Raises: Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error. :class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
""" """
is_iterable = not isinstance(message_ids, int) is_iterable = not isinstance(message_ids, int)
message_ids = list(message_ids) if is_iterable else [message_ids] message_ids = list(message_ids) if is_iterable else [message_ids]
r = await self.send( if as_copy:
functions.messages.ForwardMessages( sent_messages = []
to_peer=await self.resolve_peer(chat_id), for chunk in [message_ids[i:i + 200] for i in range(0, len(message_ids), 200)]:
from_peer=await self.resolve_peer(from_chat_id), messages = await self.get_messages(chat_id=from_chat_id, message_ids=chunk) # type: pyrogram.Messages
id=message_ids, for message in messages.messages:
silent=disable_notification or None, sent_messages.append(
random_id=[self.rnd_id() for _ in message_ids] await message.forward(
chat_id,
disable_notification=disable_notification,
as_copy=True,
remove_caption=remove_caption
)
)
return pyrogram.Messages(
client=self,
total_count=len(sent_messages),
messages=sent_messages
) if is_iterable else sent_messages[0]
else:
r = await self.send(
functions.messages.ForwardMessages(
to_peer=await self.resolve_peer(chat_id),
from_peer=await self.resolve_peer(from_chat_id),
id=message_ids,
silent=disable_notification or None,
random_id=[self.rnd_id() for _ in message_ids]
)
) )
)
messages = [] forwarded_messages = []
users = {i.id: i for i in r.users} users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats} chats = {i.id: i for i in r.chats}
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)):
messages.append( forwarded_messages.append(
await pyrogram.Message._parse( await pyrogram.Message._parse(
self, i.message, self, i.message,
users, chats users, chats
) )
) )
return pyrogram.Messages( return pyrogram.Messages(
client=self, client=self,
total_count=len(messages), total_count=len(forwarded_messages),
messages=messages messages=forwarded_messages
) if is_iterable else messages[0] ) if is_iterable else forwarded_messages[0]

View File

@ -29,8 +29,8 @@ class SendContact(BaseClient):
chat_id: Union[int, str], chat_id: Union[int, str],
phone_number: str, phone_number: str,
first_name: str, first_name: str,
last_name: str = "", last_name: str = None,
vcard: str = "", disable_notification: bool = None, vcard: str = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
@ -82,8 +82,8 @@ class SendContact(BaseClient):
media=types.InputMediaContact( media=types.InputMediaContact(
phone_number=phone_number, phone_number=phone_number,
first_name=first_name, first_name=first_name,
last_name=last_name, last_name=last_name or "",
vcard=vcard vcard=vcard or ""
), ),
message="", message="",
silent=disable_notification or None, silent=disable_notification or None,

View File

@ -59,7 +59,7 @@ class SendDocument(BaseClient):
pass an HTTP URL as a string for Telegram to get a file from the Internet, or pass an HTTP URL as a string for Telegram to get a file from the Internet, or
pass a file path as string to upload a new file that exists on your local machine. pass a file path as string to upload a new file that exists on your local machine.
thumb (``str``): thumb (``str``, *optional*):
Thumbnail of the file sent. Thumbnail of the file sent.
The thumbnail should be in JPEG format and less than 200 KB in size. The thumbnail should be in JPEG format and less than 200 KB in size.
A thumbnail's width and height should not exceed 90 pixels. A thumbnail's width and height should not exceed 90 pixels.

View File

@ -24,20 +24,20 @@ from pyrogram.client.ext import BaseClient
class SendPoll(BaseClient): class SendPoll(BaseClient):
def send_poll \ def send_poll(
(self, self,
chat_id: Union[int, str], chat_id: Union[int, str],
question: str, question: str,
options: List[str], options: List[str],
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove", "pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply" "pyrogram.ForceReply"
] = None ] = None
) -> "pyrogram.Message": ) -> "pyrogram.Message":
"""Use this method to send a new poll. """Use this method to send a new poll.
Args: Args:

View File

@ -40,7 +40,7 @@ class HTML:
def parse(self, message: str): def parse(self, message: str):
entities = [] entities = []
message = utils.add_surrogates(str(message)) message = utils.add_surrogates(str(message or ""))
offset = 0 offset = 0
for match in self.HTML_RE.finditer(message): for match in self.HTML_RE.finditer(message):

View File

@ -56,7 +56,7 @@ class Markdown:
self.peers_by_id = peers_by_id self.peers_by_id = peers_by_id
def parse(self, message: str): def parse(self, message: str):
message = utils.add_surrogates(str(message)).strip() message = utils.add_surrogates(str(message or "")).strip()
entities = [] entities = []
offset = 0 offset = 0

File diff suppressed because it is too large Load Diff

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, Union
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api import types
@ -120,3 +120,55 @@ class Messages(PyrogramType, Update):
messages=parsed_messages, messages=parsed_messages,
client=client client=client
) )
def forward(
self,
chat_id: Union[int, str],
disable_notification: bool = None,
as_copy: bool = False,
remove_caption: bool = False
):
"""Bound method *forward* of :obj:`Message <pyrogram.Messages>`.
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).
disable_notification (``bool``, *optional*):
Sends messages silently.
Users will receive a notification with no sound.
as_copy (``bool``, *optional*):
Pass True to forward messages without the forward header (i.e.: send a copy of the message content).
Defaults to False.
remove_caption (``bool``, *optional*):
If set to True and *as_copy* is enabled as well, media captions are not preserved when copying the
message. Has no effect if *as_copy* is not enabled.
Defaults to False.
Returns:
On success, a :class:`Messages <pyrogram.Messages>` containing forwarded messages is returned.
Raises:
:class:`Error <pyrogram.Error>`
"""
forwarded_messages = []
for message in self.messages:
forwarded_messages.append(
message.forward(
chat_id=chat_id,
as_copy=as_copy,
disable_notification=disable_notification,
remove_caption=remove_caption
)
)
return Messages(
total_count=len(forwarded_messages),
messages=forwarded_messages,
client=self._client
)

View File

@ -19,11 +19,13 @@
from collections import OrderedDict from collections import OrderedDict
from json import dumps from json import dumps
import pyrogram
class PyrogramType: class PyrogramType:
__slots__ = ["_client"] __slots__ = ["_client"]
def __init__(self, client): def __init__(self, client: "pyrogram.client.ext.BaseClient"):
self._client = client self._client = client
def __str__(self): def __str__(self):