Add td_api::searchStickers method.

GitOrigin-RevId: e9615b7e2cdab0b7419f6cfbbf2289787233a693
This commit is contained in:
levlam 2018-03-09 20:04:44 +03:00
parent a4fe4c93b3
commit 2a58cfd1b9
7 changed files with 163 additions and 1 deletions

View File

@ -2500,9 +2500,12 @@ clearImportedContacts = Ok;
getUserProfilePhotos user_id:int32 offset:int32 limit:int32 = UserProfilePhotos;
//@description Returns stickers from the installed sticker sets that correspond to a given emoji. If the emoji is not empty, favorite and recently used stickers may also be returned @emoji String representation of emoji. If empty, returns all known stickers @limit Maximum number of stickers to be returned
//@description Returns stickers from the installed sticker sets that correspond to a given emoji. If the emoji is not empty, favorite, recently used and trending stickers may also be returned @emoji String representation of emoji. If empty, returns all known installed stickers @limit Maximum number of stickers to be returned
getStickers emoji:string limit:int32 = Stickers;
//@description Searches for stickers from public sticker sets that correspond to a given emoji. May exclude some stickers returned by getStickers from the results @emoji String representation of emoji; must be non-empty @limit Maximum number of stickers to be returned
searchStickers emoji:string limit:int32 = Stickers;
//@description Returns a list of installed sticker sets @is_masks Pass true to return mask sticker sets; pass false to return ordinary sticker sets
getInstalledStickerSets is_masks:Bool = StickerSets;

Binary file not shown.

View File

