Merge develop -> asyncio-dev

This commit is contained in:
Dan 2020-07-29 22:40:59 +02:00
commit 6608a8d1dc
22 changed files with 145 additions and 68 deletions

View File

@ -40,10 +40,9 @@ inputMediaUploadedPhoto#1e287d04 flags:# file:InputFile stickers:flags.0?Vector<
inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia; inputMediaPhoto#b3ba0635 flags:# id:InputPhoto ttl_seconds:flags.0?int = InputMedia;
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia; inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia; inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia;
inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia; inputMediaUploadedDocument#5b38c6c1 flags:# nosound_video:flags.3?true force_file:flags.4?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector<DocumentAttribute> stickers:flags.0?Vector<InputDocument> ttl_seconds:flags.1?int = InputMedia;
inputMediaDocument#23ab23d2 flags:# id:InputDocument ttl_seconds:flags.0?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; 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#e5bbfe1a flags:# url: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; inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
inputMediaGame#d33f43f3 id:InputGame = InputMedia; inputMediaGame#d33f43f3 id:InputGame = InputMedia;
@ -53,7 +52,7 @@ inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector<bytes> s
inputMediaDice#e66fbf7b emoticon:string = InputMedia; inputMediaDice#e66fbf7b emoticon:string = InputMedia;
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto; inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
inputChatUploadedPhoto#927c55b4 file:InputFile = InputChatPhoto; inputChatUploadedPhoto#c642724e flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = InputChatPhoto;
inputChatPhoto#8953ad37 id:InputPhoto = InputChatPhoto; inputChatPhoto#8953ad37 id:InputPhoto = InputChatPhoto;
inputGeoPointEmpty#e4c123d6 = InputGeoPoint; inputGeoPointEmpty#e4c123d6 = InputGeoPoint;
@ -91,7 +90,7 @@ userEmpty#200250ba id:int = User;
user#938458c1 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User; user#938458c1 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto; userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#ecd75d8c photo_id:long photo_small:FileLocation photo_big:FileLocation dc_id:int = UserProfilePhoto; userProfilePhoto#69d3ab26 flags:# has_video:flags.0?true photo_id:long photo_small:FileLocation photo_big:FileLocation dc_id:int = UserProfilePhoto;
userStatusEmpty#9d05049 = UserStatus; userStatusEmpty#9d05049 = UserStatus;
userStatusOnline#edb93949 expires:int = UserStatus; userStatusOnline#edb93949 expires:int = UserStatus;
@ -117,7 +116,7 @@ chatParticipantsForbidden#fc900c2b flags:# chat_id:int self_participant:flags.0?
chatParticipants#3f460fed chat_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants; chatParticipants#3f460fed chat_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
chatPhotoEmpty#37c1011c = ChatPhoto; chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#475cdbd5 photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto; chatPhoto#d20b9f3c flags:# has_video:flags.0?true photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto;
messageEmpty#83e5de54 id:int = Message; messageEmpty#83e5de54 id:int = Message;
message#452c0e65 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message; message#452c0e65 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
@ -165,7 +164,7 @@ dialog#2c171f72 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer t
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
photoEmpty#2331b22d id:long = Photo; photoEmpty#2331b22d id:long = Photo;
photo#d07504a5 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> dc_id:int = Photo; photo#fb197a65 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> video_sizes:flags.1?Vector<VideoSize> dc_id:int = Photo;
photoSizeEmpty#e17e23c type:string = PhotoSize; photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize; photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
@ -191,7 +190,7 @@ inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags
peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings; peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings;
peerSettings#818426cd flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true = PeerSettings; peerSettings#733f2961 flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true geo_distance:flags.6?int = PeerSettings;
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper; wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
wallPaperNoFile#8af40b25 flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper; wallPaperNoFile#8af40b25 flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
@ -336,6 +335,7 @@ updateDialogFilter#26ffde7d flags:# id:int filter:flags.0?DialogFilter = Update;
updateDialogFilterOrder#a5d72105 order:Vector<int> = Update; updateDialogFilterOrder#a5d72105 order:Vector<int> = Update;
updateDialogFilters#3504914f = Update; updateDialogFilters#3504914f = Update;
updatePhoneCallSignalingData#2661bf09 phone_call_id:long data:bytes = Update; updatePhoneCallSignalingData#2661bf09 phone_call_id:long data:bytes = Update;
updateChannelParticipant#65d2b464 flags:# channel_id:int date:int user_id:int prev_participant:flags.0?ChannelParticipant new_participant:flags.1?ChannelParticipant qts:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -373,7 +373,7 @@ help.inviteText#18cb9f78 message:string = help.InviteText;
encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat; encryptedChatEmpty#ab7ec0a0 id:int = EncryptedChat;
encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat; encryptedChatWaiting#3bf703dc id:int access_hash:long date:int admin_id:int participant_id:int = EncryptedChat;
encryptedChatRequested#c878527e id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat; encryptedChatRequested#62718a82 flags:# folder_id:flags.0?int id:int access_hash:long date:int admin_id:int participant_id:int g_a:bytes = EncryptedChat;
encryptedChat#fa56ce36 id:int access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long = EncryptedChat; encryptedChat#fa56ce36 id:int access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long = EncryptedChat;
encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat; encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat;
@ -507,6 +507,7 @@ chatInviteExported#fc2e05bc link:string = ExportedChatInvite;
chatInviteAlready#5a686d7c chat:Chat = ChatInvite; chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector<User> = ChatInvite; chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector<User> = ChatInvite;
chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite;
inputStickerSetEmpty#ffb62b95 = InputStickerSet; inputStickerSetEmpty#ffb62b95 = InputStickerSet;
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet; inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
@ -597,11 +598,6 @@ channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector
help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService; help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService;
foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif;
foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif;
messages.foundGifs#450a1c0a next_offset:int results:Vector<FoundGif> = messages.FoundGifs;
messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs; messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs;
messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs; messages.savedGifs#2e0709a5 hash:int gifs:Vector<Document> = messages.SavedGifs;
@ -1119,7 +1115,17 @@ stats.broadcastStats#bdf78394 period:StatsDateRangeDays followers:StatsAbsValueA
help.promoDataEmpty#98f6ac75 expires:int = help.PromoData; help.promoDataEmpty#98f6ac75 expires:int = help.PromoData;
help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData; help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData;
videoSize#435bb987 type:string location:FileLocation w:int h:int size:int = VideoSize; videoSize#e831c556 flags:# type:string location:FileLocation w:int h:int size:int video_start_ts:flags.0?double = VideoSize;
statsGroupTopPoster#18f3d0f7 user_id:int messages:int avg_chars:int = StatsGroupTopPoster;
statsGroupTopAdmin#6014f412 user_id:int deleted:int kicked:int banned:int = StatsGroupTopAdmin;
statsGroupTopInviter#31962a4c user_id:int invitations:int = StatsGroupTopInviter;
stats.megagroupStats#ef7ff916 period:StatsDateRangeDays members:StatsAbsValueAndPrev messages:StatsAbsValueAndPrev viewers:StatsAbsValueAndPrev posters:StatsAbsValueAndPrev growth_graph:StatsGraph members_graph:StatsGraph new_members_by_source_graph:StatsGraph languages_graph:StatsGraph messages_graph:StatsGraph actions_graph:StatsGraph top_hours_graph:StatsGraph weekdays_graph:StatsGraph top_posters:Vector<StatsGroupTopPoster> top_admins:Vector<StatsGroupTopAdmin> top_inviters:Vector<StatsGroupTopInviter> users:Vector<User> = stats.MegagroupStats;
globalPrivacySettings#bea2f424 flags:# archive_and_mute_new_noncontact_peers:flags.0?Bool = GlobalPrivacySettings;
---functions--- ---functions---
@ -1215,6 +1221,8 @@ account.getThemes#285946f8 format:string hash:int = account.Themes;
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool; account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
account.getContentSettings#8b9b4dae = account.ContentSettings; account.getContentSettings#8b9b4dae = account.ContentSettings;
account.getMultiWallPapers#65ad71dc wallpapers:Vector<InputWallPaper> = Vector<WallPaper>; account.getMultiWallPapers#65ad71dc wallpapers:Vector<InputWallPaper> = Vector<WallPaper>;
account.getGlobalPrivacySettings#eb2b4cf6 = GlobalPrivacySettings;
account.setGlobalPrivacySettings#1edaaac2 settings:GlobalPrivacySettings = GlobalPrivacySettings;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>; users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull; users.getFullUser#ca30a5b1 id:InputUser = UserFull;
@ -1290,7 +1298,6 @@ messages.migrateChat#15a3b8e3 chat_id:int = Updates;
messages.searchGlobal#bf7225a4 flags:# folder_id:flags.0?int q:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; messages.searchGlobal#bf7225a4 flags:# folder_id:flags.0?int q:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector<long> = Bool; messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector<long> = Bool;
messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document; messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document;
messages.searchGifs#bf9a776b q:string offset:int = messages.FoundGifs;
messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs; messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool; messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults; messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
@ -1370,7 +1377,7 @@ updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:
updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference; updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference;
photos.updateProfilePhoto#f0bb5152 id:InputPhoto = UserProfilePhoto; photos.updateProfilePhoto#f0bb5152 id:InputPhoto = UserProfilePhoto;
photos.uploadProfilePhoto#4f32c098 file:InputFile = photos.Photo; photos.uploadProfilePhoto#89f30f69 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double = photos.Photo;
photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>; photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos; photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int = photos.Photos;
@ -1403,6 +1410,7 @@ help.getUserInfo#38a08d3 user_id:InputUser = help.UserInfo;
help.editUserInfo#66b91b70 user_id:InputUser message:string entities:Vector<MessageEntity> = help.UserInfo; help.editUserInfo#66b91b70 user_id:InputUser message:string entities:Vector<MessageEntity> = help.UserInfo;
help.getPromoData#c0977421 = help.PromoData; help.getPromoData#c0977421 = help.PromoData;
help.hidePromoData#1e251c95 peer:InputPeer = Bool; help.hidePromoData#1e251c95 peer:InputPeer = Bool;
help.dismissSuggestion#77fa99f suggestion:string = Bool;
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool; channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages; channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
@ -1479,5 +1487,6 @@ folders.deleteFolder#1c295881 folder_id:int = Updates;
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats; stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats;
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph; stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
// LAYER 114 // LAYER 116

