Add td_api::getSuggestedFileName.

This commit is contained in:
levlam 2021-07-24 07:19:22 +03:00
parent 796287d254
commit 07630feb8c
8 changed files with 80 additions and 0 deletions

View File

@ -4636,6 +4636,9 @@ getFileDownloadedPrefixSize file_id:int32 offset:int32 = Count;
//@description Stops the downloading of a file. If a file has already been downloaded, does nothing @file_id Identifier of a file to stop downloading @only_if_pending Pass true to stop downloading only if it hasn't been started, i.e. request hasn't been sent to server
cancelDownloadFile file_id:int32 only_if_pending:Bool = Ok;
//@description Returns suggested name for saving a file in a given directory @file_id Identifier of the file @directory Directory in which the file is supposed to be saved
getSuggestedFileName file_id:int32 directory:string = Text;
//@description Asynchronously uploads a file to the cloud without sending it in a message. updateFile will be used to notify about upload progress and successful completion of the upload. The file will not have a persistent remote identifier until it will be sent in a message @file File to upload @file_type File type
//@priority Priority of the upload (1-32). The higher the priority, the earlier the file will be uploaded. If the priorities of two files are equal, then the first one for which uploadFile was called will be uploaded first
uploadFile file:InputFile file_type:FileType priority:int32 = File;

View File

@ -6668,6 +6668,14 @@ void Td::on_request(uint64 id, const td_api::cancelDownloadFile &request) {
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
}
void Td::on_request(uint64 id, const td_api::getSuggestedFileName &request) {
Result<string> r_file_name = file_manager_->get_suggested_file_name(FileId(request.file_id_, 0), request.directory_);
if (r_file_name.is_error()) {
return send_closure(actor_id(this), &Td::send_error, id, r_file_name.move_as_error());
}
send_closure(actor_id(this), &Td::send_result, id, td_api::make_object<td_api::text>(r_file_name.ok()));
}
void Td::on_request(uint64 id, td_api::uploadFile &request) {
auto priority = request.priority_;
if (!(1 <= priority && priority <= 32)) {

View File

@ -874,6 +874,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::cancelDownloadFile &request);
void on_request(uint64 id, const td_api::getSuggestedFileName &request);
void on_request(uint64 id, td_api::uploadFile &request);
void on_request(uint64 id, const td_api::cancelUploadFile &request);

View File

@ -2666,6 +2666,11 @@ class CliClient final : public Actor {
}
} else if (op == "cdf") {
send_request(td_api::make_object<td_api::cancelDownloadFile>(as_file_id(args), false));
} else if (op == "gsfn") {
string file_id;
string directory_name;
get_args(args, file_id, directory_name);
send_request(td_api::make_object<td_api::getSuggestedFileName>(as_file_id(file_id), directory_name));
} else if (op == "uf" || op == "ufs" || op == "ufse") {
string file_path;
int32 priority;

View File

@ -16,6 +16,7 @@
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "td/utils/PathView.h"
#include "td/utils/port/Clocks.h"
#include "td/utils/port/FileFd.h"
#include "td/utils/port/path.h"
#include "td/utils/Random.h"
@ -137,6 +138,51 @@ Result<string> search_file(CSlice dir, CSlice name, int64 expected_size) {
return res;
}
Result<string> get_suggested_file_name(CSlice directory, Slice file_name) {
string cleaned_name = clean_filename(file_name.str());
file_name = cleaned_name;
if (directory.empty()) {
directory = "./";
}
auto dir_stat = stat(directory);
if (dir_stat.is_error() || !dir_stat.ok().is_dir_) {
return cleaned_name;
}
PathView path_view(file_name);
auto stem = path_view.file_stem();
auto ext = path_view.extension();
if (stem.empty()) {
return cleaned_name;
}
Slice directory_slice = directory;
while (directory_slice.size() > 1 && (directory_slice.back() == '/' || directory_slice.back() == '\\')) {
directory_slice.remove_suffix(1);
}
auto check_file_name = [directory_slice](Slice name) {
return stat(PSLICE() << directory_slice << TD_DIR_SLASH << name).is_error(); // in case of success, the name is bad
};
string checked_name = PSTRING() << stem << Ext{ext};
if (check_file_name(checked_name)) {
return checked_name;
}
for (int i = 1; i < 100; i++) {
checked_name = PSTRING() << stem << " (" << i << ")" << Ext{ext};
if (check_file_name(checked_name)) {
return checked_name;
}
}
return PSTRING() << stem << " - " << StringBuilder::FixedDouble(Clocks::system(), 3) << Ext{ext};
}
Result<FullLocalFileLocation> save_file_bytes(FileType type, BufferSlice bytes, CSlice file_name) {
auto r_old_path = search_file(get_files_dir(type), file_name, bytes.size());
if (r_old_path.is_ok()) {

View File

@ -28,6 +28,8 @@ Result<string> create_from_temp(CSlice temp_path, CSlice dir, CSlice name) TD_WA
Result<string> search_file(CSlice dir, CSlice name, int64 expected_size) TD_WARN_UNUSED_RESULT;
Result<string> get_suggested_file_name(CSlice dir, Slice file_name) TD_WARN_UNUSED_RESULT;
Result<FullLocalFileLocation> save_file_bytes(FileType type, BufferSlice bytes, CSlice file_name);
Slice get_files_base_dir(FileType file_type);

View File

@ -3844,6 +3844,18 @@ FullRemoteFileLocation *FileManager::get_remote(int32 key) {
return &remote_location_info_.get(key).remote_;
}
Result<string> FileManager::get_suggested_file_name(FileId file_id, const string &directory) {
if (!file_id.is_valid()) {
return Status::Error(400, "Invalid file identifier");
}
auto node = get_sync_file_node(file_id);
if (!node) {
return Status::Error(400, "Wrong file identifier");
}
return ::td::get_suggested_file_name(directory, PathView(node->suggested_path()).file_name());
}
void FileManager::hangup() {
file_db_.reset();
file_generate_manager_.reset();

View File

@ -452,6 +452,8 @@ class FileManager final : public FileLoadManager::Callback {
void delete_file_reference(FileId file_id, std::string file_reference);
void get_content(FileId file_id, Promise<BufferSlice> promise);
Result<string> get_suggested_file_name(FileId file_id, const string &directory);
void read_file_part(FileId file_id, int32 offset, int32 count, int left_tries,
Promise<td_api::object_ptr<td_api::filePart>> promise);