FileManager: support two file references for photos
GitOrigin-RevId: f27a9867315e12e79a456c12949d8d2580531bbe
This commit is contained in:
parent
b481ce8465
commit
2032f89723
@ -208,7 +208,7 @@ std::pair<DocumentsManager::DocumentType, FileId> DocumentsManager::on_get_docum
|
|||||||
file_reference = document->file_reference_.as_slice().str();
|
file_reference = document->file_reference_.as_slice().str();
|
||||||
|
|
||||||
if (document_type != DocumentType::VoiceNote) {
|
if (document_type != DocumentType::VoiceNote) {
|
||||||
thumbnail = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, owner_dialog_id,
|
thumbnail = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", owner_dialog_id,
|
||||||
std::move(document->thumb_), has_webp_thumbnail);
|
std::move(document->thumb_), has_webp_thumbnail);
|
||||||
}
|
}
|
||||||
} else if (remote_document.secret_file != nullptr) {
|
} else if (remote_document.secret_file != nullptr) {
|
||||||
|
@ -190,7 +190,8 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source
|
|||||||
new_promise = std::move(new_promise)]() mutable {
|
new_promise = std::move(new_promise)]() mutable {
|
||||||
auto view = file_manager.get_actor_unsafe()->get_file_view(dest.node_id);
|
auto view = file_manager.get_actor_unsafe()->get_file_view(dest.node_id);
|
||||||
CHECK(!view.empty());
|
CHECK(!view.empty());
|
||||||
if (result.is_ok() && !view.has_active_remote_location()) {
|
if (result.is_ok() &&
|
||||||
|
(!view.has_active_upload_remote_location() || !view.has_active_download_remote_location())) {
|
||||||
result = Status::Error("No active remote location");
|
result = Status::Error("No active remote location");
|
||||||
}
|
}
|
||||||
if (result.is_error() && result.error().code() != 429 && result.error().code() < 500) {
|
if (result.is_error() && result.error().code() != 429 && result.error().code() < 500) {
|
||||||
|
@ -2122,7 +2122,7 @@ tl_object_ptr<telegram_api::InputMedia> get_input_media(const MessageContent *co
|
|||||||
}
|
}
|
||||||
if (!was_uploaded) {
|
if (!was_uploaded) {
|
||||||
auto file_reference = FileManager::extract_file_reference(input_media);
|
auto file_reference = FileManager::extract_file_reference(input_media);
|
||||||
if (file_reference == FullRemoteFileLocation::invalid_file_reference()) {
|
if (file_reference == FileReferenceView::invalid_file_reference()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2132,7 +2132,7 @@ tl_object_ptr<telegram_api::InputMedia> get_input_media(const MessageContent *co
|
|||||||
tl_object_ptr<telegram_api::InputMedia> get_input_media(const MessageContent *content, Td *td, int32 ttl) {
|
tl_object_ptr<telegram_api::InputMedia> get_input_media(const MessageContent *content, Td *td, int32 ttl) {
|
||||||
auto input_media = get_input_media(content, td, nullptr, nullptr, ttl);
|
auto input_media = get_input_media(content, td, nullptr, nullptr, ttl);
|
||||||
auto file_reference = FileManager::extract_file_reference(input_media);
|
auto file_reference = FileManager::extract_file_reference(input_media);
|
||||||
if (file_reference == FullRemoteFileLocation::invalid_file_reference()) {
|
if (file_reference == FileReferenceView::invalid_file_reference()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return input_media;
|
return input_media;
|
||||||
@ -2788,7 +2788,8 @@ void merge_message_contents(Td *td, MessageContent *old_content, MessageContent
|
|||||||
FileId file_id = td->file_manager_->register_remote(
|
FileId file_id = td->file_manager_->register_remote(
|
||||||
FullRemoteFileLocation(FileType::Photo, new_file_view.remote_location().get_id(),
|
FullRemoteFileLocation(FileType::Photo, new_file_view.remote_location().get_id(),
|
||||||
new_file_view.remote_location().get_access_hash(), 0, 0, 0, DcId::invalid(),
|
new_file_view.remote_location().get_access_hash(), 0, 0, 0, DcId::invalid(),
|
||||||
new_file_view.remote_location().get_file_reference()),
|
new_file_view.remote_location().get_upload_file_reference().str(),
|
||||||
|
new_file_view.remote_location().get_download_file_reference().str()),
|
||||||
FileLocationSource::FromServer, dialog_id, old_photo->photos.back().size, 0, "");
|
FileLocationSource::FromServer, dialog_id, old_photo->photos.back().size, 0, "");
|
||||||
LOG_STATUS(td->file_manager_->merge(file_id, old_file_id));
|
LOG_STATUS(td->file_manager_->merge(file_id, old_file_id));
|
||||||
}
|
}
|
||||||
|
@ -62,13 +62,14 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Dimensions &dimen
|
|||||||
}
|
}
|
||||||
|
|
||||||
static FileId register_photo(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
|
static FileId register_photo(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
|
||||||
|
std::string upload_file_reference,
|
||||||
tl_object_ptr<telegram_api::FileLocation> &&location_ptr, DialogId owner_dialog_id,
|
tl_object_ptr<telegram_api::FileLocation> &&location_ptr, DialogId owner_dialog_id,
|
||||||
int32 file_size, bool is_webp = false) {
|
int32 file_size, bool is_webp = false) {
|
||||||
DcId dc_id;
|
DcId dc_id;
|
||||||
int32 local_id;
|
int32 local_id;
|
||||||
int64 volume_id;
|
int64 volume_id;
|
||||||
int64 secret;
|
int64 secret;
|
||||||
std::string file_reference;
|
std::string download_file_reference;
|
||||||
switch (location_ptr->get_id()) {
|
switch (location_ptr->get_id()) {
|
||||||
case telegram_api::fileLocationUnavailable::ID: {
|
case telegram_api::fileLocationUnavailable::ID: {
|
||||||
auto location = move_tl_object_as<telegram_api::fileLocationUnavailable>(location_ptr);
|
auto location = move_tl_object_as<telegram_api::fileLocationUnavailable>(location_ptr);
|
||||||
@ -88,7 +89,7 @@ static FileId register_photo(FileManager *file_manager, FileType file_type, int6
|
|||||||
local_id = location->local_id_;
|
local_id = location->local_id_;
|
||||||
volume_id = location->volume_id_;
|
volume_id = location->volume_id_;
|
||||||
secret = location->secret_;
|
secret = location->secret_;
|
||||||
file_reference = location->file_reference_.as_slice().str();
|
download_file_reference = location->file_reference_.as_slice().str();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -101,9 +102,10 @@ static FileId register_photo(FileManager *file_manager, FileType file_type, int6
|
|||||||
<< ")";
|
<< ")";
|
||||||
auto suggested_name = PSTRING() << static_cast<uint64>(volume_id) << "_" << static_cast<uint64>(local_id)
|
auto suggested_name = PSTRING() << static_cast<uint64>(volume_id) << "_" << static_cast<uint64>(local_id)
|
||||||
<< (is_webp ? ".webp" : ".jpg");
|
<< (is_webp ? ".webp" : ".jpg");
|
||||||
return file_manager->register_remote(
|
return file_manager->register_remote(FullRemoteFileLocation(file_type, id, access_hash, local_id, volume_id, secret,
|
||||||
FullRemoteFileLocation(file_type, id, access_hash, local_id, volume_id, secret, dc_id, file_reference),
|
dc_id, upload_file_reference, download_file_reference),
|
||||||
FileLocationSource::FromServer, owner_dialog_id, file_size, 0, std::move(suggested_name));
|
FileLocationSource::FromServer, owner_dialog_id, file_size, 0,
|
||||||
|
std::move(suggested_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfilePhoto get_profile_photo(FileManager *file_manager,
|
ProfilePhoto get_profile_photo(FileManager *file_manager,
|
||||||
@ -118,9 +120,9 @@ ProfilePhoto get_profile_photo(FileManager *file_manager,
|
|||||||
auto profile_photo = move_tl_object_as<telegram_api::userProfilePhoto>(profile_photo_ptr);
|
auto profile_photo = move_tl_object_as<telegram_api::userProfilePhoto>(profile_photo_ptr);
|
||||||
|
|
||||||
result.id = profile_photo->photo_id_;
|
result.id = profile_photo->photo_id_;
|
||||||
result.small_file_id = register_photo(file_manager, FileType::ProfilePhoto, result.id, 0,
|
result.small_file_id = register_photo(file_manager, FileType::ProfilePhoto, result.id, 0, "",
|
||||||
std::move(profile_photo->photo_small_), DialogId(), 0);
|
std::move(profile_photo->photo_small_), DialogId(), 0);
|
||||||
result.big_file_id = register_photo(file_manager, FileType::ProfilePhoto, result.id, 0,
|
result.big_file_id = register_photo(file_manager, FileType::ProfilePhoto, result.id, 0, "",
|
||||||
std::move(profile_photo->photo_big_), DialogId(), 0);
|
std::move(profile_photo->photo_big_), DialogId(), 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -179,10 +181,10 @@ DialogPhoto get_dialog_photo(FileManager *file_manager, tl_object_ptr<telegram_a
|
|||||||
case telegram_api::chatPhoto::ID: {
|
case telegram_api::chatPhoto::ID: {
|
||||||
auto chat_photo = move_tl_object_as<telegram_api::chatPhoto>(chat_photo_ptr);
|
auto chat_photo = move_tl_object_as<telegram_api::chatPhoto>(chat_photo_ptr);
|
||||||
|
|
||||||
result.small_file_id = register_photo(file_manager, FileType::ProfilePhoto, 0, 0,
|
result.small_file_id = register_photo(file_manager, FileType::ProfilePhoto, 0, 0, "",
|
||||||
std::move(chat_photo->photo_small_), DialogId(), 0);
|
std::move(chat_photo->photo_small_), DialogId(), 0);
|
||||||
result.big_file_id =
|
result.big_file_id = register_photo(file_manager, FileType::ProfilePhoto, 0, 0, "",
|
||||||
register_photo(file_manager, FileType::ProfilePhoto, 0, 0, std::move(chat_photo->photo_big_), DialogId(), 0);
|
std::move(chat_photo->photo_big_), DialogId(), 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -242,7 +244,7 @@ PhotoSize get_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes,
|
|||||||
auto volume_id = Random::secure_int64();
|
auto volume_id = Random::secure_int64();
|
||||||
auto secret = 0;
|
auto secret = 0;
|
||||||
res.file_id = file_manager->register_remote(
|
res.file_id = file_manager->register_remote(
|
||||||
FullRemoteFileLocation(FileType::EncryptedThumbnail, 0, 0, local_id, volume_id, secret, dc_id, ""),
|
FullRemoteFileLocation(FileType::EncryptedThumbnail, 0, 0, local_id, volume_id, secret, dc_id, "", ""),
|
||||||
FileLocationSource::FromServer, owner_dialog_id, res.size, 0,
|
FileLocationSource::FromServer, owner_dialog_id, res.size, 0,
|
||||||
PSTRING() << static_cast<uint64>(volume_id) << "_" << static_cast<uint64>(local_id) << ".jpg");
|
PSTRING() << static_cast<uint64>(volume_id) << "_" << static_cast<uint64>(local_id) << ".jpg");
|
||||||
file_manager->set_content(res.file_id, std::move(bytes));
|
file_manager->set_content(res.file_id, std::move(bytes));
|
||||||
@ -251,7 +253,8 @@ PhotoSize get_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
|
PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
|
||||||
DialogId owner_dialog_id, tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp) {
|
std::string upload_file_reference, DialogId owner_dialog_id,
|
||||||
|
tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp) {
|
||||||
tl_object_ptr<telegram_api::FileLocation> location_ptr;
|
tl_object_ptr<telegram_api::FileLocation> location_ptr;
|
||||||
string type;
|
string type;
|
||||||
|
|
||||||
@ -289,8 +292,8 @@ PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.file_id = register_photo(file_manager, file_type, id, access_hash, std::move(location_ptr), owner_dialog_id,
|
res.file_id = register_photo(file_manager, file_type, id, access_hash, upload_file_reference, std::move(location_ptr),
|
||||||
res.size, is_webp);
|
owner_dialog_id, res.size, is_webp);
|
||||||
|
|
||||||
if (!content.empty()) {
|
if (!content.empty()) {
|
||||||
file_manager->set_content(res.file_id, std::move(content));
|
file_manager->set_content(res.file_id, std::move(content));
|
||||||
@ -482,8 +485,9 @@ Photo get_photo(FileManager *file_manager, tl_object_ptr<telegram_api::photo> &&
|
|||||||
// TODO use file_reference
|
// TODO use file_reference
|
||||||
|
|
||||||
for (auto &size_ptr : photo->sizes_) {
|
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,
|
res.photos.push_back(get_photo_size(file_manager, FileType::Photo, photo->id_, photo->access_hash_,
|
||||||
std::move(size_ptr), false));
|
photo->file_reference_.as_slice().str(), owner_dialog_id, std::move(size_ptr),
|
||||||
|
false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -83,7 +83,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogPhoto &dial
|
|||||||
PhotoSize get_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id, int32 width,
|
PhotoSize get_thumbnail_photo_size(FileManager *file_manager, BufferSlice bytes, DialogId owner_dialog_id, int32 width,
|
||||||
int32 height);
|
int32 height);
|
||||||
PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
|
PhotoSize get_photo_size(FileManager *file_manager, FileType file_type, int64 id, int64 access_hash,
|
||||||
DialogId owner_dialog_id, tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp);
|
std::string upload_file_reference, DialogId owner_dialog_id,
|
||||||
|
tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, bool is_webp);
|
||||||
PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id,
|
PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id,
|
||||||
tl_object_ptr<telegram_api::WebDocument> web_document_ptr);
|
tl_object_ptr<telegram_api::WebDocument> web_document_ptr);
|
||||||
td_api::object_ptr<td_api::photoSize> get_photo_size_object(FileManager *file_manager, const PhotoSize *photo_size);
|
td_api::object_ptr<td_api::photoSize> get_photo_size_object(FileManager *file_manager, const PhotoSize *photo_size);
|
||||||
|
@ -1069,7 +1069,7 @@ std::pair<int64, FileId> StickersManager::on_get_sticker_document(tl_object_ptr<
|
|||||||
document->file_reference_.as_slice().str()),
|
document->file_reference_.as_slice().str()),
|
||||||
FileLocationSource::FromServer, DialogId(), document->size_, 0, PSTRING() << document_id << ".webp");
|
FileLocationSource::FromServer, DialogId(), document->size_, 0, PSTRING() << document_id << ".webp");
|
||||||
|
|
||||||
PhotoSize thumbnail = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, DialogId(),
|
PhotoSize thumbnail = get_photo_size(td_->file_manager_.get(), FileType::Thumbnail, 0, 0, "", DialogId(),
|
||||||
std::move(document->thumb_), has_webp_thumbnail(sticker));
|
std::move(document->thumb_), has_webp_thumbnail(sticker));
|
||||||
|
|
||||||
create_sticker(sticker_id, std::move(thumbnail), dimensions, from_message, std::move(sticker), nullptr);
|
create_sticker(sticker_id, std::move(thumbnail), dimensions, from_message, std::move(sticker), nullptr);
|
||||||
|
@ -97,10 +97,11 @@ void WallpaperManager::on_get_wallpapers(Result<vector<telegram_api::object_ptr<
|
|||||||
switch (wallpaper_ptr->get_id()) {
|
switch (wallpaper_ptr->get_id()) {
|
||||||
case telegram_api::wallPaper::ID: {
|
case telegram_api::wallPaper::ID: {
|
||||||
auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr);
|
auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr);
|
||||||
vector<PhotoSize> sizes = transform(
|
vector<PhotoSize> sizes = transform(std::move(wallpaper->sizes_),
|
||||||
std::move(wallpaper->sizes_), [file_manager](tl_object_ptr<telegram_api::PhotoSize> &&photo_size) {
|
[file_manager](tl_object_ptr<telegram_api::PhotoSize> &&photo_size) {
|
||||||
return get_photo_size(file_manager, FileType::Wallpaper, 0, 0, DialogId(), std::move(photo_size), false);
|
return get_photo_size(file_manager, FileType::Wallpaper, 0, 0, "",
|
||||||
});
|
DialogId(), std::move(photo_size), false);
|
||||||
|
});
|
||||||
return Wallpaper{wallpaper->id_, std::move(sizes), wallpaper->color_};
|
return Wallpaper{wallpaper->id_, std::move(sizes), wallpaper->color_};
|
||||||
}
|
}
|
||||||
case telegram_api::wallPaperSolid::ID: {
|
case telegram_api::wallPaperSolid::ID: {
|
||||||
|
@ -274,8 +274,8 @@ Status FileDownloader::check_net_query(NetQueryPtr &net_query) {
|
|||||||
if (net_query->is_error()) {
|
if (net_query->is_error()) {
|
||||||
auto error = net_query->move_as_error();
|
auto error = net_query->move_as_error();
|
||||||
if (FileReferenceManager::is_file_reference_error(error)) {
|
if (FileReferenceManager::is_file_reference_error(error)) {
|
||||||
error = Status::Error(error.code(),
|
error = Status::Error(error.code(), PSLICE() << error.message() << "#BASE64"
|
||||||
PSLICE() << error.message() << "#BASE64" << base64_encode(remote_.get_file_reference()));
|
<< base64_encode(remote_.get_download_file_reference()));
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,93 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
class FileReferenceView {
|
||||||
|
public:
|
||||||
|
static Slice invalid_file_reference() {
|
||||||
|
return "#";
|
||||||
|
}
|
||||||
|
static std::string create_one(td::Slice first) {
|
||||||
|
char second_length = char(255);
|
||||||
|
return PSTRING() << second_length << first;
|
||||||
|
}
|
||||||
|
static std::string create_two(td::Slice first, td::Slice second = {}) {
|
||||||
|
if (second.size() >= 255) {
|
||||||
|
LOG(ERROR) << "File reference is too big " << base64_encode(second);
|
||||||
|
second = invalid_file_reference();
|
||||||
|
}
|
||||||
|
char second_length = narrow_cast<unsigned char>(second.size());
|
||||||
|
return PSTRING() << second_length << first << second;
|
||||||
|
}
|
||||||
|
std::string create(td::Slice first, td::Slice second) const {
|
||||||
|
if (size() == 1) {
|
||||||
|
return create_one(first);
|
||||||
|
}
|
||||||
|
return create_two(first, second);
|
||||||
|
}
|
||||||
|
FileReferenceView(Slice data) {
|
||||||
|
if (data.empty()) {
|
||||||
|
size_ = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char second_size = data.ubegin()[0];
|
||||||
|
|
||||||
|
if (second_size == 255) {
|
||||||
|
first_ = data.substr(1);
|
||||||
|
second_ = data.substr(1);
|
||||||
|
size_ = 1;
|
||||||
|
} else {
|
||||||
|
if (second_size > data.size() - 1) {
|
||||||
|
size_ = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto first_size = data.size() - 1 - second_size;
|
||||||
|
first_ = data.substr(1, first_size);
|
||||||
|
second_ = data.substr(1 + first_size);
|
||||||
|
size_ = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t size() const {
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
Slice first() const {
|
||||||
|
return first_;
|
||||||
|
}
|
||||||
|
Slice second() const {
|
||||||
|
return second_;
|
||||||
|
}
|
||||||
|
bool has_first() const {
|
||||||
|
return first() != invalid_file_reference();
|
||||||
|
}
|
||||||
|
bool has_second() const {
|
||||||
|
return second() != invalid_file_reference();
|
||||||
|
}
|
||||||
|
std::pair<std::string, bool> delete_file_reference(Slice bad_file_reference) const {
|
||||||
|
if (bad_file_reference == FileReferenceView::invalid_file_reference()) {
|
||||||
|
return {"", false};
|
||||||
|
}
|
||||||
|
auto first = this->first();
|
||||||
|
auto second = this->second();
|
||||||
|
bool changed = false;
|
||||||
|
if (first == bad_file_reference) {
|
||||||
|
first = invalid_file_reference();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (second == bad_file_reference) {
|
||||||
|
second = invalid_file_reference();
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (!changed) {
|
||||||
|
return {"", false};
|
||||||
|
}
|
||||||
|
return {create(first, second), true};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Slice first_;
|
||||||
|
Slice second_;
|
||||||
|
int size_;
|
||||||
|
};
|
||||||
|
|
||||||
struct EmptyRemoteFileLocation {
|
struct EmptyRemoteFileLocation {
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
@ -399,25 +486,31 @@ class FullRemoteFileLocation {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static Slice invalid_file_reference() {
|
|
||||||
return "#";
|
|
||||||
}
|
|
||||||
bool delete_file_reference(Slice bad_file_reference) {
|
bool delete_file_reference(Slice bad_file_reference) {
|
||||||
if (file_reference_ == invalid_file_reference()) {
|
auto res = FileReferenceView(file_reference_).delete_file_reference(bad_file_reference);
|
||||||
return false;
|
if (res.second) {
|
||||||
|
file_reference_ = res.first;
|
||||||
}
|
}
|
||||||
if (file_reference_ != bad_file_reference) {
|
return res.second;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
file_reference_ = invalid_file_reference().str();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
bool has_file_reference() const {
|
bool has_upload_file_reference() const {
|
||||||
return file_reference_ != invalid_file_reference();
|
return FileReferenceView(file_reference_).has_first();
|
||||||
}
|
}
|
||||||
const string &get_file_reference() const {
|
bool has_download_file_reference() const {
|
||||||
|
return FileReferenceView(file_reference_).has_second();
|
||||||
|
}
|
||||||
|
bool has_any_file_reference() const {
|
||||||
|
return has_upload_file_reference() || has_download_file_reference();
|
||||||
|
}
|
||||||
|
Slice get_raw_file_reference() const {
|
||||||
return file_reference_;
|
return file_reference_;
|
||||||
}
|
}
|
||||||
|
Slice get_upload_file_reference() const {
|
||||||
|
return FileReferenceView(file_reference_).first();
|
||||||
|
}
|
||||||
|
Slice get_download_file_reference() const {
|
||||||
|
return FileReferenceView(file_reference_).second();
|
||||||
|
}
|
||||||
string get_url() const {
|
string get_url() const {
|
||||||
if (is_web()) {
|
if (is_web()) {
|
||||||
return web().url_;
|
return web().url_;
|
||||||
@ -460,8 +553,9 @@ class FullRemoteFileLocation {
|
|||||||
tl_object_ptr<telegram_api::InputFileLocation> as_input_file_location() const {
|
tl_object_ptr<telegram_api::InputFileLocation> as_input_file_location() const {
|
||||||
switch (location_type()) {
|
switch (location_type()) {
|
||||||
case LocationType::Photo:
|
case LocationType::Photo:
|
||||||
return make_tl_object<telegram_api::inputFileLocation>(photo().volume_id_, photo().local_id_, photo().secret_,
|
return make_tl_object<telegram_api::inputFileLocation>(
|
||||||
BufferSlice(file_reference_));
|
photo().volume_id_, photo().local_id_, photo().secret_,
|
||||||
|
BufferSlice(FileReferenceView(file_reference_).second()));
|
||||||
case LocationType::Common:
|
case LocationType::Common:
|
||||||
if (is_encrypted_secret()) {
|
if (is_encrypted_secret()) {
|
||||||
return make_tl_object<telegram_api::inputEncryptedFileLocation>(common().id_, common().access_hash_);
|
return make_tl_object<telegram_api::inputEncryptedFileLocation>(common().id_, common().access_hash_);
|
||||||
@ -490,7 +584,8 @@ class FullRemoteFileLocation {
|
|||||||
#define as_input_photo() as_input_photo_impl(__FILE__, __LINE__)
|
#define as_input_photo() as_input_photo_impl(__FILE__, __LINE__)
|
||||||
tl_object_ptr<telegram_api::inputPhoto> as_input_photo_impl(const char *file, int line) const {
|
tl_object_ptr<telegram_api::inputPhoto> as_input_photo_impl(const char *file, int line) const {
|
||||||
CHECK(is_photo()) << file << ' ' << line;
|
CHECK(is_photo()) << file << ' ' << line;
|
||||||
return make_tl_object<telegram_api::inputPhoto>(photo().id_, photo().access_hash_, BufferSlice(file_reference_));
|
return make_tl_object<telegram_api::inputPhoto>(photo().id_, photo().access_hash_,
|
||||||
|
BufferSlice(FileReferenceView(file_reference_).first()));
|
||||||
}
|
}
|
||||||
|
|
||||||
tl_object_ptr<telegram_api::inputEncryptedFile> as_input_encrypted_file() const {
|
tl_object_ptr<telegram_api::inputEncryptedFile> as_input_encrypted_file() const {
|
||||||
@ -507,13 +602,14 @@ class FullRemoteFileLocation {
|
|||||||
// TODO: this constructor is just for immediate unserialize
|
// TODO: this constructor is just for immediate unserialize
|
||||||
FullRemoteFileLocation() = default;
|
FullRemoteFileLocation() = default;
|
||||||
FullRemoteFileLocation(FileType file_type, int64 id, int64 access_hash, int32 local_id, int64 volume_id, int64 secret,
|
FullRemoteFileLocation(FileType file_type, int64 id, int64 access_hash, int32 local_id, int64 volume_id, int64 secret,
|
||||||
DcId dc_id, std::string file_reference)
|
DcId dc_id, std::string upload_file_reference, std::string download_file_reference)
|
||||||
: file_type_(file_type)
|
: file_type_(file_type)
|
||||||
, dc_id_(dc_id)
|
, dc_id_(dc_id)
|
||||||
, file_reference_(std::move(file_reference))
|
, file_reference_(FileReferenceView::create_two(upload_file_reference, download_file_reference))
|
||||||
, variant_(PhotoRemoteFileLocation{id, access_hash, volume_id, secret, local_id}) {
|
, variant_(PhotoRemoteFileLocation{id, access_hash, volume_id, secret, local_id}) {
|
||||||
CHECK(is_photo());
|
CHECK(is_photo());
|
||||||
if (file_reference_ == invalid_file_reference()) {
|
FileReferenceView view(file_reference_);
|
||||||
|
if (!view.has_first() || !view.has_second()) {
|
||||||
LOG(ERROR) << "Tried to register file with invalid file reference";
|
LOG(ERROR) << "Tried to register file with invalid file reference";
|
||||||
file_reference_.clear();
|
file_reference_.clear();
|
||||||
}
|
}
|
||||||
@ -524,7 +620,8 @@ class FullRemoteFileLocation {
|
|||||||
, file_reference_(std::move(file_reference))
|
, file_reference_(std::move(file_reference))
|
||||||
, variant_(CommonRemoteFileLocation{id, access_hash}) {
|
, variant_(CommonRemoteFileLocation{id, access_hash}) {
|
||||||
CHECK(is_common());
|
CHECK(is_common());
|
||||||
if (file_reference_ == invalid_file_reference()) {
|
FileReferenceView view(file_reference_);
|
||||||
|
if (!view.has_first() || !view.has_second()) {
|
||||||
LOG(ERROR) << "Tried to register file with invalid file reference";
|
LOG(ERROR) << "Tried to register file with invalid file reference";
|
||||||
file_reference_.clear();
|
file_reference_.clear();
|
||||||
}
|
}
|
||||||
@ -580,7 +677,7 @@ class FullRemoteFileLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const int32 KEY_MAGIC = 0x64374632;
|
static const int32 KEY_MAGIC = 0x64374632;
|
||||||
};
|
}; // namespace td
|
||||||
|
|
||||||
inline StringBuilder &operator<<(StringBuilder &string_builder,
|
inline StringBuilder &operator<<(StringBuilder &string_builder,
|
||||||
const FullRemoteFileLocation &full_remote_file_location) {
|
const FullRemoteFileLocation &full_remote_file_location) {
|
||||||
@ -659,9 +756,9 @@ class RemoteFileLocation {
|
|||||||
explicit RemoteFileLocation(const PartialRemoteFileLocation &partial) : variant_(partial) {
|
explicit RemoteFileLocation(const PartialRemoteFileLocation &partial) : variant_(partial) {
|
||||||
}
|
}
|
||||||
RemoteFileLocation(FileType file_type, int64 id, int64 access_hash, int32 local_id, int64 volume_id, int64 secret,
|
RemoteFileLocation(FileType file_type, int64 id, int64 access_hash, int32 local_id, int64 volume_id, int64 secret,
|
||||||
DcId dc_id, std::string file_reference)
|
DcId dc_id, std::string upload_file_reference, std::string download_file_reference)
|
||||||
: variant_(FullRemoteFileLocation{file_type, id, access_hash, local_id, volume_id, secret, dc_id,
|
: variant_(FullRemoteFileLocation{file_type, id, access_hash, local_id, volume_id, secret, dc_id,
|
||||||
std::move(file_reference)}) {
|
std::move(upload_file_reference), std::move(download_file_reference)}) {
|
||||||
}
|
}
|
||||||
RemoteFileLocation(FileType file_type, int64 id, int64 access_hash, DcId dc_id, std::string file_reference)
|
RemoteFileLocation(FileType file_type, int64 id, int64 access_hash, DcId dc_id, std::string file_reference)
|
||||||
: variant_(FullRemoteFileLocation{file_type, id, access_hash, dc_id, std::move(file_reference)}) {
|
: variant_(FullRemoteFileLocation{file_type, id, access_hash, dc_id, std::move(file_reference)}) {
|
||||||
|
@ -148,7 +148,7 @@ void FileNode::set_remote_location(const RemoteFileLocation &remote, FileLocatio
|
|||||||
if (remote_ == remote) {
|
if (remote_ == remote) {
|
||||||
if (remote_.type() == RemoteFileLocation::Type::Full) {
|
if (remote_.type() == RemoteFileLocation::Type::Full) {
|
||||||
if (remote_.full().get_access_hash() != remote.full().get_access_hash() ||
|
if (remote_.full().get_access_hash() != remote.full().get_access_hash() ||
|
||||||
remote_.full().get_file_reference() != remote.full().get_file_reference()) {
|
remote_.full().get_raw_file_reference() != remote.full().get_raw_file_reference()) {
|
||||||
remote_ = remote;
|
remote_ = remote;
|
||||||
remote_source_ = source;
|
remote_source_ = source;
|
||||||
on_pmc_changed();
|
on_pmc_changed();
|
||||||
@ -352,14 +352,24 @@ bool FileView::has_remote_location() const {
|
|||||||
return node_->remote_.type() == RemoteFileLocation::Type::Full;
|
return node_->remote_.type() == RemoteFileLocation::Type::Full;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileView::has_active_remote_location() const {
|
bool FileView::has_active_upload_remote_location() const {
|
||||||
if (!has_remote_location()) {
|
if (!has_remote_location()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (remote_location().is_encrypted_any()) {
|
if (remote_location().is_encrypted_any()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return remote_location().has_file_reference();
|
return remote_location().has_upload_file_reference();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileView::has_active_download_remote_location() const {
|
||||||
|
if (!has_remote_location()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (remote_location().is_encrypted_any()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return remote_location().has_download_file_reference();
|
||||||
}
|
}
|
||||||
|
|
||||||
const FullRemoteFileLocation &FileView::remote_location() const {
|
const FullRemoteFileLocation &FileView::remote_location() const {
|
||||||
@ -986,13 +996,13 @@ static int merge_choose_remote_location(const RemoteFileLocation &x, int8 x_sour
|
|||||||
if (x.full().is_web() != y.full().is_web()) {
|
if (x.full().is_web() != y.full().is_web()) {
|
||||||
return x.full().is_web(); // prefer non-web
|
return x.full().is_web(); // prefer non-web
|
||||||
}
|
}
|
||||||
auto x_ref = x.full().has_file_reference();
|
auto x_ref = x.full().has_any_file_reference();
|
||||||
auto y_ref = y.full().has_file_reference();
|
auto y_ref = y.full().has_any_file_reference();
|
||||||
if (x_ref || y_ref) {
|
if (x_ref || y_ref) {
|
||||||
if (x_ref != y_ref) {
|
if (x_ref != y_ref) {
|
||||||
return !x_ref;
|
return !x_ref;
|
||||||
}
|
}
|
||||||
if (x.full().get_file_reference() != y.full().get_file_reference()) {
|
if (x.full().get_raw_file_reference() != y.full().get_raw_file_reference()) {
|
||||||
return x_source < y_source;
|
return x_source < y_source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1799,7 +1809,7 @@ void FileManager::run_download(FileNodePtr node) {
|
|||||||
auto file_id = node->main_file_id_;
|
auto file_id = node->main_file_id_;
|
||||||
|
|
||||||
// If file reference is needed
|
// If file reference is needed
|
||||||
if (!file_view.has_active_remote_location()) {
|
if (!file_view.has_active_download_remote_location()) {
|
||||||
VLOG(file_references) << "run_download: Do not have valid file_reference for file " << file_id;
|
VLOG(file_references) << "run_download: Do not have valid file_reference for file " << file_id;
|
||||||
QueryId id = queries_container_.create(Query{file_id, Query::DownloadWaitFileReferece});
|
QueryId id = queries_container_.create(Query{file_id, Query::DownloadWaitFileReferece});
|
||||||
node->download_id_ = id;
|
node->download_id_ = id;
|
||||||
@ -1850,8 +1860,8 @@ void FileManager::resume_upload(FileId file_id, std::vector<int> bad_parts, std:
|
|||||||
node->set_upload_pause(FileId());
|
node->set_upload_pause(FileId());
|
||||||
}
|
}
|
||||||
FileView file_view(node);
|
FileView file_view(node);
|
||||||
if (file_view.has_active_remote_location() && file_view.get_type() != FileType::Thumbnail &&
|
if (file_view.has_active_upload_remote_location() && file_view.get_type() != FileType::Thumbnail &&
|
||||||
file_view.get_type() != FileType::EncryptedThumbnail && file_view.get_type() != FileType::Photo) {
|
file_view.get_type() != FileType::EncryptedThumbnail) {
|
||||||
LOG(INFO) << "File " << file_id << " is already uploaded";
|
LOG(INFO) << "File " << file_id << " is already uploaded";
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback->on_upload_ok(file_id, nullptr);
|
callback->on_upload_ok(file_id, nullptr);
|
||||||
@ -2085,9 +2095,9 @@ void FileManager::run_upload(FileNodePtr node, std::vector<int> bad_parts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CHECK(node->upload_id_ == 0);
|
CHECK(node->upload_id_ == 0);
|
||||||
if (file_view.has_remote_location() && !file_view.has_active_remote_location() &&
|
if (file_view.has_remote_location() && !file_view.has_active_upload_remote_location() &&
|
||||||
file_view.get_type() != FileType::Photo && file_view.get_type() != FileType::Thumbnail &&
|
file_view.get_type() != FileType::Thumbnail && file_view.get_type() != FileType::EncryptedThumbnail &&
|
||||||
file_view.get_type() != FileType::EncryptedThumbnail && !node->upload_was_update_file_reference_) {
|
!node->upload_was_update_file_reference_) {
|
||||||
QueryId id = queries_container_.create(Query{file_id, Query::UploadWaitFileReference});
|
QueryId id = queries_container_.create(Query{file_id, Query::UploadWaitFileReference});
|
||||||
node->upload_id_ = id;
|
node->upload_id_ = id;
|
||||||
node->upload_was_update_file_reference_ = true;
|
node->upload_was_update_file_reference_ = true;
|
||||||
|
@ -212,7 +212,8 @@ class FileView {
|
|||||||
bool has_local_location() const;
|
bool has_local_location() const;
|
||||||
const FullLocalFileLocation &local_location() const;
|
const FullLocalFileLocation &local_location() const;
|
||||||
bool has_remote_location() const;
|
bool has_remote_location() const;
|
||||||
bool has_active_remote_location() const;
|
bool has_active_upload_remote_location() const;
|
||||||
|
bool has_active_download_remote_location() const;
|
||||||
const FullRemoteFileLocation &remote_location() const;
|
const FullRemoteFileLocation &remote_location() const;
|
||||||
bool has_generate_location() const;
|
bool has_generate_location() const;
|
||||||
const FullGenerateFileLocation &generate_location() const;
|
const FullGenerateFileLocation &generate_location() const;
|
||||||
|
Reference in New Issue
Block a user