2018-07-03 19:28:00 +02:00
|
|
|
//
|
2022-01-01 01:35:39 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
|
2018-07-03 19:28:00 +02:00
|
|
|
//
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
//
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "td/telegram/net/NetQuery.h"
|
|
|
|
#include "td/telegram/td_api.h"
|
|
|
|
#include "td/telegram/telegram_api.h"
|
|
|
|
|
|
|
|
#include "td/actor/actor.h"
|
|
|
|
|
2019-02-12 22:26:36 +01:00
|
|
|
#include "td/utils/common.h"
|
2018-07-03 19:28:00 +02:00
|
|
|
#include "td/utils/Container.h"
|
2022-02-07 22:04:34 +01:00
|
|
|
#include "td/utils/FlatHashMap.h"
|
2022-11-23 17:37:32 +01:00
|
|
|
#include "td/utils/HashTableUtils.h"
|
2022-06-27 12:30:18 +02:00
|
|
|
#include "td/utils/Promise.h"
|
2018-07-22 19:22:19 +02:00
|
|
|
#include "td/utils/Slice.h"
|
2018-08-10 20:54:17 +02:00
|
|
|
#include "td/utils/Status.h"
|
2018-07-03 19:28:00 +02:00
|
|
|
|
2018-07-05 20:28:11 +02:00
|
|
|
#include <mutex>
|
2022-02-09 01:08:18 +01:00
|
|
|
#include <unordered_map>
|
2018-07-17 13:27:24 +02:00
|
|
|
#include <utility>
|
2018-07-05 20:28:11 +02:00
|
|
|
|
2018-07-03 19:28:00 +02:00
|
|
|
namespace td {
|
|
|
|
|
2018-08-23 02:45:04 +02:00
|
|
|
class SqliteKeyValue;
|
|
|
|
|
2021-07-04 04:58:54 +02:00
|
|
|
class LanguagePackManager final : public NetQueryCallback {
|
2018-07-03 19:28:00 +02:00
|
|
|
public:
|
2022-08-17 21:49:05 +02:00
|
|
|
explicit LanguagePackManager(ActorShared<> parent);
|
2018-07-20 19:50:38 +02:00
|
|
|
LanguagePackManager(const LanguagePackManager &) = delete;
|
|
|
|
LanguagePackManager &operator=(const LanguagePackManager &) = delete;
|
|
|
|
LanguagePackManager(LanguagePackManager &&) = delete;
|
|
|
|
LanguagePackManager &operator=(LanguagePackManager &&) = delete;
|
2021-07-03 22:51:36 +02:00
|
|
|
~LanguagePackManager() final;
|
2018-07-03 19:28:00 +02:00
|
|
|
|
2018-07-22 02:29:48 +02:00
|
|
|
static bool check_language_pack_name(Slice name);
|
|
|
|
|
|
|
|
static bool check_language_code_name(Slice name);
|
|
|
|
|
2018-08-06 16:22:22 +02:00
|
|
|
static bool is_custom_language_code(Slice language_code);
|
|
|
|
|
2020-08-24 22:38:45 +02:00
|
|
|
string get_main_language_code();
|
|
|
|
|
2019-07-11 03:22:17 +02:00
|
|
|
vector<string> get_used_language_codes();
|
2019-05-21 17:48:35 +02:00
|
|
|
|
2018-07-05 02:52:58 +02:00
|
|
|
void on_language_pack_changed();
|
|
|
|
|
|
|
|
void on_language_code_changed();
|
|
|
|
|
2019-02-11 01:45:09 +01:00
|
|
|
void on_language_pack_version_changed(bool is_base, int32 new_version);
|
2018-07-05 02:52:58 +02:00
|
|
|
|
2019-02-10 23:12:42 +01:00
|
|
|
void on_language_pack_too_long(string language_code);
|
|
|
|
|
2018-09-04 14:01:08 +02:00
|
|
|
void get_languages(bool only_local, Promise<td_api::object_ptr<td_api::localizationTargetInfo>> promise);
|
2018-07-03 19:28:00 +02:00
|
|
|
|
2019-02-12 02:15:45 +01:00
|
|
|
void search_language_info(string language_code, Promise<td_api::object_ptr<td_api::languagePackInfo>> promise);
|
|
|
|
|
2018-07-03 19:28:00 +02:00
|
|
|
void get_language_pack_strings(string language_code, vector<string> keys,
|
|
|
|
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
|
|
|
|
|
2018-07-23 19:29:14 +02:00
|
|
|
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);
|
|
|
|
|
2019-02-23 18:27:14 +01:00
|
|
|
void synchronize_language_pack(string language_code, Promise<Unit> promise);
|
|
|
|
|
2018-07-17 04:58:34 +02:00
|
|
|
void on_update_language_pack(tl_object_ptr<telegram_api::langPackDifference> difference);
|
|
|
|
|
2019-02-11 19:53:10 +01:00
|
|
|
void add_custom_server_language(string language_code, Promise<Unit> &&promise);
|
|
|
|
|
2019-02-11 18:57:35 +01:00
|
|
|
void set_custom_language(td_api::object_ptr<td_api::languagePackInfo> &&language_pack_info,
|
2018-08-22 23:29:26 +02:00
|
|
|
vector<tl_object_ptr<td_api::languagePackString>> strings, Promise<Unit> &&promise);
|
2018-08-06 16:22:22 +02:00
|
|
|
|
2019-02-11 18:57:35 +01:00
|
|
|
void edit_custom_language_info(td_api::object_ptr<td_api::languagePackInfo> &&language_pack_info,
|
2018-08-31 19:18:12 +02:00
|
|
|
Promise<Unit> &&promise);
|
|
|
|
|
2018-08-22 23:29:26 +02:00
|
|
|
void set_custom_language_string(string language_code, tl_object_ptr<td_api::languagePackString> str,
|
2018-08-22 22:11:54 +02:00
|
|
|
Promise<Unit> &&promise);
|
|
|
|
|
2018-08-06 16:22:22 +02:00
|
|
|
void delete_language(string language_code, Promise<Unit> &&promise);
|
|
|
|
|
2018-07-03 19:28:00 +02:00
|
|
|
private:
|
2018-07-22 00:59:13 +02:00
|
|
|
struct PluralizedString;
|
|
|
|
struct Language;
|
2018-08-06 19:18:28 +02:00
|
|
|
struct LanguageInfo;
|
2018-07-22 00:59:13 +02:00
|
|
|
struct LanguagePack;
|
2018-07-20 19:50:38 +02:00
|
|
|
struct LanguageDatabase;
|
2018-07-20 15:15:19 +02:00
|
|
|
|
2018-07-03 19:28:00 +02:00
|
|
|
ActorShared<> parent_;
|
|
|
|
|
|
|
|
string language_pack_;
|
|
|
|
string language_code_;
|
2019-02-11 01:45:09 +01:00
|
|
|
string base_language_code_;
|
2018-07-23 13:45:31 +02:00
|
|
|
LanguageDatabase *database_ = nullptr;
|
2018-07-05 02:52:58 +02:00
|
|
|
|
2018-08-24 03:53:14 +02:00
|
|
|
struct PendingQueries {
|
|
|
|
vector<Promise<td_api::object_ptr<td_api::languagePackStrings>>> queries_;
|
|
|
|
};
|
|
|
|
|
2022-02-07 20:41:07 +01:00
|
|
|
FlatHashMap<string, FlatHashMap<string, PendingQueries>> get_all_language_pack_strings_queries_;
|
2018-08-24 03:53:14 +02:00
|
|
|
|
2018-07-19 00:14:20 +02:00
|
|
|
static int32 manager_count_;
|
|
|
|
|
2018-07-20 15:15:19 +02:00
|
|
|
static std::mutex language_database_mutex_;
|
2022-11-23 17:37:32 +01:00
|
|
|
static std::unordered_map<string, unique_ptr<LanguageDatabase>, Hash<string>> language_databases_;
|
2018-07-05 20:28:11 +02:00
|
|
|
|
2021-10-19 17:11:16 +02:00
|
|
|
static LanguageDatabase *add_language_database(string path);
|
2018-07-23 19:29:14 +02:00
|
|
|
|
2018-07-20 15:15:19 +02:00
|
|
|
static Language *get_language(LanguageDatabase *database, const string &language_pack, const string &language_code);
|
2018-07-05 20:28:11 +02:00
|
|
|
static Language *get_language(LanguagePack *language_pack, const string &language_code);
|
|
|
|
|
2018-07-20 15:15:19 +02:00
|
|
|
static Language *add_language(LanguageDatabase *database, const string &language_pack, const string &language_code);
|
2018-07-05 20:28:11 +02:00
|
|
|
|
2018-08-23 02:45:04 +02:00
|
|
|
static bool language_has_string_unsafe(const Language *language, const string &key);
|
2018-07-05 20:28:11 +02:00
|
|
|
static bool language_has_strings(Language *language, const vector<string> &keys);
|
|
|
|
|
2018-09-07 18:12:48 +02:00
|
|
|
static void load_language_string_unsafe(Language *language, const string &key, const string &value);
|
2018-07-23 13:45:31 +02:00
|
|
|
static bool load_language_strings(LanguageDatabase *database, Language *language, const vector<string> &keys);
|
|
|
|
|
2018-08-22 23:29:26 +02:00
|
|
|
static td_api::object_ptr<td_api::LanguagePackStringValue> get_language_pack_string_value_object(const string &value);
|
|
|
|
static td_api::object_ptr<td_api::LanguagePackStringValue> get_language_pack_string_value_object(
|
|
|
|
const PluralizedString &value);
|
|
|
|
static td_api::object_ptr<td_api::LanguagePackStringValue> get_language_pack_string_value_object();
|
|
|
|
|
2022-02-07 22:04:34 +01:00
|
|
|
static td_api::object_ptr<td_api::languagePackString> get_language_pack_string_object(const string &key,
|
|
|
|
const string &value);
|
|
|
|
static td_api::object_ptr<td_api::languagePackString> get_language_pack_string_object(const string &key,
|
|
|
|
const PluralizedString &value);
|
|
|
|
static td_api::object_ptr<td_api::languagePackString> get_language_pack_string_object(const string &key);
|
2018-08-22 23:29:26 +02:00
|
|
|
|
2018-08-23 02:45:04 +02:00
|
|
|
static td_api::object_ptr<td_api::LanguagePackStringValue> get_language_pack_string_value_object(
|
|
|
|
const Language *language, const string &key);
|
2018-07-05 20:28:11 +02:00
|
|
|
|
2018-08-23 02:45:04 +02:00
|
|
|
static td_api::object_ptr<td_api::languagePackString> get_language_pack_string_object(const Language *language,
|
2018-07-23 19:29:14 +02:00
|
|
|
const string &key);
|
|
|
|
|
2018-07-05 20:28:11 +02:00
|
|
|
static td_api::object_ptr<td_api::languagePackStrings> get_language_pack_strings_object(Language *language,
|
|
|
|
const vector<string> &keys);
|
|
|
|
|
2019-02-11 18:57:35 +01:00
|
|
|
static td_api::object_ptr<td_api::languagePackInfo> get_language_pack_info_object(const string &language_code,
|
|
|
|
const LanguageInfo &info);
|
|
|
|
|
2019-02-12 02:15:45 +01:00
|
|
|
static Result<LanguageInfo> get_language_info(telegram_api::langPackLanguage *language);
|
|
|
|
|
2019-02-11 18:57:35 +01:00
|
|
|
static Result<LanguageInfo> get_language_info(td_api::languagePackInfo *language_pack_info);
|
|
|
|
|
|
|
|
static string get_language_info_string(const LanguageInfo &info);
|
|
|
|
|
2018-08-22 22:11:54 +02:00
|
|
|
static Result<tl_object_ptr<telegram_api::LangPackString>> convert_to_telegram_api(
|
2018-08-22 23:29:26 +02:00
|
|
|
tl_object_ptr<td_api::languagePackString> &&str);
|
2018-08-22 22:11:54 +02:00
|
|
|
|
2018-07-05 02:52:58 +02:00
|
|
|
void inc_generation();
|
2018-07-03 19:28:00 +02:00
|
|
|
|
2019-07-11 03:22:17 +02:00
|
|
|
void repair_chosen_language_info();
|
|
|
|
|
2018-07-23 13:45:31 +02:00
|
|
|
static bool is_valid_key(Slice key);
|
2018-07-22 19:22:19 +02:00
|
|
|
|
2018-08-23 02:45:04 +02:00
|
|
|
void save_strings_to_database(SqliteKeyValue *kv, int32 new_version, bool new_is_full, int32 new_key_count,
|
2021-10-19 17:11:16 +02:00
|
|
|
vector<std::pair<string, string>> &&strings);
|
2018-07-22 19:22:19 +02:00
|
|
|
|
2019-02-11 01:45:09 +01:00
|
|
|
void load_empty_language_pack(const string &language_code);
|
|
|
|
|
2018-07-17 04:58:34 +02:00
|
|
|
void on_get_language_pack_strings(string language_pack, string language_code, int32 version, bool is_diff,
|
2021-10-19 17:11:16 +02:00
|
|
|
vector<string> &&keys, vector<tl_object_ptr<telegram_api::LangPackString>> results,
|
2018-07-03 19:28:00 +02:00
|
|
|
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
|
|
|
|
|
2018-08-24 03:53:14 +02:00
|
|
|
void on_get_all_language_pack_strings(string language_pack, string language_code,
|
|
|
|
Result<td_api::object_ptr<td_api::languagePackStrings>> r_strings);
|
|
|
|
|
2021-10-19 17:11:16 +02:00
|
|
|
void send_language_get_difference_query(Language *language, string language_code, int32 version,
|
2019-02-23 18:27:14 +01:00
|
|
|
Promise<Unit> &&promise);
|
|
|
|
|
|
|
|
void on_failed_get_difference(string language_pack, string language_code, Status error);
|
2018-07-17 04:58:34 +02:00
|
|
|
|
2019-02-12 02:15:45 +01:00
|
|
|
void on_get_language_info(const string &language_pack, td_api::languagePackInfo *language_pack_info);
|
|
|
|
|
2021-10-19 17:11:16 +02:00
|
|
|
static void save_server_language_pack_infos(LanguagePack *pack);
|
2019-02-12 02:15:45 +01:00
|
|
|
|
2018-08-23 02:45:04 +02:00
|
|
|
void on_get_languages(vector<tl_object_ptr<telegram_api::langPackLanguage>> languages, string language_pack,
|
2018-09-04 14:01:08 +02:00
|
|
|
bool only_local, Promise<td_api::object_ptr<td_api::localizationTargetInfo>> promise);
|
2018-08-23 02:45:04 +02:00
|
|
|
|
2019-02-12 02:15:45 +01:00
|
|
|
void on_get_language(tl_object_ptr<telegram_api::langPackLanguage> lang_pack_language, string language_pack,
|
|
|
|
string language_code, Promise<td_api::object_ptr<td_api::languagePackInfo>> promise);
|
|
|
|
|
2021-10-19 17:11:16 +02:00
|
|
|
Status do_delete_language(const string &language_code);
|
2018-08-06 16:22:22 +02:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void on_result(NetQueryPtr query) final;
|
2018-07-03 19:28:00 +02:00
|
|
|
|
2021-07-03 22:51:36 +02:00
|
|
|
void start_up() final;
|
|
|
|
void hangup() final;
|
|
|
|
void tear_down() final;
|
2018-07-03 19:28:00 +02:00
|
|
|
|
|
|
|
Container<Promise<NetQueryPtr>> container_;
|
|
|
|
void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace td
|