LanguagePackManager draft. getLanguagePack, getLanguagePackStrings methods.

GitOrigin-RevId: 959e1fd4a76eb5005d8a53c3e88abb3054fb9a5e
This commit is contained in:
levlam 2018-07-03 20:28:00 +03:00
parent f51c0602e6
commit b28ec40407
15 changed files with 263 additions and 1 deletions

View File

@ -370,6 +370,7 @@ set(TDLIB_SOURCE
td/telegram/Global.cpp td/telegram/Global.cpp
td/telegram/HashtagHints.cpp td/telegram/HashtagHints.cpp
td/telegram/InlineQueriesManager.cpp td/telegram/InlineQueriesManager.cpp
td/telegram/LanguagePackManager.cpp
td/telegram/Location.cpp td/telegram/Location.cpp
td/telegram/MessageEntity.cpp td/telegram/MessageEntity.cpp
td/telegram/MessagesDb.cpp td/telegram/MessagesDb.cpp
@ -483,6 +484,7 @@ set(TDLIB_SOURCE
td/telegram/Global.h td/telegram/Global.h
td/telegram/HashtagHints.h td/telegram/HashtagHints.h
td/telegram/InlineQueriesManager.h td/telegram/InlineQueriesManager.h
td/telegram/LanguagePackManager.h
td/telegram/Location.h td/telegram/Location.h
td/telegram/logevent/LogEvent.h td/telegram/logevent/LogEvent.h
td/telegram/logevent/LogEventHelper.h td/telegram/logevent/LogEventHelper.h

View File

@ -1652,6 +1652,29 @@ chatEvents events:vector<chatEvent> = 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; 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
//@description An ordinary language pack string @key String key @value String value
languagePackStringValue key:string value:string = LanguagePackString;
//@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
//@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;
//@description A deleted language pack string @key String key
languagePackStringDeleted key:string = 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 @code Language code @name Language name @native_name Language native name
languageInfo code:string name:string native_name:string = LanguageInfo;
//@description Contains information about a language pack @languages List of available languages
languagePack languages:vector<languageInfo> = LanguagePack;
//@class DeviceToken @description Represents a data needed to subscribe for push notifications. To use specific push notification service, you must specify the correct application platform and upload valid server authentication data at https://my.telegram.org //@class DeviceToken @description Represents a data needed to subscribe for push notifications. To use specific push notification service, you must specify the correct application platform and upload valid server authentication data at https://my.telegram.org
//@description A token for Google Cloud Messaging @token Device registration token; may be empty to de-register a device //@description A token for Google Cloud Messaging @token Device registration token; may be empty to de-register a device
@ -3025,6 +3048,13 @@ getSupportUser = User;
getWallpapers = Wallpapers; getWallpapers = Wallpapers;
//@description Returns information about used language pack
getLanguagePack = LanguagePack;
//@description Returns strings from used language pack on specified language by their keys @language_code Language code of strings to return @keys Language pack keys of strings to return; may be empty to get all available strings
getLanguagePackStrings language_code:string keys:vector<string> = LanguagePackStrings;
//@description Registers the currently used device for receiving push notifications @device_token Device token @other_user_ids List of at most 100 user identifiers of other users currently using the client //@description Registers the currently used device for receiving push notifications @device_token Device token @other_user_ids List of at most 100 user identifiers of other users currently using the client
registerDevice device_token:DeviceToken other_user_ids:vector<int32> = Ok; registerDevice device_token:DeviceToken other_user_ids:vector<int32> = Ok;

Binary file not shown.

View File

@ -0,0 +1,131 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
//
// 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)
//
#include "td/telegram/LanguagePackManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/net/NetQueryDispatcher.h"
#include "td/utils/logging.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
namespace td {
void LanguagePackManager::get_languages(Promise<td_api::object_ptr<td_api::languagePack>> promise) {
auto request_promise = PromiseCreator::lambda([promise = std::move(promise)](Result<NetQueryPtr> r_query) mutable {
auto r_result = fetch_result<telegram_api::langpack_getLanguages>(std::move(r_query));
if (r_result.is_error()) {
return promise.set_error(r_result.move_as_error());
}
auto languages = r_result.move_as_ok();
auto results = make_tl_object<td_api::languagePack>();
results->languages_.reserve(languages.size());
for (auto &language : languages) {
results->languages_.push_back(
make_tl_object<td_api::languageInfo>(language->lang_code_, language->name_, language->native_name_));
}
promise.set_value(std::move(results));
});
send_with_promise(G()->net_query_creator().create(create_storer(telegram_api::langpack_getLanguages())),
std::move(request_promise));
}
void LanguagePackManager::get_language_pack_strings(string language_code, vector<string> keys,
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise) {
bool is_all = keys.empty();
auto result_promise =
PromiseCreator::lambda([actor_id = actor_id(this), is_all, promise = std::move(promise)](
Result<vector<tl_object_ptr<telegram_api::LangPackString>>> r_result) mutable {
send_closure(actor_id, &LanguagePackManager::on_get_language_pack_strings, std::move(r_result), is_all,
std::move(promise));
});
if (is_all) {
auto request_promise =
PromiseCreator::lambda([promise = std::move(result_promise)](Result<NetQueryPtr> r_query) mutable {
auto r_result = fetch_result<telegram_api::langpack_getLangPack>(std::move(r_query));
if (r_result.is_error()) {
return promise.set_error(r_result.move_as_error());
}
auto result = r_result.move_as_ok();
LOG(INFO) << "Receive language pack for language " << result->lang_code_ << " from version "
<< result->from_version_ << " with version " << result->version_ << " of size "
<< result->strings_.size();
promise.set_value(std::move(result->strings_));
});
send_with_promise(G()->net_query_creator().create(create_storer(telegram_api::langpack_getLangPack(language_code))),
std::move(request_promise));
} else {
auto request_promise =
PromiseCreator::lambda([promise = std::move(result_promise)](Result<NetQueryPtr> r_query) mutable {
auto r_result = fetch_result<telegram_api::langpack_getStrings>(std::move(r_query));
if (r_result.is_error()) {
return promise.set_error(r_result.move_as_error());
}
promise.set_value(r_result.move_as_ok());
});
send_with_promise(G()->net_query_creator().create(
create_storer(telegram_api::langpack_getStrings(language_code, std::move(keys)))),
std::move(request_promise));
}
}
void LanguagePackManager::on_get_language_pack_strings(
Result<vector<tl_object_ptr<telegram_api::LangPackString>>> r_result, bool ia_all,
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise) {
if (r_result.is_error()) {
return promise.set_error(r_result.move_as_error());
}
auto result =
transform(r_result.move_as_ok(), [](const auto &string_ptr) -> tl_object_ptr<td_api::LanguagePackString> {
CHECK(string_ptr != nullptr);
switch (string_ptr->get_id()) {
case telegram_api::langPackString::ID: {
auto str = static_cast<const telegram_api::langPackString *>(string_ptr.get());
return make_tl_object<td_api::languagePackStringValue>(str->key_, str->value_);
}
case telegram_api::langPackStringPluralized::ID: {
auto str = static_cast<const telegram_api::langPackStringPluralized *>(string_ptr.get());
return make_tl_object<td_api::languagePackStringPluralized>(str->key_, str->zero_value_, str->one_value_,
str->two_value_, str->few_value_,
str->many_value_, str->other_value_);
}
case telegram_api::langPackStringDeleted::ID: {
auto str = static_cast<const telegram_api::langPackStringDeleted *>(string_ptr.get());
return make_tl_object<td_api::languagePackStringDeleted>(str->key_);
}
default:
UNREACHABLE();
return nullptr;
}
});
promise.set_value(make_tl_object<td_api::languagePackStrings>(std::move(result)));
}
void LanguagePackManager::on_result(NetQueryPtr query) {
auto token = get_link_token();
container_.extract(token).set_value(std::move(query));
}
void LanguagePackManager::send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise) {
auto id = container_.create(std::move(promise));
G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id));
}
void LanguagePackManager::hangup() {
container_.for_each(
[](auto id, Promise<NetQueryPtr> &promise) { promise.set_error(Status::Error(500, "Request aborted")); });
stop();
}
} // namespace td

