From e0dd56ce8c815f1cde2fd0c6f2cf26e367f0e9aa Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 22 Jan 2019 19:08:41 +0300 Subject: [PATCH] Fix repairing of main user photo. GitOrigin-RevId: 6cd643f17af99b92eec9fe230aa30fc3469c4407 --- td/telegram/ContactsManager.cpp | 11 ++++- td/telegram/Photo.cpp | 68 ++++++++++++++++++++++++++++--- td/telegram/Photo.h | 3 ++ td/telegram/files/FileManager.cpp | 2 +- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index 1bf393f2d..2f1c349af 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -6530,8 +6530,15 @@ void ContactsManager::on_get_user_photos(UserId user_id, int32 offset, int32 lim CHECK(limit == 1); for (auto &photo_ptr : photos) { if (photo_ptr->get_id() == telegram_api::photo::ID) { - auto photo = get_photo(td_->file_manager_.get(), telegram_api::move_object_as(photo_ptr), - DialogId()); + auto server_photo = telegram_api::move_object_as(photo_ptr); + auto profile_photo = convert_photo_to_profile_photo(server_photo); + if (profile_photo) { + get_profile_photo(td_->file_manager_.get(), std::move(profile_photo)); + } else { + LOG(ERROR) << "Failed to get profile photo from " << to_string(server_photo); + } + + auto photo = get_photo(td_->file_manager_.get(), std::move(server_photo), DialogId()); add_user_photo_id(u, user_id, photo.id, photo_get_file_ids(photo)); } } diff --git a/td/telegram/Photo.cpp b/td/telegram/Photo.cpp index 477800193..c8a385d01 100644 --- a/td/telegram/Photo.cpp +++ b/td/telegram/Photo.cpp @@ -64,13 +64,12 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Dimensions &dimen static FileId register_photo(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash, tl_object_ptr &&location_ptr, DialogId owner_dialog_id, int32 file_size, bool is_webp = false) { - int32 location_id = location_ptr->get_id(); DcId dc_id; int32 local_id; int64 volume_id; int64 secret; std::string file_reference; - switch (location_id) { + switch (location_ptr->get_id()) { case telegram_api::fileLocationUnavailable::ID: { auto location = move_tl_object_as(location_ptr); dc_id = DcId::invalid(); @@ -259,8 +258,7 @@ PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id PhotoSize res; BufferSlice content; - int32 size_id = size_ptr->get_id(); - switch (size_id) { + switch (size_ptr->get_id()) { case telegram_api::photoSizeEmpty::ID: return res; case telegram_api::photoSize::ID: { @@ -286,7 +284,6 @@ PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id break; } - default: UNREACHABLE(); break; @@ -481,6 +478,9 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr && res.date = photo->date_; res.has_stickers = (photo->flags_ & telegram_api::photo::HAS_STICKERS_MASK) != 0; + auto file_reference = photo->file_reference_.as_slice().str(); + // TODO use file_reference + for (auto &size_ptr : photo->sizes_) { res.photos.push_back(get_photo_size(file_manager, FileType::Photo, photo->id_, photo->access_hash_, owner_dialog_id, std::move(size_ptr), false)); @@ -662,4 +662,62 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Photo &photo) { return string_builder << "[id = " << photo.id << ", photos = " << format::as_array(photo.photos) << "]"; } +static tl_object_ptr copy_location( + const tl_object_ptr &location_ptr) { + CHECK(location_ptr != nullptr); + switch (location_ptr->get_id()) { + case telegram_api::fileLocationUnavailable::ID: { + auto location = static_cast(location_ptr.get()); + return make_tl_object(location->volume_id_, location->local_id_, + location->secret_); + } + case telegram_api::fileLocation::ID: { + auto location = static_cast(location_ptr.get()); + return make_tl_object(location->dc_id_, location->volume_id_, location->local_id_, + location->secret_, location->file_reference_.clone()); + } + default: + UNREACHABLE(); + return nullptr; + } +} + +tl_object_ptr convert_photo_to_profile_photo( + const tl_object_ptr &photo) { + CHECK(photo != nullptr); + tl_object_ptr photo_small; + tl_object_ptr photo_big; + for (auto &size_ptr : photo->sizes_) { + switch (size_ptr->get_id()) { + case telegram_api::photoSizeEmpty::ID: + break; + case telegram_api::photoSize::ID: { + auto size = static_cast(size_ptr.get()); + if (size->type_ == "a") { + photo_small = copy_location(size->location_); + } else if (size->type_ == "c") { + photo_big = copy_location(size->location_); + } + break; + } + case telegram_api::photoCachedSize::ID: { + auto size = static_cast(size_ptr.get()); + if (size->type_ == "a") { + photo_small = copy_location(size->location_); + } else if (size->type_ == "c") { + photo_big = copy_location(size->location_); + } + break; + } + default: + UNREACHABLE(); + break; + } + } + if (photo_small == nullptr || photo_big == nullptr) { + return nullptr; + } + return make_tl_object(photo->id_, std::move(photo_small), std::move(photo_big)); +} + } // namespace td diff --git a/td/telegram/Photo.h b/td/telegram/Photo.h index 764a4dbe4..5cff517c1 100644 --- a/td/telegram/Photo.h +++ b/td/telegram/Photo.h @@ -124,4 +124,7 @@ bool operator!=(const Photo &lhs, const Photo &rhs); StringBuilder &operator<<(StringBuilder &string_builder, const Photo &photo); +tl_object_ptr convert_photo_to_profile_photo( + const tl_object_ptr &photo); + } // namespace td diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index 4aa7a2840..5bb3f281a 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -1843,7 +1843,7 @@ void FileManager::resume_upload(FileId file_id, std::vector bad_parts, std: } FileView file_view(node); if (file_view.has_active_remote_location() && file_view.get_type() != FileType::Thumbnail && - file_view.get_type() != FileType::EncryptedThumbnail) { + file_view.get_type() != FileType::EncryptedThumbnail && file_view.get_type() != FileType::Photo) { LOG(INFO) << "File " << file_id << " is already uploaded"; if (callback) { callback->on_upload_ok(file_id, nullptr);