diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-05-28 18:04:10 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-05-28 18:04:10 +0200 |
commit | 89c204bc473ba761d52be25f279d01af9237ef30 (patch) | |
tree | c7b49a19091649b8843c5deed021731c4cbb1018 /src | |
parent | 3ccd8021b7fdc6028a9eb6db1f265572759dca26 (diff) |
Fix download, remove spotify (which now requires an account)
Diffstat (limited to 'src')
-rw-r--r-- | src/DownloadUtils.cpp | 8 | ||||
-rw-r--r-- | src/QuickMedia.cpp | 8 | ||||
-rw-r--r-- | src/plugins/Spotify.cpp | 290 |
3 files changed, 6 insertions, 300 deletions
diff --git a/src/DownloadUtils.cpp b/src/DownloadUtils.cpp index b6d21b9..eb8fa63 100644 --- a/src/DownloadUtils.cpp +++ b/src/DownloadUtils.cpp @@ -223,9 +223,11 @@ namespace QuickMedia { } bool download_async_gui(const std::string &url, const std::string &file_manager_start_dir, bool use_youtube_dl, bool no_video) { - char quickmedia_path[PATH_MAX]; - if(readlink("/proc/self/exe", quickmedia_path, sizeof(quickmedia_path)) == -1) - strcpy(quickmedia_path, "quickmedia"); + // TODO: Fix this not working when installed to /usr/bin/quickmedia for some reason + //char quickmedia_path[PATH_MAX]; + //if(readlink("/proc/self/exe", quickmedia_path, sizeof(quickmedia_path)) == -1) + // strcpy(quickmedia_path, "quickmedia"); + const char *quickmedia_path = "quickmedia"; std::vector<const char*> args = { quickmedia_path, "download", "-u", url.c_str(), "--dir", file_manager_start_dir.c_str() }; if(use_youtube_dl) args.push_back("--youtube-dl"); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index c2dbf1c..db03aac 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -8,7 +8,6 @@ #include "../plugins/Fourchan.hpp" #include "../plugins/NyaaSi.hpp" #include "../plugins/Matrix.hpp" -#include "../plugins/Spotify.hpp" #include "../plugins/Soundcloud.hpp" #include "../plugins/FileManager.hpp" #include "../plugins/Pipe.hpp" @@ -68,7 +67,6 @@ static const std::pair<const char*, const char*> valid_plugins[] = { std::make_pair("readm", "readm_logo.png"), std::make_pair("manga", nullptr), std::make_pair("youtube", "yt_logo_rgb_dark_small.png"), - std::make_pair("spotify", "spotify_logo.png"), std::make_pair("soundcloud", "soundcloud_logo.png"), std::make_pair("pornhub", "pornhub_logo.png"), std::make_pair("spankbang", "spankbang_logo.png"), @@ -314,7 +312,7 @@ namespace QuickMedia { static void usage() { fprintf(stderr, "usage: quickmedia <plugin> [--no-video] [--use-system-mpv-config] [--dir <directory>] [-e <window>]\n"); fprintf(stderr, "OPTIONS:\n"); - fprintf(stderr, " plugin The plugin to use. Should be either launcher, 4chan, manga, manganelo, manganelos, mangatown, mangakatana, mangadex, readm, onimanga, youtube, spotify, soundcloud, nyaa.si, matrix, saucenao, file-manager, stdin, pornhub, spankbang, xvideos or xhamster\n"); + fprintf(stderr, " plugin The plugin to use. Should be either launcher, 4chan, manga, manganelo, manganelos, mangatown, mangakatana, mangadex, readm, onimanga, youtube, soundcloud, nyaa.si, matrix, saucenao, file-manager, stdin, pornhub, spankbang, xvideos or xhamster\n"); fprintf(stderr, " --no-video Only play audio when playing a video. Disabled by default\n"); fprintf(stderr, " --use-system-mpv-config Use system mpv config instead of no config. Disabled by default\n"); fprintf(stderr, " --upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default\n"); @@ -1020,7 +1018,6 @@ namespace QuickMedia { pipe_body->items.push_back(create_launcher_body_item("Nyaa.si", "nyaa.si", resources_root + "icons/nyaa_si_launcher.png")); pipe_body->items.push_back(create_launcher_body_item("SauceNAO", "saucenao", "")); pipe_body->items.push_back(create_launcher_body_item("Soundcloud", "soundcloud", resources_root + "icons/soundcloud_launcher.png")); - pipe_body->items.push_back(create_launcher_body_item("Spotify", "spotify", resources_root + "icons/spotify_launcher.png")); pipe_body->items.push_back(create_launcher_body_item("YouTube", "youtube", resources_root + "icons/yt_launcher.png")); pipe_body->items.push_back(create_launcher_body_item("YouTube (audio only)", "youtube-audio", resources_root + "icons/yt_launcher.png")); tabs.push_back(Tab{std::move(pipe_body), std::make_unique<PipePage>(this, "Select plugin to launch"), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); @@ -1148,9 +1145,6 @@ namespace QuickMedia { auto search_page = std::make_unique<MediaGenericSearchPage>(this, "https://xhamster.com/", sf::Vector2i(240, 135)); add_xhamster_handlers(search_page.get()); tabs.push_back(Tab{create_body(), std::move(search_page), create_search_bar("Search...", 500)}); - } else if(strcmp(plugin_name, "spotify") == 0) { - tabs.push_back(Tab{create_body(), std::make_unique<SpotifyPodcastSearchPage>(this), create_search_bar("Search...", 350)}); - no_video = true; } else if(strcmp(plugin_name, "soundcloud") == 0) { tabs.push_back(Tab{create_body(), std::make_unique<SoundcloudSearchPage>(this), create_search_bar("Search...", 500)}); no_video = true; diff --git a/src/plugins/Spotify.cpp b/src/plugins/Spotify.cpp deleted file mode 100644 index d41446b..0000000 --- a/src/plugins/Spotify.cpp +++ /dev/null @@ -1,290 +0,0 @@ -#include "../../plugins/Spotify.hpp" -#include "../../include/NetUtils.hpp" -#include "../../include/Utils.hpp" -#include "../../include/Scale.hpp" - -namespace QuickMedia { - SpotifyPage::SpotifyPage(Program *program) : Page(program) { - Path spotify_cache_path = get_cache_dir().join("spotify").join("access_token"); - if(file_get_content(spotify_cache_path, access_token) != 0) - access_token.clear(); - } - - DownloadResult SpotifyPage::download_json_error_retry(Json::Value &json_root, const std::string &url, std::vector<CommandArg> additional_args) { - if(access_token.empty()) { - PluginResult update_token_res = update_token(); - if(update_token_res != PluginResult::OK) return DownloadResult::ERR; - } - - std::string authorization = "authorization: Bearer " + access_token; - additional_args.push_back({ "-H", authorization.c_str() }); - - std::string err_msg; - DownloadResult result = download_json(json_root, url, additional_args, true, &err_msg); - if(result != DownloadResult::OK) return result; - - if(!json_root.isObject()) - return DownloadResult::ERR; - - const Json::Value &error_json = json_root["error"]; - if(error_json.isObject()) { - const Json::Value &status_json = error_json["status"]; - if(status_json.isInt() && status_json.asInt() == 401) { - fprintf(stderr, "Spotify access token expired, requesting a new token...\n"); - PluginResult update_token_res = update_token(); - if(update_token_res != PluginResult::OK) return DownloadResult::ERR; - - authorization = "authorization: Bearer " + access_token; - additional_args.back().value = authorization.c_str(); - DownloadResult result = download_json(json_root, url, additional_args, true); - if(result != DownloadResult::OK) return result; - - if(!json_root.isObject()) - return DownloadResult::ERR; - } - } - - return DownloadResult::OK; - } - - PluginResult SpotifyPage::update_token() { - std::string url = "https://open.spotify.com/get_access_token?reason=transport&productType=web_player"; - - std::vector<CommandArg> additional_args = { - { "-H", "authority: application/json" }, - { "-H", "Referer: open.spotify.com" }, - { "-H", "app-platform: WebPlayer" }, - { "-H", "spotify-app-version: 1.1.53.594.g8178ce9b" } - }; - - Json::Value json_root; - DownloadResult result = download_json(json_root, url, std::move(additional_args), true); - if(result != DownloadResult::OK) return download_result_to_plugin_result(result); - - if(!json_root.isObject()) - return PluginResult::ERR; - - const Json::Value &access_token_json = json_root["accessToken"]; - if(!access_token_json.isString()) - return PluginResult::ERR; - - access_token = access_token_json.asString(); - Path spotify_cache_dir = get_cache_dir().join("spotify"); - if(create_directory_recursive(spotify_cache_dir) == 0) - fprintf(stderr, "Failed to create spotify cache directory\n"); - spotify_cache_dir.join("access_token"); - file_overwrite_atomic(spotify_cache_dir, access_token); - return PluginResult::OK; - } - - static void image_sources_set_thumbnail(BodyItem *body_item, const Json::Value &sources_list_json) { - if(!sources_list_json.isArray()) - return; - - for(const Json::Value &source_json : sources_list_json) { - if(!source_json.isObject()) - continue; - - const Json::Value &width_json = source_json["width"]; - const Json::Value &height_json = source_json["height"]; - const Json::Value &url_json = source_json["url"]; - if(!width_json.isInt() || !height_json.isInt() || !url_json.isString()) - continue; - - if(height_json.asInt() >= 200 && height_json.asInt() <= 350) { - body_item->thumbnail_url = url_json.asString(); - body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE; - body_item->thumbnail_size.x = width_json.asInt(); - body_item->thumbnail_size.y = height_json.asInt(); - body_item->thumbnail_size = clamp_to_size(body_item->thumbnail_size, sf::Vector2i(150, 150)); - return; - } - } - } - - SearchResult SpotifyPodcastSearchPage::search(const std::string &str, BodyItems &result_items) { - PluginResult result = get_page(str, 0, result_items); - if(result != PluginResult::OK) - return SearchResult::ERR; - return SearchResult::OK; - } - - PluginResult SpotifyPodcastSearchPage::get_page(const std::string &str, int page, BodyItems &result_items) { - std::string url = "https://api.spotify.com/v1/search?query="; - url += url_param_encode(str); - url += "&type=show&include_external=audio&market=US&offset=" + std::to_string(page * 10) + "&limit=10"; - - std::vector<CommandArg> additional_args = { - { "-H", "accept: application/json" }, - { "-H", "Referer: https://open.spotify.com/" }, - { "-H", "app-platform: WebPlayer" }, - { "-H", "spotify-app-version: 1.1.53.594.g8178ce9b" } - }; - - Json::Value json_root; - DownloadResult result = download_json_error_retry(json_root, url, additional_args); - if(result != DownloadResult::OK) return download_result_to_plugin_result(result); - - if(!json_root.isObject()) - return PluginResult::ERR; - - const Json::Value &shows_json = json_root["shows"]; - if(!shows_json.isObject()) - return PluginResult::ERR; - - const Json::Value &items_json = shows_json["items"]; - if(!items_json.isArray()) - return PluginResult::ERR; - - for(const Json::Value &item_json : items_json) { - if(!item_json.isObject()) - continue; - - const Json::Value &name_json = item_json["name"]; - const Json::Value &uri_json = item_json["uri"]; - if(!name_json.isString() || !uri_json.isString()) - continue; - - auto body_item = BodyItem::create(name_json.asString()); - body_item->url = uri_json.asString(); - - const Json::Value &publisher_json = item_json["publisher"]; - if(publisher_json.isString()) { - body_item->set_description(publisher_json.asString()); - body_item->set_description_color(sf::Color(179, 179, 179)); - } - - image_sources_set_thumbnail(body_item.get(), item_json["images"]); - result_items.push_back(std::move(body_item)); - } - - return PluginResult::OK; - } - - PluginResult SpotifyPodcastSearchPage::submit(const std::string &, const std::string &url, std::vector<Tab> &result_tabs) { - auto body = create_body(); - auto episode_list_page = std::make_unique<SpotifyEpisodeListPage>(program, url); - PluginResult result = episode_list_page->get_page("", 0, body->items); - if(result != PluginResult::OK) - return result; - - result_tabs.push_back(Tab{std::move(body), std::move(episode_list_page), nullptr}); - return result; - } - - static std::string unix_time_to_local_time_str(time_t unix_time) { - struct tm time_tm; - localtime_r(&unix_time, &time_tm); - char time_str[128] = {0}; - strftime(time_str, sizeof(time_str) - 1, "%Y-%m-%d %H:%M", &time_tm); - return time_str; - } - - PluginResult SpotifyEpisodeListPage::get_page(const std::string &, int page, BodyItems &result_items) { - std::string request_url = "https://api-partner.spotify.com/pathfinder/v1/query?operationName=queryShowEpisodes&variables="; - request_url += url_param_encode("{\"uri\":\"" + url + "\",\"offset\":" + std::to_string(page * 50) + ",\"limit\":50}"); - request_url += "&extensions="; - request_url += url_param_encode("{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"e0e5ce27bd7748d2c59b4d44ba245a8992a05be75d6fabc3b20753fc8857444d\"}}"); - - std::vector<CommandArg> additional_args = { - { "-H", "authority: api-partner.spotify.com" }, - { "-H", "accept: application/json" }, - { "-H", "Referer: https://open.spotify.com/" }, - { "-H", "app-platform: WebPlayer" }, - { "-H", "spotify-app-version: 1.1.54.40.g75ab4382" } - }; - - Json::Value json_root; - DownloadResult result = download_json_error_retry(json_root, request_url, additional_args); - if(result != DownloadResult::OK) return download_result_to_plugin_result(result); - - if(!json_root.isObject()) - return PluginResult::ERR; - - const Json::Value &data_json = json_root["data"]; - if(!data_json.isObject()) - return PluginResult::ERR; - - const Json::Value &podcast_json = data_json["podcast"]; - if(!podcast_json.isObject()) - return PluginResult::ERR; - - const Json::Value &episodes_json = podcast_json["episodes"]; - if(!episodes_json.isObject()) - return PluginResult::ERR; - - const Json::Value &episode_items_json = episodes_json["items"]; - if(!episode_items_json.isArray()) - return PluginResult::ERR; - - for(const Json::Value &episode_item_json : episode_items_json) { - if(!episode_item_json.isObject()) - continue; - - const Json::Value &episode_json = episode_item_json["episode"]; - if(!episode_json.isObject()) - continue; - - const Json::Value &name_json = episode_json["name"]; - if(!name_json.isString()) - continue; - - const Json::Value &sharing_info_json = episode_json["sharingInfo"]; - if(!sharing_info_json.isObject()) - continue; - - const Json::Value &share_url_json = sharing_info_json["shareUrl"]; - if(!share_url_json.isString()) - continue; - - auto body_item = BodyItem::create(name_json.asString()); - body_item->url = share_url_json.asString(); - - std::string description; - std::string time; - - const Json::Value &description_json = episode_json["description"]; - if(description_json.isString()) - description += description_json.asString(); - - const Json::Value &release_data_json = episode_json["releaseDate"]; - if(release_data_json.isObject()) { - const Json::Value &iso_string_json = release_data_json["isoString"]; - if(iso_string_json.isString()) - time += unix_time_to_local_time_str(iso_utc_to_unix_time(iso_string_json.asCString())); - } - - const Json::Value &duration_json = episode_json["duration"]; - if(duration_json.isObject()) { - const Json::Value &total_ms_json = duration_json["totalMilliseconds"]; - if(total_ms_json.isInt()) { - if(!time.empty()) - time += " • "; - time += std::to_string(total_ms_json.asInt() / 1000 / 60) + " min"; - } - } - - if(!time.empty()) { - if(!description.empty()) - description += '\n'; - description += std::move(time); - } - - body_item->set_description(std::move(description)); - body_item->set_description_color(sf::Color(179, 179, 179)); - - const Json::Value &cover_art_json = episode_json["coverArt"]; - if(cover_art_json.isObject()) - image_sources_set_thumbnail(body_item.get(), cover_art_json["sources"]); - - result_items.push_back(std::move(body_item)); - } - - return PluginResult::OK; - } - - PluginResult SpotifyEpisodeListPage::submit(const std::string &, const std::string &url, std::vector<Tab> &result_tabs) { - result_tabs.push_back(Tab{nullptr, std::make_unique<SpotifyAudioPage>(program, url), nullptr}); - return PluginResult::OK; - } -}
\ No newline at end of file |