From d74766245facd48805c2576c711d20cafa33aa35 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 18 Sep 2021 18:07:10 +0200 Subject: Show option to open saucenao result urls ctrl+c for info should only copy the url --- src/plugins/Saucenao.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'src/plugins/Saucenao.cpp') diff --git a/src/plugins/Saucenao.cpp b/src/plugins/Saucenao.cpp index d81e233..ccb01f9 100644 --- a/src/plugins/Saucenao.cpp +++ b/src/plugins/Saucenao.cpp @@ -1,8 +1,78 @@ #include "../../plugins/Saucenao.hpp" +#include "../../plugins/Info.hpp" #include "../../include/StringUtils.hpp" #include namespace QuickMedia { + class SaucenaoBodyItemUrls : public BodyItemExtra { + public: + std::vector urls; + }; + + static int string_views_equal_case_insensitive(const QuickMediaStringView str1, const QuickMediaStringView str2) { + if(str2.size != str1.size) + return 1; + + for(size_t i = 0; i < str1.size; ++i) { + char c1 = str1.data[i]; + char c2 = str2.data[i]; + if(to_upper(c1) != to_upper(c2)) + return 1; + } + + return 0; + } + + static QuickMediaHtmlAttribute* get_attribute_by_name(QuickMediaHtmlNode *node, QuickMediaStringView name) { + for(QuickMediaHtmlAttribute *attr = node->first_attribute; attr; attr = attr->next) { + if(string_views_equal_case_insensitive(attr->key, name) == 0) + return attr; + } + return NULL; + } + + static void match_node_get_urls(QuickMediaHtmlNode *node, std::vector &urls) { + if(node->is_tag && string_views_equal_case_insensitive(node->name, {"a", 1}) == 0) { + QuickMediaHtmlAttribute *attr = get_attribute_by_name(node, {"href", 4}); + if(attr) + urls.emplace_back(attr->value.data, attr->value.size); + } + + QuickMediaHtmlChildNode *child_node = node->first_child; + while(child_node) { + match_node_get_urls(&child_node->node, urls); + child_node = child_node->next; + } + } + + static std::string get_first_line(const std::string &str) { + const size_t line_end = str.find('\n'); + if(line_end == std::string::npos) + return str; + else + return str.substr(0, line_end); + } + + PluginResult SaucenaoPage::submit(const std::string &title, const std::string&, std::vector &result_tabs) { + if(!submit_body_item) + return PluginResult::OK; + + SaucenaoBodyItemUrls *urls = static_cast(submit_body_item->extra.get()); + BodyItems body_items; + + for(const std::string &url : urls->urls) { + // Ignore saucenao info pages + if(url.find("saucenao.com") == std::string::npos) + body_items.push_back(InfoPage::add_url(url)); + } + body_items.push_back(InfoPage::add_google_search(get_first_line(title))); + + auto body = create_body(); + body->set_items(std::move(body_items)); + result_tabs.push_back(Tab{ std::move(body), std::make_unique(program), create_search_bar("Search...", SEARCH_DELAY_FILTER) }); + return PluginResult::OK; + } + PluginResult SaucenaoPage::lazy_fetch(BodyItems &result_items) { std::vector additional_args; if(is_local) { @@ -31,6 +101,9 @@ namespace QuickMedia { title = title.erase(0, p_index + 1); title = strip(title); auto item = BodyItem::create(title); + auto urls = std::make_shared(); + match_node_get_urls(node->node, urls->urls); + item->extra = std::move(urls); item_data->push_back(std::move(item)); } return 0; -- cgit v1.2.3