From 39f4091ac5917006e460ac7172bd5eee14069d6f Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 3 Feb 2023 15:58:15 +0300 Subject: [PATCH] Add td_api::setAutosaveSettings. --- td/generate/scheme/td_api.tl | 18 ++++ td/telegram/AutosaveManager.cpp | 142 ++++++++++++++++++++++++++++++-- td/telegram/AutosaveManager.h | 10 +++ td/telegram/Td.cpp | 6 ++ td/telegram/Td.h | 2 + td/telegram/cli.cpp | 25 ++++++ 6 files changed, 198 insertions(+), 5 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 9d479022c..cede01c28 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4816,6 +4816,21 @@ autoDownloadSettings is_auto_download_enabled:Bool max_photo_file_size:int32 max autoDownloadSettingsPresets low:autoDownloadSettings medium:autoDownloadSettings high:autoDownloadSettings = AutoDownloadSettingsPresets; +//@class AutosaveSettingsScope @description Describes scope of autosave settings + +//@description Autosave settings applied to all private chats without chat-specific settings +autosaveSettingsScopePrivateChats = AutosaveSettingsScope; + +//@description Autosave settings applied to all basic group and supergroup chats without chat-specific settings +autosaveSettingsScopeGroupChats = AutosaveSettingsScope; + +//@description Autosave settings applied to all channel chats without chat-specific settings +autosaveSettingsScopeChannelChats = AutosaveSettingsScope; + +//@description Autosave settings applied to a chat @chat_id Chat identifier +autosaveSettingsScopeChat chat_id:int53 = AutosaveSettingsScope; + + //@description Contains autosave settings for an autosave settings scope //@autosave_photos True, if photo autosave is enabled //@autosave_videos True, if video autosave is enabled @@ -7831,6 +7846,9 @@ setAutoDownloadSettings settings:autoDownloadSettings type:NetworkType = Ok; //@description Returns autosave settings for the current user getAutosaveSettings = AutosaveSettings; +//@description Sets autosave settings for the given scope @scope Autosave settings scope @settings New autosave settings for the scope; pass null to set autosave settings to default +setAutosaveSettings scope:AutosaveSettingsScope settings:scopeAutosaveSettings = Ok; + //@description Clears the list of all autosave settings exceptions clearAutosaveSettingsExceptions = Ok; diff --git a/td/telegram/AutosaveManager.cpp b/td/telegram/AutosaveManager.cpp index 101d0ea55..3fa5f7d57 100644 --- a/td/telegram/AutosaveManager.cpp +++ b/td/telegram/AutosaveManager.cpp @@ -43,11 +43,58 @@ class GetAutosaveSettingsQuery final : public Td::ResultHandler { } }; -class DeleteAutosaveExceptionsQuery final : public Td::ResultHandler { +class SaveAutoSaveSettingsQuery final : public Td::ResultHandler { Promise promise_; public: - explicit DeleteAutosaveExceptionsQuery(Promise &&promise) : promise_(std::move(promise)) { + explicit SaveAutoSaveSettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(bool users, bool chats, bool broadcasts, DialogId dialog_id, + telegram_api::object_ptr settings) { + int32 flags = 0; + telegram_api::object_ptr input_peer; + if (users) { + flags |= telegram_api::account_saveAutoSaveSettings::USERS_MASK; + } else if (chats) { + flags |= telegram_api::account_saveAutoSaveSettings::CHATS_MASK; + } else if (broadcasts) { + flags |= telegram_api::account_saveAutoSaveSettings::BROADCASTS_MASK; + } else { + input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + if (dialog_id.get_type() == DialogType::SecretChat) { + return on_error(Status::Error(400, "Can't set autosave settings for secret chats")); + } + return on_error(Status::Error(400, "Can't access the chat")); + } + } + send_query(G()->net_query_creator().create( + telegram_api::account_saveAutoSaveSettings(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, + std::move(input_peer), std::move(settings)), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + td_->autosave_manager_->reload_autosave_settings(Auto()); + } +}; + +class DeleteAutoSaveExceptionsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit DeleteAutoSaveExceptionsQuery(Promise &&promise) : promise_(std::move(promise)) { } void send() { @@ -78,11 +125,38 @@ void AutosaveManager::tear_down() { AutosaveManager::DialogAutosaveSettings::DialogAutosaveSettings(const telegram_api::autoSaveSettings *settings) { CHECK(settings != nullptr); + are_inited_ = true; autosave_photos_ = settings->photos_; autosave_videos_ = settings->videos_; max_video_file_size_ = settings->video_max_size_; } +AutosaveManager::DialogAutosaveSettings::DialogAutosaveSettings(const td_api::scopeAutosaveSettings *settings) { + if (settings == nullptr) { + return; + } + are_inited_ = true; + autosave_photos_ = settings->autosave_photos_; + autosave_videos_ = settings->autosave_videos_; + max_video_file_size_ = settings->max_video_file_size_; +} + +telegram_api::object_ptr +AutosaveManager::DialogAutosaveSettings::get_input_auto_save_settings() const { + int32 flags = 0; + if (autosave_photos_) { + flags |= telegram_api::autoSaveSettings::PHOTOS_MASK; + } + if (autosave_videos_) { + flags |= telegram_api::autoSaveSettings::VIDEOS_MASK; + } + if (are_inited_) { + flags |= telegram_api::autoSaveSettings::VIDEO_MAX_SIZE_MASK; + } + return telegram_api::make_object(flags, false /*ignored*/, false /*ignored*/, + max_video_file_size_); +} + td_api::object_ptr AutosaveManager::DialogAutosaveSettings::get_scope_autosave_settings_object() const { return td_api::make_object(autosave_photos_, autosave_videos_, max_video_file_size_); @@ -93,14 +167,19 @@ AutosaveManager::DialogAutosaveSettings::get_autosave_settings_exception_object( return td_api::make_object(dialog_id.get(), get_scope_autosave_settings_object()); } +bool AutosaveManager::DialogAutosaveSettings::operator==(const DialogAutosaveSettings &other) const { + return are_inited_ == other.are_inited_ && autosave_photos_ == other.autosave_photos_ && + autosave_videos_ == other.autosave_videos_ && max_video_file_size_ == other.max_video_file_size_; +} + td_api::object_ptr AutosaveManager::AutosaveSettings::get_autosave_settings_object() const { CHECK(are_inited_); auto exceptions = transform(exceptions_, [](const auto &exception) { return exception.second.get_autosave_settings_exception_object(exception.first); }); return td_api::make_object( - user_settings_.get_scope_autosave_settings_object(), user_settings_.get_scope_autosave_settings_object(), - user_settings_.get_scope_autosave_settings_object(), std::move(exceptions)); + user_settings_.get_scope_autosave_settings_object(), chat_settings_.get_scope_autosave_settings_object(), + broadcast_settings_.get_scope_autosave_settings_object(), std::move(exceptions)); } void AutosaveManager::get_autosave_settings(Promise> &&promise) { @@ -157,9 +236,62 @@ void AutosaveManager::on_get_autosave_settings( } } +void AutosaveManager::set_autosave_settings(td_api::object_ptr &&scope, + td_api::object_ptr &&settings, + Promise &&promise) { + if (scope == nullptr) { + return promise.set_error(Status::Error(400, "Scope must be non-empty")); + } + auto new_settings = DialogAutosaveSettings(settings.get()); + DialogAutosaveSettings *old_settings = nullptr; + bool users = false; + bool chats = false; + bool broadcasts = false; + DialogId dialog_id; + switch (scope->get_id()) { + case td_api::autosaveSettingsScopePrivateChats::ID: + users = true; + old_settings = &settings_.user_settings_; + break; + case td_api::autosaveSettingsScopeGroupChats::ID: + chats = true; + old_settings = &settings_.chat_settings_; + break; + case td_api::autosaveSettingsScopeChannelChats::ID: + broadcasts = true; + old_settings = &settings_.broadcast_settings_; + break; + case td_api::autosaveSettingsScopeChat::ID: + dialog_id = DialogId(static_cast(scope.get())->chat_id_); + if (!td_->messages_manager_->have_dialog_force(dialog_id, "set_autosave_settings")) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + old_settings = &settings_.exceptions_[dialog_id]; + break; + default: + UNREACHABLE(); + } + if (!dialog_id.is_valid()) { + new_settings.are_inited_ = true; + } + if (*old_settings == new_settings) { + return promise.set_value(Unit()); + } + if (settings_.are_inited_) { + if (new_settings.are_inited_) { + *old_settings = new_settings; + } else { + CHECK(dialog_id.is_valid()); + settings_.exceptions_.erase(dialog_id); + } + } + td_->create_handler(std::move(promise)) + ->send(users, chats, broadcasts, dialog_id, new_settings.get_input_auto_save_settings()); +} + void AutosaveManager::clear_autosave_settings_excpetions(Promise &&promise) { settings_.exceptions_.clear(); - td_->create_handler(std::move(promise))->send(); + td_->create_handler(std::move(promise))->send(); } } // namespace td diff --git a/td/telegram/AutosaveManager.h b/td/telegram/AutosaveManager.h index 1019b6c11..140052c48 100644 --- a/td/telegram/AutosaveManager.h +++ b/td/telegram/AutosaveManager.h @@ -29,10 +29,14 @@ class AutosaveManager final : public Actor { void get_autosave_settings(Promise> &&promise); + void set_autosave_settings(td_api::object_ptr &&scope, + td_api::object_ptr &&settings, Promise &&promise); + void clear_autosave_settings_excpetions(Promise &&promise); private: struct DialogAutosaveSettings { + bool are_inited_ = false; bool autosave_photos_ = false; bool autosave_videos_ = false; int64 max_video_file_size_ = 0; @@ -41,10 +45,16 @@ class AutosaveManager final : public Actor { explicit DialogAutosaveSettings(const telegram_api::autoSaveSettings *settings); + explicit DialogAutosaveSettings(const td_api::scopeAutosaveSettings *settings); + + telegram_api::object_ptr get_input_auto_save_settings() const; + td_api::object_ptr get_scope_autosave_settings_object() const; td_api::object_ptr get_autosave_settings_exception_object( DialogId dialog_id) const; + + bool operator==(const DialogAutosaveSettings &other) const; }; struct AutosaveSettings { diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index d4d4c03b7..c60ccade7 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -4952,6 +4952,12 @@ void Td::on_request(uint64 id, const td_api::getAutosaveSettings &request) { autosave_manager_->get_autosave_settings(std::move(promise)); } +void Td::on_request(uint64 id, td_api::setAutosaveSettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + autosave_manager_->set_autosave_settings(std::move(request.scope_), std::move(request.settings_), std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::clearAutosaveSettingsExceptions &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 27eb84d97..3371a458c 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -592,6 +592,8 @@ class Td final : public Actor { void on_request(uint64 id, const td_api::getAutosaveSettings &request); + void on_request(uint64 id, td_api::setAutosaveSettings &request); + void on_request(uint64 id, const td_api::clearAutosaveSettingsExceptions &request); void on_request(uint64 id, const td_api::getTopChats &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 827034313..4d93ab361 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -2833,6 +2833,31 @@ class CliClient final : public Actor { td_api::make_object(), as_network_type(args))); } else if (op == "gaus") { send_request(td_api::make_object()); + } else if (op == "saus") { + string scope_str; + bool autosave_photos; + bool autosave_videos; + int64 max_video_file_size; + get_args(args, scope_str, autosave_photos, autosave_videos, max_video_file_size); + auto scope = [&]() -> td_api::object_ptr { + if (scope_str == "users") { + return td_api::make_object(); + } + if (scope_str == "groups") { + return td_api::make_object(); + } + if (scope_str == "channels") { + return td_api::make_object(); + } + auto chat_id = as_chat_id(scope_str); + if (chat_id != 0) { + return td_api::make_object(chat_id); + } + return nullptr; + }(); + send_request(td_api::make_object( + std::move(scope), + td_api::make_object(autosave_photos, autosave_videos, max_video_file_size))); } else if (op == "cause") { send_request(td_api::make_object()); } else if (op == "ansc") {