diff options
Diffstat (limited to 'src/plugins/Youtube.cpp')
-rw-r--r-- | src/plugins/Youtube.cpp | 117 |
1 files changed, 59 insertions, 58 deletions
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp index 40d545c..a5670ec 100644 --- a/src/plugins/Youtube.cpp +++ b/src/plugins/Youtube.cpp @@ -12,64 +12,6 @@ namespace QuickMedia { return strstr(str, substr); } - SearchResult Youtube::search(const std::string &text, std::vector<std::unique_ptr<BodyItem>> &result_items, Page &next_page) { - next_page = Page::SEARCH_RESULT; - std::string url = "https://youtube.com/results?search_query="; - url += url_param_encode(text); - - std::string website_data; - if(download_to_string(url, website_data) != DownloadResult::OK) - return SearchResult::NET_ERR; - - struct ItemData { - std::vector<std::unique_ptr<BodyItem>> *result_items; - size_t index; - }; - ItemData item_data = { &result_items, 0 }; - - QuickMediaHtmlSearch html_search; - int result = quickmedia_html_search_init(&html_search, website_data.c_str()); - if(result != 0) - goto cleanup; - - result = quickmedia_html_find_nodes_xpath(&html_search, "//h3[class=\"yt-lockup-title\"]/a", - [](QuickMediaHtmlNode *node, void *userdata) { - auto *result_items = (std::vector<std::unique_ptr<BodyItem>>*)userdata; - const char *href = quickmedia_html_node_get_attribute_value(node, "href"); - const char *title = quickmedia_html_node_get_attribute_value(node, "title"); - // Checking for watch?v helps skipping ads - if(href && title && begins_with(href, "/watch?v=")) { - auto item = std::make_unique<BodyItem>(strip(title)); - item->url = std::string("https://www.youtube.com") + href; - result_items->push_back(std::move(item)); - } - }, &result_items); - if(result != 0) - goto cleanup; - - result = quickmedia_html_find_nodes_xpath(&html_search, "//span[class=\"yt-thumb-simple\"]//img", - [](QuickMediaHtmlNode *node, void *userdata) { - ItemData *item_data = (ItemData*)userdata; - if(item_data->index >= item_data->result_items->size()) - return; - - const char *src = quickmedia_html_node_get_attribute_value(node, "src"); - const char *data_thumb = quickmedia_html_node_get_attribute_value(node, "data-thumb"); - - if(src && contains(src, "i.ytimg.com/")) { - (*item_data->result_items)[item_data->index]->thumbnail_url = src; - ++item_data->index; - } else if(data_thumb && contains(data_thumb, "i.ytimg.com/")) { - (*item_data->result_items)[item_data->index]->thumbnail_url = data_thumb; - ++item_data->index; - } - }, &item_data); - - cleanup: - quickmedia_html_search_deinit(&html_search); - return result == 0 ? SearchResult::OK : SearchResult::ERR; - } - static void iterate_suggestion_result(const Json::Value &value, std::vector<std::unique_ptr<BodyItem>> &result_items, int &iterate_count) { ++iterate_count; if(value.isArray()) { @@ -83,7 +25,11 @@ namespace QuickMedia { } } + // TODO: Speed this up by using string.find instead of parsing html SuggestionResult Youtube::update_search_suggestions(const std::string &text, std::vector<std::unique_ptr<BodyItem>> &result_items) { + // Keep this for backup. This is using search suggestion the same way youtube does it, but the results + // are not as good as doing an actual search. + #if 0 std::string url = "https://clients1.google.com/complete/search?client=youtube&hl=en&gs_rn=64&gs_ri=youtube&ds=yt&cp=7&gs_id=x&q="; url += url_param_encode(text); @@ -125,6 +71,61 @@ namespace QuickMedia { if(!found_search_text) result_items.insert(result_items.begin(), std::make_unique<BodyItem>(text)); return SuggestionResult::OK; + #endif + std::string url = "https://youtube.com/results?search_query="; + url += url_param_encode(text); + + std::string website_data; + if(download_to_string(url, website_data) != DownloadResult::OK) + return SuggestionResult::NET_ERR; + + struct ItemData { + std::vector<std::unique_ptr<BodyItem>> *result_items; + size_t index; + }; + ItemData item_data = { &result_items, 0 }; + + QuickMediaHtmlSearch html_search; + int result = quickmedia_html_search_init(&html_search, website_data.c_str()); + if(result != 0) + goto cleanup; + + result = quickmedia_html_find_nodes_xpath(&html_search, "//h3[class=\"yt-lockup-title\"]/a", + [](QuickMediaHtmlNode *node, void *userdata) { + auto *result_items = (std::vector<std::unique_ptr<BodyItem>>*)userdata; + const char *href = quickmedia_html_node_get_attribute_value(node, "href"); + const char *title = quickmedia_html_node_get_attribute_value(node, "title"); + // Checking for watch?v helps skipping ads + if(href && title && begins_with(href, "/watch?v=")) { + auto item = std::make_unique<BodyItem>(strip(title)); + item->url = std::string("https://www.youtube.com") + href; + result_items->push_back(std::move(item)); + } + }, &result_items); + if(result != 0) + goto cleanup; + + result = quickmedia_html_find_nodes_xpath(&html_search, "//span[class=\"yt-thumb-simple\"]//img", + [](QuickMediaHtmlNode *node, void *userdata) { + ItemData *item_data = (ItemData*)userdata; + if(item_data->index >= item_data->result_items->size()) + return; + + const char *src = quickmedia_html_node_get_attribute_value(node, "src"); + const char *data_thumb = quickmedia_html_node_get_attribute_value(node, "data-thumb"); + + if(src && contains(src, "i.ytimg.com/")) { + (*item_data->result_items)[item_data->index]->thumbnail_url = src; + ++item_data->index; + } else if(data_thumb && contains(data_thumb, "i.ytimg.com/")) { + (*item_data->result_items)[item_data->index]->thumbnail_url = data_thumb; + ++item_data->index; + } + }, &item_data); + + cleanup: + quickmedia_html_search_deinit(&html_search); + return result == 0 ? SuggestionResult::OK : SuggestionResult::ERR; } std::vector<std::unique_ptr<BodyItem>> Youtube::get_related_media(const std::string &url) { |