View File

@ -145,3 +145,5 @@ BROADCAST_PUBLIC_VOTERS_FORBIDDEN Polls with public voters cannot be sent in cha
INPUT_FILTER_INVALID The filter is invalid for this query INPUT_FILTER_INVALID The filter is invalid for this query
EMOTICON_EMPTY The emoticon parameter is empty EMOTICON_EMPTY The emoticon parameter is empty
EMOTICON_INVALID The emoticon parameter is invalid EMOTICON_INVALID The emoticon parameter is invalid
VIDEO_FILE_INVALID The video file is invalid
PRIVACY_TOO_LONG Your privacy exception list has exceeded the maximum capacity
1 id message
145 INPUT_FILTER_INVALID The filter is invalid for this query
146 EMOTICON_EMPTY The emoticon parameter is empty
147 EMOTICON_INVALID The emoticon parameter is invalid
148 VIDEO_FILE_INVALID The video file is invalid
149 PRIVACY_TOO_LONG Your privacy exception list has exceeded the maximum capacity

View File

@ -30,7 +30,7 @@ Test Mode in Official Apps
You can also login yourself into test servers using official desktop apps, such as Webogram and TDesktop: You can also login yourself into test servers using official desktop apps, such as Webogram and TDesktop:
- **Webogram**: Login here: https://web.telegram.org/?test=1 - **Webogram**: Login here: https://web.telegram.org/?test=1
- **TDesktop**: Open settings and type ``testmode``. - **TDesktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server".
Test Numbers Test Numbers
------------ ------------