@ -73,6 +73,34 @@ class GetAllStickersQuery : public Td::ResultHandler {
}
};
class SearchStickersQuery : public Td::ResultHandler {
string emoji_;
public:
void send(string emoji) {
emoji_ = std::move(emoji);
int32 flags = telegram_api::messages_getStickers::EXCLUDE_FEATURED_MASK;
send_query(G()->net_query_creator().create(
create_storer(telegram_api::messages_getStickers(flags, false /*ignored*/, emoji_, ""))));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::messages_getStickers>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for search stickers: " << to_string(ptr);
td->stickers_manager_->on_find_stickers_success(emoji_, std::move(ptr));
}
void on_error(uint64 id, Status status) override {
LOG(ERROR) << "Receive error for search stickers: " << status;
td->stickers_manager_->on_find_stickers_fail(emoji_, std::move(status));
}
};
class GetArchivedStickerSetsQuery : public Td::ResultHandler {
Promise<Unit> promise_;
bool is_masks_;
@ -1885,6 +1913,93 @@ vector<FileId> StickersManager::get_stickers(string emoji, int32 limit, bool for
return result;
}
vector<FileId> StickersManager::search_stickers(string emoji, int32 limit, Promise<Unit> &&promise) {
if (td_->auth_manager_->is_bot()) {
promise.set_error(Status::Error(7, "Method is not available for bots"));
return {};
}
if (limit <= 0) {
promise.set_error(Status::Error(3, "Parameter limit must be positive"));
return {};
}
if (limit > MAX_FOUND_STICKERS) {
limit = MAX_FOUND_STICKERS;
}
if (emoji.empty()) {
promise.set_error(Status::Error(3, "Emoji must be non-empty"));
return {};
}
emoji = remove_emoji_modifiers(emoji);
if (emoji.empty()) {
promise.set_value(Unit());
return {};
}
auto it = found_stickers_.find(emoji);
if (it != found_stickers_.end()) {
promise.set_value(Unit());
auto result_size = min(static_cast<size_t>(limit), it->second.size());
return vector<FileId>(it->second.begin(), it->second.begin() + result_size);
}
auto &promises = search_stickers_queries_[emoji];
promises.push_back(std::move(promise));
if (promises.size() == 1u) {
td_->create_handler<SearchStickersQuery>()->send(std::move(emoji));
}
return {};
}
void StickersManager::on_find_stickers_success(const string &emoji,
tl_object_ptr<telegram_api::messages_Stickers> &&stickers) {
CHECK(stickers != nullptr);
switch (stickers->get_id()) {
case telegram_api::messages_stickersNotModified::ID:
return on_find_stickers_fail(emoji, Status::Error(500, "Receive messages.stickerNotModified"));
case telegram_api::messages_stickers::ID: {
auto found_stickers = move_tl_object_as<telegram_api::messages_stickers>(stickers);
vector<FileId> &sticker_ids = found_stickers_[emoji];
CHECK(sticker_ids.empty());
for (auto &sticker : found_stickers->stickers_) {
FileId sticker_id = on_get_sticker_document(std::move(sticker), false).second;
if (sticker_id.is_valid()) {
sticker_ids.push_back(sticker_id);
}
}
break;
}
default:
UNREACHABLE();
}
auto it = search_stickers_queries_.find(emoji);
CHECK(it != search_stickers_queries_.end());
CHECK(!it->second.empty());
auto promises = std::move(it->second);
search_stickers_queries_.erase(it);
for (auto &promise : promises) {
promise.set_value(Unit());
}
}
void StickersManager::on_find_stickers_fail(const string &emoji, Status &&error) {
CHECK(found_stickers_.count(emoji) == 0);
auto it = search_stickers_queries_.find(emoji);
CHECK(it != search_stickers_queries_.end());
CHECK(!it->second.empty());
auto promises = std::move(it->second);
search_stickers_queries_.erase(it);
for (auto &promise : promises) {
promise.set_error(error.clone());
}
}
vector<int64> StickersManager::get_installed_sticker_sets(bool is_masks, Promise<Unit> &&promise) {
if (!are_installed_sticker_sets_loaded_[is_masks]) {
load_installed_sticker_sets(is_masks, std::move(promise));

View File

@ -67,6 +67,8 @@ class StickersManager : public Actor {
vector<FileId> get_stickers(string emoji, int32 limit, bool force, Promise<Unit> &&promise);
vector<FileId> search_stickers(string emoji, int32 limit, Promise<Unit> &&promise);
vector<int64> get_installed_sticker_sets(bool is_masks, Promise<Unit> &&promise);
int64 add_sticker_set(tl_object_ptr<telegram_api::InputStickerSet> &&set_ptr);
@ -200,6 +202,10 @@ class StickersManager : public Actor {
void on_uploaded_sticker_file(FileId file_id, tl_object_ptr<telegram_api::MessageMedia> media,
Promise<Unit> &&promise);
void on_find_stickers_success(const string &emoji, tl_object_ptr<telegram_api::messages_Stickers> &&sticker_sets);
void on_find_stickers_fail(const string &emoji, Status &&error);
void on_find_sticker_sets_success(const string &query,
tl_object_ptr<telegram_api::messages_FoundStickerSets> &&sticker_sets);
@ -208,6 +214,7 @@ class StickersManager : public Actor {
private:
static constexpr int32 MAX_FEATURED_STICKER_SET_VIEW_DELAY = 5;
static constexpr int32 MAX_FOUND_STICKERS = 100; // server side limit
static constexpr int64 MAX_STICKER_FILE_SIZE = 1 << 19; // server side limit
static constexpr size_t MAX_STICKER_SET_TITLE_LENGTH = 64; // server side limit
static constexpr size_t MAX_STICKER_SET_SHORT_NAME_LENGTH = 64; // server side limit
@ -468,6 +475,9 @@ class StickersManager : public Actor {
Hints installed_sticker_sets_hints_[2]; // search installed sticker sets by their title and name
std::unordered_map<string, vector<FileId>> found_stickers_;
std::unordered_map<string, vector<Promise<Unit>>> search_stickers_queries_;
std::unordered_map<string, vector<int64>> found_sticker_sets_;
std::unordered_map<string, vector<Promise<Unit>>> search_sticker_sets_queries_;

View File

@ -2770,6 +2770,26 @@ class GetStickersRequest : public RequestActor<> {
}
};
class SearchStickersRequest : public RequestActor<> {
string emoji_;
int32 limit_;
vector<FileId> sticker_ids_;
void do_run(Promise<Unit> &&promise) override {
sticker_ids_ = td->stickers_manager_->search_stickers(emoji_, limit_, std::move(promise));
}
void do_send_result() override {
send_result(td->stickers_manager_->get_stickers_object(sticker_ids_));
}
public:
SearchStickersRequest(ActorShared<Td> td, uint64 request_id, string &&emoji, int32 limit)
: RequestActor(std::move(td), request_id), emoji_(std::move(emoji)), limit_(limit) {
}
};
class GetInstalledStickerSetsRequest : public RequestActor<> {
bool is_masks_;
@ -6277,6 +6297,13 @@ void Td::on_request(uint64 id, td_api::getStickers &request) {
CREATE_REQUEST(GetStickersRequest, std::move(request.emoji_), request.limit_);
}
void Td::on_request(uint64 id, td_api::searchStickers &request) {
CHECK_AUTH();
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.emoji_);
CREATE_REQUEST(SearchStickersRequest, std::move(request.emoji_), request.limit_);
}
void Td::on_request(uint64 id, const td_api::getInstalledStickerSets &request) {
CHECK_AUTH();
CHECK_IS_USER();

View File

@ -645,6 +645,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::getStickers &request);
void on_request(uint64 id, td_api::searchStickers &request);
void on_request(uint64 id, const td_api::getInstalledStickerSets &request);
void on_request(uint64 id, const td_api::getArchivedStickerSets &request);

View File

@ -1531,6 +1531,11 @@ class CliClient final : public Actor {
string emoji;
std::tie(limit, emoji) = split(args);
send_request(make_tl_object<td_api::getStickers>(emoji, to_integer<int32>(limit)));
} else if (op == "sst") {
string limit;
string emoji;
std::tie(limit, emoji) = split(args);
send_request(make_tl_object<td_api::searchStickers>(emoji, to_integer<int32>(limit)));
} else if (op == "gss") {
send_request(make_tl_object<td_api::getStickerSet>(to_integer<int64>(args)));
} else if (op == "giss") {