2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-09-08 18:25:16 +00:00

Merge branch 'develop' into session_storage

# Conflicts:
#	pyrogram/client/client.py
#	pyrogram/client/ext/base_client.py
#	pyrogram/client/ext/syncer.py
#	pyrogram/client/style/html.py
#	pyrogram/client/style/markdown.py
This commit is contained in:
bakatrouble
2019-04-14 21:49:45 +03:00
231 changed files with 7200 additions and 1929 deletions

View File

@@ -39,7 +39,11 @@ from typing import Union, List, Type
from pyrogram.api import functions, types
from pyrogram.api.core import Object
from pyrogram.api.errors import (
from pyrogram.client.handlers import DisconnectHandler
from pyrogram.client.handlers.handler import Handler
from pyrogram.client.methods.password.utils import compute_check
from pyrogram.crypto import AES
from pyrogram.errors import (
PhoneMigrate, NetworkMigrate, PhoneNumberInvalid,
PhoneNumberUnoccupied, PhoneCodeInvalid, PhoneCodeHashEmpty,
PhoneCodeExpired, PhoneCodeEmpty, SessionPasswordNeeded,
@@ -47,13 +51,8 @@ from pyrogram.api.errors import (
VolumeLocNotFound, UserMigrate, FileIdInvalid, ChannelPrivate, PhoneNumberOccupied,
PasswordRecoveryNa, PasswordEmpty
)
from pyrogram.client.handlers import DisconnectHandler
from pyrogram.client.handlers.handler import Handler
from pyrogram.client.methods.password.utils import compute_check
from pyrogram.crypto import AES
from pyrogram.session import Auth, Session
from .dispatcher import Dispatcher
from .ext import utils, Syncer, BaseClient
from .ext import utils, Syncer, BaseClient, Dispatcher
from .methods import Methods
from .session_storage import (
SessionDoesNotExist, SessionStorage, MemorySessionStorage, JsonSessionStorage,
@@ -70,9 +69,10 @@ class Client(Methods, BaseClient):
Args:
session_name (``str``):
Name to uniquely identify a session of either a User or a Bot, e.g.: "my_main_account".
You still can use bot token here, but it will be deprecated in next release.
Note: as long as a valid User session file exists, Pyrogram won't ask you again to input your phone number.
Name to uniquely identify a session of either a User or a Bot, e.g.: "my_account". This name will be used
to save a file to disk that stores details needed for reconnecting without asking again for credentials.
Note for bots: You can pass a bot token here, but this usage will be deprecated in next releases.
Use *bot_token* instead.
api_id (``int``, *optional*):
The *api_id* part of your Telegram API Key, as integer. E.g.: 12345
@@ -182,31 +182,35 @@ class Client(Methods, BaseClient):
Defaults to False (normal session).
"""
def __init__(self,
session_name: Union[str, SessionStorage],
api_id: Union[int, str] = None,
api_hash: str = None,
app_version: str = None,
device_model: str = None,
system_version: str = None,
lang_code: str = None,
ipv6: bool = False,
proxy: dict = None,
test_mode: bool = False,
phone_number: str = None,
phone_code: Union[str, callable] = None,
password: str = None,
recovery_code: callable = None,
force_sms: bool = False,
bot_token: str = None,
first_name: str = None,
last_name: str = None,
workers: int = BaseClient.WORKERS,
workdir: str = BaseClient.WORKDIR,
config_file: str = BaseClient.CONFIG_FILE,
plugins: dict = None,
no_updates: bool = None,
takeout: bool = None):
terms_of_service_displayed = False
def __init__(
self,
session_name: str,
api_id: Union[int, str] = None,
api_hash: str = None,
app_version: str = None,
device_model: str = None,
system_version: str = None,
lang_code: str = None,
ipv6: bool = False,
proxy: dict = None,
test_mode: bool = False,
phone_number: str = None,
phone_code: Union[str, callable] = None,
password: str = None,
recovery_code: callable = None,
force_sms: bool = False,
bot_token: str = None,
first_name: str = None,
last_name: str = None,
workers: int = BaseClient.WORKERS,
workdir: str = BaseClient.WORKDIR,
config_file: str = BaseClient.CONFIG_FILE,
plugins: dict = None,
no_updates: bool = None,
takeout: bool = None
):
if isinstance(session_name, str):
if session_name == ':memory:':
@@ -222,6 +226,8 @@ class Client(Methods, BaseClient):
super().__init__(session_storage)
super().__init__(session_storage)
self.session_name = str(session_name) # TODO: build correct session name
self.api_id = int(api_id) if api_id else None
self.api_hash = api_hash
@@ -277,7 +283,7 @@ class Client(Methods, BaseClient):
Requires no parameters.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
:class:`RPCError <pyrogram.RPCError>` in case of a Telegram RPC error.
``ConnectionError`` in case you try to start an already started Client.
"""
if self.is_started:
@@ -288,10 +294,10 @@ class Client(Methods, BaseClient):
self.session_storage.is_bot = True
self.bot_token = self.session_storage._session_name
self.session_storage._session_name = self.session_storage._session_name.split(":")[0]
warnings.warn('\nYou are using a bot token as session name.\n'
'It will be deprecated in next update, please use session file name to load '
'existing sessions and bot_token argument to create new sessions.',
DeprecationWarning, stacklevel=2)
warnings.warn('\nWARNING: You are using a bot token as session name!\n'
'This usage will be deprecated soon. Please use a session file name to load '
'an existing session and the bot_token argument to create new sessions.\n'
'More info: https://docs.pyrogram.ml/start/Setup#bot-authorization\n')
self.load_config()
self.load_session()
@@ -309,6 +315,7 @@ class Client(Methods, BaseClient):
try:
if self.session_storage.user_id is None:
if self.bot_token is None:
self.is_bot = False
self.authorize_user()
else:
self.session_storage.is_bot = True
@@ -446,7 +453,7 @@ class Client(Methods, BaseClient):
Requires no parameters.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
:class:`RPCError <pyrogram.RPCError>` in case of a Telegram RPC error.
"""
self.start()
self.idle()
@@ -558,9 +565,10 @@ class Client(Methods, BaseClient):
try:
r = self.send(
functions.auth.SendCode(
self.phone_number,
self.api_id,
self.api_hash
phone_number=self.phone_number,
api_id=self.api_id,
api_hash=self.api_hash,
settings=types.CodeSettings()
)
)
except (PhoneMigrate, NetworkMigrate) as e:
@@ -604,8 +612,9 @@ class Client(Methods, BaseClient):
phone_code_hash = r.phone_code_hash
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")
Client.terms_of_service_displayed = True
if self.force_sms:
self.send(
@@ -640,9 +649,9 @@ class Client(Methods, BaseClient):
try:
r = self.send(
functions.auth.SignIn(
self.phone_number,
phone_code_hash,
self.phone_code
phone_number=self.phone_number,
phone_code_hash=phone_code_hash,
phone_code=self.phone_code
)
)
except PhoneNumberUnoccupied:
@@ -653,11 +662,11 @@ class Client(Methods, BaseClient):
try:
r = self.send(
functions.auth.SignUp(
self.phone_number,
phone_code_hash,
self.phone_code,
self.first_name,
self.last_name
phone_number=self.phone_number,
phone_code_hash=phone_code_hash,
phone_code=self.phone_code,
first_name=self.first_name,
last_name=self.last_name
)
)
except PhoneNumberOccupied:
@@ -751,7 +760,11 @@ class Client(Methods, BaseClient):
break
if terms_of_service:
assert self.send(functions.help.AcceptTermsOfService(terms_of_service.id))
assert self.send(
functions.help.AcceptTermsOfService(
id=terms_of_service.id
)
)
self.password = None
self.session_storage.user_id = r.user.id
@@ -992,16 +1005,16 @@ class Client(Methods, BaseClient):
Timeout in seconds.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
:class:`RPCError <pyrogram.RPCError>` in case of a Telegram RPC error.
"""
if not self.is_started:
raise ConnectionError("Client has not been started")
if self.no_updates:
data = functions.InvokeWithoutUpdates(data)
data = functions.InvokeWithoutUpdates(query=data)
if self.takeout_id:
data = functions.InvokeWithTakeout(self.takeout_id, data)
data = functions.InvokeWithTakeout(takeout_id=self.takeout_id, query=data)
r = self.session.send(data, retries, timeout)
@@ -1118,7 +1131,7 @@ class Client(Methods, BaseClient):
try:
module = import_module(module_path)
except ModuleNotFoundError:
except ImportError:
log.warning('[LOAD] Ignoring non-existent module "{}"'.format(module_path))
continue
@@ -1154,7 +1167,7 @@ class Client(Methods, BaseClient):
try:
module = import_module(module_path)
except ModuleNotFoundError:
except ImportError:
log.warning('[UNLOAD] Ignoring non-existent module "{}"'.format(module_path))
continue
@@ -1241,7 +1254,7 @@ class Client(Methods, BaseClient):
On success, the resolved peer id is returned in form of an InputPeer object.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
:class:`RPCError <pyrogram.RPCError>` in case of a Telegram RPC error.
``KeyError`` in case the peer doesn't exist in the internal database.
"""
try:
@@ -1276,7 +1289,7 @@ class Client(Methods, BaseClient):
self.fetch_peers(
self.send(
functions.users.GetUsers(
id=[types.InputUser(peer_id, 0)]
id=[types.InputUser(user_id=peer_id, access_hash=0)]
)
)
)
@@ -1284,7 +1297,7 @@ class Client(Methods, BaseClient):
if str(peer_id).startswith("-100"):
self.send(
functions.channels.GetChannels(
id=[types.InputChannel(int(str(peer_id)[4:]), 0)]
id=[types.InputChannel(channel_id=int(str(peer_id)[4:]), access_hash=0)]
)
)
else:
@@ -1348,7 +1361,7 @@ class Client(Methods, BaseClient):
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.
:class:`RPCError <pyrogram.RPCError>` in case of a Telegram RPC error.
"""
part_size = 512 * 1024
file_size = os.path.getsize(path)
@@ -1591,8 +1604,8 @@ class Client(Methods, BaseClient):
hashes = session.send(
functions.upload.GetCdnFileHashes(
r.file_token,
offset
file_token=r.file_token,
offset=offset
)
)