Add td_api::getLanguagePackString.

GitOrigin-RevId: 37ee2203264bb78ed3de88c21350a99212d89c3e
This commit is contained in:
levlam 2018-07-23 20:29:14 +03:00
parent 5e12e43b06
commit 4717e5529a
7 changed files with 107 additions and 36 deletions

View File

@ -2609,6 +2609,9 @@ getFileExtension mime_type:string = Text;
//@description Removes potentially dangerous characters from the name of a file. The encoding of the file name is supposed to be UTF-8. Returns an empty string on failure. This is an offline method. Can be called before authorization. Can be called synchronously @file_name File name or path to the file //@description Removes potentially dangerous characters from the name of a file. The encoding of the file name is supposed to be UTF-8. Returns an empty string on failure. This is an offline method. Can be called before authorization. Can be called synchronously @file_name File name or path to the file
cleanFileName file_name:string = Text; cleanFileName file_name:string = Text;
//@description Returns a string stored in a local database from specified language pack and language by its key. Returns a 404 error if the string is not found. This is an offline method. Can be called before authorization. Can be called synchronously @language_database_path Path to a language database in which strings are stored @language_pack Language pack of string to return @language_code Language code of string to return @key Language pack key of string to return
getLanguagePackString language_database_path:string language_pack:string language_code:string key:string = LanguagePackString;
//@description Sends an inline query to a bot and returns its results. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires @bot_user_id The identifier of the target bot //@description Sends an inline query to a bot and returns its results. Returns an error with code 502 if the bot fails to answer the query before the query timeout expires @bot_user_id The identifier of the target bot
//@chat_id Identifier of the chat, where the query was sent @user_location Location of the user, only if needed @query Text of the query @offset Offset of the first entry to return //@chat_id Identifier of the chat, where the query was sent @user_location Location of the user, only if needed @query Text of the query @offset Offset of the first entry to return

Binary file not shown.

View File

