mirror of
https://github.com/Mayuri-Chan/pyrofork.git
synced 2026-01-05 14:54:51 +00:00
Merge branch 'develop' into asyncio
# Conflicts: # pyrogram/client/client.py # pyrogram/client/methods/messages/send_message.py
This commit is contained in:
commit
48b50780ce
4 changed files with 119 additions and 69 deletions
|
|
@ -13,6 +13,7 @@ Utilities
|
||||||
|
|
||||||
start
|
start
|
||||||
stop
|
stop
|
||||||
|
restart
|
||||||
idle
|
idle
|
||||||
run
|
run
|
||||||
add_handler
|
add_handler
|
||||||
|
|
|
||||||
|
|
@ -113,18 +113,28 @@ class Client(Methods, BaseClient):
|
||||||
Only applicable for new sessions and will be ignored in case previously
|
Only applicable for new sessions and will be ignored in case previously
|
||||||
created sessions are loaded.
|
created sessions are loaded.
|
||||||
|
|
||||||
phone_number (``str``, *optional*):
|
phone_number (``str`` | ``callable``, *optional*):
|
||||||
Pass your phone number (with your Country Code prefix included) to avoid
|
Pass your phone number as string (with your Country Code prefix included) to avoid entering it manually.
|
||||||
entering it manually. Only applicable for new sessions.
|
Or pass a callback function which accepts no arguments and must return the correct phone number as string
|
||||||
|
(e.g., "391234567890").
|
||||||
|
Only applicable for new sessions.
|
||||||
|
|
||||||
phone_code (``str`` | ``callable``, *optional*):
|
phone_code (``str`` | ``callable``, *optional*):
|
||||||
Pass the phone code as string (for test numbers only), or pass a callback function which accepts
|
Pass the phone code as string (for test numbers only) to avoid entering it manually. Or pass a callback
|
||||||
a single positional argument *(phone_number)* and must return the correct phone code (e.g., "12345").
|
function which accepts a single positional argument *(phone_number)* and must return the correct phone code
|
||||||
|
as string (e.g., "12345").
|
||||||
Only applicable for new sessions.
|
Only applicable for new sessions.
|
||||||
|
|
||||||
password (``str``, *optional*):
|
password (``str``, *optional*):
|
||||||
Pass your Two-Step Verification password (if you have one) to avoid entering it
|
Pass your Two-Step Verification password as string (if you have one) to avoid entering it manually.
|
||||||
manually. Only applicable for new sessions.
|
Or pass a callback function which accepts a single positional argument *(password_hint)* and must return
|
||||||
|
the correct password as string (e.g., "password").
|
||||||
|
Only applicable for new sessions.
|
||||||
|
|
||||||
|
recovery_code (``callable``, *optional*):
|
||||||
|
Pass a callback function which accepts a single positional argument *(email_pattern)* and must return the
|
||||||
|
correct password recovery code as string (e.g., "987654").
|
||||||
|
Only applicable for new sessions.
|
||||||
|
|
||||||
force_sms (``str``, *optional*):
|
force_sms (``str``, *optional*):
|
||||||
Pass True to force Telegram sending the authorization code via SMS.
|
Pass True to force Telegram sending the authorization code via SMS.
|
||||||
|
|
@ -182,6 +192,7 @@ class Client(Methods, BaseClient):
|
||||||
phone_number: str = None,
|
phone_number: str = None,
|
||||||
phone_code: Union[str, callable] = None,
|
phone_code: Union[str, callable] = None,
|
||||||
password: str = None,
|
password: str = None,
|
||||||
|
recovery_code: callable = None,
|
||||||
force_sms: bool = False,
|
force_sms: bool = False,
|
||||||
first_name: str = None,
|
first_name: str = None,
|
||||||
last_name: str = None,
|
last_name: str = None,
|
||||||
|
|
@ -207,6 +218,7 @@ class Client(Methods, BaseClient):
|
||||||
self.phone_number = phone_number
|
self.phone_number = phone_number
|
||||||
self.phone_code = phone_code
|
self.phone_code = phone_code
|
||||||
self.password = password
|
self.password = password
|
||||||
|
self.recovery_code = recovery_code
|
||||||
self.force_sms = force_sms
|
self.force_sms = force_sms
|
||||||
self.first_name = first_name
|
self.first_name = first_name
|
||||||
self.last_name = last_name
|
self.last_name = last_name
|
||||||
|
|
@ -350,6 +362,16 @@ class Client(Methods, BaseClient):
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
async def restart(self):
|
||||||
|
"""Use this method to restart the Client.
|
||||||
|
Requires no parameters.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
``ConnectionError`` in case you try to restart a stopped Client.
|
||||||
|
"""
|
||||||
|
await self.stop()
|
||||||
|
await self.start()
|
||||||
|
|
||||||
async def idle(self, stop_signals: tuple = (SIGINT, SIGTERM, SIGABRT)):
|
async def idle(self, stop_signals: tuple = (SIGINT, SIGTERM, SIGABRT)):
|
||||||
"""Blocks the program execution until one of the signals are received,
|
"""Blocks the program execution until one of the signals are received,
|
||||||
then gently stop the Client by closing the underlying connection.
|
then gently stop the Client by closing the underlying connection.
|
||||||
|
|
@ -476,20 +498,25 @@ class Client(Methods, BaseClient):
|
||||||
async def authorize_user(self):
|
async def authorize_user(self):
|
||||||
phone_number_invalid_raises = self.phone_number is not None
|
phone_number_invalid_raises = self.phone_number is not None
|
||||||
phone_code_invalid_raises = self.phone_code is not None
|
phone_code_invalid_raises = self.phone_code is not None
|
||||||
password_hash_invalid_raises = self.password is not None
|
password_invalid_raises = self.password is not None
|
||||||
first_name_invalid_raises = self.first_name is not None
|
first_name_invalid_raises = self.first_name is not None
|
||||||
|
|
||||||
|
async def default_phone_number_callback():
|
||||||
|
while True:
|
||||||
|
phone_number = await ainput("Enter phone number: ")
|
||||||
|
confirm = await ainput("Is \"{}\" correct? (y/n): ".format(phone_number))
|
||||||
|
|
||||||
|
if confirm in ("y", "1"):
|
||||||
|
return phone_number
|
||||||
|
elif confirm in ("n", "2"):
|
||||||
|
continue
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if self.phone_number is None:
|
self.phone_number = (
|
||||||
self.phone_number = await ainput("Enter phone number: ")
|
await default_phone_number_callback() if self.phone_number is None
|
||||||
|
else str(await self.phone_number()) if callable(self.phone_number)
|
||||||
while True:
|
else str(self.phone_number)
|
||||||
confirm = await ainput("Is \"{}\" correct? (y/n): ".format(self.phone_number))
|
)
|
||||||
|
|
||||||
if confirm in ("y", "1"):
|
|
||||||
break
|
|
||||||
elif confirm in ("n", "2"):
|
|
||||||
self.phone_number = await ainput("Enter phone number: ")
|
|
||||||
|
|
||||||
self.phone_number = self.phone_number.strip("+")
|
self.phone_number = self.phone_number.strip("+")
|
||||||
|
|
||||||
|
|
@ -505,23 +532,21 @@ class Client(Methods, BaseClient):
|
||||||
await self.session.stop()
|
await self.session.stop()
|
||||||
|
|
||||||
self.dc_id = e.x
|
self.dc_id = e.x
|
||||||
self.auth_key = await Auth(self.dc_id, self.test_mode, self.ipv6, self._proxy).create()
|
|
||||||
|
self.auth_key = await Auth(
|
||||||
|
self.dc_id,
|
||||||
|
self.test_mode,
|
||||||
|
self.ipv6,
|
||||||
|
self._proxy
|
||||||
|
).create()
|
||||||
|
|
||||||
self.session = Session(
|
self.session = Session(
|
||||||
self,
|
self,
|
||||||
self.dc_id,
|
self.dc_id,
|
||||||
self.auth_key
|
self.auth_key
|
||||||
)
|
)
|
||||||
await self.session.start()
|
|
||||||
|
|
||||||
r = await self.send(
|
await self.session.start()
|
||||||
functions.auth.SendCode(
|
|
||||||
self.phone_number,
|
|
||||||
self.api_id,
|
|
||||||
self.api_hash
|
|
||||||
)
|
|
||||||
)
|
|
||||||
break
|
|
||||||
except (PhoneNumberInvalid, PhoneNumberBanned) as e:
|
except (PhoneNumberInvalid, PhoneNumberBanned) as e:
|
||||||
if phone_number_invalid_raises:
|
if phone_number_invalid_raises:
|
||||||
raise
|
raise
|
||||||
|
|
@ -536,6 +561,7 @@ class Client(Methods, BaseClient):
|
||||||
time.sleep(e.x)
|
time.sleep(e.x)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(e, exc_info=True)
|
log.error(e, exc_info=True)
|
||||||
|
raise
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -555,10 +581,23 @@ class Client(Methods, BaseClient):
|
||||||
)
|
)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
if not phone_registered:
|
||||||
|
self.first_name = (
|
||||||
|
await ainput("First name: ") if self.first_name is None
|
||||||
|
else str(await self.first_name()) if callable(self.first_name)
|
||||||
|
else str(self.first_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.last_name = (
|
||||||
|
await ainput("Last name: ") if self.last_name is None
|
||||||
|
else str(await self.last_name()) if callable(self.last_name)
|
||||||
|
else str(self.last_name)
|
||||||
|
)
|
||||||
|
|
||||||
self.phone_code = (
|
self.phone_code = (
|
||||||
await ainput("Enter phone code: ") if self.phone_code is None
|
await ainput("Enter phone code: ") if self.phone_code is None
|
||||||
else self.phone_code if type(self.phone_code) is str
|
else str(await self.phone_code(self.phone_number)) if callable(self.phone_code)
|
||||||
else str(self.phone_code(self.phone_number))
|
else str(self.phone_code)
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -576,9 +615,6 @@ class Client(Methods, BaseClient):
|
||||||
phone_registered = False
|
phone_registered = False
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
self.first_name = self.first_name if self.first_name is not None else input("First name: ")
|
|
||||||
self.last_name = self.last_name if self.last_name is not None else input("Last name: ")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = await self.send(
|
r = await self.send(
|
||||||
functions.auth.SignUp(
|
functions.auth.SignUp(
|
||||||
|
|
@ -608,61 +644,62 @@ class Client(Methods, BaseClient):
|
||||||
except SessionPasswordNeeded as e:
|
except SessionPasswordNeeded as e:
|
||||||
print(e.MESSAGE)
|
print(e.MESSAGE)
|
||||||
|
|
||||||
|
async def default_password_callback(password_hint: str) -> str:
|
||||||
|
print("Hint: {}".format(password_hint))
|
||||||
|
return await ainput("Enter password (empty to recover): ")
|
||||||
|
|
||||||
|
async def default_recovery_callback(email_pattern: str) -> str:
|
||||||
|
print("An e-mail containing the recovery code has been sent to {}".format(email_pattern))
|
||||||
|
return await ainput("Enter password recovery code: ")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
r = await self.send(functions.account.GetPassword())
|
r = await self.send(functions.account.GetPassword())
|
||||||
|
|
||||||
if self.password is None:
|
self.password = (
|
||||||
print("Hint: {}".format(r.hint))
|
await default_password_callback(r.hint) if self.password is None
|
||||||
self.password = await ainput("Enter password: ")
|
else str((await self.password(r.hint)) or "") if callable(self.password)
|
||||||
|
else str(self.password)
|
||||||
|
)
|
||||||
|
|
||||||
self.password = await ainput("Enter password (empty to recover): ")
|
if self.password == "":
|
||||||
|
r = await self.send(functions.auth.RequestPasswordRecovery())
|
||||||
|
|
||||||
if self.password == "":
|
self.recovery_code = (
|
||||||
r = await self.send(functions.auth.RequestPasswordRecovery())
|
await default_recovery_callback(r.email_pattern) if self.recovery_code is None
|
||||||
|
else str(await self.recovery_code(r.email_pattern)) if callable(self.recovery_code)
|
||||||
|
else str(self.recovery_code)
|
||||||
|
)
|
||||||
|
|
||||||
print("An e-mail containing the recovery code has been sent to {}".format(
|
r = await self.send(
|
||||||
r.email_pattern
|
functions.auth.RecoverPassword(
|
||||||
))
|
code=self.recovery_code
|
||||||
|
|
||||||
r = await self.send(
|
|
||||||
functions.auth.RecoverPassword(
|
|
||||||
code=await ainput("Enter password recovery code: ")
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
)
|
||||||
r = await self.send(
|
else:
|
||||||
functions.auth.CheckPassword(
|
r = await self.send(
|
||||||
password=compute_check(r, self.password)
|
functions.auth.CheckPassword(
|
||||||
)
|
password=compute_check(r, self.password)
|
||||||
)
|
)
|
||||||
except PasswordEmpty as e:
|
)
|
||||||
if password_hash_invalid_raises:
|
except (PasswordEmpty, PasswordRecoveryNa, PasswordHashInvalid) as e:
|
||||||
raise
|
if password_invalid_raises:
|
||||||
else:
|
|
||||||
print(e.MESSAGE)
|
|
||||||
self.password = None
|
|
||||||
except PasswordRecoveryNa as e:
|
|
||||||
if password_hash_invalid_raises:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
print(e.MESSAGE)
|
|
||||||
self.password = None
|
|
||||||
except PasswordHashInvalid as e:
|
|
||||||
if password_hash_invalid_raises:
|
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
print(e.MESSAGE)
|
print(e.MESSAGE)
|
||||||
self.password = None
|
self.password = None
|
||||||
|
self.recovery_code = None
|
||||||
except FloodWait as e:
|
except FloodWait as e:
|
||||||
if password_hash_invalid_raises:
|
if password_invalid_raises:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
print(e.MESSAGE.format(x=e.x))
|
print(e.MESSAGE.format(x=e.x))
|
||||||
time.sleep(e.x)
|
time.sleep(e.x)
|
||||||
self.password = None
|
self.password = None
|
||||||
|
self.recovery_code = None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(e, exc_info=True)
|
log.error(e, exc_info=True)
|
||||||
|
raise
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
break
|
break
|
||||||
|
|
@ -674,6 +711,7 @@ class Client(Methods, BaseClient):
|
||||||
time.sleep(e.x)
|
time.sleep(e.x)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(e, exc_info=True)
|
log.error(e, exc_info=True)
|
||||||
|
raise
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,9 @@ class Filters:
|
||||||
video = create("Video", lambda _, m: bool(m.video))
|
video = create("Video", lambda _, m: bool(m.video))
|
||||||
"""Filter messages that contain :obj:`Video <pyrogram.Video>` objects."""
|
"""Filter messages that contain :obj:`Video <pyrogram.Video>` objects."""
|
||||||
|
|
||||||
|
media_group = create("MediaGroup", lambda _, m: bool(m.media_group_id))
|
||||||
|
"""Filter messages containing photos or videos being part of an album."""
|
||||||
|
|
||||||
voice = create("Voice", lambda _, m: bool(m.voice))
|
voice = create("Voice", lambda _, m: bool(m.voice))
|
||||||
"""Filter messages that contain :obj:`Voice <pyrogram.Voice>` note objects."""
|
"""Filter messages that contain :obj:`Voice <pyrogram.Voice>` note objects."""
|
||||||
|
|
||||||
|
|
@ -287,7 +290,7 @@ class Filters:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def f(_, m):
|
def f(_, m):
|
||||||
m.matches = [i for i in _.p.finditer(m.text or "")]
|
m.matches = [i for i in _.p.finditer(m.text or m.caption or "")]
|
||||||
return bool(m.matches)
|
return bool(m.matches)
|
||||||
|
|
||||||
return create("Regex", f, p=re.compile(pattern, flags))
|
return create("Regex", f, p=re.compile(pattern, flags))
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,18 @@ class SendMessage(BaseClient):
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(r, types.UpdateShortSentMessage):
|
if isinstance(r, types.UpdateShortSentMessage):
|
||||||
|
peer = await self.resolve_peer(chat_id)
|
||||||
|
|
||||||
|
peer_id = (
|
||||||
|
peer.user_id
|
||||||
|
if isinstance(peer, types.InputPeerUser)
|
||||||
|
else -peer.chat_id
|
||||||
|
)
|
||||||
|
|
||||||
return pyrogram.Message(
|
return pyrogram.Message(
|
||||||
message_id=r.id,
|
message_id=r.id,
|
||||||
chat=pyrogram.Chat(
|
chat=pyrogram.Chat(
|
||||||
id=list((await self.resolve_peer(chat_id)).__dict__.values())[0],
|
id=peer_id,
|
||||||
type="private",
|
type="private",
|
||||||
client=self
|
client=self
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue