From a3c3d5a740fa9840f44614bd4d397a9f2b70ce9c Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Thu, 18 Jan 2018 14:19:18 +0100 Subject: [PATCH 1/4] Update to v0.4.0 --- pyrogram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 4e38ddce..d98ff762 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -18,7 +18,7 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès " __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" -__version__ = "0.3.3" +__version__ = "0.4.0" from .api.errors import Error from .client import ChatAction From ea35fa24801e6767c6fd37e4221abb5abafdbbc9 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Fri, 19 Jan 2018 15:49:17 +0100 Subject: [PATCH 2/4] Update to Layer 75 --- compiler/api/source/main_api.tl | 32 ++++++++++++++++---------------- pyrogram/client/client.py | 17 ++++++++++------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/compiler/api/source/main_api.tl b/compiler/api/source/main_api.tl index ceb86ff7..08607100 100644 --- a/compiler/api/source/main_api.tl +++ b/compiler/api/source/main_api.tl @@ -33,16 +33,16 @@ inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile; inputMediaEmpty#9664f57f = InputMedia; -inputMediaUploadedPhoto#2f37e231 flags:# file:InputFile caption:string stickers:flags.0?Vector ttl_seconds:flags.1?int = InputMedia; -inputMediaPhoto#81fa373a flags:# id:InputPhoto caption:string ttl_seconds:flags.0?int = InputMedia; +inputMediaUploadedPhoto#1e287d04 flags:# file:InputFile stickers:flags.0?Vector ttl_seconds:flags.1?int = InputMedia; +inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia; inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia; inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia; -inputMediaUploadedDocument#e39621fd flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector caption:string stickers:flags.0?Vector ttl_seconds:flags.1?int = InputMedia; -inputMediaDocument#5acb668e flags:# id:InputDocument caption:string ttl_seconds:flags.0?int = InputMedia; +inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector stickers:flags.0?Vector ttl_seconds:flags.1?int = InputMedia; +inputMediaDocument#23ab23d2 flags:# id:InputDocument ttl_seconds:flags.0?int = InputMedia; inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia; inputMediaGifExternal#4843b0fd url:string q:string = InputMedia; -inputMediaPhotoExternal#922aec1 flags:# url:string caption:string ttl_seconds:flags.0?int = InputMedia; -inputMediaDocumentExternal#b6f74335 flags:# url:string caption:string ttl_seconds:flags.0?int = InputMedia; +inputMediaPhotoExternal#e5bbfe1a flags:# url:string ttl_seconds:flags.0?int = InputMedia; +inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia; inputMediaGame#d33f43f3 id:InputGame = InputMedia; inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia; inputMediaGeoLive#7b1a118f geo_point:InputGeoPoint period:int = InputMedia; @@ -118,11 +118,11 @@ message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:fl messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message; messageMediaEmpty#3ded6320 = MessageMedia; -messageMediaPhoto#b5223b0f flags:# photo:flags.0?Photo caption:flags.1?string ttl_seconds:flags.2?int = MessageMedia; +messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia; messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia; messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia; messageMediaUnsupported#9f84f49e = MessageMedia; -messageMediaDocument#7c4414d3 flags:# document:flags.0?Document caption:flags.1?string ttl_seconds:flags.2?int = MessageMedia; +messageMediaDocument#9cb070d7 flags:# document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia; messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia; messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia; messageMediaGame#fdb19008 game:Game = MessageMedia; @@ -563,7 +563,7 @@ messages.foundGifs#450a1c0a next_offset:int results:Vector = messages. messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs; messages.savedGifs#2e0709a5 hash:int gifs:Vector = messages.SavedGifs; -inputBotInlineMessageMediaAuto#292fed13 flags:# caption:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; +inputBotInlineMessageMediaAuto#3380c786 flags:# message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageMediaGeo#c1b15d65 flags:# geo_point:InputGeoPoint period:int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageMediaVenue#aaafadc8 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; @@ -575,7 +575,7 @@ inputBotInlineResultPhoto#a8d864a7 id:string type:string photo:InputPhoto send_m inputBotInlineResultDocument#fff8fdc4 flags:# id:string type:string title:flags.1?string description:flags.2?string document:InputDocument send_message:InputBotInlineMessage = InputBotInlineResult; inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:InputBotInlineMessage = InputBotInlineResult; -botInlineMessageMediaAuto#a74b15b flags:# caption:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage; +botInlineMessageMediaAuto#764cf810 flags:# message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = BotInlineMessage; botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = BotInlineMessage; botInlineMessageMediaGeo#b722de65 flags:# geo:GeoPoint period:int reply_markup:flags.2?ReplyMarkup = BotInlineMessage; botInlineMessageMediaVenue#4366232e flags:# geo:GeoPoint title:string address:string provider:string venue_id:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage; @@ -813,7 +813,7 @@ recentMeUrlStickerSet#bc0a57dc url:string set:StickerSetCovered = RecentMeUrl; help.recentMeUrls#e0310d7 urls:Vector chats:Vector users:Vector = help.RecentMeUrls; -inputSingleMedia#5eaa7809 media:InputMedia random_id:long = InputSingleMedia; +inputSingleMedia#31bc3d25 media:InputMedia flags:# random_id:long message:string entities:flags.0?Vector = InputSingleMedia; ---functions--- @@ -841,8 +841,8 @@ auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentC auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool; auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector = Bool; -account.registerDevice#f75874d1 token_type:int token:string other_uids:Vector = Bool; -account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector = Bool; +account.registerDevice#637ea878 token_type:int token:string = Bool; +account.unregisterDevice#65c55b40 token_type:int token:string = Bool; account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool; account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings; account.resetNotifySettings#db7e1747 = Bool; @@ -898,7 +898,7 @@ messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector = me messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool; messages.sendMessage#fa88427a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Updates; -messages.sendMedia#c8f16791 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates; +messages.sendMedia#b8d1262b flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Updates; messages.forwardMessages#708e0195 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true grouped:flags.9?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.hideReportSpam#a8f1709b peer:InputPeer = Bool; @@ -924,7 +924,7 @@ messages.receivedQueue#55a5bb66 max_qts:int = Vector; messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool; messages.readMessageContents#36a73f77 id:Vector = messages.AffectedMessages; messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers; -messages.getWebPagePreview#25223e24 message:string = MessageMedia; +messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector = MessageMedia; messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite; messages.checkChatInvite#3eadb1bb hash:string = ChatInvite; messages.importChatInvite#6c50051c hash:string = Updates; @@ -1074,4 +1074,4 @@ langpack.getStrings#2e1ee318 lang_code:string keys:Vector = Vector; -// LAYER 74 \ No newline at end of file +// LAYER 75 \ No newline at end of file diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index ba7470a4..14f764cc 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -602,9 +602,9 @@ class Client: peer=self.resolve_peer(chat_id), media=types.InputMediaUploadedPhoto( file=file, - caption=caption, ttl_seconds=ttl_seconds ), + **self.markdown.parse(caption), silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -673,7 +673,6 @@ class Client: media=types.InputMediaUploadedDocument( mime_type=mimetypes.types_map.get("." + audio.split(".")[-1], "audio/mpeg"), file=file, - caption=caption, attributes=[ types.DocumentAttributeAudio( duration=duration, @@ -683,6 +682,7 @@ class Client: types.DocumentAttributeFilename(os.path.basename(audio)) ] ), + **self.markdown.parse(caption), silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -737,11 +737,11 @@ class Client: media=types.InputMediaUploadedDocument( mime_type=mimetypes.types_map.get("." + document.split(".")[-1], "text/plain"), file=file, - caption=caption, attributes=[ types.DocumentAttributeFilename(os.path.basename(document)) ] ), + **self.markdown.parse(caption), silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -808,7 +808,6 @@ class Client: media=types.InputMediaUploadedDocument( mime_type=mimetypes.types_map[".mp4"], file=file, - caption=caption, attributes=[ types.DocumentAttributeVideo( duration=duration, @@ -817,6 +816,7 @@ class Client: ) ] ), + **self.markdown.parse(caption), silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -875,7 +875,6 @@ class Client: media=types.InputMediaUploadedDocument( mime_type=mimetypes.types_map.get("." + voice.split(".")[-1], "audio/mpeg"), file=file, - caption=caption, attributes=[ types.DocumentAttributeAudio( voice=True, @@ -883,6 +882,7 @@ class Client: ) ] ), + **self.markdown.parse(caption), silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -941,7 +941,6 @@ class Client: media=types.InputMediaUploadedDocument( mime_type=mimetypes.types_map[".mp4"], file=file, - caption="", attributes=[ types.DocumentAttributeVideo( round_message=True, @@ -951,6 +950,7 @@ class Client: ) ] ), + message="", silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -1003,6 +1003,7 @@ class Client: longitude ) ), + message="", silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -1068,6 +1069,7 @@ class Client: venue_id=foursquare_id, venue_type="" ), + message="", silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -1119,6 +1121,7 @@ class Client: first_name, last_name ), + message="", silent=disable_notification or None, reply_to_msg_id=reply_to_message_id, random_id=self.rnd_id() @@ -1244,7 +1247,7 @@ class Client: functions.messages.EditMessage( peer=self.resolve_peer(chat_id), id=message_id, - message=caption + **self.markdown.parse(caption) ) ) From 8c88a69d812a472613db5811da32430a0e65df37 Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 20 Jan 2018 14:45:13 +0100 Subject: [PATCH 3/4] Remove redundant escape characters --- pyrogram/client/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 14f764cc..04bf90fa 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -72,7 +72,7 @@ class Client: created sessions are loaded. """ - INVITE_LINK_RE = re.compile(r"^(?:https?:\/\/)?t\.me\/joinchat\/(.+)$") + INVITE_LINK_RE = re.compile(r"^(?:https?://)?t\.me/joinchat/(.+)$") DIALOGS_AT_ONCE = 100 def __init__(self, session_name: str, test_mode: bool = False): From 8cc0fe14daebdcf8098b8bec7b8f5f5d247d0fda Mon Sep 17 00:00:00 2001 From: Dan <14043624+delivrance@users.noreply.github.com> Date: Sat, 20 Jan 2018 15:46:17 +0100 Subject: [PATCH 4/4] Add Cloud Password (two-step verification) support --- pyrogram/client/client.py | 112 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/pyrogram/client/client.py b/pyrogram/client/client.py index 04bf90fa..73bf2a20 100644 --- a/pyrogram/client/client.py +++ b/pyrogram/client/client.py @@ -1640,3 +1640,115 @@ class Client: return channel_full.exported_invite.link else: raise ChatAdminRequired + + def enable_cloud_password(self, password: str, hint: str = "", email: str = ""): + """Use this method to enable two-step verification (Cloud Password) + + This password will be asked when you log in on a new device in addition to the SMS code. + + Args: + password (:obj:`str`): + Your password. + + hint (:obj:`str`, optional): + A password hint. + + email (:obj:`str`, optional): + Recovery e-mail. + + Returns: + True on success, False otherwise. + + Raises: + :class:`pyrogram.Error` + """ + r = self.send(functions.account.GetPassword()) + + if isinstance(r, types.account.NoPassword): + salt = r.new_salt + os.urandom(8) + password_hash = sha256(salt + password.encode() + salt).digest() + + return self.send( + functions.account.UpdatePasswordSettings( + current_password_hash=salt, + new_settings=types.account.PasswordInputSettings( + new_salt=salt, + new_password_hash=password_hash, + hint=hint, + email=email + ) + ) + ) + else: + return False + + def change_cloud_password(self, current_password: str, new_password: str, new_hint: str = ""): + """Use this method to change your two-step verification password (Cloud Password) + + Args: + current_password (:obj:`str`): + Your current password. + + new_password (:obj:`str`): + Your new password. + + new_hint (:obj:`str`, optional): + A new password hint. + + Returns: + True on success, False otherwise. + + Raises: + :class:`pyrogram.Error` + """ + r = self.send(functions.account.GetPassword()) + + if isinstance(r, types.account.Password): + current_password_hash = sha256(r.current_salt + current_password.encode() + r.current_salt).digest() + + new_salt = r.new_salt + os.urandom(8) + new_password_hash = sha256(new_salt + new_password.encode() + new_salt).digest() + + return self.send( + functions.account.UpdatePasswordSettings( + current_password_hash=current_password_hash, + new_settings=types.account.PasswordInputSettings( + new_salt=new_salt, + new_password_hash=new_password_hash, + hint=new_hint + ) + ) + ) + else: + return False + + def remove_cloud_password(self, password: str): + """Use this method to turn off your two-step verification password (Cloud Password) + + Args: + password (:obj:`str`): + Your current password. + + Returns: + True on success, False otherwise. + + Raises: + :class:`pyrogram.Error` + """ + r = self.send(functions.account.GetPassword()) + + if isinstance(r, types.account.Password): + password_hash = sha256(r.current_salt + password.encode() + r.current_salt).digest() + + return self.send( + functions.account.UpdatePasswordSettings( + current_password_hash=password_hash, + new_settings=types.account.PasswordInputSettings( + new_salt=b"", + new_password_hash=b"", + hint="" + ) + ) + ) + else: + return False