2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-29 13:27:47 +00:00

Merge develop -> asyncio

This commit is contained in:
Dan 2020-05-07 13:00:03 +02:00
commit 74674cd615
7 changed files with 104 additions and 130 deletions

View File

@ -23,7 +23,6 @@ import os
import re import re
import shutil import shutil
import tempfile import tempfile
import time
from configparser import ConfigParser from configparser import ConfigParser
from hashlib import sha256, md5 from hashlib import sha256, md5
from importlib import import_module, reload from importlib import import_module, reload
@ -154,6 +153,12 @@ class Client(Methods, BaseClient):
download_media, ...) are less prone to throw FloodWait exceptions. download_media, ...) are less prone to throw FloodWait exceptions.
Only available for users, bots will ignore this parameter. Only available for users, bots will ignore this parameter.
Defaults to False (normal session). Defaults to False (normal session).
sleep_threshold (``int``, *optional*):
Set a sleep threshold for flood wait exceptions happening globally in this client instance, below which any
request that raises a flood wait will be automatically invoked again after sleeping for the required amount
of time. Flood wait exceptions requiring higher waiting times will be raised.
Defaults to 60 (seconds).
""" """
def __init__( def __init__(
@ -178,7 +183,8 @@ class Client(Methods, BaseClient):
config_file: str = BaseClient.CONFIG_FILE, config_file: str = BaseClient.CONFIG_FILE,
plugins: dict = None, plugins: dict = None,
no_updates: bool = None, no_updates: bool = None,
takeout: bool = None takeout: bool = None,
sleep_threshold: int = 60
): ):
super().__init__() super().__init__()
@ -204,6 +210,7 @@ class Client(Methods, BaseClient):
self.plugins = plugins self.plugins = plugins
self.no_updates = no_updates self.no_updates = no_updates
self.takeout = takeout self.takeout = takeout
self.sleep_threshold = sleep_threshold
if isinstance(session_name, str): if isinstance(session_name, str):
if session_name == ":memory:" or len(session_name) >= MemoryStorage.SESSION_STRING_SIZE: if session_name == ":memory:" or len(session_name) >= MemoryStorage.SESSION_STRING_SIZE:
@ -1403,13 +1410,31 @@ class Client(Methods, BaseClient):
if not self.is_connected: if not self.is_connected:
raise ConnectionError("Client has not been started yet") raise ConnectionError("Client has not been started yet")
# Some raw methods that expect a query as argument are used here.
# Keep the original request query because is needed.
unwrapped_data = data
if self.no_updates: if self.no_updates:
data = functions.InvokeWithoutUpdates(query=data) data = functions.InvokeWithoutUpdates(query=data)
if self.takeout_id: if self.takeout_id:
data = functions.InvokeWithTakeout(takeout_id=self.takeout_id, query=data) data = functions.InvokeWithTakeout(takeout_id=self.takeout_id, query=data)
while True:
try:
r = await self.session.send(data, retries, timeout) r = await self.session.send(data, retries, timeout)
except FloodWait as e:
amount = e.x
if amount > self.sleep_threshold:
raise
log.warning('[{}] Sleeping for {}s (required by "{}")'.format(
self.session_name, amount, ".".join(unwrapped_data.QUALNAME.split(".")[1:])))
await asyncio.sleep(amount)
else:
break
self.fetch_peers(getattr(r, "users", [])) self.fetch_peers(getattr(r, "users", []))
self.fetch_peers(getattr(r, "chats", [])) self.fetch_peers(getattr(r, "chats", []))

View File

@ -16,13 +16,11 @@
# 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/>.
import asyncio
import logging import logging
from typing import Union, List from typing import Union, List
import pyrogram import pyrogram
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.errors import FloodWait
from ...ext import BaseClient from ...ext import BaseClient
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -136,8 +134,6 @@ class GetChatMembers(BaseClient):
else: else:
raise ValueError("Invalid filter \"{}\"".format(filter)) raise ValueError("Invalid filter \"{}\"".format(filter))
while True:
try:
r = await self.send( r = await self.send(
functions.channels.GetParticipants( functions.channels.GetParticipants(
channel=peer, channel=peer,
@ -152,8 +148,5 @@ class GetChatMembers(BaseClient):
users = {i.id: i for i in r.users} users = {i.id: i for i in r.users}
return pyrogram.List(pyrogram.ChatMember._parse(self, member, users) for member in members) return pyrogram.List(pyrogram.ChatMember._parse(self, member, users) for member in members)
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else: else:
raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id)) raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id))

View File

@ -16,13 +16,11 @@
# 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/>.
import asyncio
import logging import logging
from typing import List from typing import List
import pyrogram import pyrogram
from pyrogram.api import functions, types from pyrogram.api import functions, types
from pyrogram.errors import FloodWait
from ...ext import BaseClient, utils from ...ext import BaseClient, utils
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -66,8 +64,6 @@ class GetDialogs(BaseClient):
app.get_dialogs(pinned_only=True) app.get_dialogs(pinned_only=True)
""" """
while True:
try:
if pinned_only: if pinned_only:
r = await self.send(functions.messages.GetPinnedDialogs(folder_id=0)) r = await self.send(functions.messages.GetPinnedDialogs(folder_id=0))
else: else:
@ -81,11 +77,6 @@ class GetDialogs(BaseClient):
exclude_pinned=True exclude_pinned=True
) )
) )
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
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}

View File

@ -85,8 +85,6 @@ class GetHistory(BaseClient):
offset_id = offset_id or (1 if reverse else 0) offset_id = offset_id or (1 if reverse else 0)
while True:
try:
messages = await utils.parse_messages( messages = await utils.parse_messages(
self, self,
await self.send( await self.send(
@ -102,11 +100,6 @@ class GetHistory(BaseClient):
) )
) )
) )
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
if reverse: if reverse:
messages.reverse() messages.reverse()

View File

@ -112,14 +112,7 @@ class GetMessages(BaseClient):
else: else:
rpc = functions.messages.GetMessages(id=ids) rpc = functions.messages.GetMessages(id=ids)
while True:
try:
r = await self.send(rpc) r = await self.send(rpc)
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
messages = await utils.parse_messages(self, r, replies=replies) messages = await utils.parse_messages(self, r, replies=replies)

View File

@ -78,8 +78,6 @@ class SendMediaGroup(BaseClient):
for i in media: for i in media:
if isinstance(i, pyrogram.InputMediaPhoto): if isinstance(i, pyrogram.InputMediaPhoto):
if os.path.exists(i.media): if os.path.exists(i.media):
while True:
try:
media = await self.send( media = await self.send(
functions.messages.UploadMedia( functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
@ -88,11 +86,6 @@ class SendMediaGroup(BaseClient):
) )
) )
) )
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
media = types.InputMediaPhoto( media = types.InputMediaPhoto(
id=types.InputPhoto( id=types.InputPhoto(
@ -122,8 +115,6 @@ class SendMediaGroup(BaseClient):
media = utils.get_input_media_from_file_id(i.media, i.file_ref, 2) media = utils.get_input_media_from_file_id(i.media, i.file_ref, 2)
elif isinstance(i, pyrogram.InputMediaVideo): elif isinstance(i, pyrogram.InputMediaVideo):
if os.path.exists(i.media): if os.path.exists(i.media):
while True:
try:
media = await self.send( media = await self.send(
functions.messages.UploadMedia( functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
@ -143,11 +134,6 @@ class SendMediaGroup(BaseClient):
) )
) )
) )
except FloodWait as e:
log.warning("Sleeping for {}s".format(e.x))
await asyncio.sleep(e.x)
else:
break
media = types.InputMediaDocument( media = types.InputMediaDocument(
id=types.InputDocument( id=types.InputDocument(
@ -184,8 +170,6 @@ class SendMediaGroup(BaseClient):
) )
) )
while True:
try:
r = await self.send( r = await self.send(
functions.messages.SendMultiMedia( functions.messages.SendMultiMedia(
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
@ -194,11 +178,6 @@ class SendMediaGroup(BaseClient):
reply_to_msg_id=reply_to_message_id 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 utils.parse_messages( return await utils.parse_messages(
self, self,

View File

@ -50,13 +50,13 @@ class UpdateProfile(BaseClient):
.. code-block:: python .. code-block:: python
# Update your first name only # Update your first name only
app.update_bio(first_name="Pyrogram") app.update_profile(first_name="Pyrogram")
# Update first name and bio # Update first name and bio
app.update_bio(first_name="Pyrogram", bio="https://docs.pyrogram.org/") app.update_profile(first_name="Pyrogram", bio="https://docs.pyrogram.org/")
# Remove the last name # Remove the last name
app.update_bio(last_name="") app.update_profile(last_name="")
""" """
return bool( return bool(