From 88d3dbbd12d17056323f40effe00ce8ab8180691 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 16 Apr 2021 20:09:02 +0200 Subject: Add mangakatana --- src/QuickMedia.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) (limited to 'src/QuickMedia.cpp') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 26760ec..955a189 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -62,6 +62,7 @@ static const std::pair valid_plugins[] = { std::make_pair("manganelo", "manganelo_logo.png"), std::make_pair("manganelos", "manganelos_logo.png"), std::make_pair("mangatown", "mangatown_logo.png"), + std::make_pair("mangakatana", "mangakatana_logo.png"), std::make_pair("mangadex", "mangadex_logo.png"), std::make_pair("youtube", "yt_logo_rgb_dark_small.png"), std::make_pair("spotify", "spotify_logo.png"), @@ -420,7 +421,7 @@ namespace QuickMedia { static void usage() { fprintf(stderr, "usage: quickmedia [--no-video] [--use-system-mpv-config] [--dir ] [-e ]\n"); fprintf(stderr, "OPTIONS:\n"); - fprintf(stderr, " plugin The plugin to use. Should be either launcher, 4chan, manganelo, manganelos, mangatown, mangadex, pornhub, spankbang, youtube, spotify, soundcloud, nyaa.si, matrix, file-manager or stdin\n"); + fprintf(stderr, " plugin The plugin to use. Should be either launcher, 4chan, manganelo, manganelos, mangatown, mangakatana, mangadex, pornhub, spankbang, youtube, spotify, soundcloud, nyaa.si, matrix, file-manager or stdin\n"); fprintf(stderr, " --no-video Only play audio when playing a video. Disabled by default\n"); fprintf(stderr, " --use-system-mpv-config Use system mpv config instead of no config. Disabled by default\n"); fprintf(stderr, " --upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default\n"); @@ -435,7 +436,7 @@ namespace QuickMedia { } static bool is_manga_plugin(const char *plugin_name) { - return strcmp(plugin_name, "manganelo") == 0 || strcmp(plugin_name, "manganelos") == 0 || strcmp(plugin_name, "mangatown") == 0 || strcmp(plugin_name, "mangadex") == 0; + return strcmp(plugin_name, "manganelo") == 0 || strcmp(plugin_name, "manganelos") == 0 || strcmp(plugin_name, "mangatown") == 0 || strcmp(plugin_name, "mangakatana") == 0 || strcmp(plugin_name, "mangadex") == 0; } static std::shared_ptr create_launcher_body_item(const char *title, const char *plugin_name, const std::string &thumbnail_url) { @@ -679,7 +680,7 @@ namespace QuickMedia { } static void add_manganelos_handlers(MangaGenericSearchPage *manga_generic_search_page) { - manga_generic_search_page->search_handler("http://manganelos.com/search?q=", "&page=", 1) + manga_generic_search_page->search_handler("http://manganelos.com/search?q=%s&page=%p", 1) .text_handler("//div[class='media-left cover-manga']//a", "title", "href", "/manga/") .thumbnail_handler("//div[class='media-left cover-manga']//img[class='media-object']", "src", "/mangaimage/") .list_chapters_handler("//section[id='examples']//div[class='chapter-list']//a", "text", "href", nullptr) @@ -701,18 +702,48 @@ namespace QuickMedia { } static void add_mangatown_handlers(MangaGenericSearchPage *manga_generic_search_page) { - manga_generic_search_page->search_handler("https://www.mangatown.com/search?name=", "&page=", 1) + manga_generic_search_page->search_handler("https://mangatown.com/search?name=%s&page=%p", 1) .text_handler("//p[class='title']/a", "title", "href", "/manga/") .thumbnail_handler("//a[class='manga_cover']/img", "src", nullptr) .list_chapters_handler("//ul[class='chapter_list']//a", "text", "href", "/manga/") .list_chapters_uploaded_time_handler("//ul[class='chapter_list']//span[class='time']", "text", nullptr) .list_page_images_pagination_handler( - "//div[class='page_select']//option", "value", "/manga/", [](int num_pages){ return std::max(0, (num_pages /= 2) - 1); }, + "//div[class='page_select']//option", "text", "//img[id='image']", "src", nullptr, "//a[class='next_page']", "href", nullptr) .manga_id_handler("/manga/", "/"); } + static void add_mangakatana_handlers(MangaGenericSearchPage *manga_generic_search_page) { + manga_generic_search_page->search_handler("https://mangakatana.com/page/%p?search=%s&search_by=book_name", 1) + .text_handler("//div[id='book_list']//h3[class='title']//a", "text", "href", "/manga/") + .thumbnail_handler("//div[id='book_list']//img", "src", "/cover/") + .list_chapters_handler("//div[class='chapters']//div[class='chapter']//a", "text", "href", "/manga/") + .list_chapters_uploaded_time_handler("//div[class='chapters']//div[class='update_time']", "text", nullptr) + .list_page_images_custom_handler([](const std::string &html_source) { + std::vector urls; + size_t sources_start = html_source.find("ytaw=["); + if(sources_start == std::string::npos) + return urls; + + sources_start += 6; + size_t sources_end = html_source.find("]", sources_start); + if(sources_end == std::string::npos) + return urls; + + std::string urls_str = html_source.substr(sources_start, sources_end - sources_start); + string_replace_all(urls_str, "'", ""); + + string_split(urls_str, ',', [&urls](const char *str, size_t size) { + std::string url(str, size); + urls.push_back(std::move(url)); + return true; + }); + return urls; + }) + .manga_id_handler("/manga/", nullptr); + } + void Program::load_plugin_by_name(std::vector &tabs, const char *start_dir) { if(!plugin_name || plugin_name[0] == '\0') return; @@ -742,6 +773,7 @@ namespace QuickMedia { auto pipe_body = create_body(); pipe_body->items.push_back(create_launcher_body_item("4chan", "4chan", resources_root + "icons/4chan_launcher.png")); pipe_body->items.push_back(create_launcher_body_item("Mangadex", "mangadex", resources_root + "icons/mangadex_launcher.png")); + pipe_body->items.push_back(create_launcher_body_item("Mangakatana", "mangakatana", resources_root + "icons/mangakatana_launcher.png")); pipe_body->items.push_back(create_launcher_body_item("Manganelo", "manganelo", resources_root + "icons/manganelo_launcher.png")); pipe_body->items.push_back(create_launcher_body_item("Manganelos", "manganelos", resources_root + "icons/manganelos_launcher.png")); pipe_body->items.push_back(create_launcher_body_item("Mangatown", "mangatown", resources_root + "icons/mangatown_launcher.png")); @@ -776,6 +808,16 @@ namespace QuickMedia { add_mangatown_handlers(search_page.get()); tabs.push_back(Tab{std::move(search_body), std::move(search_page), create_search_bar("Search...", 400)}); + auto history_body = create_body(); + auto search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER); + auto history_page = std::make_unique(this, tabs.front().page.get(), search_bar.get(), HistoryType::MANGA); + tabs.push_back(Tab{std::move(history_body), std::move(history_page), std::move(search_bar)}); + } else if(strcmp(plugin_name, "mangakatana") == 0) { + auto search_body = create_body(); + auto search_page = std::make_unique(this, plugin_name, "https://mangakatana.com", false); + add_mangakatana_handlers(search_page.get()); + tabs.push_back(Tab{std::move(search_body), std::move(search_page), create_search_bar("Search...", 400)}); + auto history_body = create_body(); auto search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER); auto history_page = std::make_unique(this, tabs.front().page.get(), search_bar.get(), HistoryType::MANGA); @@ -1055,6 +1097,8 @@ namespace QuickMedia { body_item->url = "https://mangadex.org/title/" + base64_decode(filename.string()); else if(strcmp(plugin_name, "mangatown") == 0) body_item->url = "https://mangatown.com/manga/" + base64_decode(filename.string()); + else if(strcmp(plugin_name, "mangakatana") == 0) + body_item->url = "https://mangakatana.com/manga/" + base64_decode(filename.string()); else fprintf(stderr, "Error: Not implemented: filename to manga chapter list\n"); history_items.push_back(std::move(body_item)); -- cgit v1.2.3