Merge branch 'develop' into asyncio

# Conflicts:
#	pyrogram/__init__.py
#	pyrogram/client/client.py
#	pyrogram/client/methods/contacts/get_contacts.py
#	pyrogram/client/methods/messages/send_media_group.py
#	requirements.txt
This commit is contained in:
Dan 2019-02-07 16:20:03 +01:00
commit 1e6d03108f
11 changed files with 2545 additions and 58 deletions

View File

@ -87,4 +87,6 @@ MESSAGE_POLL_CLOSED You can't interact with a closed poll
MEDIA_INVALID The media is invalid
BOT_SCORE_NOT_MODIFIED The bot score was not modified
USER_BOT_REQUIRED The method can be used by bots only
IMAGE_PROCESS_FAILED The server failed to process your image
IMAGE_PROCESS_FAILED The server failed to process your image
CALL_ALREADY_ACCEPTED The call is already accepted
CALL_ALREADY_DECLINED The call is already declined

1 id message
87 MEDIA_INVALID The media is invalid
88 BOT_SCORE_NOT_MODIFIED The bot score was not modified
89 USER_BOT_REQUIRED The method can be used by bots only
90 IMAGE_PROCESS_FAILED The server failed to process your image
91 CALL_ALREADY_ACCEPTED The call is already accepted
92 CALL_ALREADY_DECLINED The call is already declined

View File

@ -82,7 +82,7 @@ If no error shows up you are good to go.
>>> import pyrogram
>>> pyrogram.__version__
'0.10.3'
'0.11.0'
.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto
.. _develop: http://github.com/pyrogram/pyrogram

View File

