diff options
author | dec05eba <dec05eba@protonmail.com> | 2019-08-03 01:52:27 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2019-08-03 01:52:30 +0200 |
commit | 117eb25e36ac3b1e1ba18cc9f1e177016c076f34 (patch) | |
tree | 04bd7fe4662af4c8b5d352098430c489082e71aa /src/Youtube.cpp | |
parent | 65cf7681a04f2511db8c7829e9828b53a6676c88 (diff) |
Add search suggestions for youtube & manganelo
Diffstat (limited to 'src/Youtube.cpp')
-rw-r--r-- | src/Youtube.cpp | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/src/Youtube.cpp b/src/Youtube.cpp index d8b046f..9f9c4c2 100644 --- a/src/Youtube.cpp +++ b/src/Youtube.cpp @@ -1,11 +1,11 @@ #include "../plugins/Youtube.hpp" #include <quickmedia/HtmlSearch.h> +#include <json/reader.h> namespace QuickMedia { SearchResult Youtube::search(const std::string &text, std::vector<std::unique_ptr<BodyItem>> &result_items) { std::string url = "https://youtube.com/results?search_query="; - // TODO: Escape @text - url += text; + url += url_param_encode(text); std::string website_data; if(download_to_string(url, website_data) != DownloadResult::OK) @@ -21,8 +21,6 @@ namespace QuickMedia { 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"); - printf("a href: %s, title: %s\n", href, title); - auto item = std::make_unique<BodyItem>(title); result_items->push_back(std::move(item)); }, &result_items); @@ -31,4 +29,56 @@ namespace QuickMedia { 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 &ignore_count) { + if(value.isArray()) { + for(const Json::Value &child : value) { + iterate_suggestion_result(child, result_items, ignore_count); + } + } else if(value.isString()) { + if(ignore_count > 1) { + auto item = std::make_unique<BodyItem>(value.asString()); + result_items.push_back(std::move(item)); + } + ++ignore_count; + } + } + + SuggestionResult Youtube::update_search_suggestions(const std::string &text, std::vector<std::unique_ptr<BodyItem>> &result_items) { + if(text.empty()) + return SuggestionResult::OK; + + std::string url = "https://clients1.google.com/complete/search?client=youtube&hl=en&gl=us&q="; + url += url_param_encode(text); + + std::string server_response; + if(download_to_string(url, server_response) != DownloadResult::OK) + return SuggestionResult::NET_ERR; + + size_t json_start = server_response.find_first_of('('); + if(json_start == std::string::npos) + return SuggestionResult::ERR; + ++json_start; + + size_t json_end = server_response.find_last_of(')'); + if(json_end == std::string::npos) + return SuggestionResult::ERR; + + if(json_end == 0 || json_start >= json_end) + return SuggestionResult::ERR; + --json_end; + + Json::Value json_root; + Json::CharReaderBuilder json_builder; + std::unique_ptr<Json::CharReader> json_reader(json_builder.newCharReader()); + std::string json_errors; + if(json_reader->parse(&server_response[json_start], &server_response[json_end], &json_root, &json_errors)) { + fprintf(stderr, "Youtube suggestions json error: %s\n", json_errors.c_str()); + return SuggestionResult::ERR; + } + + int ignore_count = 0; + iterate_suggestion_result(json_root, result_items, ignore_count); + return SuggestionResult::OK; + } }
\ No newline at end of file |