Accept formattedText in getWebPageInstantView.

GitOrigin-RevId: b9f2345eb170da6cbdbb6c70abf11fa682630802
This commit is contained in:
levlam 2018-02-21 00:20:45 +03:00
parent f0e5accbb4
commit c3fe3f97ec
11 changed files with 109 additions and 76 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(TDLib VERSION 1.1.2 LANGUAGES CXX C) project(TDLib VERSION 1.1.3 LANGUAGES CXX C)
option(TD_ENABLE_JNI "Use \"ON\" to enable JNI-compatible TDLib API.") option(TD_ENABLE_JNI "Use \"ON\" to enable JNI-compatible TDLib API.")

View File

@ -107,7 +107,7 @@ target_link_libraries(YourTarget PRIVATE Td::TdStatic)
Or you could install `TDLib` and then reference it in your CMakeLists.txt like this: Or you could install `TDLib` and then reference it in your CMakeLists.txt like this:
``` ```
find_package(Td 1.1.2 REQUIRED) find_package(Td 1.1.3 REQUIRED)
target_link_libraries(YourTarget PRIVATE Td::TdStatic) target_link_libraries(YourTarget PRIVATE Td::TdStatic)
``` ```
See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/tree/master/example/cpp/CMakeLists.txt). See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/tree/master/example/cpp/CMakeLists.txt).

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
project(TdExample VERSION 1.0 LANGUAGES CXX) project(TdExample VERSION 1.0 LANGUAGES CXX)
find_package(Td 1.1.2 REQUIRED) find_package(Td 1.1.3 REQUIRED)
add_executable(tdjson_example tdjson_example.cpp) add_executable(tdjson_example tdjson_example.cpp)
target_link_libraries(tdjson_example PRIVATE Td::TdJson) target_link_libraries(tdjson_example PRIVATE Td::TdJson)

View File

@ -2302,6 +2302,7 @@ viewMessages chat_id:int53 message_ids:vector<int53> force_read:Bool = Ok;
//@description This method should be called if the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed @chat_id Chat identifier of the message @message_id Identifier of the message with the opened content //@description This method should be called if the message content has been opened (e.g., the user has opened a photo, video, document, location or venue, or has listened to an audio file or voice note message). An updateMessageContentOpened update will be generated if something has changed @chat_id Chat identifier of the message @message_id Identifier of the message with the opened content
openMessageContent chat_id:int53 message_id:int53 = Ok; openMessageContent chat_id:int53 message_id:int53 = Ok;
//@description Marks all mentions in a chat as read @chat_id Chat identifier //@description Marks all mentions in a chat as read @chat_id Chat identifier
readAllChatMentions chat_id:int53 = Ok; readAllChatMentions chat_id:int53 = Ok;
@ -2545,8 +2546,8 @@ searchHashtags prefix:string limit:int32 = Hashtags;
removeRecentHashtag hashtag:string = Ok; removeRecentHashtag hashtag:string = Ok;
//@description Returns a web page preview by the text of the message. Do not call this function too often. Returns a 404 error if the web page has no preview @message_text Message text //@description Returns a web page preview by the text of the message. Do not call this function too often. Returns a 404 error if the web page has no preview @text Message text with formatting
getWebPagePreview message_text:string = WebPage; getWebPagePreview text:formattedText = WebPage;
//@description Returns an instant view version of a web page if available. Returns a 404 error if the web page has no instant view page @url The web page URL @force_full If true, the full instant view for the web page will be returned //@description Returns an instant view version of a web page if available. Returns a 404 error if the web page has no instant view page @url The web page URL @force_full If true, the full instant view for the web page will be returned
getWebPageInstantView url:string force_full:Bool = WebPageInstantView; getWebPageInstantView url:string force_full:Bool = WebPageInstantView;

Binary file not shown.

View File

