aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Mangadex.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-10-11 21:35:37 +0200
committerdec05eba <dec05eba@protonmail.com>2020-10-13 13:13:01 +0200
commit77ed51898157d99112be7550471ec06e32344c9e (patch)
tree0645274d0f13b4fa6940d4054f74a070611a8ef0 /src/plugins/Mangadex.cpp
parentda89ec98fb34757f0c46dc8cb2dd87ae78d317ce (diff)
Refactor plugin into seperate pages
TODO: Readd 4chan login page, manganelo creators page, autocomplete
Diffstat (limited to 'src/plugins/Mangadex.cpp')
-rw-r--r--src/plugins/Mangadex.cpp201
1 files changed, 98 insertions, 103 deletions
diff --git a/src/plugins/Mangadex.cpp b/src/plugins/Mangadex.cpp
index 9808654..be2d342 100644
--- a/src/plugins/Mangadex.cpp
+++ b/src/plugins/Mangadex.cpp
@@ -1,6 +1,7 @@
#include "../../plugins/Mangadex.hpp"
#include "../../include/Storage.hpp"
#include "../../include/Notification.hpp"
+#include "../../include/StringUtils.hpp"
#include <quickmedia/HtmlSearch.h>
#include <json/reader.h>
@@ -27,30 +28,96 @@ namespace QuickMedia {
return url.substr(find_index + 9);
}
+ static bool get_cookie_filepath(std::string &cookie_filepath) {
+ Path cookie_path = get_storage_dir().join("cookies");
+ if(create_directory_recursive(cookie_path) != 0) {
+ show_notification("Storage", "Failed to create directory: " + cookie_path.data, Urgency::CRITICAL);
+ return false;
+ }
+ cookie_filepath = cookie_path.join("mangadex.txt").data;
+ return true;
+ }
+
struct BodyItemChapterContext {
BodyItems *body_items;
int prev_chapter_number;
bool *is_last_page;
};
- SearchResult Mangadex::search(const std::string &url, BodyItems &result_items) {
+ // TODO: Implement pagination (go to next page and get all results as well)
+ SearchResult MangadexSearchPage::search(const std::string &str, BodyItems &result_items) {
+ std::string rememberme_token;
+ if(!get_rememberme_token(rememberme_token))
+ return SearchResult::ERR;
+
+ std::string url = "https://mangadex.org/search?title=";
+ url += url_param_encode(str);
+ CommandArg cookie_arg = { "-H", "cookie: mangadex_rememberme_token=" + rememberme_token };
+
+ std::string website_data;
+ if(download_to_string(url, website_data, {std::move(cookie_arg)}, is_tor_enabled(), true) != DownloadResult::OK)
+ return SearchResult::NET_ERR;
+
+ 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, "//a",
+ [](QuickMediaHtmlNode *node, void *userdata) {
+ auto *item_data = (BodyItems*)userdata;
+ const char *href = quickmedia_html_node_get_attribute_value(node, "href");
+ const char *title = quickmedia_html_node_get_attribute_value(node, "title");
+ if(title && href && strncmp(href, "/title/", 7) == 0) {
+ auto item = BodyItem::create(strip(title));
+ item->url = mangadex_url + href;
+ item_data->push_back(std::move(item));
+ }
+ }, &result_items);
+
+ if(result != 0)
+ goto cleanup;
+
+ BodyItemImageContext body_item_image_context;
+ body_item_image_context.body_items = &result_items;
+ body_item_image_context.index = 0;
+
+ result = quickmedia_html_find_nodes_xpath(&html_search, "//img",
+ [](QuickMediaHtmlNode *node, void *userdata) {
+ auto *item_data = (BodyItemImageContext*)userdata;
+ const char *src = quickmedia_html_node_get_attribute_value(node, "src");
+ if(src && strncmp(src, "/images/manga/", 14) == 0 && item_data->index < item_data->body_items->size()) {
+ (*item_data->body_items)[item_data->index]->thumbnail_url = mangadex_url + src;
+ item_data->index++;
+ }
+ }, &body_item_image_context);
+
+ if(result != 0)
+ goto cleanup;
+
+ cleanup:
+ quickmedia_html_search_deinit(&html_search);
+ return result == 0 ? SearchResult::OK : SearchResult::ERR;
+ }
+
+ PluginResult MangadexSearchPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
std::string manga_id = title_url_extract_manga_id(url);
std::string request_url = "https://mangadex.org/api/?id=" + manga_id + "&type=manga";
Json::Value json_root;
DownloadResult result = download_json(json_root, request_url, {}, true);
- if(result != DownloadResult::OK) return download_result_to_search_result(result);
+ if(result != DownloadResult::OK) return download_result_to_plugin_result(result);
if(!json_root.isObject())
- return SearchResult::ERR;
+ return PluginResult::ERR;
Json::Value &status_json = json_root["status"];
if(!status_json.isString() || status_json.asString() != "OK")
- return SearchResult::ERR;
+ return PluginResult::ERR;
Json::Value &chapter_json = json_root["chapter"];
if(!chapter_json.isObject())
- return SearchResult::ERR;
+ return PluginResult::ERR;
std::vector<std::pair<std::string, Json::Value>> chapters(chapter_json.size());
/* TODO: Optimize member access */
@@ -74,6 +141,8 @@ namespace QuickMedia {
time_t time_now = time(NULL);
+ auto body = create_body();
+
/* TODO: Pointer */
std::string prev_chapter_number;
for(auto it = chapters.begin(); it != chapters.end(); ++it) {
@@ -106,22 +175,17 @@ namespace QuickMedia {
auto item = BodyItem::create(std::move(chapter_name));
item->url = std::move(chapter_url);
- result_items.push_back(std::move(item));
+ body->items.push_back(std::move(item));
}
- return SearchResult::OK;
- }
- static bool get_cookie_filepath(std::string &cookie_filepath) {
- Path cookie_path = get_storage_dir().join("cookies");
- if(create_directory_recursive(cookie_path) != 0) {
- show_notification("Storage", "Failed to create directory: " + cookie_path.data, Urgency::CRITICAL);
- return false;
- }
- cookie_filepath = cookie_path.join("mangadex.txt").data;
- return true;
+ result_tabs.push_back(Tab{std::move(body), std::make_unique<MangadexChaptersPage>(program, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+
+ if(load_manga_content_storage("mangadex", title, manga_id))
+ return PluginResult::OK;
+ return PluginResult::ERR;
}
- bool Mangadex::get_rememberme_token(std::string &rememberme_token_output) {
+ bool MangadexSearchPage::get_rememberme_token(std::string &rememberme_token_output) {
if(rememberme_token) {
rememberme_token_output = rememberme_token.value();
return true;
@@ -153,93 +217,34 @@ namespace QuickMedia {
return true;
}
- struct BodyItemImageContext {
- BodyItems *body_items;
- size_t index;
- };
-
- // TODO: Implement pagination (go to next page and get all results as well)
- SuggestionResult Mangadex::update_search_suggestions(const std::string &text, BodyItems &result_items) {
- std::string rememberme_token;
- if(!get_rememberme_token(rememberme_token))
- return SuggestionResult::ERR;
-
- std::string url = "https://mangadex.org/search?title=";
- url += url_param_encode(text);
- CommandArg cookie_arg = { "-H", "cookie: mangadex_rememberme_token=" + rememberme_token };
-
- std::string website_data;
- if(download_to_string(url, website_data, {std::move(cookie_arg)}, use_tor, true) != DownloadResult::OK)
- return SuggestionResult::NET_ERR;
-
- 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, "//a",
- [](QuickMediaHtmlNode *node, void *userdata) {
- auto *item_data = (BodyItems*)userdata;
- const char *href = quickmedia_html_node_get_attribute_value(node, "href");
- const char *title = quickmedia_html_node_get_attribute_value(node, "title");
- if(title && href && strncmp(href, "/title/", 7) == 0) {
- auto item = BodyItem::create(strip(title));
- item->url = mangadex_url + href;
- item_data->push_back(std::move(item));
- }
- }, &result_items);
-
- if(result != 0)
- goto cleanup;
-
- BodyItemImageContext body_item_image_context;
- body_item_image_context.body_items = &result_items;
- body_item_image_context.index = 0;
-
- result = quickmedia_html_find_nodes_xpath(&html_search, "//img",
- [](QuickMediaHtmlNode *node, void *userdata) {
- auto *item_data = (BodyItemImageContext*)userdata;
- const char *src = quickmedia_html_node_get_attribute_value(node, "src");
- if(src && strncmp(src, "/images/manga/", 14) == 0 && item_data->index < item_data->body_items->size()) {
- (*item_data->body_items)[item_data->index]->thumbnail_url = mangadex_url + src;
- item_data->index++;
- }
- }, &body_item_image_context);
-
- if(result != 0)
- goto cleanup;
-
- cleanup:
- quickmedia_html_search_deinit(&html_search);
- return result == 0 ? SuggestionResult::OK : SuggestionResult::ERR;
+ PluginResult MangadexChaptersPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
+ result_tabs.push_back(Tab{create_body(), std::make_unique<MangadexImagesPage>(program, content_title, title, url), nullptr});
+ return PluginResult::OK;
}
- ImageResult Mangadex::get_number_of_images(const std::string &url, int &num_images) {
- std::lock_guard<std::mutex> lock(image_urls_mutex);
+ ImageResult MangadexImagesPage::get_number_of_images(int &num_images) {
num_images = 0;
ImageResult image_result = get_image_urls_for_chapter(url);
if(image_result != ImageResult::OK)
return image_result;
- num_images = last_chapter_image_urls.size();
+ num_images = chapter_image_urls.size();
return ImageResult::OK;
}
- bool Mangadex::save_mangadex_cookies(const std::string &url, const std::string &cookie_filepath) {
+ bool MangadexImagesPage::save_mangadex_cookies(const std::string &url, const std::string &cookie_filepath) {
CommandArg cookie_arg = { "-c", cookie_filepath };
std::string server_response;
- if(download_to_string(url, server_response, {std::move(cookie_arg)}, use_tor, true) != DownloadResult::OK)
+ if(download_to_string(url, server_response, {std::move(cookie_arg)}, is_tor_enabled(), true) != DownloadResult::OK)
return false;
return true;
}
- ImageResult Mangadex::get_image_urls_for_chapter(const std::string &url) {
- if(url == last_chapter_url)
+ ImageResult MangadexImagesPage::get_image_urls_for_chapter(const std::string &url) {
+ if(!chapter_image_urls.empty())
return ImageResult::OK;
- last_chapter_image_urls.clear();
-
std::string cookie_filepath;
if(!get_cookie_filepath(cookie_filepath))
return ImageResult::ERR;
@@ -281,38 +286,28 @@ namespace QuickMedia {
continue;
std::string image_url = server + chapter_hash_str + "/" + image_name.asCString();
- last_chapter_image_urls.push_back(std::move(image_url));
+ chapter_image_urls.push_back(std::move(image_url));
}
}
- last_chapter_url = url;
- if(last_chapter_image_urls.empty()) {
- last_chapter_url.clear();
+ if(chapter_image_urls.empty())
return ImageResult::ERR;
- }
return ImageResult::OK;
}
- ImageResult Mangadex::for_each_page_in_chapter(const std::string &chapter_url, PageCallback callback) {
+ ImageResult MangadexImagesPage::for_each_page_in_chapter(PageCallback callback) {
std::vector<std::string> image_urls;
- {
- std::lock_guard<std::mutex> lock(image_urls_mutex);
- ImageResult image_result = get_image_urls_for_chapter(chapter_url);
- if(image_result != ImageResult::OK)
- return image_result;
+ ImageResult image_result = get_image_urls_for_chapter(url);
+ if(image_result != ImageResult::OK)
+ return image_result;
- image_urls = last_chapter_image_urls;
- }
+ image_urls = chapter_image_urls;
for(const std::string &url : image_urls) {
if(!callback(url))
break;
}
- return ImageResult::OK;
- }
- bool Mangadex::extract_id_from_url(const std::string &url, std::string &manga_id) {
- manga_id = title_url_extract_manga_id(url);
- return true;
+ return ImageResult::OK;
}
}