aboutsummaryrefslogtreecommitdiff
path: root/src/QuickMedia.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r--src/QuickMedia.cpp133
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;