@ -19,6 +19,11 @@
import asyncio
import sys
from .vendor import typing
# Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one.
sys.modules["typing"] = typing
try:
import uvloop
except ImportError:
@ -31,7 +36,7 @@ __copyright__ = "Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance
"e" if sys.getfilesystemencoding() != "utf-8" else "\xe8"
)
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
__version__ = "0.11.0.asyncio"
__version__ = "0.11.1.asyncio"
from .api.errors import Error
from .client.types import (

View File

@ -62,16 +62,16 @@ class Filters:
create = create
me = create("Me", lambda _, m: bool(m.from_user and m.from_user.is_self))
"""Filter messages coming from you yourself"""
"""Filter messages generated by you yourself."""
bot = create("Bot", lambda _, m: bool(m.from_user and m.from_user.is_bot))
"""Filter messages coming from bots"""
"""Filter messages coming from bots."""
incoming = create("Incoming", lambda _, m: not m.outgoing)
"""Filter incoming messages."""
"""Filter incoming messages. Messages sent to your own chat (Saved Messages) are also recognised as incoming."""
outgoing = create("Outgoing", lambda _, m: m.outgoing)
"""Filter outgoing messages."""
"""Filter outgoing messages. Messages sent to your own chat (Saved Messages) are not recognized as outgoing."""
text = create("Text", lambda _, m: bool(m.text))
"""Filter text messages."""

View File

@ -19,7 +19,8 @@
import asyncio
import logging
from pyrogram.api import functions, types
import pyrogram
from pyrogram.api import functions
from pyrogram.api.errors import FloodWait
from ...ext import BaseClient
@ -28,12 +29,10 @@ log = logging.getLogger(__name__)
class GetContacts(BaseClient):
async def get_contacts(self):
"""Use this method to get contacts from your Telegram address book
Requires no parameters.
"""Use this method to get contacts from your Telegram address book.
Returns:
On success, the user's contacts are returned
On success, a list of :obj:`User` objects is returned.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
@ -44,9 +43,6 @@ class GetContacts(BaseClient):
except FloodWait as e:
log.warning("get_contacts flood: waiting {} seconds".format(e.x))
await asyncio.sleep(e.x)
continue
else:
if isinstance(contacts, types.contacts.Contacts):
log.info("Total contacts: {}".format(len(self.peers_by_phone)))
return contacts
log.info("Total contacts: {}".format(len(self.peers_by_phone)))
return [pyrogram.User._parse(self, user) for user in contacts.users]

View File

@ -17,20 +17,23 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import binascii
import logging
import mimetypes
import os
import struct
from typing import Union, List
import asyncio
import pyrogram
from pyrogram.api import functions, types
from pyrogram.api.errors import FileIdInvalid
from pyrogram.api.errors import FileIdInvalid, FloodWait
from pyrogram.client.ext import BaseClient, utils
log = logging.getLogger(__name__)
class SendMediaGroup(BaseClient):
# TODO: Add progress parameter
# TODO: Return new Message object
# TODO: Figure out how to send albums using URLs
async def send_media_group(self,
chat_id: Union[int, str],
@ -38,7 +41,6 @@ class SendMediaGroup(BaseClient):
disable_notification: bool = None,
reply_to_message_id: int = None):
"""Use this method to send a group of photos or videos as an album.
On success, an Update containing the sent Messages is returned.
Args:
chat_id (``int`` | ``str``):
@ -57,6 +59,13 @@ class SendMediaGroup(BaseClient):
reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message.
Returns:
On success, a :obj:`Messages <pyrogram.Messages>` object is returned containing all the
single messages sent.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
"""
multi_media = []
@ -65,14 +74,21 @@ class SendMediaGroup(BaseClient):
if isinstance(i, pyrogram.InputMediaPhoto):
if os.path.exists(i.media):
media = await self.send(
functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedPhoto(
file=await self.save_file(i.media)
while True:
try:
media = await self.send(
functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedPhoto(
file=await self.save_file(i.media)
)
)
)
)
)
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
media = types.InputMediaPhoto(
id=types.InputPhoto(
@ -106,25 +122,32 @@ class SendMediaGroup(BaseClient):
)
elif isinstance(i, pyrogram.InputMediaVideo):
if os.path.exists(i.media):
media = await self.send(
functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedDocument(
file=await self.save_file(i.media),
thumb=None if i.thumb is None else self.save_file(i.thumb),
mime_type=mimetypes.types_map[".mp4"],
attributes=[
types.DocumentAttributeVideo(
supports_streaming=i.supports_streaming or None,
duration=i.duration,
w=i.width,
h=i.height
),
types.DocumentAttributeFilename(os.path.basename(i.media))
]
while True:
try:
media = await self.send(
functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedDocument(
file=await self.save_file(i.media),
thumb=None if i.thumb is None else self.save_file(i.thumb),
mime_type=mimetypes.types_map[".mp4"],
attributes=[
types.DocumentAttributeVideo(
supports_streaming=i.supports_streaming or None,
duration=i.duration,
w=i.width,
h=i.height
),
types.DocumentAttributeFilename(os.path.basename(i.media))
]
)
)
)
)
)
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
media = types.InputMediaDocument(
id=types.InputDocument(
@ -165,11 +188,30 @@ class SendMediaGroup(BaseClient):
)
)
return await self.send(
functions.messages.SendMultiMedia(
peer=await self.resolve_peer(chat_id),
multi_media=multi_media,
silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id
while True:
try:
r = await self.send(
functions.messages.SendMultiMedia(
peer=await self.resolve_peer(chat_id),
multi_media=multi_media,
silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id
)
)
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
return await pyrogram.Messages._parse(
self,
types.messages.Messages(
messages=[m.message for m in filter(
lambda u: isinstance(u, (types.UpdateNewMessage, types.UpdateNewChannelMessage)),
r.updates
)],
users=r.users,
chats=r.chats
)
)

19
pyrogram/vendor/__init__.py vendored Normal file
View File

@ -0,0 +1,19 @@
# 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 typing

17
pyrogram/vendor/typing/__init__.py vendored Normal file
View File

@ -0,0 +1,17 @@
# 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/>.

2413
pyrogram/vendor/typing/typing.py vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
build:
image: latest
python:
version: 3.6
setup_py_install: true

View File

@ -1,5 +1,4 @@
pyaes==1.6.1
pysocks==1.6.8
typing==3.6.6; python_version<"3.5"
async_lru==1.0.1
async_generator==1.10