View File

@ -0,0 +1,48 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
//
// 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"
#include "td/actor/PromiseFuture.h"
#include "td/utils/Container.h"
namespace td {
class LanguagePackManager : public NetQueryCallback {
public:
explicit LanguagePackManager(ActorShared<> parent) : parent_(std::move(parent)) {
}
void get_languages(Promise<td_api::object_ptr<td_api::languagePack>> promise);
void get_language_pack_strings(string language_code, vector<string> keys,
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
private:
ActorShared<> parent_;
string language_pack_;
string language_code_;
void on_get_language_pack_strings(Result<vector<tl_object_ptr<telegram_api::LangPackString>>> r_result, bool ia_all,
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
void on_result(NetQueryPtr query) override;
void hangup() override;
Container<Promise<NetQueryPtr>> container_;
void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);
};
} // namespace td

View File

@ -50,13 +50,13 @@ class PasswordManager : public NetQueryCallback {
explicit PasswordManager(ActorShared<> parent) : parent_(std::move(parent)) { explicit PasswordManager(ActorShared<> parent) : parent_(std::move(parent)) {
} }
void get_state(Promise<State> promise); void get_state(Promise<State> promise);
void set_password(string current_password, string new_password, string new_hint, bool set_recovery_email_address, void set_password(string current_password, string new_password, string new_hint, bool set_recovery_email_address,
string recovery_email_address, Promise<State> promise); string recovery_email_address, Promise<State> promise);
void set_recovery_email_address(string password, string new_recovery_email_address, Promise<State> promise); void set_recovery_email_address(string password, string new_recovery_email_address, Promise<State> promise);
void get_recovery_email_address(string password, Promise<tl_object_ptr<td_api::recoveryEmailAddress>> promise); void get_recovery_email_address(string password, Promise<tl_object_ptr<td_api::recoveryEmailAddress>> promise);
string last_verified_email_address_;
void send_email_address_verification_code( void send_email_address_verification_code(
string email, Promise<td_api::object_ptr<td_api::emailAddressAuthenticationCodeInfo>> promise); string email, Promise<td_api::object_ptr<td_api::emailAddressAuthenticationCodeInfo>> promise);
void resend_email_address_verification_code( void resend_email_address_verification_code(
@ -125,6 +125,8 @@ class PasswordManager : public NetQueryCallback {
TempPasswordState temp_password_state_; TempPasswordState temp_password_state_;
Promise<TempState> create_temp_password_promise_; Promise<TempState> create_temp_password_promise_;
string last_verified_email_address_;
void update_password_settings(UpdateSettings update_settings, Promise<State> promise); void update_password_settings(UpdateSettings update_settings, Promise<State> promise);
void do_update_password_settings(UpdateSettings update_settings, PasswordFullState full_state, Promise<bool> promise); void do_update_password_settings(UpdateSettings update_settings, PasswordFullState full_state, Promise<bool> promise);
void do_get_state(Promise<PasswordState> promise); void do_get_state(Promise<PasswordState> promise);

View File

@ -40,6 +40,7 @@
#include "td/telegram/Global.h" #include "td/telegram/Global.h"
#include "td/telegram/HashtagHints.h" #include "td/telegram/HashtagHints.h"
#include "td/telegram/InlineQueriesManager.h" #include "td/telegram/InlineQueriesManager.h"
#include "td/telegram/LanguagePackManager.h"
#include "td/telegram/MessageEntity.h" #include "td/telegram/MessageEntity.h"
#include "td/telegram/MessageId.h" #include "td/telegram/MessageId.h"
#include "td/telegram/MessagesManager.h" #include "td/telegram/MessagesManager.h"
@ -3229,6 +3230,8 @@ bool Td::is_preinitialization_request(int32 id) {
bool Td::is_preauthentication_request(int32 id) { bool Td::is_preauthentication_request(int32 id) {
switch (id) { switch (id) {
case td_api::processDcUpdate::ID: case td_api::processDcUpdate::ID:
case td_api::getLanguagePack::ID:
case td_api::getLanguagePackStrings::ID:
case td_api::getOption::ID: case td_api::getOption::ID:
case td_api::setOption::ID: case td_api::setOption::ID:
case td_api::setNetworkType::ID: case td_api::setNetworkType::ID:
@ -3758,6 +3761,8 @@ void Td::clear() {
LOG(DEBUG) << "DeviceTokenManager was cleared " << timer; LOG(DEBUG) << "DeviceTokenManager was cleared " << timer;
hashtag_hints_.reset(); hashtag_hints_.reset();
LOG(DEBUG) << "HashtagHints was cleared " << timer; LOG(DEBUG) << "HashtagHints was cleared " << timer;
language_pack_manager_.reset();
LOG(DEBUG) << "LanguagePackManager was cleared " << timer;
net_stats_manager_.reset(); net_stats_manager_.reset();
LOG(DEBUG) << "NetStatsManager was cleared " << timer; LOG(DEBUG) << "NetStatsManager was cleared " << timer;
password_manager_.reset(); password_manager_.reset();
@ -4060,6 +4065,7 @@ Status Td::init(DbKey key) {
"ConfirmPhoneNumberManager", PhoneNumberManager::Type::ConfirmPhone, create_reference()); "ConfirmPhoneNumberManager", PhoneNumberManager::Type::ConfirmPhone, create_reference());
device_token_manager_ = create_actor<DeviceTokenManager>("DeviceTokenManager", create_reference()); device_token_manager_ = create_actor<DeviceTokenManager>("DeviceTokenManager", create_reference());
hashtag_hints_ = create_actor<HashtagHints>("HashtagHints", "text", create_reference()); hashtag_hints_ = create_actor<HashtagHints>("HashtagHints", "text", create_reference());
language_pack_manager_ = create_actor<LanguagePackManager>("LanguagePackManager", create_reference());
password_manager_ = create_actor<PasswordManager>("PasswordManager", create_reference()); password_manager_ = create_actor<PasswordManager>("PasswordManager", create_reference());
G()->set_password_manager(password_manager_.get()); G()->set_password_manager(password_manager_.get());
privacy_manager_ = create_actor<PrivacyManager>("PrivacyManager", create_reference()); privacy_manager_ = create_actor<PrivacyManager>("PrivacyManager", create_reference());
@ -5922,6 +5928,23 @@ void Td::on_request(uint64 id, const td_api::resetAllNotificationSettings &reque
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>()); send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
} }
void Td::on_request(uint64 id, const td_api::getLanguagePack &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
send_closure(language_pack_manager_, &LanguagePackManager::get_languages, std::move(promise));
}
void Td::on_request(uint64 id, td_api::getLanguagePackStrings &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.language_code_);
for (auto &key : request.keys_) {
CLEAN_INPUT_STRING(key);
}
CREATE_REQUEST_PROMISE();
send_closure(language_pack_manager_, &LanguagePackManager::get_language_pack_strings,
std::move(request.language_code_), std::move(request.keys_), std::move(promise));
}
void Td::on_request(uint64 id, td_api::getOption &request) { void Td::on_request(uint64 id, td_api::getOption &request) {
CLEAN_INPUT_STRING(request.name_); CLEAN_INPUT_STRING(request.name_);

View File

@ -45,6 +45,7 @@ class DocumentsManager;
class FileManager; class FileManager;
class InlineQueriesManager; class InlineQueriesManager;
class HashtagHints; class HashtagHints;
class LanguagePackManager;
class MessagesManager; class MessagesManager;
class NetStatsManager; class NetStatsManager;
class PasswordManager; class PasswordManager;
@ -152,6 +153,7 @@ class Td final : public NetQueryCallback {
ActorOwn<PhoneNumberManager> confirm_phone_number_manager_; ActorOwn<PhoneNumberManager> confirm_phone_number_manager_;
ActorOwn<DeviceTokenManager> device_token_manager_; ActorOwn<DeviceTokenManager> device_token_manager_;
ActorOwn<HashtagHints> hashtag_hints_; ActorOwn<HashtagHints> hashtag_hints_;
ActorOwn<LanguagePackManager> language_pack_manager_;
ActorOwn<NetStatsManager> net_stats_manager_; ActorOwn<NetStatsManager> net_stats_manager_;
ActorOwn<PasswordManager> password_manager_; ActorOwn<PasswordManager> password_manager_;
ActorOwn<PrivacyManager> privacy_manager_; ActorOwn<PrivacyManager> privacy_manager_;
@ -749,6 +751,10 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::reportChat &request); void on_request(uint64 id, td_api::reportChat &request);
void on_request(uint64 id, const td_api::getLanguagePack &request);
void on_request(uint64 id, td_api::getLanguagePackStrings &request);
void on_request(uint64 id, td_api::getOption &request); void on_request(uint64 id, td_api::getOption &request);
void on_request(uint64 id, td_api::setOption &request); void on_request(uint64 id, td_api::setOption &request);

View File

@ -1699,6 +1699,14 @@ class CliClient final : public Actor {
std::tie(chat_id, message_id) = split(args); std::tie(chat_id, message_id) = split(args);
send_request(make_tl_object<td_api::deleteChatReplyMarkup>(as_chat_id(chat_id), as_message_id(message_id))); send_request(make_tl_object<td_api::deleteChatReplyMarkup>(as_chat_id(chat_id), as_message_id(message_id)));
} else if (op == "glp") {
send_request(make_tl_object<td_api::getLanguagePack>());
} else if (op == "glps") {
string language_code;
string keys;
std::tie(language_code, keys) = split(args);
send_request(make_tl_object<td_api::getLanguagePackStrings>(language_code, full_split(keys)));
} 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") {

View File

@ -11,6 +11,7 @@
#include "td/utils/logging.h" #include "td/utils/logging.h"
namespace td { namespace td {
class Condition { class Condition {
class Helper : public Actor { class Helper : public Actor {
public: public:
@ -44,4 +45,5 @@ class Condition {
ActorId<Helper> actor_; ActorId<Helper> actor_;
ActorOwn<Helper> own_actor_; ActorOwn<Helper> own_actor_;
}; };
} // namespace td } // namespace td

View File

@ -7,6 +7,7 @@
#include "td/actor/MultiPromise.h" #include "td/actor/MultiPromise.h"
namespace td { namespace td {
void MultiPromiseActor::add_promise(Promise<Unit> &&promise) { void MultiPromiseActor::add_promise(Promise<Unit> &&promise) {
promises_.emplace_back(std::move(promise)); promises_.emplace_back(std::move(promise));
} }
@ -87,4 +88,5 @@ MultiPromiseActorSafe::~MultiPromiseActorSafe() {
register_existing_actor(std::move(multi_promise_)).release(); register_existing_actor(std::move(multi_promise_)).release();
} }
} }
} // namespace td } // namespace td

View File

@ -22,6 +22,7 @@
#include <utility> #include <utility>
namespace td { namespace td {
template <class T = Unit> template <class T = Unit>
class PromiseInterface { class PromiseInterface {
public: public:
@ -651,4 +652,5 @@ class PromiseCreator {
return Promise<T>(std::make_unique<PromiseActor<T>>(std::move(from))); return Promise<T>(std::make_unique<PromiseActor<T>>(std::move(from)));
} }
}; };
} // namespace td } // namespace td

View File

@ -14,6 +14,7 @@
#include <functional> #include <functional>
namespace td { namespace td {
template <class T> template <class T>
class SchedulerLocalStorage { class SchedulerLocalStorage {
public: public:

View File

@ -9,7 +9,9 @@
#include "td/actor/actor.h" #include "td/actor/actor.h"
namespace td { namespace td {
class Slot; class Slot;
class Signal { class Signal {
public: public:
void emit(); void emit();
@ -20,6 +22,7 @@ class Signal {
private: private:
ActorId<Slot> slot_id_; ActorId<Slot> slot_id_;
}; };
class Slot final : public Actor { class Slot final : public Actor {
public: public:
Slot() = default; Slot() = default;
@ -101,6 +104,7 @@ class Slot final : public Actor {
signal(); signal();
} }
}; };
inline void Signal::emit() { inline void Signal::emit() {
send_closure(slot_id_, &Slot::signal); send_closure(slot_id_, &Slot::signal);
} }

View File

@ -15,6 +15,7 @@
#include <set> #include <set>
namespace td { namespace td {
class Timeout final : public Actor { class Timeout final : public Actor {
public: public:
using Data = void *; using Data = void *;