@ -16278,7 +16278,7 @@ bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, boo
auto channel_id = dialog_id.get_channel_id(); auto channel_id = dialog_id.get_channel_id();
auto channel_status = td_->contacts_manager_->get_channel_status(channel_id); auto channel_status = td_->contacts_manager_->get_channel_status(channel_id);
if (m->is_channel_post) { if (m->is_channel_post) {
if (!channel_status.can_edit_messages() && (!channel_status.can_post_messages() || !m->is_outgoing)) { if (!channel_status.can_edit_messages() && !(channel_status.can_post_messages() && m->is_outgoing)) {
return false; return false;
} }
} else { } else {

View File

@ -1727,22 +1727,22 @@ class ReadAllChatMentionsRequest : public RequestOnceActor {
} }
}; };
class GetWebPagePreviewRequest : public RequestActor<> { class GetWebPagePreviewRequest : public RequestOnceActor {
string message_text_; td_api::object_ptr<td_api::formattedText> text_;
WebPageId web_page_id_; int64 request_id_ = 0;
void do_run(Promise<Unit> &&promise) override { void do_run(Promise<Unit> &&promise) override {
web_page_id_ = td->web_pages_manager_->get_web_page_preview(message_text_, std::move(promise)); request_id_ = td->web_pages_manager_->get_web_page_preview(std::move(text_), std::move(promise));
} }
void do_send_result() override { void do_send_result() override {
send_result(td->web_pages_manager_->get_web_page_object(web_page_id_)); send_result(td->web_pages_manager_->get_web_page_preview_result(request_id_));
} }
public: public:
GetWebPagePreviewRequest(ActorShared<Td> td, uint64 request_id, string message_text) GetWebPagePreviewRequest(ActorShared<Td> td, uint64 request_id, td_api::object_ptr<td_api::formattedText> text)
: RequestActor(std::move(td), request_id), message_text_(std::move(message_text)) { : RequestOnceActor(std::move(td), request_id), text_(std::move(text)) {
} }
}; };
@ -5531,8 +5531,7 @@ void Td::on_request(uint64 id, const td_api::forwardMessages &request) {
void Td::on_request(uint64 id, td_api::getWebPagePreview &request) { void Td::on_request(uint64 id, td_api::getWebPagePreview &request) {
CHECK_AUTH(); CHECK_AUTH();
CHECK_IS_USER(); CHECK_IS_USER();
CLEAN_INPUT_STRING(request.message_text_); CREATE_REQUEST(GetWebPagePreviewRequest, std::move(request.text_));
CREATE_REQUEST(GetWebPagePreviewRequest, std::move(request.message_text_));
} }
void Td::on_request(uint64 id, td_api::getWebPageInstantView &request) { void Td::on_request(uint64 id, td_api::getWebPageInstantView &request) {

View File

@ -192,7 +192,7 @@ class Td final : public NetQueryCallback {
static td_api::object_ptr<td_api::Object> static_request(td_api::object_ptr<td_api::Function> function); static td_api::object_ptr<td_api::Object> static_request(td_api::object_ptr<td_api::Function> function);
private: private:
static constexpr const char *tdlib_version = "1.1.2"; static constexpr const char *tdlib_version = "1.1.3";
static constexpr int64 ONLINE_ALARM_ID = 0; static constexpr int64 ONLINE_ALARM_ID = 0;
static constexpr int32 ONLINE_TIMEOUT = 240; static constexpr int32 ONLINE_TIMEOUT = 240;
static constexpr int64 PING_SERVER_ALARM_ID = -1; static constexpr int64 PING_SERVER_ALARM_ID = -1;

View File

@ -51,16 +51,25 @@ namespace td {
class GetWebPagePreviewQuery : public Td::ResultHandler { class GetWebPagePreviewQuery : public Td::ResultHandler {
Promise<Unit> promise_; Promise<Unit> promise_;
string message_text_; int64 request_id_;
string url_;
public: public:
explicit GetWebPagePreviewQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) { explicit GetWebPagePreviewQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
} }
void send(const string &message_text) { void send(const string &text, vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities, int64 request_id,
message_text_ = message_text; string url) {
request_id_ = request_id;
url_ = std::move(url);
int32 flags = 0;
if (!entities.empty()) {
flags |= telegram_api::messages_getWebPagePreview::ENTITIES_MASK;
}
send_query(G()->net_query_creator().create( send_query(G()->net_query_creator().create(
create_storer(telegram_api::messages_getWebPagePreview(0, message_text, Auto())))); create_storer(telegram_api::messages_getWebPagePreview(flags, text, std::move(entities)))));
} }
void on_result(uint64 id, BufferSlice packet) override { void on_result(uint64 id, BufferSlice packet) override {
@ -71,11 +80,11 @@ class GetWebPagePreviewQuery : public Td::ResultHandler {
auto ptr = result_ptr.move_as_ok(); auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for GetWebPagePreviewQuery " << to_string(ptr); LOG(INFO) << "Receive result for GetWebPagePreviewQuery " << to_string(ptr);
td->web_pages_manager_->on_get_web_page_preview_success(message_text_, std::move(ptr), std::move(promise_)); td->web_pages_manager_->on_get_web_page_preview_success(request_id_, url_, std::move(ptr), std::move(promise_));
} }
void on_error(uint64 id, Status status) override { void on_error(uint64 id, Status status) override {
td->web_pages_manager_->on_get_web_page_preview_fail(message_text_, std::move(status), std::move(promise_)); td->web_pages_manager_->on_get_web_page_preview_fail(request_id_, url_, std::move(status), std::move(promise_));
} }
}; };
@ -1619,19 +1628,19 @@ void WebPagesManager::wait_for_pending_web_page(DialogId dialog_id, MessageId me
pending_web_pages_timeout_.add_timeout_in(web_page_id.get(), 1.0); pending_web_pages_timeout_.add_timeout_in(web_page_id.get(), 1.0);
} }
void WebPagesManager::on_get_web_page_preview_success(const string &message_text, void WebPagesManager::on_get_web_page_preview_success(int64 request_id, const string &url,
tl_object_ptr<telegram_api::MessageMedia> &&message_media_ptr, tl_object_ptr<telegram_api::MessageMedia> &&message_media_ptr,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
CHECK(message_media_ptr != nullptr); CHECK(message_media_ptr != nullptr);
int32 constructor_id = message_media_ptr->get_id(); int32 constructor_id = message_media_ptr->get_id();
if (constructor_id != telegram_api::messageMediaWebPage::ID) { if (constructor_id != telegram_api::messageMediaWebPage::ID) {
if (constructor_id == telegram_api::messageMediaEmpty::ID) { if (constructor_id == telegram_api::messageMediaEmpty::ID) {
on_get_web_page_preview_success(message_text, WebPageId(), std::move(promise)); on_get_web_page_preview_success(request_id, url, WebPageId(), std::move(promise));
return; return;
} }
LOG(ERROR) << "Receive " << to_string(message_media_ptr) << " instead of web page"; LOG(ERROR) << "Receive " << to_string(message_media_ptr) << " instead of web page";
on_get_web_page_preview_fail(message_text, Status::Error(500, "Receive not web page in GetWebPagePreview"), on_get_web_page_preview_fail(request_id, url, Status::Error(500, "Receive not web page in GetWebPagePreview"),
std::move(promise)); std::move(promise));
return; return;
} }
@ -1641,65 +1650,86 @@ void WebPagesManager::on_get_web_page_preview_success(const string &message_text
auto web_page_id = on_get_web_page(std::move(message_media_web_page->webpage_), DialogId()); auto web_page_id = on_get_web_page(std::move(message_media_web_page->webpage_), DialogId());
if (web_page_id.is_valid() && !have_web_page(web_page_id)) { if (web_page_id.is_valid() && !have_web_page(web_page_id)) {
pending_get_web_pages_[web_page_id].emplace(message_text, std::move(promise)); // TODO MultiPromise ? pending_get_web_pages_[web_page_id].emplace(request_id,
std::make_pair(url, std::move(promise))); // TODO MultiPromise ?
pending_web_pages_timeout_.add_timeout_in(web_page_id.get(), 1.0); pending_web_pages_timeout_.add_timeout_in(web_page_id.get(), 1.0);
return; return;
} }
on_get_web_page_preview_success(message_text, web_page_id, std::move(promise)); on_get_web_page_preview_success(request_id, url, web_page_id, std::move(promise));
} }
void WebPagesManager::on_get_web_page_preview_success(const string &message_text, WebPageId web_page_id, void WebPagesManager::on_get_web_page_preview_success(int64 request_id, const string &url, WebPageId web_page_id,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
CHECK(web_page_id == WebPageId() || have_web_page(web_page_id)); CHECK(web_page_id == WebPageId() || have_web_page(web_page_id));
CHECK(got_web_page_previews_.find(message_text) == got_web_page_previews_.end()); CHECK(got_web_page_previews_.find(request_id) == got_web_page_previews_.end());
got_web_page_previews_[message_text] = web_page_id; got_web_page_previews_[request_id] = web_page_id;
auto erased_count = running_get_web_page_previews_.erase(message_text); if (web_page_id.is_valid() && !url.empty()) {
CHECK(erased_count > 0); on_get_web_page_by_url(url, web_page_id, true);
}
promise.set_value(Unit()); promise.set_value(Unit());
} }
void WebPagesManager::on_get_web_page_preview_fail(const string &message_text, Status error, Promise<Unit> &&promise) { void WebPagesManager::on_get_web_page_preview_fail(int64 request_id, const string &url, Status error,
LOG(INFO) << "Clean up getting of web page preview"; Promise<Unit> &&promise) {
auto erased_count = running_get_web_page_previews_.erase(message_text); LOG(INFO) << "Clean up getting of web page preview with url \"" << url << '"';
CHECK(erased_count > 0);
CHECK(error.is_error()); CHECK(error.is_error());
promise.set_error(std::move(error)); promise.set_error(std::move(error));
} }
WebPageId WebPagesManager::get_web_page_preview(const string &message_text, Promise<Unit> &&promise) { int64 WebPagesManager::get_web_page_preview(td_api::object_ptr<td_api::formattedText> &&text, Promise<Unit> &&promise) {
LOG(INFO) << "Trying to get web page preview for message \"" << message_text << '"'; if (text == nullptr) {
auto it = got_web_page_previews_.find(message_text);
if (it != got_web_page_previews_.end()) {
auto web_page_id = it->second;
if (web_page_id.is_valid()) {
auto entities = find_entities(message_text, true, true);
auto url = get_first_url(message_text, entities);
if (!url.empty()) {
on_get_web_page_by_url(url, web_page_id, true);
}
}
got_web_page_previews_.erase(it);
promise.set_value(Unit()); promise.set_value(Unit());
return web_page_id; return 0;
} }
if (!running_get_web_page_previews_.insert(message_text).second) { auto r_entities = get_message_entities(td_->contacts_manager_.get(), text->entities_);
// TODO MultiPromise if (r_entities.is_error()) {
promise.set_error(Status::Error(3, "Request with the same text is already running")); promise.set_error(r_entities.move_as_error());
return WebPageId(); return 0;
}
auto entities = r_entities.move_as_ok();
auto result = fix_formatted_text(text->text_, entities, true, false, true, false);
if (text->text_.empty()) {
promise.set_value(Unit());
return 0;
} }
td_->create_handler<GetWebPagePreviewQuery>(std::move(promise))->send(message_text); auto url = get_first_url(text->text_, entities);
return WebPageId(); if (url.empty()) {
promise.set_value(Unit());
return 0;
}
LOG(INFO) << "Trying to get web page preview for message \"" << text->text_ << '"';
int64 request_id = get_web_page_preview_request_id_++;
auto web_page_id = get_web_page_by_url(url);
if (web_page_id.is_valid()) {
got_web_page_previews_[request_id] = web_page_id;
promise.set_value(Unit());
} else {
td_->create_handler<GetWebPagePreviewQuery>(std::move(promise))
->send(text->text_, get_input_message_entities(td_->contacts_manager_.get(), entities), request_id,
std::move(url));
}
return request_id;
}
tl_object_ptr<td_api::webPage> WebPagesManager::get_web_page_preview_result(int64 request_id) {
if (request_id == 0) {
return nullptr;
}
auto it = got_web_page_previews_.find(request_id);
CHECK(it != got_web_page_previews_.end());
auto web_page_id = it->second;
got_web_page_previews_.erase(it);
return get_web_page_object(web_page_id);
} }
WebPageId WebPagesManager::get_web_page_instant_view(const string &url, bool force_full, Promise<Unit> &&promise) { WebPageId WebPagesManager::get_web_page_instant_view(const string &url, bool force_full, Promise<Unit> &&promise) {
@ -2077,8 +2107,8 @@ void WebPagesManager::update_messages_content(WebPageId web_page_id, bool have_w
auto requests = std::move(get_it->second); auto requests = std::move(get_it->second);
pending_get_web_pages_.erase(get_it); pending_get_web_pages_.erase(get_it);
for (auto &request : requests) { for (auto &request : requests) {
on_get_web_page_preview_success(request.first, have_web_page ? web_page_id : WebPageId(), on_get_web_page_preview_success(request.first, request.second.first, have_web_page ? web_page_id : WebPageId(),
std::move(request.second)); std::move(request.second.second));
} }
} }
pending_web_pages_timeout_.cancel_timeout(web_page_id.get()); pending_web_pages_timeout_.cancel_timeout(web_page_id.get());
@ -2139,8 +2169,8 @@ void WebPagesManager::on_pending_web_page_timeout(WebPageId web_page_id) {
auto requests = std::move(get_it->second); auto requests = std::move(get_it->second);
pending_get_web_pages_.erase(get_it); pending_get_web_pages_.erase(get_it);
for (auto &request : requests) { for (auto &request : requests) {
on_get_web_page_preview_fail(request.first, Status::Error(500, "Request timeout exceeded"), on_get_web_page_preview_fail(request.first, request.second.first, Status::Error(500, "Request timeout exceeded"),
std::move(request.second)); std::move(request.second.second));
count++; count++;
} }
} }

View File

@ -26,6 +26,7 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <utility>
namespace td { namespace td {
@ -55,7 +56,9 @@ class WebPagesManager : public Actor {
tl_object_ptr<td_api::webPageInstantView> get_web_page_instant_view_object(WebPageId web_page_id) const; tl_object_ptr<td_api::webPageInstantView> get_web_page_instant_view_object(WebPageId web_page_id) const;
WebPageId get_web_page_preview(const string &message_text, Promise<Unit> &&promise); int64 get_web_page_preview(td_api::object_ptr<td_api::formattedText> &&text, Promise<Unit> &&promise);
tl_object_ptr<td_api::webPage> get_web_page_preview_result(int64 request_id);
WebPageId get_web_page_instant_view(const string &url, bool force_full, Promise<Unit> &&promise); WebPageId get_web_page_instant_view(const string &url, bool force_full, Promise<Unit> &&promise);
@ -63,11 +66,11 @@ class WebPagesManager : public Actor {
WebPageId get_web_page_by_url(const string &url, Promise<Unit> &&promise); WebPageId get_web_page_by_url(const string &url, Promise<Unit> &&promise);
void on_get_web_page_preview_success(const string &message_text, void on_get_web_page_preview_success(int64 request_id, const string &url,
tl_object_ptr<telegram_api::MessageMedia> &&message_media_ptr, tl_object_ptr<telegram_api::MessageMedia> &&message_media_ptr,
Promise<Unit> &&promise); Promise<Unit> &&promise);
void on_get_web_page_preview_fail(const string &message_text, Status error, Promise<Unit> &&promise); void on_get_web_page_preview_fail(int64 request_id, const string &url, Status error, Promise<Unit> &&promise);
SecretInputMedia get_secret_input_media(WebPageId web_page_id) const; SecretInputMedia get_secret_input_media(WebPageId web_page_id) const;
@ -152,7 +155,8 @@ class WebPagesManager : public Actor {
static void on_pending_web_page_timeout_callback(void *web_pages_manager_ptr, int64 web_page_id); static void on_pending_web_page_timeout_callback(void *web_pages_manager_ptr, int64 web_page_id);
void on_pending_web_page_timeout(WebPageId web_page_id); void on_pending_web_page_timeout(WebPageId web_page_id);
void on_get_web_page_preview_success(const string &message_text, WebPageId web_page_id, Promise<Unit> &&promise); void on_get_web_page_preview_success(int64 request_id, const string &url, WebPageId web_page_id,
Promise<Unit> &&promise);
static RichText get_rich_text(tl_object_ptr<telegram_api::RichText> &&rich_text_ptr); static RichText get_rich_text(tl_object_ptr<telegram_api::RichText> &&rich_text_ptr);
@ -229,10 +233,11 @@ class WebPagesManager : public Actor {
std::unordered_map<WebPageId, PendingWebPageInstantViewQueries, WebPageIdHash> load_web_page_instant_view_queries_; std::unordered_map<WebPageId, PendingWebPageInstantViewQueries, WebPageIdHash> load_web_page_instant_view_queries_;
std::unordered_map<WebPageId, std::unordered_set<FullMessageId, FullMessageIdHash>, WebPageIdHash> pending_web_pages_; std::unordered_map<WebPageId, std::unordered_set<FullMessageId, FullMessageIdHash>, WebPageIdHash> pending_web_pages_;
std::unordered_map<WebPageId, std::unordered_map<string, Promise<Unit>>, WebPageIdHash> pending_get_web_pages_; std::unordered_map<WebPageId, std::unordered_map<int64, std::pair<string, Promise<Unit>>>, WebPageIdHash>
pending_get_web_pages_;
std::unordered_map<string, WebPageId> got_web_page_previews_; int64 get_web_page_preview_request_id_ = 1;
std::unordered_set<string> running_get_web_page_previews_; std::unordered_map<int64, WebPageId> got_web_page_previews_;
std::unordered_map<string, WebPageId> url_to_web_page_id_; std::unordered_map<string, WebPageId> url_to_web_page_id_;

View File

@ -762,9 +762,7 @@ class CliClient final : public Actor {
auto parsed_caption = auto parsed_caption =
execute(make_tl_object<td_api::parseTextEntities>(caption, make_tl_object<td_api::textParseModeMarkdown>())); execute(make_tl_object<td_api::parseTextEntities>(caption, make_tl_object<td_api::textParseModeMarkdown>()));
if (parsed_caption->get_id() == td_api::formattedText::ID) { if (parsed_caption->get_id() == td_api::formattedText::ID) {
auto text = td_api::move_object_as<td_api::formattedText>(parsed_caption); return td_api::move_object_as<td_api::formattedText>(parsed_caption);
caption = std::move(text->text_);
entities = std::move(text->entities_);
} }
} }
return make_tl_object<td_api::formattedText>(caption, std::move(entities)); return make_tl_object<td_api::formattedText>(caption, std::move(entities));
@ -2702,7 +2700,7 @@ class CliClient final : public Actor {
} else if (op == "crfcs") { } else if (op == "crfcs") {
send_request(make_tl_object<td_api::clearRecentlyFoundChats>()); send_request(make_tl_object<td_api::clearRecentlyFoundChats>());
} else if (op == "gwpp") { } else if (op == "gwpp") {
send_request(make_tl_object<td_api::getWebPagePreview>(args)); send_request(make_tl_object<td_api::getWebPagePreview>(as_caption(args)));
} else if (op == "gwpiv") { } else if (op == "gwpiv") {
string url; string url;
string force_full; string force_full;