diff options
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r-- | src/QuickMedia.cpp | 133 |
1 files changed, 49 insertions, 84 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index d7c15b1..5a13179 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1,5 +1,6 @@ #include "../include/QuickMedia.hpp" #include "../plugins/Manganelo.hpp" +#include "../plugins/Mangadex.hpp" #include "../plugins/Youtube.hpp" #include "../plugins/Pornhub.hpp" #include "../plugins/Fourchan.hpp" @@ -8,6 +9,7 @@ #include "../include/VideoPlayer.hpp" #include "../include/StringUtils.hpp" #include "../include/GoogleCaptcha.hpp" +#include "../include/Notification.hpp" #include <cppcodec/base64_rfc4648.hpp> #include <SFML/Graphics/RectangleShape.hpp> @@ -91,7 +93,7 @@ namespace QuickMedia { static void usage() { fprintf(stderr, "usage: QuickMedia <plugin> [--tor]\n"); fprintf(stderr, "OPTIONS:\n"); - fprintf(stderr, "plugin The plugin to use. Should be either 4chan, manganelo, pornhub or youtube\n"); + fprintf(stderr, "plugin The plugin to use. Should be either 4chan, manganelo, mangadex, pornhub or youtube\n"); fprintf(stderr, "--tor Use tor. Disabled by default\n"); fprintf(stderr, "EXAMPLES:\n"); fprintf(stderr, "QuickMedia manganelo\n"); @@ -132,6 +134,9 @@ namespace QuickMedia { if(strcmp(argv[i], "manganelo") == 0) { current_plugin = new Manganelo(); plugin_logo_path = "../../../images/manganelo_logo.png"; + } else if(strcmp(argv[i], "mangadex") == 0) { + current_plugin = new Mangadex(); + plugin_logo_path = "../../../images/mangadex_logo.png"; } else if(strcmp(argv[i], "youtube") == 0) { current_plugin = new Youtube(); plugin_logo_path = "../../../images/yt_logo_rgb_dark_small.png"; @@ -261,31 +266,6 @@ namespace QuickMedia { } } - enum class Urgency { - LOW, - NORMAL, - CRITICAL - }; - - const char* urgency_string(Urgency urgency) { - switch(urgency) { - case Urgency::LOW: - return "low"; - case Urgency::NORMAL: - return "normal"; - case Urgency::CRITICAL: - return "critical"; - } - assert(false); - return nullptr; - } - - static void show_notification(const std::string &title, const std::string &description, Urgency urgency = Urgency::NORMAL) { - const char *args[] = { "notify-send", "-u", urgency_string(urgency), "--", title.c_str(), description.c_str(), nullptr }; - exec_program_async(args, nullptr); - printf("Notification: title: %s, description: %s\n", title.c_str(), description.c_str()); - } - static std::string base64_encode(const std::string &data) { return cppcodec::base64_rfc4648::encode(data); } @@ -315,39 +295,6 @@ namespace QuickMedia { return file_overwrite(path, Json::writeString(json_builder, json)) == 0; } - static bool manga_extract_id_from_url(const std::string &url, std::string &manga_id) { - bool manganelo_website = false; - if(url.find("mangakakalot") != std::string::npos || url.find("manganelo") != std::string::npos) - manganelo_website = true; - - if(manganelo_website) { - size_t index = url.find("manga/"); - if(index == std::string::npos) { - std::string err_msg = "Url "; - err_msg += url; - err_msg += " doesn't contain manga id"; - show_notification("Manga", err_msg, Urgency::CRITICAL); - return false; - } - - manga_id = url.substr(index + 6); - if(manga_id.size() <= 2) { - std::string err_msg = "Url "; - err_msg += url; - err_msg += " doesn't contain manga id"; - show_notification("Manga", err_msg, Urgency::CRITICAL); - return false; - } - return true; - } else { - std::string err_msg = "Unexpected url "; - err_msg += url; - err_msg += " is not manganelo or mangakakalot"; - show_notification("Manga", err_msg, Urgency::CRITICAL); - return false; - } - } - enum class SearchSuggestionTab { ALL, HISTORY @@ -373,14 +320,20 @@ namespace QuickMedia { int selected_tab = 0; // TOOD: Make generic, instead of checking for plugin - if(current_plugin->name == "manganelo") { - Path content_storage_dir = get_storage_dir().join("manga"); + if(current_plugin->is_manga()) { + Path content_storage_dir = get_storage_dir().join(current_plugin->name); if(create_directory_recursive(content_storage_dir) != 0) { show_notification("Storage", "Failed to create directory: " + content_storage_dir.data, Urgency::CRITICAL); exit(1); } + Path credentials_storage_dir = get_storage_dir().join("credentials"); + if(create_directory_recursive(credentials_storage_dir) != 0) { + show_notification("Storage", "Failed to create directory: " + credentials_storage_dir.data, Urgency::CRITICAL); + exit(1); + } // TODO: Make asynchronous - for_files_in_dir_sort_last_modified(content_storage_dir, [&history_body](const std::filesystem::path &filepath) { + // TODO: Make this also work for mangadex. Would require storing both id and name of the manga + for_files_in_dir_sort_last_modified(content_storage_dir, [&history_body, this](const std::filesystem::path &filepath) { Path fullpath(filepath.c_str()); Json::Value body; if(!read_file_as_json(fullpath, body)) { @@ -393,7 +346,10 @@ namespace QuickMedia { if(!filename.empty() && manga_name.isString()) { // TODO: Add thumbnail auto body_item = std::make_unique<BodyItem>(manga_name.asString()); - body_item->url = "https://manganelo.com/manga/" + base64_decode(filename.string()); + if(current_plugin->name == "manganelo") + body_item->url = "https://manganelo.com/manga/" + base64_decode(filename.string()); + else if(current_plugin->name == "mangadex") + body_item->url = "https://mangadex.org/title/" + base64_decode(filename.string()); history_body.items.push_back(std::move(body_item)); } return true; @@ -417,16 +373,17 @@ namespace QuickMedia { return false; } - if(next_page == Page::EPISODE_LIST) { + if(next_page == Page::EPISODE_LIST && current_plugin->is_manga()) { + Manga *manga_plugin = static_cast<Manga*>(current_plugin); if(content_url.empty()) { show_notification("Manga", "Url is missing for manga!", Urgency::CRITICAL); return false; } - Path content_storage_dir = get_storage_dir().join("manga"); + Path content_storage_dir = get_storage_dir().join(current_plugin->name); std::string manga_id; - if(!manga_extract_id_from_url(content_url, manga_id)) + if(!manga_plugin->extract_id_from_url(content_url, manga_id)) return false; manga_id_base64 = base64_encode(manga_id); @@ -513,7 +470,9 @@ namespace QuickMedia { if(!update_search_text.empty() && !search_running) { search_suggestion_future = std::async(std::launch::async, [this, update_search_text]() { BodyItems result; - SuggestionResult suggestion_result = current_plugin->update_search_suggestions(update_search_text, result); + if(current_plugin->update_search_suggestions(update_search_text, result) != SuggestionResult::OK) { + show_notification("Search", "Search failed!", Urgency::CRITICAL); + } return result; }); update_search_text.clear(); @@ -1004,7 +963,7 @@ namespace QuickMedia { return LoadImageResult::FAILED; } } else { - show_notification("Manganelo", "Failed to load image for page " + std::to_string(image_index + 1) + ". Image filepath: " + image_path.data, Urgency::CRITICAL); + show_notification("Manga", "Failed to load image for page " + std::to_string(image_index + 1) + ". Image filepath: " + image_path.data, Urgency::CRITICAL); error_message = std::string("Failed to load image for page ") + std::to_string(image_index + 1); return LoadImageResult::FAILED; } @@ -1014,7 +973,7 @@ namespace QuickMedia { } } - void Program::download_chapter_images_if_needed(Manganelo *image_plugin) { + void Program::download_chapter_images_if_needed(Manga *image_plugin) { if(downloading_chapter_url == images_url) return; @@ -1044,6 +1003,7 @@ namespace QuickMedia { Path image_filepath = content_cache_dir_; image_filepath.join(image_filename); #endif + // TODO: Save image with the file extension that url says it has? right now the file is saved without any extension Path image_filepath = content_cache_dir_; image_filepath.join(std::to_string(page++)); @@ -1053,22 +1013,27 @@ namespace QuickMedia { std::string image_content; if(download_to_string(url, image_content, {}, current_plugin->use_tor) != DownloadResult::OK || image_content.size() <= 255) { - bool try_backup_url = false; - std::string new_url = url; - if(string_replace_all(new_url, "s3.mkklcdnv3.com", "bu.mkklcdnbuv1.com") > 0) { - try_backup_url = true; - } else { - try_backup_url = (string_replace_all(new_url, "s41.mkklcdnv41.com", "bu.mkklcdnbuv1.com") > 0); - } + if(current_plugin->name == "manganelo") { + bool try_backup_url = false; + std::string new_url = url; + if(string_replace_all(new_url, "s3.mkklcdnv3.com", "bu.mkklcdnbuv1.com") > 0) { + try_backup_url = true; + } else { + try_backup_url = (string_replace_all(new_url, "s41.mkklcdnv41.com", "bu.mkklcdnbuv1.com") > 0); + } - if(try_backup_url) { - image_content.clear(); - if(download_to_string(new_url, image_content, {}, current_plugin->use_tor) != DownloadResult::OK || image_content.size() <= 255) { - show_notification("Manganelo", "Failed to download image: " + new_url, Urgency::CRITICAL); + if(try_backup_url) { + image_content.clear(); + if(download_to_string(new_url, image_content, {}, current_plugin->use_tor) != DownloadResult::OK || image_content.size() <= 255) { + show_notification("Manganelo", "Failed to download image: " + new_url, Urgency::CRITICAL); + return false; + } + } else { + show_notification("Manganelo", "Failed to download image: " + url, Urgency::CRITICAL); return false; } } else { - show_notification("Manganelo", "Failed to download image: " + url, Urgency::CRITICAL); + show_notification("Manga", "Failed to download image: " + url, Urgency::CRITICAL); return false; } } @@ -1096,12 +1061,12 @@ namespace QuickMedia { sf::Text error_message("", font, 30); error_message.setFillColor(sf::Color::White); - assert(current_plugin->name == "manganelo"); - Manganelo *image_plugin = static_cast<Manganelo*>(current_plugin); + assert(current_plugin->is_manga()); + Manga *image_plugin = static_cast<Manga*>(current_plugin); std::string image_data; bool download_in_progress = false; - content_cache_dir = get_cache_dir().join("manga").join(manga_id_base64).join(base64_encode(chapter_title)); + content_cache_dir = get_cache_dir().join(image_plugin->name).join(manga_id_base64).join(base64_encode(chapter_title)); if(create_directory_recursive(content_cache_dir) != 0) { show_notification("Storage", "Failed to create directory: " + content_cache_dir.data, Urgency::CRITICAL); current_page = Page::EPISODE_LIST; |