aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/MangaGeneric.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-04-26 18:37:00 +0200
committerdec05eba <dec05eba@protonmail.com>2021-04-26 18:37:00 +0200
commit76e1aebbe075287a8297194b38343467c76dd964 (patch)
tree0afa513ab80f2247686bbb62e5d2a6fa9aabc70c /src/plugins/MangaGeneric.cpp
parent8b5901000e9073d9ff6a3a86cd7c0e0172de7f5a (diff)
Fix soundcloud (fetch client id), add authors to mangakatana, some other fixes
Diffstat (limited to 'src/plugins/MangaGeneric.cpp')
-rw-r--r--src/plugins/MangaGeneric.cpp159
1 files changed, 105 insertions, 54 deletions
diff --git a/src/plugins/MangaGeneric.cpp b/src/plugins/MangaGeneric.cpp
index 24472e5..58bedf4 100644
--- a/src/plugins/MangaGeneric.cpp
+++ b/src/plugins/MangaGeneric.cpp
@@ -49,11 +49,6 @@ namespace QuickMedia {
return quickmedia_html_node_get_attribute_value(node, field_name);
}
- static bool starts_with(const std::string &str, const char *sub) {
- size_t sub_len = strlen(sub);
- return str.size() >= sub_len && memcmp(str.c_str(), sub, sub_len) == 0;
- }
-
static int html_append_search(QuickMediaHtmlSearch *html_search, const char *html_query, HtmlSearchUserdata *search_userdata) {
return quickmedia_html_find_nodes_xpath(html_search, html_query,
[](QuickMediaHtmlNode *node, void *userdata) {
@@ -149,12 +144,8 @@ namespace QuickMedia {
return plugin_result_to_search_result(get_page(str, 0, result_items));
}
- PluginResult MangaGenericSearchPage::get_page(const std::string &str, int page, BodyItems &result_items) {
+ PluginResult MangaGenericSearchPage::get_page(const std::string &url, BodyItems &result_items) {
std::string target_url;
- std::string url = search_query.search_template;
- string_replace_all(url, "%s", url_param_encode(str));
- string_replace_all(url, "%p", std::to_string(search_query.page_start + page));
-
std::string website_data;
if(download_to_string(url, website_data, {}, true, fail_on_http_error) != DownloadResult::OK)
return PluginResult::NET_ERR;
@@ -184,36 +175,6 @@ namespace QuickMedia {
if(result != 0)
goto cleanup;
- for(const DescriptionQuery &description_query : description_queries) {
- assert(description_query.html_query && description_query.field_name);
- if(description_query.html_query && description_query.field_name) {
- HtmlMergeUserdata merge_userdata;
- merge_userdata.type = MergeType::DESCRIPTION;
- merge_userdata.body_item_image_context.body_items = &new_result_items;
- merge_userdata.body_item_image_context.index = 0;
- merge_userdata.field_name = description_query.field_name;
- merge_userdata.field_contains = nullptr;
- result = html_body_item_merge(&html_search, description_query.html_query, &merge_userdata);
- if(result != 0)
- goto cleanup;
- }
- }
-
- for(const ThumbnailQuery &thumbnail_query : thumbnail_queries) {
- assert(thumbnail_query.html_query && thumbnail_query.field_name);
- if(thumbnail_query.html_query && thumbnail_query.field_name) {
- HtmlMergeUserdata merge_userdata;
- merge_userdata.type = MergeType::THUMBNAIL;
- merge_userdata.body_item_image_context.body_items = &new_result_items;
- merge_userdata.body_item_image_context.index = 0;
- merge_userdata.field_name = thumbnail_query.field_name;
- merge_userdata.field_contains = thumbnail_query.field_contains;
- result = html_body_item_merge(&html_search, thumbnail_query.html_query, &merge_userdata);
- if(result != 0)
- goto cleanup;
- }
- }
-
if(!text_query.url_field && !new_result_items.empty()) {
if(target_url.empty()) {
std::string response_headers;
@@ -239,15 +200,45 @@ namespace QuickMedia {
result_items.insert(result_items.end(), std::move_iterator(new_result_items.begin()), std::move_iterator(new_result_items.end()));
}
+ for(const DescriptionQuery &description_query : description_queries) {
+ assert(description_query.html_query && description_query.field_name);
+ if(description_query.html_query && description_query.field_name) {
+ HtmlMergeUserdata merge_userdata;
+ merge_userdata.type = MergeType::DESCRIPTION;
+ merge_userdata.body_item_image_context.body_items = &result_items;
+ merge_userdata.body_item_image_context.index = 0;
+ merge_userdata.field_name = description_query.field_name;
+ merge_userdata.field_contains = nullptr;
+ result = html_body_item_merge(&html_search, description_query.html_query, &merge_userdata);
+ if(result != 0)
+ goto cleanup;
+ }
+ }
+
+ for(const ThumbnailQuery &thumbnail_query : thumbnail_queries) {
+ assert(thumbnail_query.html_query && thumbnail_query.field_name);
+ if(thumbnail_query.html_query && thumbnail_query.field_name) {
+ HtmlMergeUserdata merge_userdata;
+ merge_userdata.type = MergeType::THUMBNAIL;
+ merge_userdata.body_item_image_context.body_items = &result_items;
+ merge_userdata.body_item_image_context.index = 0;
+ merge_userdata.field_name = thumbnail_query.field_name;
+ merge_userdata.field_contains = thumbnail_query.field_contains;
+ result = html_body_item_merge(&html_search, thumbnail_query.html_query, &merge_userdata);
+ if(result != 0)
+ goto cleanup;
+ }
+ }
+
for(auto &body_item : result_items) {
- if(starts_with(body_item->url, "//"))
+ if(string_starts_with(body_item->url, "//"))
body_item->url = "https://" + body_item->url.substr(2);
- else if(starts_with(body_item->url, "/"))
+ else if(string_starts_with(body_item->url, "/"))
body_item->url = website_url + body_item->url.substr(1);
- if(starts_with(body_item->thumbnail_url, "//"))
+ if(string_starts_with(body_item->thumbnail_url, "//"))
body_item->thumbnail_url = "https://" + body_item->thumbnail_url.substr(2);
- else if(starts_with(body_item->thumbnail_url, "/"))
+ else if(string_starts_with(body_item->thumbnail_url, "/"))
body_item->thumbnail_url = website_url + body_item->thumbnail_url.substr(1);
}
@@ -261,12 +252,20 @@ namespace QuickMedia {
}
}
+ PluginResult MangaGenericSearchPage::get_page(const std::string &str, int page, BodyItems &result_items) {
+ std::string url = search_query.search_template;
+ string_replace_all(url, "%s", url_param_encode(str));
+ string_replace_all(url, "%p", std::to_string(search_query.page_start + page));
+ return get_page(url, result_items);
+ }
+
PluginResult MangaGenericSearchPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
if(!list_chapters_query.html_query || !list_chapters_query.title_field || !list_chapters_query.url_field) {
assert(false);
return PluginResult::ERR;
}
+ std::vector<Creator> creators;
BodyItems chapters_items;
HtmlSearchUserdata search_userdata;
search_userdata.body_items = &chapters_items;
@@ -299,18 +298,49 @@ namespace QuickMedia {
result = html_body_item_merge(&html_search, list_chapters_query.uploaded_time_html_query, &merge_userdata);
}
+ if(authors_query.html_query && authors_query.title_field && authors_query.url_field) {
+ struct HtmlAuthorsUserdata {
+ std::vector<Creator> *creators;
+ AuthorsQuery *authors_query;
+ };
+
+ HtmlAuthorsUserdata authors_userdata;
+ authors_userdata.creators = &creators;
+ authors_userdata.authors_query = &authors_query;
+
+ quickmedia_html_find_nodes_xpath(&html_search, authors_query.html_query,
+ [](QuickMediaHtmlNode *node, void *userdata) {
+ HtmlAuthorsUserdata *authors_userdata = (HtmlAuthorsUserdata*)userdata;
+ const char *title_value = html_attr_or_inner_text(node, authors_userdata->authors_query->title_field);
+ const char *url_value = html_attr_or_inner_text(node, authors_userdata->authors_query->url_field);
+ if(title_value && url_value && (!authors_userdata->authors_query->url_contains || strstr(url_value, authors_userdata->authors_query->url_contains))) {
+ Creator creator;
+ creator.name = strip(title_value);
+ creator.url = strip(url_value);
+ authors_userdata->creators->push_back(std::move(creator));
+ }
+ }, &authors_userdata);
+ }
+
for(auto &body_item : chapters_items) {
- if(starts_with(body_item->url, "//"))
+ if(string_starts_with(body_item->url, "//"))
body_item->url = "https://" + body_item->url.substr(2);
- else if(starts_with(body_item->url, "/"))
+ else if(string_starts_with(body_item->url, "/"))
body_item->url = website_url + body_item->url.substr(1);
- if(starts_with(body_item->thumbnail_url, "//"))
+ if(string_starts_with(body_item->thumbnail_url, "//"))
body_item->thumbnail_url = "https://" + body_item->thumbnail_url.substr(2);
- else if(starts_with(body_item->thumbnail_url, "/"))
+ else if(string_starts_with(body_item->thumbnail_url, "/"))
body_item->thumbnail_url = website_url + body_item->thumbnail_url.substr(1);
}
+ for(auto &creator : creators) {
+ if(string_starts_with(creator.url, "//"))
+ creator.url = "https://" + creator.url.substr(2);
+ else if(string_starts_with(creator.url, "/"))
+ creator.url = website_url + creator.url.substr(1);
+ }
+
cleanup:
quickmedia_html_search_deinit(&html_search);
if(result != 0)
@@ -319,6 +349,11 @@ namespace QuickMedia {
auto body = create_body();
body->items = std::move(chapters_items);
result_tabs.push_back(Tab{std::move(body), std::make_unique<MangaGenericChaptersPage>(program, title, url, manga_id_extractor, service_name, website_url, &list_page_query, fail_on_http_error), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+
+ for(Creator &creator : creators) {
+ result_tabs.push_back(Tab{create_body(), std::make_unique<MangaGenericCreatorPage>(program, this, std::move(creator)), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
+ }
+
return PluginResult::OK;
}
@@ -348,6 +383,14 @@ namespace QuickMedia {
return true;
}
+ PluginResult MangaGenericCreatorPage::submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
+ return search_page->submit(title, url, result_tabs);
+ }
+
+ PluginResult MangaGenericCreatorPage::lazy_fetch(BodyItems &result_items) {
+ return search_page->get_page(creator.url, result_items);
+ }
+
static bool is_number(const char *str) {
while(*str) {
char c = *str;
@@ -443,9 +486,9 @@ namespace QuickMedia {
return ImageResult::ERR;
}
- if(starts_with(current_image_url, "//"))
+ if(string_starts_with(current_image_url, "//"))
current_image_url = "https://" + current_image_url.substr(2);
- else if(starts_with(current_image_url, "/"))
+ else if(string_starts_with(current_image_url, "/"))
current_image_url = website_url + current_image_url.substr(1);
num_images = page_count_userdata.num_pages;
@@ -523,9 +566,9 @@ namespace QuickMedia {
cleanup:
quickmedia_html_search_deinit(&html_search);
- if(starts_with(current_image_url, "//"))
+ if(string_starts_with(current_image_url, "//"))
current_image_url = "https://" + current_image_url.substr(2);
- else if(starts_with(current_image_url, "/"))
+ else if(string_starts_with(current_image_url, "/"))
current_image_url = website_url + current_image_url.substr(1);
if(!callback(current_image_url))
@@ -603,9 +646,9 @@ namespace QuickMedia {
}
for(std::string &url : chapter_image_urls) {
- if(starts_with(url, "//"))
+ if(string_starts_with(url, "//"))
url = "https://" + url.substr(2);
- else if(starts_with(url, "/"))
+ else if(string_starts_with(url, "/"))
url = website_url + url.substr(1);
}
@@ -635,6 +678,14 @@ namespace QuickMedia {
return *this;
}
+ MangaGenericSearchPage& MangaGenericSearchPage::authors_handler(const char *html_query, const char *title_field, const char *url_field, const char *url_contains) {
+ authors_query.html_query = html_query;
+ authors_query.title_field = title_field;
+ authors_query.url_field = url_field;
+ authors_query.url_contains = url_contains;
+ return *this;
+ }
+
MangaGenericSearchPage& MangaGenericSearchPage::list_chapters_handler(const char *html_query, const char *title_field, const char *url_field, const char *url_contains) {
list_chapters_query.html_query = html_query;
list_chapters_query.title_field = title_field;