diff options
Diffstat (limited to 'src/plugins/Soundcloud.cpp')
-rw-r--r-- | src/plugins/Soundcloud.cpp | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/plugins/Soundcloud.cpp b/src/plugins/Soundcloud.cpp index a0184b4..6740504 100644 --- a/src/plugins/Soundcloud.cpp +++ b/src/plugins/Soundcloud.cpp @@ -2,9 +2,11 @@ #include "../../include/NetUtils.hpp" #include "../../include/StringUtils.hpp" #include "../../include/Scale.hpp" +#include <quickmedia/HtmlSearch.h> +#include <thread> namespace QuickMedia { - static std::string client_id = "Na04L87fnpWDMVCCW2ngWldN4JMoLTAc"; + static std::string client_id; class SoundcloudPlaylist : public BodyItemExtra { public: @@ -218,6 +220,11 @@ namespace QuickMedia { return PluginResult::OK; } + PluginResult SoundcloudSearchPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) { + submit_page.submit_body_item = submit_body_item; + return submit_page.submit(title, url, result_tabs); + } + SearchResult SoundcloudSearchPage::search(const std::string &str, BodyItems &result_items) { query_urn.clear(); PluginResult result = get_page(str, 0, result_items); @@ -268,6 +275,65 @@ namespace QuickMedia { return PluginResult::OK; } + PluginResult SoundcloudSearchPage::lazy_fetch(BodyItems&) { + std::string website_data; + DownloadResult download_result = download_to_string("https://soundcloud.com/", website_data, {}, true); + if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result); + + if(client_id.empty()) { + std::vector<std::string> script_sources; + 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, "//script", + [](QuickMediaHtmlNode *node, void *userdata) { + std::vector<std::string> *script_sources = (std::vector<std::string>*)userdata; + const char *src = quickmedia_html_node_get_attribute_value(node, "src"); + if(src) + script_sources->push_back(strip(src)); + }, &script_sources); + + cleanup: + quickmedia_html_search_deinit(&html_search); + if(result != 0) + return PluginResult::ERR; + + std::vector<std::future<std::string>> async_download_threads; + for(std::string &script_source : script_sources) { + if(string_starts_with(script_source, "//")) + script_source = "https://" + script_source.substr(2); + else if(string_starts_with(script_source, "/")) + script_source = "https://soundcloud.com/" + script_source.substr(1); + + async_download_threads.push_back(std::async(std::launch::async, [script_source]() -> std::string { + std::string website_data; + DownloadResult download_result = download_to_string(script_source, website_data, {}, true); + if(download_result != DownloadResult::OK) return ""; + + size_t index = website_data.find("web-auth?client_id="); + if(index == std::string::npos) return ""; + + index += 19; + size_t end = website_data.find('&', index); + if(end == std::string::npos) end = website_data.size(); + return website_data.substr(index, end - index); + })); + } + + for(auto &download_thread : async_download_threads) { + if(download_thread.valid()) { + std::string fetched_client_id = download_thread.get(); + if(client_id.empty() && !fetched_client_id.empty()) + client_id = std::move(fetched_client_id); + } + } + } + + return PluginResult::OK; + } + PluginResult SoundcloudUserPage::get_page(const std::string&, int page, BodyItems &result_items) { while(current_page < page) { PluginResult plugin_result = get_continuation_page(result_items); |