Support new languagePackInfo fields.
GitOrigin-RevId: ad99afe9694458448fddc84803a8beeb33a64a70
This commit is contained in:
parent
9995e9aa5b
commit
350e7fd6fc
@ -91,7 +91,7 @@ authorizationStateWaitPhoneNumber = AuthorizationState;
|
||||
//@description TDLib needs the user's authentication code to finalize authorization @is_registered True, if the user is already registered @terms_of_service Telegram terms of service, which should be accepted before user can continue registration; may be null @code_info Information about the authorization code that was sent
|
||||
authorizationStateWaitCode is_registered:Bool terms_of_service:termsOfService code_info:authenticationCodeInfo = AuthorizationState;
|
||||
|
||||
//@description The user has been authorized, but needs to enter a password to start using the application @password_hint Hint for the password; can be empty @has_recovery_email_address True if a recovery email address has been set up
|
||||
//@description The user has been authorized, but needs to enter a password to start using the application @password_hint Hint for the password; may be empty @has_recovery_email_address True if a recovery email address has been set up
|
||||
//@recovery_email_address_pattern Pattern of the email address to which the recovery email was sent; empty until a recovery email has been sent
|
||||
authorizationStateWaitPassword password_hint:string has_recovery_email_address:Bool recovery_email_address_pattern:string = AuthorizationState;
|
||||
|
||||
@ -109,7 +109,7 @@ authorizationStateClosing = AuthorizationState;
|
||||
authorizationStateClosed = AuthorizationState;
|
||||
|
||||
|
||||
//@description Represents the current state of 2-step verification @has_password True, if a 2-step verification password is set @password_hint Hint for the password; can be empty
|
||||
//@description Represents the current state of 2-step verification @has_password True, if a 2-step verification password is set @password_hint Hint for the password; may be empty
|
||||
//@has_recovery_email_address True, if a recovery email is set @has_passport_data True, if some Telegram Passport elements were saved
|
||||
//@recovery_email_address_code_info Information about the recovery email address to which the confirmation email was sent; may be null
|
||||
passwordState has_password:Bool password_hint:string has_recovery_email_address:Bool has_passport_data:Bool recovery_email_address_code_info:emailAddressAuthenticationCodeInfo = PasswordState;
|
||||
@ -743,8 +743,8 @@ pageBlockVerticalAlignmentBottom = PageBlockVerticalAlignment;
|
||||
//@align Horizontal cell content alignment @valign Vertical cell content alignment
|
||||
pageBlockTableCell text:RichText is_header:Bool colspan:int32 rowspan:int32 align:PageBlockHorizontalAlignment valign:PageBlockVerticalAlignment = PageBlockTableCell;
|
||||
|
||||
//@description Contains information about a related article @url Related article URL @title Article title; can be empty @param_description Article description, can be empty
|
||||
//@photo Article photo; may be null @author Article author, can be empty @published_date Article publish date; 0 if unknown
|
||||
//@description Contains information about a related article @url Related article URL @title Article title; may be empty @param_description Article description; may be empty
|
||||
//@photo Article photo; may be null @author Article author; may be empty @published_date Article publish date; 0 if unknown
|
||||
pageBlockRelatedArticle url:string title:string description:string photo:photo author:string published_date:int32 = PageBlockRelatedArticle;
|
||||
|
||||
|
||||
@ -1118,7 +1118,7 @@ passportRequiredElement suitable_elements:vector<passportSuitableElement> = Pass
|
||||
|
||||
//@description Contains information about a Telegram Passport authorization form that was requested @id Unique identifier of the authorization form
|
||||
//@required_elements Information about the Telegram Passport elements that need to be provided to complete the form
|
||||
//@privacy_policy_url URL for the privacy policy of the service; can be empty
|
||||
//@privacy_policy_url URL for the privacy policy of the service; may be empty
|
||||
passportAuthorizationForm id:int32 required_elements:vector<passportRequiredElement> privacy_policy_url:string = PassportAuthorizationForm;
|
||||
|
||||
//@description Contains information about a Telegram Passport elements and corresponding errors @elements Telegram Passport elements @errors Errors in the elements that are already available
|
||||
@ -1265,7 +1265,7 @@ messageChatSetTtl ttl:int32 = MessageContent;
|
||||
//@description A non-standard action has happened in the chat @text Message text to be shown in the chat
|
||||
messageCustomServiceAction text:string = MessageContent;
|
||||
|
||||
//@description A new high score was achieved in a game @game_message_id Identifier of the message with the game, can be an identifier of a deleted message @game_id Identifier of the game, may be different from the games presented in the message with the game @score New score
|
||||
//@description A new high score was achieved in a game @game_message_id Identifier of the message with the game, can be an identifier of a deleted message @game_id Identifier of the game; may be different from the games presented in the message with the game @score New score
|
||||
messageGameScore game_message_id:int53 game_id:int64 score:int32 = MessageContent;
|
||||
|
||||
//@description A payment has been completed @invoice_message_id Identifier of the message with the corresponding invoice; can be an identifier of a deleted message @currency Currency for the price of the product @total_amount Total price for the product, in the minimal quantity of the currency
|
||||
@ -1804,7 +1804,8 @@ chatEventLogFilters message_edits:Bool message_deletions:Bool message_pins:Bool
|
||||
//@description An ordinary language pack string @value String value
|
||||
languagePackStringValueOrdinary value:string = LanguagePackStringValue;
|
||||
|
||||
//@description A language pack string which has different forms based on the number of some object it mentions @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 the number of some object it mentions. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more info
|
||||
//@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
|
||||
languagePackStringValuePluralized zero_value:string one_value:string two_value:string few_value:string many_value:string other_value:string = LanguagePackStringValue;
|
||||
|
||||
@ -1818,8 +1819,14 @@ languagePackString key:string value:LanguagePackStringValue = LanguagePackString
|
||||
//@description Contains a list of language pack strings @strings A list of language pack strings
|
||||
languagePackStrings strings:vector<languagePackString> = LanguagePackStrings;
|
||||
|
||||
//@description Contains information about a language pack @id Unique language pack identifier @name Language name @native_name Name of the language in that language @local_string_count Total number of non-deleted strings from the language pack available locally
|
||||
languagePackInfo id:string name:string native_name:string local_string_count:int32 = LanguagePackInfo;
|
||||
//@description Contains information about a language pack @id Unique language pack identifier
|
||||
//@base_language_pack_id Identifier of a base language pack; may be empty. If a string is missed in the language pack, then it should be fetched from base language pack. Unsupported in custom language packs
|
||||
//@name Language name @native_name Name of the language in that language
|
||||
//@plural_code A language code to be used to apply plural forms. See https://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html for more info
|
||||
//@is_official True, if the language pack is official @is_rtl True, if the language pack strings are RTL @is_beta True, if the language pack is a beta language pack
|
||||
//@total_string_count Total number of non-deleted strings from the language pack @translated_string_count Total number of translated strings from the language pack
|
||||
//@local_string_count Total number of non-deleted strings from the language pack available locally @translation_url Link to language translation interface; empty for custom local language packs
|
||||
languagePackInfo id:string base_language_pack_id:string name:string native_name:string plural_code:string is_official:Bool is_rtl:Bool is_beta:Bool total_string_count:int32 translated_string_count:int32 local_string_count:int32 translation_url:string = LanguagePackInfo;
|
||||
|
||||
//@description Contains information about the current localization target @language_packs List of available language packs for this application
|
||||
localizationTargetInfo language_packs:vector<languagePackInfo> = LocalizationTargetInfo;
|
||||
@ -3132,7 +3139,7 @@ importContacts contacts:vector<contact> = ImportedContacts;
|
||||
//@description Returns all user contacts
|
||||
getContacts = Users;
|
||||
|
||||
//@description Searches for the specified query in the first names, last names and usernames of the known user contacts @query Query to search for; can be empty to return all contacts @limit Maximum number of users to be returned
|
||||
//@description Searches for the specified query in the first names, last names and usernames of the known user contacts @query Query to search for; may be empty to return all contacts @limit Maximum number of users to be returned
|
||||
searchContacts query:string limit:int32 = Users;
|
||||
|
||||
//@description Removes users from the contact list @user_ids Identifiers of users to be deleted
|
||||
|
Binary file not shown.
@ -14,6 +14,7 @@
|
||||
#include "td/telegram/net/NetQueryDispatcher.h"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
#include "td/telegram/misc.h"
|
||||
#include "td/telegram/td_api.h"
|
||||
#include "td/telegram/td_api.hpp"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
@ -57,11 +58,23 @@ struct LanguagePackManager::Language {
|
||||
};
|
||||
|
||||
struct LanguagePackManager::LanguageInfo {
|
||||
string name;
|
||||
string native_name;
|
||||
string name_;
|
||||
string native_name_;
|
||||
string base_language_code_;
|
||||
string plural_code_;
|
||||
bool is_official_ = false;
|
||||
bool is_rtl_ = false;
|
||||
bool is_beta_ = false;
|
||||
int32 total_string_count_ = 0; // TODO move to LanguagePack and calculate as max(total_string_count)
|
||||
int32 translated_string_count_ = 0;
|
||||
string translation_url_;
|
||||
|
||||
friend bool operator==(const LanguageInfo &lhs, const LanguageInfo &rhs) {
|
||||
return lhs.name == rhs.name && lhs.native_name == rhs.native_name;
|
||||
return lhs.name_ == rhs.name_ && lhs.native_name_ == rhs.native_name_ &&
|
||||
lhs.base_language_code_ == rhs.base_language_code_ && lhs.plural_code_ == rhs.plural_code_ &&
|
||||
lhs.is_official_ == rhs.is_official_ && lhs.is_rtl_ == rhs.is_rtl_ && lhs.is_beta_ == rhs.is_beta_ &&
|
||||
lhs.total_string_count_ == rhs.total_string_count_ &&
|
||||
lhs.translated_string_count_ == rhs.translated_string_count_ && lhs.translation_url_ == rhs.translation_url_;
|
||||
}
|
||||
};
|
||||
|
||||
@ -195,7 +208,7 @@ void LanguagePackManager::start_up() {
|
||||
std::lock_guard<std::mutex> language_lock(language->mutex_);
|
||||
base_language_code_ = language->base_language_code_;
|
||||
if (!check_language_code_name(base_language_code_)) {
|
||||
LOG(ERROR) << "Have invalid base language code name \"" << base_language_code_ << '"';
|
||||
LOG(ERROR) << "Have invalid base language pack ID \"" << base_language_code_ << '"';
|
||||
base_language_code_.clear();
|
||||
}
|
||||
if (!base_language_code_.empty()) {
|
||||
@ -372,7 +385,7 @@ void LanguagePackManager::inc_generation() {
|
||||
std::lock_guard<std::mutex> lock(language->mutex_);
|
||||
base_language_code_ = language->base_language_code_;
|
||||
if (!check_language_code_name(base_language_code_)) {
|
||||
LOG(ERROR) << "Have invalid base language code name \"" << base_language_code_ << '"';
|
||||
LOG(ERROR) << "Have invalid base language pack ID \"" << base_language_code_ << '"';
|
||||
base_language_code_.clear();
|
||||
}
|
||||
if (!base_language_code_.empty()) {
|
||||
@ -420,27 +433,68 @@ LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabas
|
||||
if (!database->database_.empty()) {
|
||||
pack->pack_kv_.init_with_connection(database->database_.clone(), get_database_table_name(language_pack, "0"))
|
||||
.ensure();
|
||||
bool need_drop_server = false;
|
||||
for (auto &lang : pack->pack_kv_.get_all()) {
|
||||
auto as_bool = [](Slice data) {
|
||||
if (data == "true") {
|
||||
return true;
|
||||
}
|
||||
if (data != "false") {
|
||||
LOG(ERROR) << "Have invalid boolean value \"" << data << "\" in the database";
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (lang.first == "!server") {
|
||||
// legacy info format, drop cache
|
||||
need_drop_server = true;
|
||||
continue;
|
||||
}
|
||||
if (lang.first == "!server2") {
|
||||
auto all_infos = full_split(lang.second, '\x00');
|
||||
if (all_infos.size() % 3 == 0) {
|
||||
for (size_t i = 0; i < all_infos.size(); i += 3) {
|
||||
if (all_infos.size() % 11 == 0) {
|
||||
for (size_t i = 0; i < all_infos.size(); i += 11) {
|
||||
LanguageInfo info;
|
||||
info.name = std::move(all_infos[i + 1]);
|
||||
info.native_name = std::move(all_infos[i + 2]);
|
||||
info.name_ = std::move(all_infos[i + 1]);
|
||||
info.native_name_ = std::move(all_infos[i + 2]);
|
||||
info.base_language_code_ = std::move(all_infos[i + 3]);
|
||||
info.plural_code_ = std::move(all_infos[i + 4]);
|
||||
info.is_official_ = as_bool(all_infos[i + 5]);
|
||||
info.is_rtl_ = as_bool(all_infos[i + 6]);
|
||||
info.is_beta_ = as_bool(all_infos[i + 7]);
|
||||
info.total_string_count_ = to_integer<int32>(all_infos[i + 8]);
|
||||
info.translated_string_count_ = to_integer<int32>(all_infos[i + 9]);
|
||||
info.translation_url_ = std::move(all_infos[i + 10]);
|
||||
pack->server_language_pack_infos_.emplace_back(std::move(all_infos[i]), std::move(info));
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "Have wrong language pack info \"" << lang.second << "\" in the database";
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
auto names = split(lang.second, '\x00');
|
||||
auto all_infos = full_split(lang.second, '\x00');
|
||||
if (all_infos.size() < 2) {
|
||||
LOG(ERROR) << "Have wrong custom language pack info \"" << lang.second << '"';
|
||||
continue;
|
||||
}
|
||||
auto &info = pack->custom_language_pack_infos_[lang.first];
|
||||
info.name = std::move(names.first);
|
||||
info.native_name = std::move(names.second);
|
||||
info.name_ = std::move(all_infos[0]);
|
||||
info.native_name_ = std::move(all_infos[1]);
|
||||
if (all_infos.size() >= 2) {
|
||||
CHECK(all_infos.size() == 10);
|
||||
info.base_language_code_ = std::move(all_infos[2]);
|
||||
info.plural_code_ = std::move(all_infos[3]);
|
||||
info.is_official_ = as_bool(all_infos[4]);
|
||||
info.is_rtl_ = as_bool(all_infos[5]);
|
||||
info.is_beta_ = as_bool(all_infos[6]);
|
||||
info.total_string_count_ = to_integer<int32>(all_infos[7]);
|
||||
info.translated_string_count_ = to_integer<int32>(all_infos[8]);
|
||||
info.translation_url_ = std::move(all_infos[9]);
|
||||
}
|
||||
}
|
||||
if (need_drop_server) {
|
||||
pack->pack_kv_.erase("!server");
|
||||
}
|
||||
}
|
||||
pack_it = database->language_packs_.emplace(language_pack, std::move(pack)).first;
|
||||
@ -673,10 +727,31 @@ void LanguagePackManager::get_languages(bool only_local,
|
||||
std::move(request_promise));
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::languagePackInfo> LanguagePackManager::get_language_pack_info_object(
|
||||
const string &language_code, const LanguageInfo &info) {
|
||||
return td_api::make_object<td_api::languagePackInfo>(
|
||||
language_code, info.base_language_code_, info.name_, info.native_name_, info.plural_code_, info.is_official_,
|
||||
info.is_rtl_, info.is_beta_, info.total_string_count_, info.translated_string_count_, 0, info.translation_url_);
|
||||
}
|
||||
|
||||
string LanguagePackManager::get_language_info_string(const LanguageInfo &info) {
|
||||
return PSTRING() << info.name_ << '\x00' << info.native_name_ << '\x00' << info.base_language_code_ << '\x00'
|
||||
<< info.plural_code_ << '\x00' << info.is_official_ << '\x00' << info.is_rtl_ << '\x00'
|
||||
<< info.is_beta_ << '\x00' << info.total_string_count_ << '\x00' << info.translated_string_count_
|
||||
<< '\x00' << info.translation_url_;
|
||||
}
|
||||
|
||||
void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::langPackLanguage>> languages,
|
||||
string language_pack, bool only_local,
|
||||
Promise<td_api::object_ptr<td_api::localizationTargetInfo>> promise) {
|
||||
auto results = td_api::make_object<td_api::localizationTargetInfo>();
|
||||
std::unordered_set<string> added_languages;
|
||||
|
||||
auto add_language_info = [&results, &added_languages](const string &language_code, const LanguageInfo &info) {
|
||||
if (added_languages.insert(language_code).second) {
|
||||
results->language_packs_.push_back(get_language_pack_info_object(language_code, info));
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> packs_lock(database_->mutex_);
|
||||
@ -684,13 +759,11 @@ void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::la
|
||||
if (pack_it != database_->language_packs_.end()) {
|
||||
LanguagePack *pack = pack_it->second.get();
|
||||
for (auto &info : pack->custom_language_pack_infos_) {
|
||||
results->language_packs_.push_back(
|
||||
make_tl_object<td_api::languagePackInfo>(info.first, info.second.name, info.second.native_name, 0));
|
||||
add_language_info(info.first, info.second);
|
||||
}
|
||||
if (only_local) {
|
||||
for (auto &info : pack->server_language_pack_infos_) {
|
||||
results->language_packs_.push_back(
|
||||
make_tl_object<td_api::languagePackInfo>(info.first, info.second.name, info.second.native_name, 0));
|
||||
add_language_info(info.first, info.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -703,23 +776,68 @@ void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::la
|
||||
continue;
|
||||
}
|
||||
if (is_custom_language_code(language->lang_code_)) {
|
||||
LOG(ERROR) << "Receive custom language pack ID " << language->lang_code_ << " from server";
|
||||
LOG(ERROR) << "Receive custom language pack ID \"" << language->lang_code_ << "\" from server";
|
||||
continue;
|
||||
}
|
||||
|
||||
results->language_packs_.push_back(
|
||||
make_tl_object<td_api::languagePackInfo>(language->lang_code_, language->name_, language->native_name_, 0));
|
||||
|
||||
LanguageInfo info;
|
||||
info.name = std::move(language->name_);
|
||||
info.native_name = std::move(language->native_name_);
|
||||
info.name_ = std::move(language->name_);
|
||||
info.native_name_ = std::move(language->native_name_);
|
||||
info.base_language_code_ = std::move(language->base_lang_code_);
|
||||
info.plural_code_ = std::move(language->plural_code_);
|
||||
info.is_official_ = (language->flags_ & telegram_api::langPackLanguage::OFFICIAL_MASK) != 0;
|
||||
info.is_rtl_ = (language->flags_ & telegram_api::langPackLanguage::RTL_MASK) != 0;
|
||||
info.is_beta_ = (language->flags_ & telegram_api::langPackLanguage::BETA_MASK) != 0;
|
||||
info.total_string_count_ = language->strings_count_;
|
||||
info.translated_string_count_ = language->translated_count_;
|
||||
info.translation_url_ = language->translations_url_;
|
||||
|
||||
if (!check_language_code_name(info.base_language_code_)) {
|
||||
LOG(ERROR) << "Have invalid base language pack ID \"" << info.base_language_code_ << '"';
|
||||
info.base_language_code_.clear();
|
||||
}
|
||||
if (is_custom_language_code(info.base_language_code_)) {
|
||||
LOG(ERROR) << "Receive custom base language pack ID \"" << info.base_language_code_ << "\" from server";
|
||||
info.base_language_code_.clear();
|
||||
}
|
||||
if (info.base_language_code_ == language->lang_code_) {
|
||||
LOG(ERROR) << "Receive language pack \"" << info.base_language_code_ << "\"based on self";
|
||||
info.base_language_code_.clear();
|
||||
}
|
||||
|
||||
add_language_info(language->lang_code_, info);
|
||||
all_server_infos.emplace_back(std::move(language->lang_code_), std::move(info));
|
||||
}
|
||||
|
||||
for (auto &language_info : results->language_packs_) {
|
||||
auto language = add_language(database_, language_pack, language_info->id_);
|
||||
language_info->local_string_count_ = language->key_count_;
|
||||
// TODO if (language_info->base_language_pack_name != language->base_language_pack_name) update it
|
||||
SqliteKeyValue *kv = nullptr;
|
||||
bool was_updated_base_language_code = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(language->mutex_);
|
||||
if (language_info->base_language_pack_id_ != language->base_language_code_) {
|
||||
language->base_language_code_ = language_info->base_language_pack_id_;
|
||||
if (language_info->id_ == language_code_) {
|
||||
base_language_code_ = language->base_language_code_;
|
||||
was_updated_base_language_code = true;
|
||||
}
|
||||
if (!language->kv_.empty()) {
|
||||
kv = &language->kv_;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (was_updated_base_language_code) {
|
||||
G()->shared_config().set_option_empty("base_language_pack_version");
|
||||
if (!base_language_code_.empty()) {
|
||||
add_language(database_, language_pack_, base_language_code_);
|
||||
on_language_pack_version_changed(true, std::numeric_limits<int32>::max());
|
||||
}
|
||||
}
|
||||
if (kv != nullptr) {
|
||||
std::lock_guard<std::mutex> lock(database_->mutex_);
|
||||
kv->set("!base_language_code", language_info->base_language_pack_id_);
|
||||
}
|
||||
}
|
||||
|
||||
if (!only_local) {
|
||||
@ -732,14 +850,13 @@ void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::la
|
||||
|
||||
if (!pack->pack_kv_.empty()) {
|
||||
vector<string> all_strings;
|
||||
all_strings.reserve(3 * pack->server_language_pack_infos_.size());
|
||||
all_strings.reserve(2 * pack->server_language_pack_infos_.size());
|
||||
for (auto &info : pack->server_language_pack_infos_) {
|
||||
all_strings.push_back(info.first);
|
||||
all_strings.push_back(info.second.name);
|
||||
all_strings.push_back(info.second.native_name);
|
||||
all_strings.push_back(get_language_info_string(info.second));
|
||||
}
|
||||
|
||||
pack->pack_kv_.set("!server", implode(all_strings, '\x00'));
|
||||
pack->pack_kv_.set("!server2", implode(all_strings, '\x00'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1191,15 +1308,75 @@ Result<tl_object_ptr<telegram_api::LangPackString>> LanguagePackManager::convert
|
||||
}
|
||||
}
|
||||
|
||||
void LanguagePackManager::set_custom_language(string language_code, string language_name, string language_native_name,
|
||||
Result<LanguagePackManager::LanguageInfo> LanguagePackManager::get_language_info(
|
||||
td_api::languagePackInfo *language_pack_info) {
|
||||
if (language_pack_info == nullptr) {
|
||||
return Status::Error(400, "Language pack info must not be empty");
|
||||
}
|
||||
|
||||
if (!clean_input_string(language_pack_info->id_)) {
|
||||
return Status::Error(400, "Language pack ID must be encoded in UTF-8");
|
||||
}
|
||||
if (!clean_input_string(language_pack_info->base_language_pack_id_)) {
|
||||
return Status::Error(400, "Base language pack ID must be encoded in UTF-8");
|
||||
}
|
||||
if (!clean_input_string(language_pack_info->name_)) {
|
||||
return Status::Error(400, "Language pack name must be encoded in UTF-8");
|
||||
}
|
||||
if (!clean_input_string(language_pack_info->native_name_)) {
|
||||
return Status::Error(400, "Language pack native name must be encoded in UTF-8");
|
||||
}
|
||||
if (!clean_input_string(language_pack_info->plural_code_)) {
|
||||
return Status::Error(400, "Language pack plural code must be encoded in UTF-8");
|
||||
}
|
||||
if (!clean_input_string(language_pack_info->translation_url_)) {
|
||||
return Status::Error(400, "Language pack translation url must be encoded in UTF-8");
|
||||
}
|
||||
if (language_pack_info->total_string_count_ < 0) {
|
||||
language_pack_info->total_string_count_ = 0;
|
||||
}
|
||||
if (language_pack_info->translated_string_count_ < 0) {
|
||||
language_pack_info->translated_string_count_ = 0;
|
||||
}
|
||||
if (!check_language_code_name(language_pack_info->id_)) {
|
||||
return Status::Error(400, "Language pack ID must contain only letters, digits and hyphen");
|
||||
}
|
||||
|
||||
if (is_custom_language_code(language_pack_info->id_)) {
|
||||
language_pack_info->base_language_pack_id_.clear();
|
||||
language_pack_info->is_official_ = false;
|
||||
language_pack_info->is_rtl_ = false;
|
||||
language_pack_info->is_beta_ = false;
|
||||
language_pack_info->translation_url_.clear();
|
||||
}
|
||||
|
||||
LanguageInfo info;
|
||||
info.name_ = std::move(language_pack_info->name_);
|
||||
info.native_name_ = std::move(language_pack_info->native_name_);
|
||||
info.base_language_code_ = std::move(language_pack_info->base_language_pack_id_);
|
||||
info.plural_code_ = std::move(language_pack_info->plural_code_);
|
||||
info.is_official_ = language_pack_info->is_official_;
|
||||
info.is_rtl_ = language_pack_info->is_rtl_;
|
||||
info.is_beta_ = language_pack_info->is_beta_;
|
||||
info.total_string_count_ = language_pack_info->total_string_count_;
|
||||
info.translated_string_count_ = language_pack_info->translated_string_count_;
|
||||
info.translation_url_ = std::move(language_pack_info->translation_url_);
|
||||
|
||||
return std::move(info);
|
||||
}
|
||||
|
||||
void LanguagePackManager::set_custom_language(td_api::object_ptr<td_api::languagePackInfo> &&language_pack_info,
|
||||
vector<tl_object_ptr<td_api::languagePackString>> strings,
|
||||
Promise<Unit> &&promise) {
|
||||
if (language_pack_.empty()) {
|
||||
return promise.set_error(Status::Error(400, "Option \"localization_target\" needs to be set first"));
|
||||
}
|
||||
if (!check_language_code_name(language_code)) {
|
||||
return promise.set_error(Status::Error(400, "Language pack ID must contain only letters, digits and hyphen"));
|
||||
|
||||
auto r_info = get_language_info(language_pack_info.get());
|
||||
if (r_info.is_error()) {
|
||||
return promise.set_error(r_info.move_as_error());
|
||||
}
|
||||
auto language_code = std::move(language_pack_info->id_);
|
||||
if (!is_custom_language_code(language_code)) {
|
||||
return promise.set_error(Status::Error(400, "Custom language pack ID must begin with 'X'"));
|
||||
}
|
||||
@ -1222,23 +1399,25 @@ void LanguagePackManager::set_custom_language(string language_code, string langu
|
||||
CHECK(pack_it != database_->language_packs_.end());
|
||||
LanguagePack *pack = pack_it->second.get();
|
||||
auto &info = pack->custom_language_pack_infos_[language_code];
|
||||
info.name = std::move(language_name);
|
||||
info.native_name = std::move(language_native_name);
|
||||
info = r_info.move_as_ok();
|
||||
if (!pack->pack_kv_.empty()) {
|
||||
pack->pack_kv_.set(language_code, PSLICE() << info.name << '\x00' << info.native_name);
|
||||
pack->pack_kv_.set(language_code, get_language_info_string(info));
|
||||
}
|
||||
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
void LanguagePackManager::edit_custom_language_info(string language_code, string language_name,
|
||||
string language_native_name, Promise<Unit> &&promise) {
|
||||
void LanguagePackManager::edit_custom_language_info(td_api::object_ptr<td_api::languagePackInfo> &&language_pack_info,
|
||||
Promise<Unit> &&promise) {
|
||||
if (language_pack_.empty()) {
|
||||
return promise.set_error(Status::Error(400, "Option \"localization_target\" needs to be set first"));
|
||||
}
|
||||
if (!check_language_code_name(language_code)) {
|
||||
return promise.set_error(Status::Error(400, "Language pack ID must contain only letters, digits and hyphen"));
|
||||
|
||||
auto r_info = get_language_info(language_pack_info.get());
|
||||
if (r_info.is_error()) {
|
||||
return promise.set_error(r_info.move_as_error());
|
||||
}
|
||||
auto language_code = std::move(language_pack_info->id_);
|
||||
if (!is_custom_language_code(language_code)) {
|
||||
return promise.set_error(Status::Error(400, "Custom language pack ID must begin with 'X'"));
|
||||
}
|
||||
@ -1252,10 +1431,9 @@ void LanguagePackManager::edit_custom_language_info(string language_code, string
|
||||
return promise.set_error(Status::Error(400, "Custom language pack is not found"));
|
||||
}
|
||||
auto &info = language_info_it->second;
|
||||
info.name = std::move(language_name);
|
||||
info.native_name = std::move(language_native_name);
|
||||
info = r_info.move_as_ok();
|
||||
if (!pack->pack_kv_.empty()) {
|
||||
pack->pack_kv_.set(language_code, PSLICE() << info.name << '\x00' << info.native_name);
|
||||
pack->pack_kv_.set(language_code, get_language_info_string(info));
|
||||
}
|
||||
|
||||
promise.set_value(Unit());
|
||||
@ -1349,12 +1527,10 @@ Status LanguagePackManager::do_delete_language(string language_code) {
|
||||
language->pluralized_strings_.clear();
|
||||
language->deleted_strings_.clear();
|
||||
|
||||
if (is_custom_language_code(language_code)) {
|
||||
if (!pack->pack_kv_.empty()) {
|
||||
pack->pack_kv_.erase(language_code);
|
||||
}
|
||||
pack->custom_language_pack_infos_.erase(language_code);
|
||||
if (!pack->pack_kv_.empty()) {
|
||||
pack->pack_kv_.erase(language_code);
|
||||
}
|
||||
pack->custom_language_pack_infos_.erase(language_code);
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
@ -61,10 +61,10 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
|
||||
void on_update_language_pack(tl_object_ptr<telegram_api::langPackDifference> difference);
|
||||
|
||||
void set_custom_language(string language_code, string language_name, string language_native_name,
|
||||
void set_custom_language(td_api::object_ptr<td_api::languagePackInfo> &&language_pack_info,
|
||||
vector<tl_object_ptr<td_api::languagePackString>> strings, Promise<Unit> &&promise);
|
||||
|
||||
void edit_custom_language_info(string language_code, string language_name, string language_native_name,
|
||||
void edit_custom_language_info(td_api::object_ptr<td_api::languagePackInfo> &&language_pack_info,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void set_custom_language_string(string language_code, tl_object_ptr<td_api::languagePackString> str,
|
||||
@ -130,6 +130,13 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
static td_api::object_ptr<td_api::languagePackStrings> get_language_pack_strings_object(Language *language,
|
||||
const vector<string> &keys);
|
||||
|
||||
static td_api::object_ptr<td_api::languagePackInfo> get_language_pack_info_object(const string &language_code,
|
||||
const LanguageInfo &info);
|
||||
|
||||
static Result<LanguageInfo> get_language_info(td_api::languagePackInfo *language_pack_info);
|
||||
|
||||
static string get_language_info_string(const LanguageInfo &info);
|
||||
|
||||
static Result<tl_object_ptr<telegram_api::LangPackString>> convert_to_telegram_api(
|
||||
tl_object_ptr<td_api::languagePackString> &&str);
|
||||
|
||||
|
@ -6196,29 +6196,16 @@ void Td::on_request(uint64 id, td_api::getLanguagePackStrings &request) {
|
||||
|
||||
void Td::on_request(uint64 id, td_api::setCustomLanguagePack &request) {
|
||||
CHECK_IS_USER();
|
||||
if (request.info_ == nullptr) {
|
||||
return send_error_raw(id, 400, "Language pack info must not be empty");
|
||||
}
|
||||
CLEAN_INPUT_STRING(request.info_->id_);
|
||||
CLEAN_INPUT_STRING(request.info_->name_);
|
||||
CLEAN_INPUT_STRING(request.info_->native_name_);
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
send_closure(language_pack_manager_, &LanguagePackManager::set_custom_language, std::move(request.info_->id_),
|
||||
std::move(request.info_->name_), std::move(request.info_->native_name_), std::move(request.strings_),
|
||||
std::move(promise));
|
||||
send_closure(language_pack_manager_, &LanguagePackManager::set_custom_language, std::move(request.info_),
|
||||
std::move(request.strings_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::editCustomLanguagePackInfo &request) {
|
||||
CHECK_IS_USER();
|
||||
if (request.info_ == nullptr) {
|
||||
return send_error_raw(id, 400, "Language pack info must not be empty");
|
||||
}
|
||||
CLEAN_INPUT_STRING(request.info_->id_);
|
||||
CLEAN_INPUT_STRING(request.info_->name_);
|
||||
CLEAN_INPUT_STRING(request.info_->native_name_);
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
send_closure(language_pack_manager_, &LanguagePackManager::edit_custom_language_info, std::move(request.info_->id_),
|
||||
std::move(request.info_->name_), std::move(request.info_->native_name_), std::move(promise));
|
||||
send_closure(language_pack_manager_, &LanguagePackManager::edit_custom_language_info, std::move(request.info_),
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::setCustomLanguagePackString &request) {
|
||||
|
@ -485,7 +485,7 @@ class CliClient final : public Actor {
|
||||
return transform(full_split(user_ids, delimiter), [this](Slice str) { return as_user_id(str); });
|
||||
}
|
||||
|
||||
int32 as_basic_group_id(Slice str) const {
|
||||
static int32 as_basic_group_id(Slice str) {
|
||||
str = trim(str);
|
||||
auto result = to_integer<int32>(str);
|
||||
if (result < 0) {
|
||||
@ -494,7 +494,7 @@ class CliClient final : public Actor {
|
||||
return result;
|
||||
}
|
||||
|
||||
int32 as_supergroup_id(Slice str) const {
|
||||
static int32 as_supergroup_id(Slice str) {
|
||||
str = trim(str);
|
||||
auto result = to_integer<int64>(str);
|
||||
int64 shift = static_cast<int64>(-1000000000000ll);
|
||||
@ -504,7 +504,7 @@ class CliClient final : public Actor {
|
||||
return static_cast<int32>(result);
|
||||
}
|
||||
|
||||
int32 as_secret_chat_id(Slice str) const {
|
||||
static int32 as_secret_chat_id(Slice str) {
|
||||
str = trim(str);
|
||||
auto result = to_integer<int64>(str);
|
||||
int64 shift = static_cast<int64>(-2000000000000ll);
|
||||
@ -882,7 +882,7 @@ class CliClient final : public Actor {
|
||||
return as_formatted_text(caption, std::move(entities));
|
||||
}
|
||||
|
||||
tl_object_ptr<td_api::NotificationSettingsScope> get_notification_settings_scope(Slice scope) const {
|
||||
static tl_object_ptr<td_api::NotificationSettingsScope> get_notification_settings_scope(Slice scope) {
|
||||
if (scope == "channels" || scope == "ch") {
|
||||
return make_tl_object<td_api::notificationSettingsScopeChannelChats>();
|
||||
}
|
||||
@ -988,7 +988,7 @@ class CliClient final : public Actor {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tl_object_ptr<td_api::TopChatCategory> get_top_chat_category(MutableSlice category) {
|
||||
static tl_object_ptr<td_api::TopChatCategory> get_top_chat_category(MutableSlice category) {
|
||||
category = trim(category);
|
||||
to_lower_inplace(category);
|
||||
if (!category.empty() && category.back() == 's') {
|
||||
@ -1177,6 +1177,13 @@ class CliClient final : public Actor {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::languagePackInfo> as_language_pack_info(const string &language_code,
|
||||
const string &name,
|
||||
const string &native_name) {
|
||||
return td_api::make_object<td_api::languagePackInfo>(language_code, "test", name, native_name, "en", true, true,
|
||||
true, -1, 5, 3, "abacaba");
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::Object> execute(tl_object_ptr<td_api::Function> f) {
|
||||
if (GET_VERBOSITY_LEVEL() < VERBOSITY_NAME(td_requests)) {
|
||||
LOG(ERROR) << "Execute request: " << to_string(f);
|
||||
@ -1859,7 +1866,7 @@ class CliClient final : public Actor {
|
||||
"DELETED", make_tl_object<td_api::languagePackStringValueDeleted>()));
|
||||
|
||||
send_request(make_tl_object<td_api::setCustomLanguagePack>(
|
||||
make_tl_object<td_api::languagePackInfo>(language_code, name, native_name, 3), std::move(strings)));
|
||||
as_language_pack_info(language_code, name, native_name), std::move(strings)));
|
||||
} else if (op == "eclpi") {
|
||||
string language_code;
|
||||
string name;
|
||||
@ -1868,8 +1875,8 @@ class CliClient final : public Actor {
|
||||
std::tie(language_code, args) = split(args);
|
||||
std::tie(name, native_name) = split(args);
|
||||
|
||||
send_request(make_tl_object<td_api::editCustomLanguagePackInfo>(
|
||||
make_tl_object<td_api::languagePackInfo>(language_code, name, native_name, 3)));
|
||||
send_request(
|
||||
make_tl_object<td_api::editCustomLanguagePackInfo>(as_language_pack_info(language_code, name, native_name)));
|
||||
} else if (op == "sclpsv" || op == "sclpsp" || op == "sclpsd") {
|
||||
string language_code;
|
||||
string key;
|
||||
|
Loading…
Reference in New Issue
Block a user