From 595eb119d731599ae8d93eb776c6bdc362dbd80b Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 29 Jan 2019 02:32:26 +0300 Subject: [PATCH] Repair file_reference in UpdateProfilePhoto. GitOrigin-RevId: 1edb98b56d2af603ac51d7ba6ee9e6cd08e12595 --- td/telegram/ContactsManager.cpp | 38 ++++++++++++++------ td/telegram/ContactsManager.h | 2 ++ td/telegram/files/FileManager.cpp | 59 ++++++++++++++++++++----------- td/telegram/files/FileManager.h | 7 ++++ 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 98483c4a..d1ea24a1 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -708,12 +708,17 @@ class UploadProfilePhotoQuery : public Td::ResultHandler { class UpdateProfilePhotoQuery : public Td::ResultHandler { Promise promise_; + FileId file_id_; + string file_reference_; public: explicit UpdateProfilePhotoQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(tl_object_ptr &&input_photo) { + void send(FileId file_id, tl_object_ptr &&input_photo) { + CHECK(input_photo != nullptr); + file_id_ = file_id; + file_reference_ = FileManager::extract_file_reference(input_photo); send_query(G()->net_query_creator().create( create_storer(telegram_api::photos_updateProfilePhoto(std::move(input_photo))))); } @@ -731,6 +736,16 @@ class UpdateProfilePhotoQuery : public Td::ResultHandler { } void on_error(uint64 id, Status status) override { + if (FileReferenceManager::is_file_reference_error(status)) { + if (file_id_.is_valid()) { + td->file_manager_->delete_file_reference(file_id_, file_reference_); + td->contacts_manager_->upload_profile_photo(file_id_, std::move(promise_)); + return; + } else { + LOG(ERROR) << "Receive file reference error, but file_id = " << file_id_; + } + } + promise_.set_error(std::move(status)); } }; @@ -3912,23 +3927,26 @@ void ContactsManager::set_profile_photo(const tl_object_ptr & CHECK(!file_view.is_encrypted()); if (file_view.has_remote_location() && !file_view.remote_location().is_web()) { td_->create_handler(std::move(promise)) - ->send(file_view.remote_location().as_input_photo()); + ->send(file_id, file_view.remote_location().as_input_photo()); return; } - auto upload_file_id = td_->file_manager_->dup_file_id(file_id); - CHECK(upload_file_id.is_valid()); - CHECK(uploaded_profile_photos_.find(upload_file_id) == uploaded_profile_photos_.end()); - uploaded_profile_photos_.emplace(upload_file_id, std::move(promise)); - LOG(INFO) << "Ask to upload profile photo " << upload_file_id; - td_->file_manager_->upload(upload_file_id, upload_profile_photo_callback_, 1, 0); + upload_profile_photo(td_->file_manager_->dup_file_id(file_id), std::move(promise)); +} + +void ContactsManager::upload_profile_photo(FileId file_id, Promise &&promise) { + CHECK(file_id.is_valid()); + CHECK(uploaded_profile_photos_.find(file_id) == uploaded_profile_photos_.end()); + uploaded_profile_photos_.emplace(file_id, std::move(promise)); + LOG(INFO) << "Ask to upload profile photo " << file_id; + td_->file_manager_->upload(file_id, upload_profile_photo_callback_, 1, 0); } void ContactsManager::delete_profile_photo(int64 profile_photo_id, Promise &&promise) { const User *u = get_user(get_my_id()); if (u != nullptr && u->photo.id == profile_photo_id) { td_->create_handler(std::move(promise)) - ->send(make_tl_object()); + ->send(FileId(), make_tl_object()); return; } @@ -9752,7 +9770,7 @@ void ContactsManager::on_upload_profile_photo(FileId file_id, tl_object_ptrcreate_handler(std::move(promise)) - ->send(file_view.remote_location().as_input_photo()); + ->send(file_id, file_view.remote_location().as_input_photo()); return; } CHECK(input_file != nullptr); diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index aa24d804..f5e854fb 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -283,6 +283,8 @@ class ContactsManager : public Actor { void delete_profile_photo(int64 profile_photo_id, Promise &&promise); + void upload_profile_photo(FileId file_id, Promise &&promise); + void set_name(const string &first_name, const string &last_name, Promise &&promise); void set_bio(const string &bio, Promise &&promise); diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index 3460dba7..9f88e24b 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -2476,27 +2476,46 @@ bool FileManager::extract_was_thumbnail_uploaded(const tl_object_ptr &input_media) { - if (input_media != nullptr) { - switch (input_media->get_id()) { - case telegram_api::inputMediaDocument::ID: { - const auto *id = static_cast(input_media.get())->id_.get(); - CHECK(id != nullptr); - if (id->get_id() == telegram_api::inputDocument::ID) { - return static_cast(id)->file_reference_.as_slice().str(); - } - break; - } - case telegram_api::inputMediaPhoto::ID: { - const auto *id = static_cast(input_media.get())->id_.get(); - CHECK(id != nullptr); - if (id->get_id() == telegram_api::inputPhoto::ID) { - return static_cast(id)->file_reference_.as_slice().str(); - } - break; - } - } + if (input_media == nullptr) { + return string(); } - return string(); + + switch (input_media->get_id()) { + case telegram_api::inputMediaDocument::ID: + return extract_file_reference(static_cast(input_media.get())->id_); + case telegram_api::inputMediaPhoto::ID: + return extract_file_reference(static_cast(input_media.get())->id_); + default: + return string(); + } +} + +string FileManager::extract_file_reference(const tl_object_ptr &input_document) { + if (input_document == nullptr || input_document->get_id() != telegram_api::inputDocument::ID) { + return string(); + } + + return static_cast(input_document.get())->file_reference_.as_slice().str(); +} + +string FileManager::extract_file_reference(const tl_object_ptr &input_photo) { + if (input_photo == nullptr || input_photo->get_id() != telegram_api::inputPhoto::ID) { + return string(); + } + + return static_cast(input_photo.get())->file_reference_.as_slice().str(); +} + +bool FileManager::extract_was_uploaded(const tl_object_ptr &input_chat_photo) { + return input_chat_photo != nullptr && input_chat_photo->get_id() == telegram_api::inputChatUploadedPhoto::ID; +} + +string FileManager::extract_file_reference(const tl_object_ptr &input_chat_photo) { + if (input_chat_photo == nullptr || input_chat_photo->get_id() != telegram_api::inputChatPhoto::ID) { + return string(); + } + + return extract_file_reference(static_cast(input_chat_photo.get())->id_); } FileId FileManager::next_file_id() { diff --git a/td/telegram/files/FileManager.h b/td/telegram/files/FileManager.h index 9c4a05aa..c5631f37 100644 --- a/td/telegram/files/FileManager.h +++ b/td/telegram/files/FileManager.h @@ -396,6 +396,13 @@ class FileManager : public FileLoadManager::Callback { static bool extract_was_thumbnail_uploaded(const tl_object_ptr &input_media); static string extract_file_reference(const tl_object_ptr &input_media); + static string extract_file_reference(const tl_object_ptr &input_document); + + static string extract_file_reference(const tl_object_ptr &input_photo); + + static bool extract_was_uploaded(const tl_object_ptr &input_chat_photo); + static string extract_file_reference(const tl_object_ptr &input_chat_photo); + template void store_file(FileId file_id, T &storer, int32 ttl = 5) const;