diff --git a/td/telegram/files/FileGenerateManager.cpp b/td/telegram/files/FileGenerateManager.cpp index d04930f6..ade86e8a 100644 --- a/td/telegram/files/FileGenerateManager.cpp +++ b/td/telegram/files/FileGenerateManager.cpp @@ -20,6 +20,7 @@ #include "td/utils/common.h" #include "td/utils/logging.h" #include "td/utils/misc.h" +#include "td/utils/Parser.h" #include "td/utils/port/path.h" #include "td/utils/Slice.h" @@ -342,9 +343,39 @@ FileGenerateManager::Query::~Query() = default; FileGenerateManager::Query::Query(Query &&other) = default; FileGenerateManager::Query &FileGenerateManager::Query::operator=(Query &&other) = default; -void FileGenerateManager::generate_file(uint64 query_id, const FullGenerateFileLocation &generate_location, +Status check_mtime(std::string &conversion, CSlice original_path) { + if (original_path.empty()) { + return Status::OK(); + } + Parser parser(conversion); + if (!parser.skip_start_with("#mtime#")) { + return td::Status::OK(); + } + auto mtime_str = parser.read_till('#'); + parser.skip('#'); + auto r_mtime = to_integer_safe(mtime_str); + if (parser.status().is_error() || r_mtime.is_error()) { + return td::Status::OK(); + } + auto expected_mtime = r_mtime.move_as_ok(); + conversion = parser.read_all().str(); + auto r_stat = stat(original_path); + uint64 actual_mtime = r_stat.is_ok() ? r_stat.ok().mtime_nsec_ : 0; + if (expected_mtime == actual_mtime) { + return td::Status::OK(); + } + return td::Status::Error(PSLICE() << "mtime changed " << tag("file", original_path) + << tag("expected mtime", expected_mtime) << tag("actual mtime", actual_mtime)); +} + +void FileGenerateManager::generate_file(uint64 query_id, FullGenerateFileLocation generate_location, const LocalFileLocation &local_location, string name, unique_ptr callback) { + auto mtime_status = check_mtime(generate_location.conversion_, generate_location.original_path_); + if (mtime_status.is_error()) { + return callback->on_error(std::move(mtime_status)); + } + CHECK(query_id != 0); auto it_flag = query_id_to_query_.insert(std::make_pair(query_id, Query{})); CHECK(it_flag.second) << "Query id must be unique"; diff --git a/td/telegram/files/FileGenerateManager.h b/td/telegram/files/FileGenerateManager.h index 312fe9ba..6a78ca7c 100644 --- a/td/telegram/files/FileGenerateManager.h +++ b/td/telegram/files/FileGenerateManager.h @@ -35,7 +35,7 @@ class FileGenerateManager : public Actor { explicit FileGenerateManager(ActorShared<> parent) : parent_(std::move(parent)) { } - void generate_file(uint64 query_id, const FullGenerateFileLocation &generate_location, + void generate_file(uint64 query_id, FullGenerateFileLocation generate_location, const LocalFileLocation &local_location, string name, unique_ptr callback); void cancel(uint64 query_id); diff --git a/td/telegram/files/FileManager.cpp b/td/telegram/files/FileManager.cpp index fd49ba7e..fd69e669 100644 --- a/td/telegram/files/FileManager.cpp +++ b/td/telegram/files/FileManager.cpp @@ -697,6 +697,15 @@ FileId FileManager::register_url(string url, FileType file_type, FileLocationSou Result FileManager::register_generate(FileType file_type, FileLocationSource file_location_source, string original_path, string conversion, DialogId owner_dialog_id, int64 expected_size) { + // add #mtime# into conversion + if (!original_path.empty() && !begins_with(conversion, "#mtime#") && !begins_with(conversion, "#file_id#") && + !begins_with(conversion, "#map#")) { + auto r_stat = stat(original_path); + uint64 mtime = r_stat.is_ok() ? r_stat.ok().mtime_nsec_ : 0; + auto new_conversion = PSTRING() << "#mtime#" << mtime << "#" << conversion; + conversion = std::move(new_conversion); + } + FileData data; data.generate_ = td::make_unique(file_type, std::move(original_path), std::move(conversion));