aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/HotExamples.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-07-19 19:28:45 +0200
committerdec05eba <dec05eba@protonmail.com>2021-07-19 19:28:45 +0200
commitcd4d2e98c34ed413ca164dbad61ba19636377f77 (patch)
tree69a1ab7f19acc4b9abf016025921efed3b80c2a9 /src/plugins/HotExamples.cpp
parente671784144174c4fceaa6df3737ba9b4de4a6c63 (diff)
Add hotexamples
Diffstat (limited to 'src/plugins/HotExamples.cpp')
-rw-r--r--src/plugins/HotExamples.cpp139
1 files changed, 139 insertions, 0 deletions
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 <quickmedia/HtmlSearch.h>
+
+namespace QuickMedia {
+ static std::shared_ptr<BodyItem> 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<Tab> &result_tabs) {
+ result_tabs.push_back({ create_body(), std::make_unique<HotExamplesSearchPage>(program, url), create_search_bar("Search...", 500) });
+ return PluginResult::OK;
+ }
+
+ SearchResult HotExamplesSearchPage::search(const std::string &str, BodyItems &result_items) {
+ std::vector<CommandArg> 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<Tab> &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<HotExamplesCodeExamplesPage>(program, title + " code examples"), create_search_bar("Search...", SEARCH_DELAY_FILTER) });
+ return PluginResult::OK;
+ }
+} \ No newline at end of file