aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Manganelo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Manganelo.cpp')
-rw-r--r--src/plugins/Manganelo.cpp277
1 files changed, 128 insertions, 149 deletions
diff --git a/src/plugins/Manganelo.cpp b/src/plugins/Manganelo.cpp
index 52b9ebd..e96bc65 100644
--- a/src/plugins/Manganelo.cpp
+++ b/src/plugins/Manganelo.cpp
@@ -1,56 +1,10 @@
#include "../../plugins/Manganelo.hpp"
#include "../../include/Notification.hpp"
+#include "../../include/StringUtils.hpp"
#include <quickmedia/HtmlSearch.h>
namespace QuickMedia {
- struct BodyItemImageContext {
- BodyItems *body_items;
- size_t index;
- };
-
- SearchResult Manganelo::search(const std::string &url, BodyItems &result_items) {
- creators.clear();
-
- std::string website_data;
- if(download_to_string(url, website_data, {}, use_tor, 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, "//ul[class='row-content-chapter']//a",
- [](QuickMediaHtmlNode *node, void *userdata) {
- auto *item_data = (BodyItems*)userdata;
- const char *href = quickmedia_html_node_get_attribute_value(node, "href");
- const char *text = quickmedia_html_node_get_text(node);
- if(href && text) {
- auto item = BodyItem::create(strip(text));
- item->url = href;
- item_data->push_back(std::move(item));
- }
- }, &result_items);
-
- quickmedia_html_find_nodes_xpath(&html_search, "//a[class='a-h']",
- [](QuickMediaHtmlNode *node, void *userdata) {
- std::vector<Creator> *creators = (std::vector<Creator>*)userdata;
- const char *href = quickmedia_html_node_get_attribute_value(node, "href");
- const char *text = quickmedia_html_node_get_text(node);
- if(href && text && strstr(href, "/author/story/")) {
- Creator creator;
- creator.name = strip(text);
- creator.url = href;
- creators->push_back(std::move(creator));
- }
- }, &creators);
-
- cleanup:
- quickmedia_html_search_deinit(&html_search);
- return result == 0 ? SearchResult::OK : SearchResult::ERR;
- }
-
- // Returns true if changed
+ // Returns true if modified
static bool remove_html_span(std::string &str) {
size_t open_tag_start = str.find("<span");
if(open_tag_start == std::string::npos)
@@ -70,103 +24,103 @@ namespace QuickMedia {
return true;
}
- SuggestionResult Manganelo::update_search_suggestions(const std::string &text, BodyItems &result_items) {
+ SearchResult ManganeloSearchPage::search(const std::string &str, BodyItems &result_items) {
std::string url = "https://manganelo.com/getstorysearchjson";
std::string search_term = "searchword=";
- search_term += url_param_encode(text);
+ search_term += url_param_encode(str);
CommandArg data_arg = { "--data", std::move(search_term) };
Json::Value json_root;
DownloadResult result = download_json(json_root, url, {data_arg}, true);
- if(result != DownloadResult::OK) return download_result_to_suggestion_result(result);
-
- if(json_root.isArray()) {
- for(const Json::Value &child : json_root) {
- if(child.isObject()) {
- Json::Value name = child.get("name", "");
- Json::Value nameunsigned = child.get("nameunsigned", "");
- if(name.isString() && name.asCString()[0] != '\0' && nameunsigned.isString() && nameunsigned.asCString()[0] != '\0') {
- std::string name_str = name.asString();
- while(remove_html_span(name_str)) {}
- auto item = BodyItem::create(strip(name_str));
- item->url = "https://manganelo.com/manga/" + url_param_encode(nameunsigned.asString());
- Json::Value image = child.get("image", "");
- if(image.isString() && image.asCString()[0] != '\0')
- item->thumbnail_url = image.asString();
- result_items.push_back(std::move(item));
- }
- }
+ if(result != DownloadResult::OK) return download_result_to_search_result(result);
+
+ if(json_root.isNull())
+ return SearchResult::OK;
+
+ if(!json_root.isArray())
+ return SearchResult::ERR;
+
+ for(const Json::Value &child : json_root) {
+ if(!child.isObject())
+ continue;
+
+ Json::Value name = child.get("name", "");
+ Json::Value nameunsigned = child.get("nameunsigned", "");
+ if(name.isString() && name.asCString()[0] != '\0' && nameunsigned.isString() && nameunsigned.asCString()[0] != '\0') {
+ std::string name_str = name.asString();
+ while(remove_html_span(name_str)) {}
+ auto item = BodyItem::create(strip(name_str));
+ item->url = "https://manganelo.com/manga/" + url_param_encode(nameunsigned.asString());
+ Json::Value image = child.get("image", "");
+ if(image.isString() && image.asCString()[0] != '\0')
+ item->thumbnail_url = image.asString();
+ result_items.push_back(std::move(item));
}
}
- return SuggestionResult::OK;
- }
- ImageResult Manganelo::get_number_of_images(const std::string &url, int &num_images) {
- std::lock_guard<std::mutex> lock(image_urls_mutex);
- 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();
- return ImageResult::OK;
+ return SearchResult::OK;
}
- ImageResult Manganelo::get_image_urls_for_chapter(const std::string &url) {
- if(url == last_chapter_url)
- return ImageResult::OK;
-
- last_chapter_image_urls.clear();
+ PluginResult ManganeloSearchPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
+ BodyItems chapters_items;
+ std::vector<Creator> creators;
std::string website_data;
- if(download_to_string(url, website_data, {}, use_tor, true) != DownloadResult::OK)
- return ImageResult::NET_ERR;
+ if(download_to_string(url, website_data, {}, is_tor_enabled(), true) != DownloadResult::OK)
+ return PluginResult::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, "//div[class='container-chapter-reader']/img",
+ result = quickmedia_html_find_nodes_xpath(&html_search, "//ul[class='row-content-chapter']//a",
[](QuickMediaHtmlNode *node, void *userdata) {
- auto *urls = (std::vector<std::string>*)userdata;
- const char *src = quickmedia_html_node_get_attribute_value(node, "src");
- if(src) {
- std::string image_url = src;
- urls->emplace_back(std::move(image_url));
+ auto *item_data = (BodyItems*)userdata;
+ const char *href = quickmedia_html_node_get_attribute_value(node, "href");
+ const char *text = quickmedia_html_node_get_text(node);
+ if(href && text) {
+ auto item = BodyItem::create(strip(text));
+ item->url = href;
+ item_data->push_back(std::move(item));
+ }
+ }, &chapters_items);
+
+ quickmedia_html_find_nodes_xpath(&html_search, "//a[class='a-h']",
+ [](QuickMediaHtmlNode *node, void *userdata) {
+ std::vector<Creator> *creators = (std::vector<Creator>*)userdata;
+ const char *href = quickmedia_html_node_get_attribute_value(node, "href");
+ const char *text = quickmedia_html_node_get_text(node);
+ if(href && text && strstr(href, "/author/story/")) {
+ Creator creator;
+ creator.name = strip(text);
+ creator.url = href;
+ creators->push_back(std::move(creator));
}
- }, &last_chapter_image_urls);
+ }, &creators);
cleanup:
quickmedia_html_search_deinit(&html_search);
- if(result == 0)
- last_chapter_url = url;
- if(last_chapter_image_urls.empty()) {
- last_chapter_url.clear();
- return ImageResult::ERR;
- }
- return result == 0 ? ImageResult::OK : ImageResult::ERR;
- }
+ if(result != 0)
+ return PluginResult::ERR;
- ImageResult Manganelo::for_each_page_in_chapter(const std::string &chapter_url, 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;
+ auto chapters_body = create_body();
+ chapters_body->items = std::move(chapters_items);
+ result_tabs.push_back(Tab{std::move(chapters_body), std::make_unique<ManganeloChaptersPage>(program, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
- image_urls = last_chapter_image_urls;
+ for(Creator &creator : creators) {
+ result_tabs.push_back(Tab{create_body(), std::make_unique<ManganeloCreatorPage>(program, std::move(creator)), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
}
- for(const std::string &url : image_urls) {
- if(!callback(url))
- break;
+ std::string manga_id;
+ if(extract_id_from_url(url, manga_id)) {
+ if(load_manga_content_storage("manganelo", title, manga_id))
+ return PluginResult::OK;
}
- return ImageResult::OK;
+ return PluginResult::ERR;
}
-
- bool Manganelo::extract_id_from_url(const std::string &url, std::string &manga_id) {
+
+ bool ManganeloSearchPage::extract_id_from_url(const std::string &url, std::string &manga_id) const {
bool manganelo_website = false;
if(url.find("mangakakalot") != std::string::npos || url.find("manganelo") != std::string::npos)
manganelo_website = true;
@@ -177,7 +131,7 @@ namespace QuickMedia {
std::string err_msg = "Url ";
err_msg += url;
err_msg += " doesn't contain manga id";
- show_notification("Manga", err_msg, Urgency::CRITICAL);
+ show_notification("QuickMedia", err_msg, Urgency::CRITICAL);
return false;
}
@@ -186,7 +140,7 @@ namespace QuickMedia {
std::string err_msg = "Url ";
err_msg += url;
err_msg += " doesn't contain manga id";
- show_notification("Manga", err_msg, Urgency::CRITICAL);
+ show_notification("QuickMedia", err_msg, Urgency::CRITICAL);
return false;
}
return true;
@@ -194,56 +148,81 @@ namespace QuickMedia {
std::string err_msg = "Unexpected url ";
err_msg += url;
err_msg += " is not manganelo or mangakakalot";
- show_notification("Manga", err_msg, Urgency::CRITICAL);
+ show_notification("QuickMedia", err_msg, Urgency::CRITICAL);
return false;
}
}
- PluginResult Manganelo::get_creators_manga_list(const std::string &url, BodyItems &result_items) {
+ PluginResult ManganeloChaptersPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
+ result_tabs.push_back(Tab{create_body(), std::make_unique<ManganeloImagesPage>(program, content_title, title, url), nullptr});
+ return PluginResult::OK;
+ }
+
+ PluginResult ManganeloCreatorPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
+ (void)title;
+ (void)url;
+ (void)result_tabs;
+ // TODO: Implement
+ return PluginResult::ERR;
+ }
+
+ ImageResult ManganeloImagesPage::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 = chapter_image_urls.size();
+ return ImageResult::OK;
+ }
+
+ ImageResult ManganeloImagesPage::for_each_page_in_chapter(PageCallback callback) {
+ std::vector<std::string> image_urls;
+ ImageResult image_result = get_image_urls_for_chapter(url);
+ if(image_result != ImageResult::OK)
+ return image_result;
+
+ image_urls = chapter_image_urls;
+
+ for(const std::string &url : image_urls) {
+ if(!callback(url))
+ break;
+ }
+
+ return ImageResult::OK;
+ }
+
+ ImageResult ManganeloImagesPage::get_image_urls_for_chapter(const std::string &url) {
+ if(!chapter_image_urls.empty())
+ return ImageResult::OK;
+
std::string website_data;
- if(download_to_string(url, website_data, {}, use_tor, true) != DownloadResult::OK)
- return PluginResult::NET_ERR;
+ if(download_to_string(url, website_data, {}, is_tor_enabled(), true) != DownloadResult::OK)
+ return ImageResult::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, "//div[class='search-story-item']//a[class='item-img']",
- [](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(href && title && strstr(href, "/manga/")) {
- auto body_item = BodyItem::create(title);
- body_item->url = href;
- item_data->push_back(std::move(body_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, "//div[class='search-story-item']//a[class='item-img']//img",
+ result = quickmedia_html_find_nodes_xpath(&html_search, "//div[class='container-chapter-reader']/img",
[](QuickMediaHtmlNode *node, void *userdata) {
- auto *item_data = (BodyItemImageContext*)userdata;
+ auto *urls = (std::vector<std::string>*)userdata;
const char *src = quickmedia_html_node_get_attribute_value(node, "src");
- if(src && item_data->index < item_data->body_items->size()) {
- (*item_data->body_items)[item_data->index]->thumbnail_url = src;
- item_data->index++;
+ if(src) {
+ std::string image_url = src;
+ urls->push_back(std::move(image_url));
}
- }, &body_item_image_context);
+ }, &chapter_image_urls);
cleanup:
quickmedia_html_search_deinit(&html_search);
if(result != 0) {
- result_items.clear();
- return PluginResult::ERR;
+ chapter_image_urls.clear();
+ return ImageResult::ERR;
}
- return PluginResult::OK;
+ if(chapter_image_urls.empty())
+ return ImageResult::ERR;
+ return ImageResult::OK;
}
} \ No newline at end of file