Base language pack support.
GitOrigin-RevId: 165941c5074e49f66e5f5aeded77ca0372a0ab3f
This commit is contained in:
parent
f67138815a
commit
9995e9aa5b
@ -823,9 +823,11 @@ void ConfigManager::process_config(tl_object_ptr<telegram_api::config> config) {
|
||||
if ((config->flags_ & telegram_api::config::SUGGESTED_LANG_CODE_MASK) != 0) {
|
||||
shared_config.set_option_string("suggested_language_pack_id", config->suggested_lang_code_);
|
||||
shared_config.set_option_integer("language_pack_version", config->lang_pack_version_);
|
||||
shared_config.set_option_integer("base_language_pack_version", config->base_lang_pack_version_);
|
||||
} else {
|
||||
shared_config.set_option_empty("suggested_language_pack_id");
|
||||
shared_config.set_option_empty("language_pack_version");
|
||||
shared_config.set_option_empty("base_language_pack_version");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ struct LanguagePackManager::Language {
|
||||
std::mutex mutex_;
|
||||
std::atomic<int32> version_{-1};
|
||||
std::atomic<int32> key_count_{0};
|
||||
std::string base_language_code_;
|
||||
bool is_full_ = false;
|
||||
bool was_loaded_full_ = false;
|
||||
bool has_get_difference_query_ = false;
|
||||
@ -145,6 +146,14 @@ static int32 load_database_language_key_count(SqliteKeyValue *kv) {
|
||||
return to_integer<int32>(str_key_count);
|
||||
}
|
||||
|
||||
static string load_database_language_base_language_code(SqliteKeyValue *kv) {
|
||||
CHECK(kv != nullptr);
|
||||
if (kv->empty()) {
|
||||
return string();
|
||||
}
|
||||
return kv->get("!base_language_code");
|
||||
}
|
||||
|
||||
LanguagePackManager::LanguageDatabase *LanguagePackManager::add_language_database(const string &path) {
|
||||
auto it = language_databases_.find(path);
|
||||
if (it != language_databases_.end()) {
|
||||
@ -169,7 +178,7 @@ LanguagePackManager::LanguageDatabase *LanguagePackManager::add_language_databas
|
||||
}
|
||||
|
||||
void LanguagePackManager::start_up() {
|
||||
std::lock_guard<std::mutex> lock(language_database_mutex_);
|
||||
std::lock_guard<std::mutex> database_lock(language_database_mutex_);
|
||||
manager_count_++;
|
||||
language_pack_ = G()->shared_config().get_option_string("localization_target");
|
||||
language_code_ = G()->shared_config().get_option_string("language_pack_id");
|
||||
@ -179,12 +188,26 @@ void LanguagePackManager::start_up() {
|
||||
database_ = add_language_database(G()->shared_config().get_option_string("language_pack_database_path"));
|
||||
if (!language_pack_.empty() && !language_code_.empty()) {
|
||||
auto language = add_language(database_, language_pack_, language_code_);
|
||||
if (!is_custom_language_code(language_code_) && language->version_ == -1) {
|
||||
get_language_pack_strings(language_code_, vector<string>(), Auto());
|
||||
if (language->version_ == -1) {
|
||||
load_empty_language_pack(language_code_);
|
||||
}
|
||||
|
||||
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_ << '"';
|
||||
base_language_code_.clear();
|
||||
}
|
||||
if (!base_language_code_.empty()) {
|
||||
auto base_language = add_language(database_, language_pack_, base_language_code_);
|
||||
if (base_language->version_ == -1) {
|
||||
load_empty_language_pack(base_language_code_);
|
||||
}
|
||||
}
|
||||
|
||||
LOG(INFO) << "Use localization target \"" << language_pack_ << "\" with language pack \"" << language_code_
|
||||
<< "\" of version " << language->version_.load() << " with database \"" << database_->path_ << '"';
|
||||
<< "\" based on \"" << base_language_code_ << "\" of version " << language->version_.load()
|
||||
<< " with database \"" << database_->path_ << '"';
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,21 +243,41 @@ void LanguagePackManager::on_language_code_changed() {
|
||||
inc_generation();
|
||||
}
|
||||
|
||||
void LanguagePackManager::on_language_pack_version_changed(int32 new_version) {
|
||||
if (is_custom_language_code(language_code_) || language_pack_.empty() || language_code_.empty()) {
|
||||
void LanguagePackManager::on_language_pack_version_changed(bool is_base, int32 new_version) {
|
||||
if (language_pack_.empty() || language_code_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Language *language = get_language(database_, language_pack_, language_code_);
|
||||
int32 version = language == nullptr ? static_cast<int32>(-1) : language->version_.load();
|
||||
if (version == -1) {
|
||||
get_language_pack_strings(language_code_, vector<string>(), Auto());
|
||||
return load_empty_language_pack(language_code_);
|
||||
}
|
||||
|
||||
if (new_version < 0) {
|
||||
Slice version_key = is_base ? Slice("base_language_pack_version") : Slice("language_pack_version");
|
||||
new_version = G()->shared_config().get_option_integer(version_key, -1);
|
||||
}
|
||||
if (new_version <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto new_language_pack_version =
|
||||
new_version >= 0 ? new_version : G()->shared_config().get_option_integer("language_pack_version", -1);
|
||||
if (new_language_pack_version <= version) {
|
||||
string language_code;
|
||||
if (is_base) {
|
||||
language_code = base_language_code_;
|
||||
if (language_code.empty()) {
|
||||
LOG(ERROR) << "Have no base language, but received new version " << new_version;
|
||||
return;
|
||||
}
|
||||
language = get_language(database_, language_pack_, language_code);
|
||||
version = language == nullptr ? static_cast<int32>(-1) : language->version_.load();
|
||||
if (version == -1) {
|
||||
return load_empty_language_pack(language_code);
|
||||
}
|
||||
} else {
|
||||
language_code = language_code_;
|
||||
}
|
||||
if (is_custom_language_code(language_code) || new_version <= version) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -245,7 +288,7 @@ void LanguagePackManager::on_language_pack_version_changed(int32 new_version) {
|
||||
|
||||
language->has_get_difference_query_ = true;
|
||||
auto request_promise =
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, language_code = language_code_,
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, language_code,
|
||||
from_version = version](Result<NetQueryPtr> r_query) mutable {
|
||||
auto r_result = fetch_result<telegram_api::langpack_getDifference>(std::move(r_query));
|
||||
if (r_result.is_error()) {
|
||||
@ -267,17 +310,20 @@ void LanguagePackManager::on_language_pack_version_changed(int32 new_version) {
|
||||
Promise<td_api::object_ptr<td_api::languagePackStrings>>());
|
||||
});
|
||||
send_with_promise(
|
||||
G()->net_query_creator().create(create_storer(telegram_api::langpack_getDifference(language_code_, version)),
|
||||
G()->net_query_creator().create(create_storer(telegram_api::langpack_getDifference(language_code, version)),
|
||||
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off),
|
||||
std::move(request_promise));
|
||||
}
|
||||
|
||||
void LanguagePackManager::on_language_pack_too_long(string language_code) {
|
||||
if (language_code == language_code_) {
|
||||
return on_language_pack_version_changed(std::numeric_limits<int32>::max());
|
||||
return on_language_pack_version_changed(false, std::numeric_limits<int32>::max());
|
||||
}
|
||||
if (language_code == base_language_code_) {
|
||||
return on_language_pack_version_changed(true, std::numeric_limits<int32>::max());
|
||||
}
|
||||
LOG(WARNING) << "Receive languagePackTooLong for language " << language_code << ", but use language "
|
||||
<< language_code_;
|
||||
<< language_code_ << " with base language " << base_language_code_;
|
||||
}
|
||||
|
||||
void LanguagePackManager::on_update_language_pack(tl_object_ptr<telegram_api::langPackDifference> difference) {
|
||||
@ -289,7 +335,7 @@ void LanguagePackManager::on_update_language_pack(tl_object_ptr<telegram_api::la
|
||||
<< ", because used language pack was unset";
|
||||
return;
|
||||
}
|
||||
if (difference->lang_code_ != language_code_) {
|
||||
if (difference->lang_code_ != language_code_ && difference->lang_code_ != base_language_code_) {
|
||||
LOG(WARNING) << "Ignore difference for language pack " << difference->lang_code_;
|
||||
return;
|
||||
}
|
||||
@ -298,7 +344,7 @@ void LanguagePackManager::on_update_language_pack(tl_object_ptr<telegram_api::la
|
||||
return;
|
||||
}
|
||||
|
||||
Language *language = get_language(database_, language_pack_, language_code_);
|
||||
Language *language = get_language(database_, language_pack_, difference->lang_code_);
|
||||
int32 version = language == nullptr ? static_cast<int32>(-1) : language->version_.load();
|
||||
if (difference->version_ <= version) {
|
||||
LOG(INFO) << "Skip applying already applied language pack updates";
|
||||
@ -306,7 +352,7 @@ void LanguagePackManager::on_update_language_pack(tl_object_ptr<telegram_api::la
|
||||
}
|
||||
if (version == -1 || version < difference->from_version_) {
|
||||
LOG(INFO) << "Can't apply language pack difference";
|
||||
return on_language_pack_version_changed(difference->version_);
|
||||
return on_language_pack_version_changed(difference->lang_code_ != language_code_, difference->version_);
|
||||
}
|
||||
|
||||
on_get_language_pack_strings(language_pack_, std::move(difference->lang_code_), difference->version_, true,
|
||||
@ -316,7 +362,24 @@ void LanguagePackManager::on_update_language_pack(tl_object_ptr<telegram_api::la
|
||||
|
||||
void LanguagePackManager::inc_generation() {
|
||||
G()->shared_config().set_option_empty("language_pack_version");
|
||||
on_language_pack_version_changed(std::numeric_limits<int32>::max());
|
||||
G()->shared_config().set_option_empty("base_language_pack_version");
|
||||
|
||||
if (!language_pack_.empty() && !language_code_.empty()) {
|
||||
CHECK(check_language_code_name(language_code_));
|
||||
auto language = add_language(database_, language_pack_, language_code_);
|
||||
on_language_pack_version_changed(false, std::numeric_limits<int32>::max());
|
||||
|
||||
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_ << '"';
|
||||
base_language_code_.clear();
|
||||
}
|
||||
if (!base_language_code_.empty()) {
|
||||
add_language(database_, language_pack_, base_language_code_);
|
||||
on_language_pack_version_changed(true, std::numeric_limits<int32>::max());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LanguagePackManager::Language *LanguagePackManager::get_language(LanguageDatabase *database,
|
||||
@ -394,6 +457,7 @@ LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabas
|
||||
.ensure();
|
||||
language->version_ = load_database_language_version(&language->kv_);
|
||||
language->key_count_ = load_database_language_key_count(&language->kv_);
|
||||
language->base_language_code_ = load_database_language_base_language_code(&language->kv_);
|
||||
}
|
||||
code_it = pack->languages_.emplace(language_code, std::move(language)).first;
|
||||
}
|
||||
@ -638,6 +702,10 @@ void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::la
|
||||
LOG(ERROR) << "Receive unsupported language pack ID " << language->lang_code_ << " from server";
|
||||
continue;
|
||||
}
|
||||
if (is_custom_language_code(language->lang_code_)) {
|
||||
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));
|
||||
@ -651,6 +719,7 @@ void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::la
|
||||
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
|
||||
}
|
||||
|
||||
if (!only_local) {
|
||||
@ -759,6 +828,13 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector
|
||||
}
|
||||
}
|
||||
|
||||
void LanguagePackManager::load_empty_language_pack(const string &language_code) {
|
||||
if (is_custom_language_code(language_code)) {
|
||||
return;
|
||||
}
|
||||
get_language_pack_strings(language_code, vector<string>(), Auto());
|
||||
}
|
||||
|
||||
static td_api::object_ptr<td_api::LanguagePackStringValue> copy_language_pack_string_value(
|
||||
const td_api::LanguagePackStringValue *value) {
|
||||
switch (value->get_id()) {
|
||||
@ -1049,8 +1125,10 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
is_version_changed = true;
|
||||
}
|
||||
}
|
||||
if (is_version_changed && language_pack == language_pack_ && language_code == language_code_) {
|
||||
send_closure_later(actor_id(this), &LanguagePackManager::on_language_pack_version_changed, -1);
|
||||
if (is_version_changed && language_pack == language_pack_ &&
|
||||
(language_code == language_code_ || language_code == base_language_code_)) {
|
||||
send_closure_later(actor_id(this), &LanguagePackManager::on_language_pack_version_changed,
|
||||
language_code != language_code_, -1);
|
||||
}
|
||||
|
||||
if (promise) {
|
||||
@ -1064,8 +1142,9 @@ void LanguagePackManager::on_failed_get_difference(string language_pack, string
|
||||
std::lock_guard<std::mutex> lock(language->mutex_);
|
||||
if (language->has_get_difference_query_) {
|
||||
language->has_get_difference_query_ = false;
|
||||
if (language_pack == language_pack_ && language_code == language_code_) {
|
||||
send_closure_later(actor_id(this), &LanguagePackManager::on_language_pack_version_changed, -1);
|
||||
if (language_pack == language_pack_ && (language_code == language_code_ || language_code == base_language_code_)) {
|
||||
send_closure_later(actor_id(this), &LanguagePackManager::on_language_pack_version_changed,
|
||||
language_code != language_code_, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1227,7 +1306,7 @@ void LanguagePackManager::delete_language(string language_code, Promise<Unit> &&
|
||||
if (language_code.empty()) {
|
||||
return promise.set_error(Status::Error(400, "Language pack ID is empty"));
|
||||
}
|
||||
if (language_code_ == language_code) {
|
||||
if (language_code_ == language_code || base_language_code_ == language_code) {
|
||||
return promise.set_error(Status::Error(400, "Currently used language pack can't be deleted"));
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
|
||||
void on_language_code_changed();
|
||||
|
||||
void on_language_pack_version_changed(int32 new_version);
|
||||
void on_language_pack_version_changed(bool is_base, int32 new_version);
|
||||
|
||||
void on_language_pack_too_long(string language_code);
|
||||
|
||||
@ -83,6 +83,7 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
|
||||
string language_pack_;
|
||||
string language_code_;
|
||||
string base_language_code_;
|
||||
LanguageDatabase *database_ = nullptr;
|
||||
|
||||
struct PendingQueries {
|
||||
@ -139,6 +140,8 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
void save_strings_to_database(SqliteKeyValue *kv, int32 new_version, bool new_is_full, int32 new_key_count,
|
||||
vector<std::pair<string, string>> strings);
|
||||
|
||||
void load_empty_language_pack(const string &language_code);
|
||||
|
||||
void on_get_language_pack_strings(string language_pack, string language_code, int32 version, bool is_diff,
|
||||
vector<string> keys, vector<tl_object_ptr<telegram_api::LangPackString>> results,
|
||||
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
|
||||
|
@ -3430,6 +3430,8 @@ bool Td::is_internal_config_option(Slice name) {
|
||||
switch (name[0]) {
|
||||
case 'a':
|
||||
return name == "auth";
|
||||
case 'b':
|
||||
return name == "base_language_pack_version";
|
||||
case 'c':
|
||||
return name == "call_ring_timeout_ms" || name == "call_receive_timeout_ms" ||
|
||||
name == "channels_read_media_period";
|
||||
@ -3499,8 +3501,9 @@ void Td::on_config_option_updated(const string &name) {
|
||||
G()->net_query_dispatcher().update_mtproto_header();
|
||||
}
|
||||
} else if (name == "language_pack_version") {
|
||||
send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, -1);
|
||||
return;
|
||||
return send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, false, -1);
|
||||
} else if (name == "base_language_pack_version") {
|
||||
return send_closure(language_pack_manager_, &LanguagePackManager::on_language_pack_version_changed, true, -1);
|
||||
} else if (name == "notification_group_count_max") {
|
||||
send_closure(notification_manager_actor_, &NotificationManager::on_notification_group_count_max_changed, true);
|
||||
} else if (name == "notification_group_size_max") {
|
||||
|
Reference in New Issue
Block a user