MangaGeneric.hpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #pragma once
  2. #include "Manga.hpp"
  3. #include <functional>
  4. namespace QuickMedia {
  5. struct MangaFormData {
  6. const char *key;
  7. const char *value;
  8. };
  9. struct MangaFormDataStr {
  10. const char *key;
  11. std::string value;
  12. };
  13. using SearchQueryJsonHandler = std::function<BodyItems(Json::Value&)>;
  14. struct SearchQuery {
  15. const char *search_template = nullptr;
  16. int page_start = 0;
  17. std::vector<MangaFormData> form_data;
  18. bool is_post = false;
  19. SearchQueryJsonHandler json_handler = nullptr;
  20. };
  21. struct TextQuery {
  22. const char *html_query = nullptr;
  23. const char *title_field = nullptr;
  24. const char *url_field = nullptr;
  25. const char *url_contains = nullptr;
  26. };
  27. struct DescriptionQuery {
  28. const char *html_query = nullptr;
  29. const char *field_name = nullptr;
  30. };
  31. struct ThumbnailQuery {
  32. const char *html_query = nullptr;
  33. const char *field_name = nullptr;
  34. const char *field_contains = nullptr;
  35. };
  36. struct AuthorsQuery {
  37. const char *html_query = nullptr;
  38. const char *title_field = nullptr;
  39. const char *url_field = nullptr;
  40. const char *url_contains = nullptr;
  41. };
  42. struct ListChaptersQuery {
  43. const char *html_query = nullptr;
  44. const char *title_field = nullptr;
  45. const char *url_field = nullptr;
  46. const char *url_contains = nullptr;
  47. const char *uploaded_time_html_query = nullptr;
  48. const char *uploaded_time_field_name = nullptr;
  49. const char *uploaded_time_field_contains = nullptr;
  50. };
  51. using ListPageImagesQueryPost = std::function<void(std::vector<std::string> &image_urls)>;
  52. struct ListPageImagesQuery {
  53. const char *html_query = nullptr;
  54. const char *field_name = nullptr;
  55. const char *field_contains = nullptr;
  56. ListPageImagesQueryPost post_handler = nullptr;
  57. };
  58. struct ListPagePaginationQuery {
  59. const char *pages_html_query = nullptr;
  60. const char *pages_field_name = nullptr;
  61. const char *image_html_query = nullptr;
  62. const char *image_field_name = nullptr;
  63. const char *image_field_contains = nullptr;
  64. const char *next_page_html_query = nullptr;
  65. const char *next_page_field_name = nullptr;
  66. const char *next_page_field_contains = nullptr;
  67. };
  68. // Return the image sources
  69. using ListPageCustomHandler = std::function<std::vector<std::string>(const std::string &html_source)>;
  70. struct ListPageCustomQuery {
  71. ListPageCustomHandler handler;
  72. };
  73. enum class ListPageQueryType {
  74. IMAGES,
  75. PAGINATION,
  76. CUSTOM
  77. };
  78. struct ListPageQuery {
  79. ListPageQueryType type = ListPageQueryType::IMAGES;
  80. ListPageImagesQuery images_query;
  81. ListPagePaginationQuery pagination_query;
  82. ListPageCustomQuery custom_query;
  83. };
  84. struct MangaIdExtractor {
  85. const char *prefix = nullptr;
  86. const char *end = nullptr;
  87. };
  88. class MangaGenericSearchPage : public Page {
  89. public:
  90. MangaGenericSearchPage(Program *program, const char *service_name, const char *website_url, bool fail_on_http_error = true);
  91. const char* get_title() const override { return "Search"; }
  92. bool search_is_filter() override { return false; }
  93. SearchResult search(const std::string &str, BodyItems &result_items) override;
  94. PluginResult get_page(const std::string &url, bool is_post, const std::vector<MangaFormDataStr> &form_data, BodyItems &result_items);
  95. PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
  96. PluginResult submit(const SubmitArgs &args, std::vector<Tab> &result_tabs) override;
  97. const char* get_bookmark_name() const override { return service_name; }
  98. MangaGenericSearchPage& search_handler(const char *search_template, int page_start);
  99. MangaGenericSearchPage& search_post_handler(const char *url, std::vector<MangaFormData> form_data, SearchQueryJsonHandler result_handler);
  100. MangaGenericSearchPage& text_handler(std::vector<TextQuery> queries);
  101. MangaGenericSearchPage& description_handler(std::vector<DescriptionQuery> queries);
  102. MangaGenericSearchPage& thumbnail_handler(std::vector<ThumbnailQuery> queries);
  103. MangaGenericSearchPage& authors_handler(std::vector<AuthorsQuery> queries);
  104. MangaGenericSearchPage& list_chapters_handler(const char *html_query, const char *title_field, const char *url_field, const char *url_contains);
  105. MangaGenericSearchPage& list_chapters_uploaded_time_handler(const char *html_query, const char *field_name, const char *field_contains);
  106. MangaGenericSearchPage& list_page_images_handler(const char *html_query, const char *field_name, const char *field_contains, ListPageImagesQueryPost post_handler = nullptr);
  107. MangaGenericSearchPage& list_page_images_pagination_handler(
  108. const char *pages_html_query, const char *pages_field_name,
  109. const char *image_html_query, const char *image_field_name, const char *image_field_contains,
  110. const char *next_page_html_query, const char *next_page_field_name, const char *next_page_field_contains);
  111. MangaGenericSearchPage& list_page_images_custom_handler(ListPageCustomHandler handler);
  112. // For example: mangasite.com/manga/204353&f=23
  113. // /manga/ here would be the |prefix| and & would be |end|. |end| is optional.
  114. // The goal is to extract 204353 from the manga chapter page url.
  115. MangaGenericSearchPage& manga_id_handler(const char *prefix, const char *end);
  116. private:
  117. const char *service_name;
  118. std::string website_url;
  119. bool fail_on_http_error;
  120. SearchQuery search_query;
  121. std::vector<TextQuery> text_queries;
  122. std::vector<DescriptionQuery> description_queries;
  123. std::vector<ThumbnailQuery> thumbnail_queries;
  124. std::vector<AuthorsQuery> authors_queries;
  125. ListChaptersQuery list_chapters_query;
  126. ListPageQuery list_page_query;
  127. MangaIdExtractor manga_id_extractor;
  128. };
  129. class MangaGenericChaptersPage : public MangaChaptersPage {
  130. public:
  131. MangaGenericChaptersPage(Program *program, std::string manga_name, std::string manga_url, const std::string &thumbnail_url, const MangaIdExtractor &manga_id_extractor, const char *service_name, const std::string &website_url, const ListPageQuery *list_page_query, bool fail_on_http_error) :
  132. MangaChaptersPage(program, std::move(manga_name), std::move(manga_url), thumbnail_url), manga_id_extractor(manga_id_extractor), service_name(service_name), website_url(website_url), list_page_query(list_page_query), fail_on_http_error(fail_on_http_error) {}
  133. PluginResult submit(const SubmitArgs &args, std::vector<Tab> &result_tabs) override;
  134. const char* get_bookmark_name() const override { return service_name; }
  135. protected:
  136. bool extract_id_from_url(const std::string &url, std::string &manga_id) const override;
  137. const char* get_service_name() const override { return service_name; }
  138. private:
  139. MangaIdExtractor manga_id_extractor;
  140. const char *service_name;
  141. std::string website_url;
  142. const ListPageQuery *list_page_query;
  143. bool fail_on_http_error;
  144. };
  145. class MangaGenericCreatorPage : public LazyFetchPage {
  146. public:
  147. MangaGenericCreatorPage(Program *program, MangaGenericSearchPage *search_page, Creator creator) : LazyFetchPage(program), search_page(search_page), creator(std::move(creator)) {}
  148. const char* get_title() const override { return creator.name.c_str(); }
  149. PluginResult submit(const SubmitArgs &args, std::vector<Tab> &result_tabs) override;
  150. PluginResult lazy_fetch(BodyItems &result_items) override;
  151. const char* get_bookmark_name() const override { return search_page->get_bookmark_name(); }
  152. private:
  153. MangaGenericSearchPage *search_page;
  154. Creator creator;
  155. };
  156. class MangaGenericImagesPage : public MangaImagesPage {
  157. public:
  158. MangaGenericImagesPage(Program *program, std::string manga_name, std::string chapter_name, std::string url, const char *service_name, const std::string &website_url, const ListPageQuery *list_page_query, bool fail_on_http_error, std::string thumbnail_url) :
  159. MangaImagesPage(program, std::move(manga_name), std::move(chapter_name), std::move(url), std::move(thumbnail_url)), service_name(service_name), website_url(website_url), list_page_query(list_page_query), fail_on_http_error(fail_on_http_error) {}
  160. virtual ImageResult update_image_urls(int &num_images) override;
  161. ImageResult for_each_page_in_chapter(PageCallback callback) override;
  162. const char* get_service_name() const override { return service_name; }
  163. const char* get_website_url() const override { return website_url.c_str(); }
  164. private:
  165. ImageResult get_page_image_urls();
  166. private:
  167. const char *service_name;
  168. std::string website_url;
  169. const ListPageQuery *list_page_query;
  170. bool fail_on_http_error;
  171. std::string current_image_url;
  172. std::string next_page_url;
  173. };
  174. }