View File

@ -13,4 +13,4 @@ with app:
app.send_location("me", 51.500729, -0.124583) app.send_location("me", 51.500729, -0.124583)
# Send a sticker # Send a sticker
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") app.send_sticker("me", "CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")

View File

@ -1787,6 +1787,8 @@ class Client(Methods, BaseClient):
Raises: Raises:
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
""" """
if path is None:
return None
async def worker(session): async def worker(session):
while True: while True:

View File

@ -45,11 +45,12 @@ from .set_chat_description import SetChatDescription
from .set_chat_permissions import SetChatPermissions from .set_chat_permissions import SetChatPermissions
from .set_chat_photo import SetChatPhoto from .set_chat_photo import SetChatPhoto
from .set_chat_title import SetChatTitle from .set_chat_title import SetChatTitle
from .set_slow_mode import SetSlowMode
from .unarchive_chats import UnarchiveChats from .unarchive_chats import UnarchiveChats
from .unban_chat_member import UnbanChatMember from .unban_chat_member import UnbanChatMember
from .unpin_chat_message import UnpinChatMessage from .unpin_chat_message import UnpinChatMessage
from .update_chat_username import UpdateChatUsername from .update_chat_username import UpdateChatUsername
from .set_slow_mode import SetSlowMode
class Chats( class Chats(
GetChat, GetChat,

View File

@ -17,7 +17,7 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import os import os
from typing import Union from typing import Union, BinaryIO
from pyrogram.api import functions, types from pyrogram.api import functions, types
from ...ext import BaseClient, utils from ...ext import BaseClient, utils
@ -27,10 +27,15 @@ class SetChatPhoto(BaseClient):
async def set_chat_photo( async def set_chat_photo(
self, self,
chat_id: Union[int, str], chat_id: Union[int, str],
photo: str, *,
photo: Union[str, BinaryIO] = None,
video: Union[str, BinaryIO] = None,
file_ref: str = None file_ref: str = None
) -> bool: ) -> bool:
"""Set a new profile photo for the chat. """Set a new chat photo or video (H.264/MPEG-4 AVC video, max 5 seconds).
The ``photo`` and ``video`` arguments are mutually exclusive.
Pass either one as named argument (see examples below).
You must be an administrator in the chat for this to work and must have the appropriate admin rights. You must be an administrator in the chat for this to work and must have the appropriate admin rights.
@ -38,13 +43,19 @@ class SetChatPhoto(BaseClient):
chat_id (``int`` | ``str``): chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat. Unique identifier (int) or username (str) of the target chat.
photo (``str``): photo (``str`` | ``BinaryIO``, *optional*):
New chat photo. You can pass a :obj:`Photo` file_id or a file path to upload a new photo from your local New chat photo. You can pass a :obj:`Photo` file_id (in pair with a valid file_ref), a file path to
machine. upload a new photo from your local machine or a binary file-like object with its attribute ".name"
set for in-memory uploads.
video (``str`` | ``BinaryIO``, *optional*):
New chat video. You can pass a :obj:`Video` file_id (in pair with a valid file_ref), a file path to
upload a new video from your local machine or a binary file-like object with its attribute ".name"
set for in-memory uploads.
file_ref (``str``, *optional*): file_ref (``str``, *optional*):
A valid file reference obtained by a recently fetched media message. A valid file reference obtained by a recently fetched media message.
To be used in combination with a file id in case a file reference is needed. To be used in combination with a file_id in case a file reference is needed.
Returns: Returns:
``bool``: True on success. ``bool``: True on success.
@ -56,18 +67,34 @@ class SetChatPhoto(BaseClient):
.. code-block:: python .. code-block:: python
# Set chat photo using a local file # Set chat photo using a local file
app.set_chat_photo(chat_id, "photo.jpg") app.set_chat_photo(chat_id, photo="photo.jpg")
# Set chat photo using an exiting Photo file_id # Set chat photo using an exiting Photo file_id
app.set_chat_photo(chat_id, photo.file_id, photo.file_ref) app.set_chat_photo(chat_id, photo=photo.file_id, file_ref=photo.file_ref)
# Set chat video using a local file
app.set_chat_photo(chat_id, video="video.mp4")
# Set chat photo using an exiting Video file_id
app.set_chat_photo(chat_id, video=video.file_id, file_ref=video.file_ref)
""" """
peer = await self.resolve_peer(chat_id) peer = await self.resolve_peer(chat_id)
if os.path.isfile(photo): if isinstance(photo, str):
photo = types.InputChatUploadedPhoto(file=await self.save_file(photo)) if os.path.isfile(photo):
photo = types.InputChatUploadedPhoto(
file=await self.save_file(photo),
video=await self.save_file(video)
)
else:
photo = utils.get_input_media_from_file_id(photo, file_ref, 2)
photo = types.InputChatPhoto(id=photo.id)
else: else:
photo = utils.get_input_media_from_file_id(photo, file_ref, 2) photo = types.InputChatUploadedPhoto(
photo = types.InputChatPhoto(id=photo.id) file=await self.save_file(photo),
video=await self.save_file(video)
)
if isinstance(peer, types.InputPeerChat): if isinstance(peer, types.InputPeerChat):
await self.send( await self.send(

View File

@ -99,7 +99,7 @@ class DownloadMedia(BaseClient):
app.download_media(message) app.download_media(message)
# Download from file id # Download from file id
app.download_media("CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") app.download_media("CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")
# Keep track of the progress while downloading # Keep track of the progress while downloading
def progress(current, total): def progress(current, total):

View File

@ -36,7 +36,8 @@ class EditMessageMedia(BaseClient):
chat_id: Union[int, str], chat_id: Union[int, str],
message_id: int, message_id: int,
media: InputMedia, media: InputMedia,
reply_markup: "pyrogram.InlineKeyboardMarkup" = None reply_markup: "pyrogram.InlineKeyboardMarkup" = None,
file_name: str = None
) -> "pyrogram.Message": ) -> "pyrogram.Message":
"""Edit animation, audio, document, photo or video messages. """Edit animation, audio, document, photo or video messages.
@ -58,6 +59,10 @@ class EditMessageMedia(BaseClient):
reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
An InlineKeyboardMarkup object. An InlineKeyboardMarkup object.
file_name (``str``, *optional*):
File name of the media to be sent. Not applicable to photos.
Defaults to file's path basename.
Returns: Returns:
:obj:`Message`: On success, the edited message is returned. :obj:`Message`: On success, the edited message is returned.
@ -109,7 +114,7 @@ class EditMessageMedia(BaseClient):
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedDocument( media=types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(media.media) or "video/mp4", mime_type=self.guess_mime_type(media.media) or "video/mp4",
thumb=None if media.thumb is None else await self.save_file(media.thumb), thumb=await self.save_file(media.thumb),
file=await self.save_file(media.media), file=await self.save_file(media.media),
attributes=[ attributes=[
types.DocumentAttributeVideo( types.DocumentAttributeVideo(
@ -119,7 +124,7 @@ class EditMessageMedia(BaseClient):
h=media.height h=media.height
), ),
types.DocumentAttributeFilename( types.DocumentAttributeFilename(
file_name=os.path.basename(media.media) file_name=file_name or os.path.basename(media.media)
) )
] ]
) )
@ -146,7 +151,7 @@ class EditMessageMedia(BaseClient):
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedDocument( media=types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(media.media) or "audio/mpeg", mime_type=self.guess_mime_type(media.media) or "audio/mpeg",
thumb=None if media.thumb is None else await self.save_file(media.thumb), thumb=await self.save_file(media.thumb),
file=await self.save_file(media.media), file=await self.save_file(media.media),
attributes=[ attributes=[
types.DocumentAttributeAudio( types.DocumentAttributeAudio(
@ -155,7 +160,7 @@ class EditMessageMedia(BaseClient):
title=media.title title=media.title
), ),
types.DocumentAttributeFilename( types.DocumentAttributeFilename(
file_name=os.path.basename(media.media) file_name=file_name or os.path.basename(media.media)
) )
] ]
) )
@ -182,7 +187,7 @@ class EditMessageMedia(BaseClient):
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedDocument( media=types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(media.media) or "video/mp4", mime_type=self.guess_mime_type(media.media) or "video/mp4",
thumb=None if media.thumb is None else self.save_file(media.thumb), thumb=self.save_file(media.thumb),
file=await self.save_file(media.media), file=await self.save_file(media.media),
attributes=[ attributes=[
types.DocumentAttributeVideo( types.DocumentAttributeVideo(
@ -192,7 +197,7 @@ class EditMessageMedia(BaseClient):
h=media.height h=media.height
), ),
types.DocumentAttributeFilename( types.DocumentAttributeFilename(
file_name=os.path.basename(media.media) file_name=file_name or os.path.basename(media.media)
), ),
types.DocumentAttributeAnimated() types.DocumentAttributeAnimated()
] ]
@ -220,11 +225,11 @@ class EditMessageMedia(BaseClient):
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedDocument( media=types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(media.media) or "application/zip", mime_type=self.guess_mime_type(media.media) or "application/zip",
thumb=None if media.thumb is None else await self.save_file(media.thumb), thumb=await self.save_file(media.thumb),
file=await self.save_file(media.media), file=await self.save_file(media.media),
attributes=[ attributes=[
types.DocumentAttributeFilename( types.DocumentAttributeFilename(
file_name=os.path.basename(media.media) file_name=file_name or os.path.basename(media.media)
) )
] ]
) )

