1 // 2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 #pragma once 8 9 #include "td/telegram/BackgroundId.h" 10 #include "td/telegram/ChannelId.h" 11 #include "td/telegram/ChatId.h" 12 #include "td/telegram/files/FileId.h" 13 #include "td/telegram/files/FileSourceId.h" 14 #include "td/telegram/FullMessageId.h" 15 #include "td/telegram/PhotoSizeSource.h" 16 #include "td/telegram/SetWithPosition.h" 17 #include "td/telegram/UserId.h" 18 19 #include "td/actor/actor.h" 20 #include "td/actor/PromiseFuture.h" 21 22 #include "td/utils/common.h" 23 #include "td/utils/logging.h" 24 #include "td/utils/Slice.h" 25 #include "td/utils/Status.h" 26 #include "td/utils/Variant.h" 27 28 #include <unordered_map> 29 30 namespace td { 31 32 class Td; 33 34 extern int VERBOSITY_NAME(file_references); 35 36 class FileReferenceManager final : public Actor { 37 public: 38 static bool is_file_reference_error(const Status &error); 39 static size_t get_file_reference_error_pos(const Status &error); 40 41 FileSourceId create_message_file_source(FullMessageId full_message_id); 42 FileSourceId create_user_photo_file_source(UserId user_id, int64 photo_id); 43 // file reference aren't used for chat/channel photo download and the photos can't be reused 44 // FileSourceId create_chat_photo_file_source(ChatId chat_id); 45 // FileSourceId create_channel_photo_file_source(ChannelId channel_id); 46 // FileSourceId create_wallpapers_file_source(); old wallpapers can't be repaired 47 FileSourceId create_web_page_file_source(string url); 48 FileSourceId create_saved_animations_file_source(); 49 FileSourceId create_recent_stickers_file_source(bool is_attached); 50 FileSourceId create_favorite_stickers_file_source(); 51 FileSourceId create_background_file_source(BackgroundId background_id, int64 access_hash); 52 FileSourceId create_chat_full_file_source(ChatId chat_id); 53 FileSourceId create_channel_full_file_source(ChannelId channel_id); 54 FileSourceId create_app_config_file_source(); 55 56 using NodeId = FileId; 57 void repair_file_reference(NodeId node_id, Promise<> promise); 58 59 static void reload_photo(PhotoSizeSource source, Promise<Unit> promise); 60 61 bool add_file_source(NodeId node_id, FileSourceId file_source_id); 62 63 vector<FileSourceId> get_some_file_sources(NodeId node_id); 64 65 vector<FullMessageId> get_some_message_file_sources(NodeId node_id); 66 67 bool remove_file_source(NodeId node_id, FileSourceId file_source_id); 68 69 void merge(NodeId to_node_id, NodeId from_node_id); 70 71 template <class StorerT> 72 void store_file_source(FileSourceId file_source_id, StorerT &storer) const; 73 74 template <class ParserT> 75 FileSourceId parse_file_source(Td *td, ParserT &parser); 76 77 private: 78 struct Destination { 79 NodeId node_id; 80 int64 generation{0}; 81 82 Destination() = default; DestinationDestination83 Destination(NodeId node_id, int64 generation) : node_id(node_id), generation(generation) { 84 } is_emptyDestination85 bool is_empty() const { 86 return node_id.empty(); 87 } 88 }; 89 struct Query { 90 std::vector<Promise<>> promises; 91 int32 active_queries{0}; 92 Destination proxy; 93 int64 generation{0}; 94 }; 95 96 struct Node { 97 SetWithPosition<FileSourceId> file_source_ids; 98 unique_ptr<Query> query; 99 double last_successful_repair_time = -1e10; 100 }; 101 102 struct FileSourceMessage { 103 FullMessageId full_message_id; 104 }; 105 struct FileSourceUserPhoto { 106 int64 photo_id; 107 UserId user_id; 108 }; 109 struct FileSourceChatPhoto { 110 ChatId chat_id; 111 }; 112 struct FileSourceChannelPhoto { 113 ChannelId channel_id; 114 }; 115 struct FileSourceWallpapers { 116 // empty 117 }; 118 struct FileSourceWebPage { 119 string url; 120 }; 121 struct FileSourceSavedAnimations { 122 // empty 123 }; 124 struct FileSourceRecentStickers { 125 bool is_attached; 126 }; 127 struct FileSourceFavoriteStickers { 128 // empty 129 }; 130 struct FileSourceBackground { 131 BackgroundId background_id; 132 int64 access_hash; 133 }; 134 struct FileSourceChatFull { 135 ChatId chat_id; 136 }; 137 struct FileSourceChannelFull { 138 ChannelId channel_id; 139 }; 140 struct FileSourceAppConfig { 141 // empty 142 }; 143 144 // append only 145 using FileSource = 146 Variant<FileSourceMessage, FileSourceUserPhoto, FileSourceChatPhoto, FileSourceChannelPhoto, FileSourceWallpapers, 147 FileSourceWebPage, FileSourceSavedAnimations, FileSourceRecentStickers, FileSourceFavoriteStickers, 148 FileSourceBackground, FileSourceChatFull, FileSourceChannelFull, FileSourceAppConfig>; 149 vector<FileSource> file_sources_; 150 151 int64 query_generation_{0}; 152 153 std::unordered_map<NodeId, Node, FileIdHash> nodes_; 154 155 void run_node(NodeId node); 156 void send_query(Destination dest, FileSourceId file_source_id); 157 Destination on_query_result(Destination dest, FileSourceId file_source_id, Status status, int32 sub = 0); 158 159 template <class T> 160 FileSourceId add_file_source_id(T source, Slice source_str); 161 162 FileSourceId get_current_file_source_id() const; 163 }; 164 165 } // namespace td 166