diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 3cd0c63e..370fb829 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1703,21 +1703,24 @@ chatEvents events:vector = ChatEvents; chatEventLogFilters message_edits:Bool message_deletions:Bool message_pins:Bool member_joins:Bool member_leaves:Bool member_invites:Bool member_promotions:Bool member_restrictions:Bool info_changes:Bool setting_changes:Bool = ChatEventLogFilters; -//@class LanguagePackString @description Represents one language pack string +//@class LanguagePackStringValue @description Represents a value of language pack string -//@description An ordinary language pack string @key String key @value String value -languagePackStringValue key:string value:string = LanguagePackString; +//@description An ordinary language pack string @value String value +languagePackStringValueOrdinary value:string = LanguagePackStringValue; -//@description A language pack string, which has different forms based on some quantity @key String key @zero_value Value for zero objects @one_value Value for one object @two_value Value for two objects +//@description A language pack string, which has different forms based on some quantity @zero_value Value for zero objects @one_value Value for one object @two_value Value for two objects //@few_value Value for few objects @many_value Value for many objects @other_value Default value -languagePackStringPluralized key:string zero_value:string one_value:string two_value:string few_value:string many_value:string other_value:string = LanguagePackString; +languagePackStringValuePluralized zero_value:string one_value:string two_value:string few_value:string many_value:string other_value:string = LanguagePackStringValue; -//@description A deleted language pack string, the value should be taken from a built-in english language pack @key String key -languagePackStringDeleted key:string = LanguagePackString; +//@description A deleted language pack string, the value should be taken from a built-in english language pack +languagePackStringValueDeleted = LanguagePackStringValue; +//@description Represents one language pack string @key String key @value String value +languagePackString key:string value:LanguagePackStringValue = LanguagePackString; + //@description Contains a list of language pack strings @strings A list of language pack strings -languagePackStrings strings:vector = LanguagePackStrings; +languagePackStrings strings:vector = LanguagePackStrings; //@description Contains information about a language @code Language code @name Language name @native_name Language native name languageInfo code:string name:string native_name:string = LanguageInfo; @@ -2268,7 +2271,7 @@ updateFavoriteStickers sticker_ids:vector = Update; updateSavedAnimations animation_ids:vector = Update; //@description Some language pack strings was updated @language_pack Changed language pack @language_code Code of the language, which was updated @strings List of changed language pack strings -updateLanguagePackStrings language_pack:string language_code:string strings:vector = Update; +updateLanguagePackStrings language_pack:string language_code:string strings:vector = Update; //@description The connection state has changed @state The new connection state updateConnectionState state:ConnectionState = Update; @@ -2646,7 +2649,7 @@ getFileExtension mime_type: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; +getLanguagePackString language_database_path:string language_pack:string language_code:string key:string = LanguagePackStringValue; //@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 @@ -3134,10 +3137,10 @@ getLanguagePackInfo = LanguagePack; getLanguagePackStrings language_code:string keys:vector = LanguagePackStrings; //@description Adds or changes a custom language to the used language pack @info Information about the language. Language code must start with 'X' @strings New language pack strings -setCustomLanguage info:languageInfo strings:vector = Ok; +setCustomLanguage info:languageInfo strings:vector = Ok; -//@description Sets new value for a string in a custom language in the used language pack @language_code The code of previously added custom language, must start with 'X' @string New language pack string -setCustomLanguageString language_code:string string:LanguagePackString = Ok; +//@description Sets new value for a string in a custom language in the used language pack @language_code The code of previously added custom language, must start with 'X' @new_string New language pack string +setCustomLanguageString language_code:string new_string:languagePackString = Ok; //@description Deletes all information about a language in the used language pack. Currently used language can't be deleted @language_code Language code of a language to delete deleteLanguage language_code:string = Ok; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index d7ea2441..529a16a4 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/LanguagePackManager.cpp b/td/telegram/LanguagePackManager.cpp index be95e9f1..0a7735bb 100644 --- a/td/telegram/LanguagePackManager.cpp +++ b/td/telegram/LanguagePackManager.cpp @@ -430,35 +430,53 @@ bool LanguagePackManager::load_language_strings(LanguageDatabase *database, Lang return true; } -td_api::object_ptr LanguagePackManager::get_language_pack_string_object( +td_api::object_ptr LanguagePackManager::get_language_pack_string_value_object( + const string &value) { + return td_api::make_object(value); +} + +td_api::object_ptr LanguagePackManager::get_language_pack_string_value_object( + const PluralizedString &value) { + return td_api::make_object( + value.zero_value_, value.one_value_, value.two_value_, value.few_value_, value.many_value_, value.other_value_); +} + +td_api::object_ptr LanguagePackManager::get_language_pack_string_value_object() { + return td_api::make_object(); +} + +td_api::object_ptr LanguagePackManager::get_language_pack_string_object( const std::pair &str) { - return td_api::make_object(str.first, str.second); + return td_api::make_object(str.first, get_language_pack_string_value_object(str.second)); } -td_api::object_ptr LanguagePackManager::get_language_pack_string_object( +td_api::object_ptr LanguagePackManager::get_language_pack_string_object( const std::pair &str) { - return td_api::make_object( - str.first, str.second.zero_value_, str.second.one_value_, str.second.two_value_, str.second.few_value_, - str.second.many_value_, str.second.other_value_); + return td_api::make_object(str.first, get_language_pack_string_value_object(str.second)); } -td_api::object_ptr LanguagePackManager::get_language_pack_string_object(const string &str) { - return td_api::make_object(str); +td_api::object_ptr LanguagePackManager::get_language_pack_string_object(const string &str) { + return td_api::make_object(str, get_language_pack_string_value_object()); } -td_api::object_ptr LanguagePackManager::get_language_pack_string_object(Language *language, - const string &key) { +td_api::object_ptr LanguagePackManager::get_language_pack_string_value_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); + return get_language_pack_string_value_object(ordinary_it->second); } auto pluralized_it = language->pluralized_strings_.find(key); if (pluralized_it != language->pluralized_strings_.end()) { - return get_language_pack_string_object(*pluralized_it); + return get_language_pack_string_value_object(pluralized_it->second); } 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); + return get_language_pack_string_value_object(key); +} + +td_api::object_ptr LanguagePackManager::get_language_pack_string_object(Language *language, + const string &key) { + return td_api::make_object(key, get_language_pack_string_value_object(language, key)); } td_api::object_ptr LanguagePackManager::get_language_pack_strings_object( @@ -466,7 +484,7 @@ td_api::object_ptr LanguagePackManager::get_languag CHECK(language != nullptr); std::lock_guard lock(language->mutex_); - vector> strings; + vector> strings; if (keys.empty()) { for (auto &str : language->ordinary_strings_) { strings.push_back(get_language_pack_string_object(str)); @@ -597,10 +615,10 @@ td_api::object_ptr LanguagePackManager::get_language_pack_string vector keys{key}; if (language_has_strings(language, keys)) { std::lock_guard lock(language->mutex_); - return get_language_pack_string_object(language, key); + return get_language_pack_string_value_object(language, key); } if (!database->database_.empty() && load_language_strings(database, language, keys)) { - return get_language_pack_string_object(language, key); + return get_language_pack_string_value_object(language, key); } return td_api::make_object(404, "Not Found"); } @@ -669,7 +687,7 @@ void LanguagePackManager::on_get_language_pack_strings( } std::lock_guard lock(language->mutex_); if (language->version_ < version || !keys.empty()) { - vector> strings; + vector> strings; if (language->version_ < version && !(is_diff && language->version_ == -1)) { LOG(INFO) << "Set language " << language_code << " version to " << version; language->version_ = version; @@ -793,26 +811,29 @@ void LanguagePackManager::on_failed_get_difference(string language_pack, string } Result> LanguagePackManager::convert_to_telegram_api( - tl_object_ptr &&str) { + tl_object_ptr &&str) { if (str == nullptr) { return Status::Error(400, "Language strings must not be null"); } - string key; - downcast_call(*str, [&key](auto &value) { key = std::move(value.key_); }); + string key = std::move(str->key_); if (!is_valid_key(key)) { return Status::Error(400, "Key is invalid"); } - switch (str->get_id()) { - case td_api::languagePackStringValue::ID: { - auto value = static_cast(str.get()); + + if (str->value_ == nullptr) { + return make_tl_object(std::move(key)); + } + switch (str->value_->get_id()) { + case td_api::languagePackStringValueOrdinary::ID: { + auto value = static_cast(str->value_.get()); if (!clean_input_string(value->value_)) { return Status::Error(400, "Strings must be encoded in UTF-8"); } return make_tl_object(std::move(key), std::move(value->value_)); } - case td_api::languagePackStringPluralized::ID: { - auto value = static_cast(str.get()); + case td_api::languagePackStringValuePluralized::ID: { + auto value = static_cast(str->value_.get()); if (!clean_input_string(value->zero_value_) || !clean_input_string(value->one_value_) || !clean_input_string(value->two_value_) || !clean_input_string(value->few_value_) || !clean_input_string(value->many_value_) || !clean_input_string(value->other_value_)) { @@ -822,7 +843,7 @@ Result> LanguagePackManager::convert 31, std::move(key), std::move(value->zero_value_), std::move(value->one_value_), std::move(value->two_value_), std::move(value->few_value_), std::move(value->many_value_), std::move(value->other_value_)); } - case td_api::languagePackStringDeleted::ID: + case td_api::languagePackStringValueDeleted::ID: // there is no reason to save deleted strings in a custom language pack to database return make_tl_object(std::move(key)); default: @@ -832,7 +853,7 @@ Result> LanguagePackManager::convert } void LanguagePackManager::set_custom_language(string language_code, string language_name, string language_native_name, - vector> strings, + vector> strings, Promise &&promise) { if (!check_language_code_name(language_code)) { return promise.set_error(Status::Error(400, "Language code name must contain only letters and hyphen")); @@ -869,7 +890,7 @@ void LanguagePackManager::set_custom_language(string language_code, string langu } void LanguagePackManager::set_custom_language_string(string language_code, - tl_object_ptr str, + tl_object_ptr str, Promise &&promise) { if (!check_language_code_name(language_code)) { return promise.set_error(Status::Error(400, "Language code name must contain only letters and hyphen")); @@ -881,12 +902,12 @@ void LanguagePackManager::set_custom_language_string(string language_code, if (get_language(database_, language_pack_, language_code) == nullptr) { return promise.set_error(Status::Error(400, "Custom language not found")); } - - string key; - if (str != nullptr) { - downcast_call(*str, [&key](auto &value) { key = value.key_; }); + if (str == nullptr) { + return promise.set_error(Status::Error(400, "Language strings must not be null")); } + vector keys{str->key_}; + auto r_str = convert_to_telegram_api(std::move(str)); if (r_str.is_error()) { return promise.set_error(r_str.move_as_error()); @@ -895,7 +916,7 @@ void LanguagePackManager::set_custom_language_string(string language_code, vector> server_strings; server_strings.push_back(r_str.move_as_ok()); - on_get_language_pack_strings(language_pack_, language_code, 1, true, {std::move(key)}, std::move(server_strings), + on_get_language_pack_strings(language_pack_, language_code, 1, true, std::move(keys), std::move(server_strings), Auto()); promise.set_value(Unit()); } diff --git a/td/telegram/LanguagePackManager.h b/td/telegram/LanguagePackManager.h index 262d958b..51a5eac4 100644 --- a/td/telegram/LanguagePackManager.h +++ b/td/telegram/LanguagePackManager.h @@ -58,9 +58,9 @@ class LanguagePackManager : public NetQueryCallback { void on_update_language_pack(tl_object_ptr difference); void set_custom_language(string language_code, string language_name, string language_native_name, - vector> strings, Promise &&promise); + vector> strings, Promise &&promise); - void set_custom_language_string(string language_code, tl_object_ptr str, + void set_custom_language_string(string language_code, tl_object_ptr str, Promise &&promise); void delete_language(string language_code, Promise &&promise); @@ -96,20 +96,28 @@ class LanguagePackManager : public NetQueryCallback { static void load_language_string_unsafe(Language *language, const string &key, string &value); static bool load_language_strings(LanguageDatabase *database, Language *language, const vector &keys); - static td_api::object_ptr get_language_pack_string_object( - const std::pair &str); - static td_api::object_ptr get_language_pack_string_object( - const std::pair &str); - static td_api::object_ptr get_language_pack_string_object(const string &str); + static td_api::object_ptr get_language_pack_string_value_object(const string &value); + static td_api::object_ptr get_language_pack_string_value_object( + const PluralizedString &value); + static td_api::object_ptr get_language_pack_string_value_object(); - static td_api::object_ptr get_language_pack_string_object(Language *language, + static td_api::object_ptr get_language_pack_string_object( + const std::pair &str); + static td_api::object_ptr get_language_pack_string_object( + const std::pair &str); + static td_api::object_ptr get_language_pack_string_object(const string &str); + + static td_api::object_ptr get_language_pack_string_value_object(Language *language, + const string &key); + + static td_api::object_ptr get_language_pack_string_object(Language *language, const string &key); static td_api::object_ptr get_language_pack_strings_object(Language *language, const vector &keys); static Result> convert_to_telegram_api( - tl_object_ptr &&str); + tl_object_ptr &&str); void inc_generation(); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 32dce692..bad98a25 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6059,7 +6059,7 @@ void Td::on_request(uint64 id, td_api::setCustomLanguageString &request) { CLEAN_INPUT_STRING(request.language_code_); CREATE_OK_REQUEST_PROMISE(); send_closure(language_pack_manager_, &LanguagePackManager::set_custom_language_string, - std::move(request.language_code_), std::move(request.string_), std::move(promise)); + std::move(request.language_code_), std::move(request.new_string_), std::move(promise)); } void Td::on_request(uint64 id, td_api::deleteLanguage &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 992afd88..866975e0 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1778,11 +1778,14 @@ class CliClient final : public Actor { std::tie(name, args) = split(args); std::tie(native_name, key) = split(args); - vector> strings; - strings.push_back(make_tl_object(key, "Ordinary value")); - strings.push_back(make_tl_object("Plu", "Zero", string("One\0One", 7), - "Two", "Few", "Many", "Other")); - strings.push_back(make_tl_object("DELETED")); + vector> strings; + strings.push_back(make_tl_object( + key, make_tl_object("Ordinary value"))); + strings.push_back(make_tl_object( + "Plu", make_tl_object("Zero", string("One\0One", 7), "Two", "Few", + "Many", "Other"))); + strings.push_back(make_tl_object( + "DELETED", make_tl_object())); send_request(make_tl_object( make_tl_object(language_code, name, native_name), std::move(strings))); @@ -1794,14 +1797,14 @@ class CliClient final : public Actor { std::tie(language_code, args) = split(args); std::tie(key, value) = split(args); - tl_object_ptr str; + tl_object_ptr str = make_tl_object(key, nullptr); if (op == "sclsv") { - str = make_tl_object(key, value); + str->value_ = make_tl_object(value); } else if (op == "sclsp") { - str = make_tl_object(key, value, string("One\0One", 7), "Two", "Few", - "Many", "Other"); + str->value_ = make_tl_object(value, string("One\0One", 7), "Two", + "Few", "Many", "Other"); } else { - str = make_tl_object(key); + str->value_ = make_tl_object(); } send_request(make_tl_object(language_code, std::move(str)));