View File

@ -167,7 +167,7 @@ class SendAnimation(BaseClient):
try: try:
if isinstance(animation, str): if isinstance(animation, str):
if os.path.isfile(animation): if os.path.isfile(animation):
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(animation, progress=progress, progress_args=progress_args) file = await self.save_file(animation, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(animation) or "video/mp4", mime_type=self.guess_mime_type(animation) or "video/mp4",
@ -191,7 +191,7 @@ class SendAnimation(BaseClient):
else: else:
media = utils.get_input_media_from_file_id(animation, file_ref, 10) media = utils.get_input_media_from_file_id(animation, file_ref, 10)
else: else:
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(animation, progress=progress, progress_args=progress_args) file = await self.save_file(animation, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(animation.name) or "video/mp4", mime_type=self.guess_mime_type(animation.name) or "video/mp4",

View File

@ -37,7 +37,7 @@ class SendAudio(BaseClient):
duration: int = 0, duration: int = 0,
performer: str = None, performer: str = None,
title: str = None, title: str = None,
thumb: Union[str, BinaryIO] = None,file_name: str = None, thumb: Union[str, BinaryIO] = None, file_name: str = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None, schedule_date: int = None,
@ -166,7 +166,7 @@ class SendAudio(BaseClient):
try: try:
if isinstance(audio, str): if isinstance(audio, str):
if os.path.isfile(audio): if os.path.isfile(audio):
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(audio, progress=progress, progress_args=progress_args) file = await self.save_file(audio, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(audio) or "audio/mpeg", mime_type=self.guess_mime_type(audio) or "audio/mpeg",
@ -188,7 +188,7 @@ class SendAudio(BaseClient):
else: else:
media = utils.get_input_media_from_file_id(audio, file_ref, 9) media = utils.get_input_media_from_file_id(audio, file_ref, 9)
else: else:
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(audio, progress=progress, progress_args=progress_args) file = await self.save_file(audio, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(audio.name) or "audio/mpeg", mime_type=self.guess_mime_type(audio.name) or "audio/mpeg",

View File

@ -91,7 +91,7 @@ class SendCachedMedia(BaseClient):
Example: Example:
.. code-block:: python .. code-block:: python
app.send_cached_media("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") app.send_cached_media("me", "CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")
""" """
r = await self.send( r = await self.send(

View File

@ -47,7 +47,7 @@ class SendDice(BaseClient):
For a contact that exists in your Telegram address book you can use his phone number (str). For a contact that exists in your Telegram address book you can use his phone number (str).
emoji (``str``, *optional*): emoji (``str``, *optional*):
Emoji on which the dice throw animation is based. Currently, must be one of "🎲", "🎯" or "🏀". Emoji on which the dice throw animation is based. Currently, must be one of "🎲", "🎯", "🏀" or "⚽️".
Defaults to "🎲". Defaults to "🎲".
disable_notification (``bool``, *optional*): disable_notification (``bool``, *optional*):

View File

@ -147,11 +147,12 @@ class SendDocument(BaseClient):
try: try:
if isinstance(document, str): if isinstance(document, str):
if os.path.isfile(document): if os.path.isfile(document):
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(document, progress=progress, progress_args=progress_args) file = await self.save_file(document, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(document) or "application/zip", mime_type=self.guess_mime_type(document) or "application/zip",
file=file, file=file,
force_file=True,
thumb=thumb, thumb=thumb,
attributes=[ attributes=[
types.DocumentAttributeFilename(file_name=file_name or os.path.basename(document)) types.DocumentAttributeFilename(file_name=file_name or os.path.basename(document))
@ -164,7 +165,7 @@ class SendDocument(BaseClient):
else: else:
media = utils.get_input_media_from_file_id(document, file_ref, 5) media = utils.get_input_media_from_file_id(document, file_ref, 5)
else: else:
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(document, progress=progress, progress_args=progress_args) file = await self.save_file(document, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(document.name) or "application/zip", mime_type=self.guess_mime_type(document.name) or "application/zip",

View File

@ -119,7 +119,7 @@ class SendMediaGroup(BaseClient):
peer=await self.resolve_peer(chat_id), peer=await self.resolve_peer(chat_id),
media=types.InputMediaUploadedDocument( media=types.InputMediaUploadedDocument(
file=await self.save_file(i.media), file=await self.save_file(i.media),
thumb=None if i.thumb is None else self.save_file(i.thumb), thumb=self.save_file(i.thumb),
mime_type=self.guess_mime_type(i.media) or "video/mp4", mime_type=self.guess_mime_type(i.media) or "video/mp4",
attributes=[ attributes=[
types.DocumentAttributeVideo( types.DocumentAttributeVideo(

View File

@ -110,7 +110,7 @@ class SendSticker(BaseClient):
app.send_sticker("me", "sticker.webp") app.send_sticker("me", "sticker.webp")
# Send sticker using file_id # Send sticker using file_id
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") app.send_sticker("me", "CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")
""" """
file = None file = None

View File

@ -164,7 +164,7 @@ class SendVideo(BaseClient):
try: try:
if isinstance(video, str): if isinstance(video, str):
if os.path.isfile(video): if os.path.isfile(video):
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(video, progress=progress, progress_args=progress_args) file = await self.save_file(video, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(video) or "video/mp4", mime_type=self.guess_mime_type(video) or "video/mp4",
@ -187,7 +187,7 @@ class SendVideo(BaseClient):
else: else:
media = utils.get_input_media_from_file_id(video, file_ref, 4) media = utils.get_input_media_from_file_id(video, file_ref, 4)
else: else:
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(video, progress=progress, progress_args=progress_args) file = await self.save_file(video, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(video.name) or "video/mp4", mime_type=self.guess_mime_type(video.name) or "video/mp4",

View File

@ -131,7 +131,7 @@ class SendVideoNote(BaseClient):
try: try:
if isinstance(video_note, str): if isinstance(video_note, str):
if os.path.isfile(video_note): if os.path.isfile(video_note):
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(video_note, progress=progress, progress_args=progress_args) file = await self.save_file(video_note, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(video_note) or "video/mp4", mime_type=self.guess_mime_type(video_note) or "video/mp4",
@ -149,7 +149,7 @@ class SendVideoNote(BaseClient):
else: else:
media = utils.get_input_media_from_file_id(video_note, file_ref, 13) media = utils.get_input_media_from_file_id(video_note, file_ref, 13)
else: else:
thumb = None if thumb is None else await self.save_file(thumb) thumb = await self.save_file(thumb)
file = await self.save_file(video_note, progress=progress, progress_args=progress_args) file = await self.save_file(video_note, progress=progress, progress_args=progress_args)
media = types.InputMediaUploadedDocument( media = types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(video_note.name) or "video/mp4", mime_type=self.guess_mime_type(video_note.name) or "video/mp4",

View File

@ -42,6 +42,6 @@ class Users(
GetProfilePhotosCount, GetProfilePhotosCount,
IterProfilePhotos, IterProfilePhotos,
UnblockUser, UnblockUser,
UpdateProfile UpdateProfile,
): ):
pass pass

View File

@ -16,6 +16,8 @@
# 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/>.
from typing import Union, BinaryIO
from pyrogram.api import functions from pyrogram.api import functions
from ...ext import BaseClient from ...ext import BaseClient
@ -23,17 +25,30 @@ from ...ext import BaseClient
class SetProfilePhoto(BaseClient): class SetProfilePhoto(BaseClient):
async def set_profile_photo( async def set_profile_photo(
self, self,
photo: str *,
photo: Union[str, BinaryIO] = None,
video: Union[str, BinaryIO] = None
) -> bool: ) -> bool:
"""Set a new profile photo. """Set a new profile photo or video (H.264/MPEG-4 AVC video, max 5 seconds).
This method only works for Users. The ``photo`` and ``video`` arguments are mutually exclusive.
Bots profile photos must be set using BotFather. Pass either one as named argument (see examples below).
.. note::
This method only works for Users.
Bots profile photos must be set using BotFather.
Parameters: Parameters:
photo (``str``): photo (``str`` | ``BinaryIO``, *optional*):
Profile photo to set. Profile photo to set.
Pass a file path as string to upload a new photo that exists on your local machine. Pass a file path as string to upload a new photo that exists on your local machine or
pass a binary file-like object with its attribute ".name" set for in-memory uploads.
video (``str`` | ``BinaryIO``, *optional*):
Profile video to set.
Pass a file path as string to upload a new video that exists on your local machine or
pass a binary file-like object with its attribute ".name" set for in-memory uploads.
Returns: Returns:
``bool``: True on success. ``bool``: True on success.
@ -41,13 +56,18 @@ class SetProfilePhoto(BaseClient):
Example: Example:
.. code-block:: python .. code-block:: python
app.set_profile_photo("new_photo.jpg") # Set a new profile photo
app.set_profile_photo(photo="new_photo.jpg")
# Set a new profile video
app.set_profile_photo(video="new_video.mp4")
""" """
return bool( return bool(
await self.send( await self.send(
functions.photos.UploadProfilePhoto( functions.photos.UploadProfilePhoto(
file=await self.save_file(photo) file=await self.save_file(photo),
video=await self.save_file(video)
) )
) )
) )

View File

@ -251,6 +251,9 @@ class Message(Object, Update):
Messages sent from yourself to other chats are outgoing (*outgoing* is True). Messages sent from yourself to other chats are outgoing (*outgoing* is True).
An exception is made for your own personal chat; messages sent there will be incoming. An exception is made for your own personal chat; messages sent there will be incoming.
link (``str``):
A link to the message, only for groups and channels.
matches (List of regex Matches, *optional*): matches (List of regex Matches, *optional*):
A list containing all `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ that match A list containing all `Match Objects <https://docs.python.org/3/library/re.html#match-objects>`_ that match
the text of this message. Only applicable when using :obj:`Filters.regex <pyrogram.Filters.regex>`. the text of this message. Only applicable when using :obj:`Filters.regex <pyrogram.Filters.regex>`.
@ -670,6 +673,13 @@ class Message(Object, Update):
return parsed_message return parsed_message
@property
def link(self) -> str:
if self.chat.type in ("group", "supergroup", "channel") and self.chat.username:
return "https://t.me/{}/{}".format(self.chat.username, self.message_id)
else:
return "https://t.me/c/{}/{}".format(utils.get_channel_id(self.chat.id), self.message_id)
async def reply_text( async def reply_text(
self, self,
text: str, text: str,

View File

@ -82,7 +82,7 @@ class Photo(Object):
@staticmethod @staticmethod
def _parse(client, photo: types.Photo, ttl_seconds: int = None) -> "Photo": def _parse(client, photo: types.Photo, ttl_seconds: int = None) -> "Photo":
if isinstance(photo, types.Photo): if isinstance(photo, types.Photo):
big = photo.sizes[-1] big = list(filter(lambda p: isinstance(p, types.PhotoSize), photo.sizes))[-1]
return Photo( return Photo(
file_id=encode_file_id( file_id=encode_file_id(