aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/Mangatown.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/Mangatown.cpp')
-rw-r--r--src/plugins/Mangatown.cpp212
1 files changed, 115 insertions, 97 deletions
diff --git a/src/plugins/Mangatown.cpp b/src/plugins/Mangatown.cpp
index 400d1ef..5d6f97f 100644
--- a/src/plugins/Mangatown.cpp
+++ b/src/plugins/Mangatown.cpp
@@ -1,59 +1,26 @@
#include "../../plugins/Mangatown.hpp"
#include "../../include/Notification.hpp"
+#include "../../include/StringUtils.hpp"
#include <quickmedia/HtmlSearch.h>
static const std::string mangatown_url = "https://www.mangatown.com";
namespace QuickMedia {
- SearchResult Mangatown::search(const std::string &url, BodyItems &result_items) {
- 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='chapter_list']//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 && strncmp(href, "/manga/", 7) == 0) {
- auto item = BodyItem::create(strip(text));
- item->url = mangatown_url + href;
- item_data->push_back(std::move(item));
- }
- }, &result_items);
-
- cleanup:
- quickmedia_html_search_deinit(&html_search);
-
- int chapter_num = result_items.size();
- for(auto &body_item : result_items) {
- body_item->set_title("Ch. " + std::to_string(chapter_num));
- chapter_num--;
- }
-
- return result == 0 ? SearchResult::OK : SearchResult::ERR;
+ static bool is_number_with_zero_fill(const char *str) {
+ while(*str == '0') { ++str; }
+ return atoi(str) != 0;
}
- struct BodyItemImageContext {
- BodyItems *body_items;
- size_t index;
- };
-
- SuggestionResult Mangatown::update_search_suggestions(const std::string &text, BodyItems &result_items) {
+ SearchResult MangatownSearchPage::search(const std::string &str, BodyItems &result_items) {
std::string url = "https://www.mangatown.com/search?name=";
- url += url_param_encode(text);
+ url += url_param_encode(str);
std::string website_data;
- if(download_to_string(url, website_data, {}, use_tor, true) != DownloadResult::OK)
- return SuggestionResult::NET_ERR;
+ if(download_to_string(url, website_data, {}, is_tor_enabled(), true) != DownloadResult::OK)
+ return SearchResult::NET_ERR;
if(website_data.empty())
- return SuggestionResult::OK;
+ return SearchResult::OK;
QuickMediaHtmlSearch html_search;
int result = quickmedia_html_search_init(&html_search, website_data.c_str());
@@ -88,77 +55,101 @@ namespace QuickMedia {
cleanup:
quickmedia_html_search_deinit(&html_search);
- return SuggestionResult::OK;
+ return SearchResult::OK;
}
- static bool is_number_with_zero_fill(const char *str) {
- while(*str == '0') { ++str; }
- return atoi(str) != 0;
- }
-
- ImageResult Mangatown::get_number_of_images(const std::string &url, int &num_images) {
- std::lock_guard<std::mutex> lock(image_urls_mutex);
-
- num_images = last_num_pages;
- if(url == last_chapter_url_num_images)
- return ImageResult::OK;
-
- last_num_pages = 0;
+ PluginResult MangatownSearchPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
+ BodyItems chapters_items;
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='page_select']//option",
+ result = quickmedia_html_find_nodes_xpath(&html_search, "//ul[class='chapter_list']//a",
[](QuickMediaHtmlNode *node, void *userdata) {
- int *last_num_pages = (int*)userdata;
- const char *value = quickmedia_html_node_get_attribute_value(node, "value");
+ 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(value && strncmp(value, "/manga/", 7) == 0) {
- if(is_number_with_zero_fill(text)) {
- (*last_num_pages)++;
- }
+ if(href && text && strncmp(href, "/manga/", 7) == 0) {
+ auto item = BodyItem::create(strip(text));
+ item->url = mangatown_url + href;
+ item_data->push_back(std::move(item));
}
- }, &last_num_pages);
-
- last_num_pages /= 2;
- num_images = last_num_pages;
+ }, &chapters_items);
cleanup:
quickmedia_html_search_deinit(&html_search);
+ if(result != 0)
+ return PluginResult::ERR;
- if(result == 0)
- last_chapter_url_num_images = url;
- if(last_num_pages == 0) {
- last_chapter_url_num_images.clear();
- return ImageResult::ERR;
+ int chapter_num = chapters_items.size();
+ for(auto &body_item : chapters_items) {
+ body_item->set_title("Ch. " + std::to_string(chapter_num));
+ chapter_num--;
}
- return result == 0 ? ImageResult::OK : ImageResult::ERR;
+
+ auto body = create_body();
+ body->items = std::move(chapters_items);
+ result_tabs.push_back(Tab{std::move(body), std::make_unique<MangatownChaptersPage>(program, title, url), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+
+ std::string manga_id;
+ if(extract_id_from_url(url, manga_id)) {
+ if(load_manga_content_storage("mangatown", title, manga_id))
+ return PluginResult::OK;
+ }
+ return PluginResult::ERR;
+ }
+
+ bool MangatownSearchPage::extract_id_from_url(const std::string &url, std::string &manga_id) const {
+ size_t start_index = url.find("/manga/");
+ if(start_index == std::string::npos)
+ return false;
+
+ start_index += 7;
+ size_t end_index = url.find("/", start_index);
+ if(end_index == std::string::npos) {
+ manga_id = url.substr(start_index);
+ return true;
+ }
+
+ manga_id = url.substr(start_index, end_index - start_index);
+ return true;
}
- ImageResult Mangatown::for_each_page_in_chapter(const std::string &chapter_url, PageCallback callback) {
- int num_pages;
- ImageResult image_result = get_number_of_images(chapter_url, num_pages);
+ PluginResult MangatownChaptersPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
+ result_tabs.push_back(Tab{create_body(), std::make_unique<MangatownImagesPage>(program, content_title, title, url), nullptr});
+ return PluginResult::OK;
+ }
+
+ ImageResult MangatownImagesPage::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;
- int result = 0;
- int page_index = 1;
+ num_images = chapter_image_urls.size();
+ return ImageResult::OK;
+ }
+
+ ImageResult MangatownImagesPage::for_each_page_in_chapter(PageCallback callback) {
+ int num_pages;
+ ImageResult image_result = get_number_of_images(num_pages);
+ if(image_result != ImageResult::OK)
+ return image_result;
- while(true) {
+ for(const std::string &full_url : chapter_image_urls) {
std::string image_src;
std::string website_data;
- std::string full_url = chapter_url + std::to_string(page_index++) + ".html";
- if(download_to_string_cache(full_url, website_data, {}, use_tor, true) != DownloadResult::OK)
+ if(download_to_string_cache(full_url, website_data, {}, is_tor_enabled(), true) != DownloadResult::OK)
break;
QuickMediaHtmlSearch html_search;
- result = quickmedia_html_search_init(&html_search, website_data.c_str());
+ int result = quickmedia_html_search_init(&html_search, website_data.c_str());
if(result != 0)
goto cleanup;
@@ -190,19 +181,46 @@ namespace QuickMedia {
return ImageResult::OK;
}
- bool Mangatown::extract_id_from_url(const std::string &url, std::string &manga_id) {
- size_t start_index = url.find("/manga/");
- if(start_index == std::string::npos)
- return false;
-
- start_index += 7;
- size_t end_index = url.find("/", start_index);
- if(end_index == std::string::npos) {
- manga_id = url.substr(start_index);
- return true;
+ ImageResult MangatownImagesPage::get_image_urls_for_chapter(const std::string &url) {
+ if(!chapter_image_urls.empty())
+ return ImageResult::OK;
+
+ int num_pages = 0;
+
+ std::string website_data;
+ 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='page_select']//option",
+ [](QuickMediaHtmlNode *node, void *userdata) {
+ int *last_num_pages = (int*)userdata;
+ const char *value = quickmedia_html_node_get_attribute_value(node, "value");
+ const char *text = quickmedia_html_node_get_text(node);
+ if(value && strncmp(value, "/manga/", 7) == 0) {
+ if(is_number_with_zero_fill(text)) {
+ (*last_num_pages)++;
+ }
+ }
+ }, &num_pages);
+
+ num_pages /= 2;
+
+ cleanup:
+ quickmedia_html_search_deinit(&html_search);
+ if(result != 0) {
+ chapter_image_urls.clear();
+ return ImageResult::ERR;
}
-
- manga_id = url.substr(start_index, end_index - start_index);
- return true;
+ if(num_pages == 0)
+ return ImageResult::ERR;
+ for(int i = 0; i < num_pages; ++i) {
+ chapter_image_urls.push_back(url + std::to_string(1 + i) + ".html");
+ }
+ return ImageResult::OK;
}
} \ No newline at end of file