From df7e6f83f533e41359901d767392eb8cb0a0a9d1 Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Mon, 17 Dec 2018 22:56:47 +0300 Subject: [PATCH] Files: support remote id for map thumbnails GitOrigin-RevId: d9b5281ce55fd7bd2f4557a933b7f9dba2b591af --- td/telegram/files/FileManager.cpp | 58 ++++++++++++++++++++++--------- td/telegram/files/FileManager.h | 6 +++- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index 61898529..cecc6945 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -1847,6 +1847,13 @@ static bool is_document_type(FileType type) { type == FileType::Animation; } +string FileManager::get_persistent_id(const FullGenerateFileLocation &location) { + auto binary = serialize(location); + + binary = zero_encode(binary); + binary.push_back(PERSISTENT_ID_VERSION_MAP); + return base64url_encode(binary); +} string FileManager::get_persistent_id(const FullRemoteFileLocation &location) { auto binary = serialize(location); @@ -1855,17 +1862,6 @@ string FileManager::get_persistent_id(const FullRemoteFileLocation &location) { return base64url_encode(binary); } -Result FileManager::to_persistent_id(FileId file_id) { - auto view = get_file_view(file_id); - if (view.empty()) { - return Status::Error(10, "Unknown file id"); - } - if (!view.has_remote_location()) { - return Status::Error(10, "File has no persistent id"); - } - return get_persistent_id(view.remote_location()); -} - Result FileManager::from_persistent_id(CSlice persistent_id, FileType file_type) { if (persistent_id.find('.') != string::npos) { string input_url = persistent_id.str(); // TODO do not copy persistent_id @@ -1885,10 +1881,37 @@ Result FileManager::from_persistent_id(CSlice persistent_id, FileType fi if (binary.empty()) { return Status::Error(10, "Remote file id can't be empty"); } - if (binary.back() != PERSISTENT_ID_VERSION) { - return Status::Error(10, "Wrong remote file id specified: can't unserialize it. Wrong last symbol"); + if (binary.back() == PERSISTENT_ID_VERSION) { + return from_persistent_id_v2(binary, file_type); } - binary.pop_back(); + if (binary.back() == PERSISTENT_ID_VERSION_MAP) { + return from_persistent_id_map(binary, file_type); + } + return Status::Error(10, "Wrong remote file id specified: can't unserialize it. Wrong last symbol"); +} + +Result FileManager::from_persistent_id_map(Slice binary, FileType file_type) { + binary.remove_suffix(1); + binary = zero_decode(binary); + FullGenerateFileLocation generate_location; + auto status = unserialize(generate_location, binary); + if (status.is_error()) { + return Status::Error(10, "Wrong remote file id specified: can't unserialize it"); + } + auto real_file_type = generate_location.file_type_; + if ((real_file_type != file_type && file_type != FileType::Temp) || real_file_type != FileType::Thumbnail) { + return Status::Error(10, "Type of file mismatch"); + } + if (!begins_with(generate_location.conversion_, "#map#")) { + return Status::Error(10, "Unexpected converstioion type"); + } + FileData data; + data.generate_ = make_unique(std::move(generate_location)); + return register_file(std::move(data), FileLocationSource::FromUser, "from_persistent_id_map", false).move_as_ok(); +} + +Result FileManager::from_persistent_id_v2(Slice binary, FileType file_type) { + binary.remove_suffix(1); binary = zero_decode(binary); FullRemoteFileLocation remote_location; auto status = unserialize(remote_location, binary); @@ -1903,7 +1926,7 @@ Result FileManager::from_persistent_id(CSlice persistent_id, FileType fi } FileData data; data.remote_ = RemoteFileLocation(std::move(remote_location)); - return register_file(std::move(data), FileLocationSource::FromUser, "from_persistent_id", false).move_as_ok(); + return register_file(std::move(data), FileLocationSource::FromUser, "from_persistent_id_v2", false).move_as_ok(); } FileView FileManager::get_file_view(FileId file_id) const { @@ -1934,7 +1957,10 @@ tl_object_ptr FileManager::get_file_object(FileId file_id, bool wi persistent_file_id = get_persistent_id(file_view.remote_location()); } else if (file_view.has_url()) { persistent_file_id = file_view.url(); + } else if (file_view.has_generate_location() && begins_with(file_view.generate_location().conversion_, "#map#")) { + persistent_file_id = get_persistent_id(file_view.generate_location()); } + bool is_uploading_completed = !persistent_file_id.empty(); int32 size = narrow_cast(file_view.size()); int32 expected_size = narrow_cast(file_view.expected_size()); @@ -1963,7 +1989,7 @@ tl_object_ptr FileManager::get_file_object(FileId file_id, bool wi file_view.is_downloading(), file_view.has_local_location(), local_size, local_total_size), td_api::make_object(std::move(persistent_file_id), file_view.is_uploading(), - file_view.has_remote_location(), remote_size)); + is_uploading_completed, remote_size)); } vector> FileManager::get_files_object(const vector &file_ids, diff --git a/td/telegram/files/FileManager.h b/td/telegram/files/FileManager.h index 54083f79..2fcdf31c 100644 --- a/td/telegram/files/FileManager.h +++ b/td/telegram/files/FileManager.h @@ -340,7 +340,7 @@ class FileManager : public FileLoadManager::Callback { void external_file_generate_finish(int64 id, Status status, Promise<> promise); static constexpr char PERSISTENT_ID_VERSION = 2; - Result to_persistent_id(FileId file_id) TD_WARN_UNUSED_RESULT; + static constexpr char PERSISTENT_ID_VERSION_MAP = 3; Result from_persistent_id(CSlice persistent_id, FileType file_type) TD_WARN_UNUSED_RESULT; FileView get_file_view(FileId file_id) const; FileView get_sync_file_view(FileId file_id); @@ -451,8 +451,12 @@ class FileManager : public FileLoadManager::Callback { void flush_to_pmc(FileNodePtr node, bool new_remote, bool new_local, bool new_generate); void load_from_pmc(FileNodePtr node, bool new_remote, bool new_local, bool new_generate); + string get_persistent_id(const FullGenerateFileLocation &location); string get_persistent_id(const FullRemoteFileLocation &location); + Result from_persistent_id_map(Slice binary, FileType file_type); + Result from_persistent_id_v2(Slice binary, FileType file_type); + string fix_file_extension(Slice file_name, Slice file_type, Slice file_extension); string get_file_name(FileType file_type, Slice path);