From cd4d2e98c34ed413ca164dbad61ba19636377f77 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 19 Jul 2021 19:28:45 +0200 Subject: Add hotexamples --- src/plugins/HotExamples.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/plugins/HotExamples.cpp (limited to 'src/plugins/HotExamples.cpp') diff --git a/src/plugins/HotExamples.cpp b/src/plugins/HotExamples.cpp new file mode 100644 index 0000000..02f1217 --- /dev/null +++ b/src/plugins/HotExamples.cpp @@ -0,0 +1,139 @@ +#include "../../plugins/HotExamples.hpp" +#include "../../include/Theme.hpp" +#include "../../include/StringUtils.hpp" +#include + +namespace QuickMedia { + static std::shared_ptr create_body_item_with_url(const std::string &title, const std::string &url) { + auto body_item = BodyItem::create(title); + body_item->url = url; + return body_item; + } + + void hot_examples_front_page_fill(BodyItems &body_items) { + body_items.push_back(create_body_item_with_url("C++", "cpp")); + body_items.push_back(create_body_item_with_url("C#", "csharp")); + body_items.push_back(create_body_item_with_url("Go", "go")); + body_items.push_back(create_body_item_with_url("Java", "java")); + body_items.push_back(create_body_item_with_url("JavaScript", "javascript")); + body_items.push_back(create_body_item_with_url("PHP", "php")); + body_items.push_back(create_body_item_with_url("Python", "python")); + body_items.push_back(create_body_item_with_url("TypeScript", "typescript")); + } + + PluginResult HotExamplesLanguageSelectPage::submit(const std::string&, const std::string &url, std::vector &result_tabs) { + result_tabs.push_back({ create_body(), std::make_unique(program, url), create_search_bar("Search...", 500) }); + return PluginResult::OK; + } + + SearchResult HotExamplesSearchPage::search(const std::string &str, BodyItems &result_items) { + std::vector additional_args = { + { "-H", "content-type: application/x-www-form-urlencoded" }, + { "--data-raw", "SearchForm[lang]=" + language + "&SearchForm[search]=" + url_param_encode(str) } + }; + + std::string website_data; + DownloadResult download_result = download_to_string("https://hotexamples.com/search", website_data, additional_args, true); + if(download_result != DownloadResult::OK) return download_result_to_search_result(download_result); + + QuickMediaHtmlSearch html_search; + int result = quickmedia_html_search_init(&html_search, website_data.c_str(), website_data.size()); + if(result != 0) + return SearchResult::ERR; + + quickmedia_html_find_nodes_xpath(&html_search, "//div[class='search-result row']//div[class='header']//a", + [](QuickMediaMatchNode *node, void *userdata) { + auto *item_data = (BodyItems*)userdata; + QuickMediaStringView href = quickmedia_html_node_get_attribute_value(node, "href"); + if(href.data && memmem(href.data, href.size, "/examples/", 10)) { + QuickMediaStringView text = quickmedia_html_node_get_text(node); + if(text.data) { + std::string title(text.data, text.size); + html_unescape_sequences(title); + + auto item = BodyItem::create(std::move(title)); + item->url.assign(href.data, href.size); + item_data->push_back(std::move(item)); + } + } + return 0; + }, &result_items); + + BodyItemContext body_item_context; + body_item_context.body_items = &result_items; + body_item_context.index = 0; + + quickmedia_html_find_nodes_xpath(&html_search, "//div[class='search-result row']//span[class='count']", + [](QuickMediaMatchNode *node, void *userdata) { + auto *item_data = (BodyItemContext*)userdata; + QuickMediaStringView text = quickmedia_html_node_get_text(node); + if(text.data && item_data->index < item_data->body_items->size()) { + std::string desc(text.data, text.size); + html_unescape_sequences(desc); + + (*item_data->body_items)[item_data->index]->set_description(std::move(desc)); + (*item_data->body_items)[item_data->index]->set_description_color(get_current_theme().faded_text_color); + item_data->index++; + } + return 0; + }, &body_item_context); + + quickmedia_html_search_deinit(&html_search); + return SearchResult::OK; + } + + PluginResult HotExamplesSearchPage::submit(const std::string &title, const std::string &url, std::vector &result_tabs) { + BodyItems result_items; + std::string website_data; + DownloadResult download_result = download_to_string(url, website_data, {}, true); + if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result); + + QuickMediaHtmlSearch html_search; + int result = quickmedia_html_search_init(&html_search, website_data.c_str(), website_data.size()); + if(result != 0) + return PluginResult::ERR; + + quickmedia_html_find_nodes_xpath(&html_search, "//div[class='example-item']//div[class='example-project-info']", + [](QuickMediaMatchNode *node, void *userdata) { + auto *item_data = (BodyItems*)userdata; + QuickMediaStringView text = quickmedia_html_node_get_text(node); + if(text.data) { + std::string title(text.data, text.size); + html_unescape_sequences(title); + string_replace_all(title, "Project:", " Project:"); + + auto item = BodyItem::create(std::move(title)); + //item->url.assign(href.data, href.size); + item_data->push_back(std::move(item)); + } + return 0; + }, &result_items); + + BodyItemContext body_item_context; + body_item_context.body_items = &result_items; + body_item_context.index = 0; + + quickmedia_html_find_nodes_xpath(&html_search, "//div[class='example-item']//div[class='example']", + [](QuickMediaMatchNode *node, void *userdata) { + auto *item_data = (BodyItemContext*)userdata; + QuickMediaStringView text = quickmedia_html_node_get_text(node); + if(text.data && item_data->index < item_data->body_items->size()) { + std::string desc(text.data, text.size); + html_unescape_sequences(desc); + + (*item_data->body_items)[item_data->index]->set_description(std::move(desc)); + (*item_data->body_items)[item_data->index]->set_description_color(get_current_theme().text_color); + // TODO: Use monospace + item_data->index++; + } + return 0; + }, &body_item_context); + + quickmedia_html_search_deinit(&html_search); + + auto body = create_body(); + body->items = std::move(result_items); + result_tabs.push_back({ std::move(body), std::make_unique(program, title + " code examples"), create_search_bar("Search...", SEARCH_DELAY_FILTER) }); + return PluginResult::OK; + } +} \ No newline at end of file -- cgit v1.2.3