@ -102,6 +102,29 @@ static int32 load_database_language_version(SqliteKeyValue *kv) {
return to_integer<int32>(str_version); return to_integer<int32>(str_version);
} }
LanguagePackManager::LanguageDatabase *LanguagePackManager::add_language_database(const string &path) {
auto it = language_databases_.find(path);
if (it != language_databases_.end()) {
return it->second.get();
}
SqliteDb database;
if (!path.empty()) {
auto r_database = open_database(path);
if (r_database.is_error()) {
LOG(ERROR) << "Can't open language database " << path << ": " << r_database.error();
return add_language_database(string());
}
database = r_database.move_as_ok();
}
it = language_databases_.emplace(path, make_unique<LanguageDatabase>()).first;
it->second->path_ = std::move(path);
it->second->database_ = std::move(database);
return it->second.get();
}
void LanguagePackManager::start_up() { void LanguagePackManager::start_up() {
std::lock_guard<std::mutex> lock(language_database_mutex_); std::lock_guard<std::mutex> lock(language_database_mutex_);
manager_count_++; manager_count_++;
@ -110,29 +133,7 @@ void LanguagePackManager::start_up() {
CHECK(check_language_pack_name(language_pack_)); CHECK(check_language_pack_name(language_pack_));
CHECK(check_language_code_name(language_code_)); CHECK(check_language_code_name(language_code_));
string database_path = G()->shared_config().get_option_string("language_database_path"); database_ = add_language_database(G()->shared_config().get_option_string("language_database_path"));
auto it = language_databases_.find(database_path);
if (it == language_databases_.end()) {
SqliteDb database;
if (!database_path.empty()) {
auto r_database = open_database(database_path);
if (r_database.is_error()) {
LOG(ERROR) << "Can't open language database " << database_path << ": " << r_database.error();
database_path = string();
it = language_databases_.find(database_path);
} else {
database = r_database.move_as_ok();
}
}
if (it == language_databases_.end()) {
it = language_databases_.emplace(database_path, make_unique<LanguageDatabase>()).first;
it->second->path_ = std::move(database_path);
it->second->database_ = std::move(database);
}
}
database_ = it->second.get();
auto language = add_language(database_, language_pack_, language_code_); auto language = add_language(database_, language_pack_, language_code_);
LOG(INFO) << "Use language pack " << language_pack_ << " with language " << language_code_ << " of version " LOG(INFO) << "Use language pack " << language_pack_ << " with language " << language_code_ << " of version "
@ -412,6 +413,21 @@ td_api::object_ptr<td_api::LanguagePackString> LanguagePackManager::get_language
return td_api::make_object<td_api::languagePackStringDeleted>(str); return td_api::make_object<td_api::languagePackStringDeleted>(str);
} }
td_api::object_ptr<td_api::LanguagePackString> LanguagePackManager::get_language_pack_string_object(Language *language,
const string &key) {
CHECK(language != nullptr);
auto ordinary_it = language->ordinary_strings_.find(key);
if (ordinary_it != language->ordinary_strings_.end()) {
return get_language_pack_string_object(*ordinary_it);
}
auto pluralized_it = language->pluralized_strings_.find(key);
if (pluralized_it != language->pluralized_strings_.end()) {
return get_language_pack_string_object(*pluralized_it);
}
LOG_IF(ERROR, !language->is_full_ && language->deleted_strings_.count(key) == 0) << "Have no string for key " << key;
return get_language_pack_string_object(key);
}
td_api::object_ptr<td_api::languagePackStrings> LanguagePackManager::get_language_pack_strings_object( td_api::object_ptr<td_api::languagePackStrings> LanguagePackManager::get_language_pack_strings_object(
Language *language, const vector<string> &keys) { Language *language, const vector<string> &keys) {
CHECK(language != nullptr); CHECK(language != nullptr);
@ -427,19 +443,7 @@ td_api::object_ptr<td_api::languagePackStrings> LanguagePackManager::get_languag
} }
} else { } else {
for (auto &key : keys) { for (auto &key : keys) {
auto ordinary_it = language->ordinary_strings_.find(key); strings.push_back(get_language_pack_string_object(language, key));
if (ordinary_it != language->ordinary_strings_.end()) {
strings.push_back(get_language_pack_string_object(*ordinary_it));
continue;
}
auto pluralized_it = language->pluralized_strings_.find(key);
if (pluralized_it != language->pluralized_strings_.end()) {
strings.push_back(get_language_pack_string_object(*pluralized_it));
continue;
}
LOG_IF(ERROR, !language->is_full_ && language->deleted_strings_.count(key) == 0)
<< "Have no string for key " << key;
strings.push_back(get_language_pack_string_object(key));
} }
} }
@ -525,6 +529,37 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector
} }
} }
td_api::object_ptr<td_api::Object> LanguagePackManager::get_language_pack_string(const string &database_path,
const string &language_pack,
const string &language_code,
const string &key) {
if (!check_language_pack_name(language_pack) || language_pack.empty()) {
return td_api::make_object<td_api::error>(400, "Language pack is invalid");
}
if (!check_language_code_name(language_code) || language_code.empty()) {
return td_api::make_object<td_api::error>(400, "Language code is invalid");
}
if (!is_valid_key(key)) {
return td_api::make_object<td_api::error>(400, "Key is invalid");
}
std::unique_lock<std::mutex> language_databases_lock(language_database_mutex_);
LanguageDatabase *database = add_language_database(database_path);
CHECK(database != nullptr);
language_databases_lock.unlock();
Language *language = add_language(database, language_pack, language_code);
vector<string> keys{key};
if (language_has_strings(language, keys)) {
std::lock_guard<std::mutex> lock(language->mutex_);
return get_language_pack_string_object(language, key);
}
if (!database->database_.empty() && load_language_strings(database, language, keys)) {
return get_language_pack_string_object(language, key);
}
return td_api::make_object<td_api::error>(404, "Not Found");
}
bool LanguagePackManager::is_valid_key(Slice key) { bool LanguagePackManager::is_valid_key(Slice key) {
for (auto c : key) { for (auto c : key) {
if (!is_alnum(c) && c != '_' && c != '.' && c != '-') { if (!is_alnum(c) && c != '_' && c != '.' && c != '-') {

View File

@ -49,6 +49,10 @@ class LanguagePackManager : public NetQueryCallback {
void get_language_pack_strings(string language_code, vector<string> keys, void get_language_pack_strings(string language_code, vector<string> keys,
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise); Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
static td_api::object_ptr<td_api::Object> get_language_pack_string(const string &database_path,
const string &language_pack,
const string &language_code, const string &key);
void on_update_language_pack(tl_object_ptr<telegram_api::langPackDifference> difference); void on_update_language_pack(tl_object_ptr<telegram_api::langPackDifference> difference);
private: private:
@ -68,6 +72,8 @@ class LanguagePackManager : public NetQueryCallback {
static std::mutex language_database_mutex_; static std::mutex language_database_mutex_;
static std::unordered_map<string, std::unique_ptr<LanguageDatabase>> language_databases_; static std::unordered_map<string, std::unique_ptr<LanguageDatabase>> language_databases_;
static LanguageDatabase *add_language_database(const string &path);
static Language *get_language(LanguageDatabase *database, const string &language_pack, const string &language_code); static Language *get_language(LanguageDatabase *database, const string &language_pack, const string &language_code);
static Language *get_language(LanguagePack *language_pack, const string &language_code); static Language *get_language(LanguagePack *language_pack, const string &language_code);
@ -85,6 +91,9 @@ class LanguagePackManager : public NetQueryCallback {
const std::pair<string, PluralizedString> &str); const std::pair<string, PluralizedString> &str);
static td_api::object_ptr<td_api::LanguagePackString> get_language_pack_string_object(const string &str); static td_api::object_ptr<td_api::LanguagePackString> get_language_pack_string_object(const string &str);
static td_api::object_ptr<td_api::LanguagePackString> get_language_pack_string_object(Language *language,
const string &key);
static td_api::object_ptr<td_api::languagePackStrings> get_language_pack_strings_object(Language *language, static td_api::object_ptr<td_api::languagePackStrings> get_language_pack_strings_object(Language *language,
const vector<string> &keys); const vector<string> &keys);

View File

@ -3236,6 +3236,7 @@ bool Td::is_synchronous_request(int32 id) {
case td_api::getFileMimeType::ID: case td_api::getFileMimeType::ID:
case td_api::getFileExtension::ID: case td_api::getFileExtension::ID:
case td_api::cleanFileName::ID: case td_api::cleanFileName::ID:
case td_api::getLanguagePackString::ID:
return true; return true;
default: default:
return false; return false;
@ -6618,6 +6619,10 @@ void Td::on_request(uint64 id, const td_api::cleanFileName &request) {
send_closure(actor_id(this), &Td::send_result, id, do_static_request(request)); send_closure(actor_id(this), &Td::send_result, id, do_static_request(request));
} }
void Td::on_request(uint64 id, const td_api::getLanguagePackString &request) {
send_closure(actor_id(this), &Td::send_result, id, do_static_request(request));
}
template <class T> template <class T>
td_api::object_ptr<td_api::Object> Td::do_static_request(const T &request) { td_api::object_ptr<td_api::Object> Td::do_static_request(const T &request) {
return make_error(400, "Function can't be executed synchronously"); return make_error(400, "Function can't be executed synchronously");
@ -6672,6 +6677,11 @@ td_api::object_ptr<td_api::Object> Td::do_static_request(const td_api::cleanFile
return make_tl_object<td_api::text>(clean_filename(request.file_name_)); return make_tl_object<td_api::text>(clean_filename(request.file_name_));
} }
td_api::object_ptr<td_api::Object> Td::do_static_request(const td_api::getLanguagePackString &request) {
return LanguagePackManager::get_language_pack_string(request.language_database_path_, request.language_pack_,
request.language_code_, request.key_);
}
// test // test
void Td::on_request(uint64 id, td_api::testNetwork &request) { void Td::on_request(uint64 id, td_api::testNetwork &request) {
create_handler<TestQuery>(id)->send(); create_handler<TestQuery>(id)->send();

View File

@ -871,6 +871,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::cleanFileName &request); void on_request(uint64 id, const td_api::cleanFileName &request);
void on_request(uint64 id, const td_api::getLanguagePackString &request);
// test // test
void on_request(uint64 id, td_api::testNetwork &request); void on_request(uint64 id, td_api::testNetwork &request);
void on_request(uint64 id, td_api::testGetDifference &request); void on_request(uint64 id, td_api::testGetDifference &request);
@ -892,6 +894,7 @@ class Td final : public NetQueryCallback {
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::getFileMimeType &request); static td_api::object_ptr<td_api::Object> do_static_request(const td_api::getFileMimeType &request);
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::getFileExtension &request); static td_api::object_ptr<td_api::Object> do_static_request(const td_api::getFileExtension &request);
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::cleanFileName &request); static td_api::object_ptr<td_api::Object> do_static_request(const td_api::cleanFileName &request);
static td_api::object_ptr<td_api::Object> do_static_request(const td_api::getLanguagePackString &request);
Status init(DbKey key) TD_WARN_UNUSED_RESULT; Status init(DbKey key) TD_WARN_UNUSED_RESULT;
void clear(); void clear();

View File

@ -1741,6 +1741,17 @@ class CliClient final : public Actor {
std::tie(language_code, keys) = split(args); std::tie(language_code, keys) = split(args);
send_request(make_tl_object<td_api::getLanguagePackStrings>(language_code, full_split(keys))); send_request(make_tl_object<td_api::getLanguagePackStrings>(language_code, full_split(keys)));
} else if (op == "glpss") {
string language_database_path;
string language_pack;
string language_code;
string key;
std::tie(language_database_path, args) = split(args);
std::tie(language_pack, args) = split(args);
std::tie(language_code, key) = split(args);
send_request(
make_tl_object<td_api::getLanguagePackString>(language_database_path, language_pack, language_code, key));
} else if (op == "go") { } else if (op == "go") {
send_request(make_tl_object<td_api::getOption>(args)); send_request(make_tl_object<td_api::getOption>(args));
} else if (op == "sob") { } else if (op == "sob") {