From 7d4825e3c466ec90ea3e6508545636ead96ec164 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 13 Oct 2021 04:00:44 +0200 Subject: Fix soundcloud after website update --- plugins/Soundcloud.hpp | 1 + src/plugins/Soundcloud.cpp | 112 +++++++++++++++++++++++++-------------------- 2 files changed, 64 insertions(+), 49 deletions(-) diff --git a/plugins/Soundcloud.hpp b/plugins/Soundcloud.hpp index c7883ba..fa41e88 100644 --- a/plugins/Soundcloud.hpp +++ b/plugins/Soundcloud.hpp @@ -24,6 +24,7 @@ namespace QuickMedia { PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override; PluginResult lazy_fetch(BodyItems &result_items) override; bool lazy_fetch_is_loader() override { return true; } + void cancel_operation() override; private: SoundcloudPage submit_page; std::string query_urn; diff --git a/src/plugins/Soundcloud.cpp b/src/plugins/Soundcloud.cpp index 8885dfb..ffd202c 100644 --- a/src/plugins/Soundcloud.cpp +++ b/src/plugins/Soundcloud.cpp @@ -1,6 +1,7 @@ #include "../../plugins/Soundcloud.hpp" #include "../../include/NetUtils.hpp" #include "../../include/StringUtils.hpp" +#include "../../include/Notification.hpp" #include "../../include/Utils.hpp" #include "../../include/Scale.hpp" #include "../../include/Theme.hpp" @@ -30,11 +31,11 @@ namespace QuickMedia { static std::string collection_item_get_duration(const Json::Value &item_json) { const Json::Value &full_duration_json = item_json["full_duration"]; if(full_duration_json.isInt64()) - return seconds_to_duration(full_duration_json.asInt64()); + return seconds_to_duration(full_duration_json.asInt64() / 1000); const Json::Value &duration_json = item_json["duration"]; if(duration_json.isInt64()) - return seconds_to_duration(duration_json.asInt64()); + return seconds_to_duration(duration_json.asInt64() / 1000); return ""; } @@ -317,65 +318,78 @@ namespace QuickMedia { } PluginResult SoundcloudSearchPage::lazy_fetch(BodyItems&) { + if(!client_id.empty()) + return PluginResult::OK; + 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 script_sources; - QuickMediaHtmlSearch html_search; - int result = quickmedia_html_search_init(&html_search, website_data.c_str(), website_data.size()); - if(result != 0) - goto cleanup; - - result = quickmedia_html_find_nodes_xpath(&html_search, "//script", - [](QuickMediaMatchNode *node, void *userdata) { - std::vector *script_sources = (std::vector*)userdata; - QuickMediaStringView src = quickmedia_html_node_get_attribute_value(node, "src"); - if(src.data) - script_sources->push_back(std::string(src.data, src.size)); - return 0; - }, &script_sources); - - cleanup: - quickmedia_html_search_deinit(&html_search); - if(result != 0) - return PluginResult::ERR; + std::vector script_sources; + QuickMediaHtmlSearch html_search; + int result = quickmedia_html_search_init(&html_search, website_data.c_str(), website_data.size()); + if(result != 0) + goto cleanup; + + result = quickmedia_html_find_nodes_xpath(&html_search, "//script", + [](QuickMediaMatchNode *node, void *userdata) { + std::vector *script_sources = (std::vector*)userdata; + QuickMediaStringView src = quickmedia_html_node_get_attribute_value(node, "src"); + if(src.data && (memmem(src.data, src.size, "sndcdn.com", 10) || memmem(src.data, src.size, "soundcloud.com", 14))) + script_sources->push_back(std::string(src.data, src.size)); + return 0; + }, &script_sources); + + cleanup: + quickmedia_html_search_deinit(&html_search); + if(result != 0) + return PluginResult::ERR; - async_download_tasks.clear(); - 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_tasks.push_back(AsyncTask([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); - })); - } + async_download_tasks.clear(); + 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_tasks.push_back(AsyncTask([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("client_id="); + if(index == std::string::npos) return ""; + + index += 10; + 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_task : async_download_tasks) { - if(download_task.valid()) { - std::string fetched_client_id = download_task.get(); - if(client_id.empty() && !fetched_client_id.empty()) - client_id = std::move(fetched_client_id); - } + for(auto &download_task : async_download_tasks) { + if(download_task.valid()) { + std::string fetched_client_id = download_task.get(); + if(client_id.empty() && !fetched_client_id.empty()) + client_id = std::move(fetched_client_id); } } + + if(client_id.empty()) { + show_notification("QuickMedia", "Failed to get client id for soundcloud. Try updating QuickMedia or wait until it has been fixed", Urgency::CRITICAL); + return PluginResult::ERR; + } return PluginResult::OK; } + void SoundcloudSearchPage::cancel_operation() { + for(auto &download_task : async_download_tasks) { + download_task.cancel(); + } + async_download_tasks.clear(); + } + PluginResult SoundcloudUserPage::get_page(const std::string&, int page, BodyItems &result_items) { while(current_page < page) { PluginResult plugin_result = get_continuation_page(result_items); -- cgit v1.2.3