From 4694f8544c4cbd7e7d92323976b63cc77fdadb27 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 28 Apr 2021 20:02:14 +0200 Subject: Lazy load recommendations, simplify html parser --- depends/html-parser | 2 +- include/QuickMedia.hpp | 6 +- src/QuickMedia.cpp | 140 +++++++++++++++++++++++++--------------------- src/plugins/Pleroma.cpp | 5 +- src/plugins/Pornhub.cpp | 7 +-- src/plugins/Spankbang.cpp | 11 +--- src/plugins/Youtube.cpp | 5 +- 7 files changed, 86 insertions(+), 90 deletions(-) diff --git a/depends/html-parser b/depends/html-parser index 4a2f50f..efdd24c 160000 --- a/depends/html-parser +++ b/depends/html-parser @@ -1 +1 @@ -Subproject commit 4a2f50f00529aa0894486a099b721826add9205b +Subproject commit efdd24c40d9d6ffa5207ddc369b03eba86e9e22e diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp index ec788bf..cb7e421 100644 --- a/include/QuickMedia.hpp +++ b/include/QuickMedia.hpp @@ -95,6 +95,9 @@ namespace QuickMedia { const char* get_plugin_name() const; void manga_get_watch_history(const char *plugin_name, BodyItems &history_items); void youtube_get_watch_history(BodyItems &history_items); + + Json::Value load_video_history_json(); + Json::Value load_recommended_json(); private: void init(Window parent_window); void load_plugin_by_name(std::vector &tabs, const char *start_dir); @@ -129,9 +132,6 @@ namespace QuickMedia { // Returns PageType::EXIT if empty PageType pop_page_stack(); - Json::Value load_video_history_json(); - Json::Value load_recommended_json(); - void save_recommendations_from_related_videos(const std::string &video_url, const std::string &video_title, const BodyItems &related_media_body_items); private: enum class UpscaleImageAction { diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 842ecbe..4b645d4 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -246,62 +246,16 @@ static sf::Color interpolate_colors(sf::Color source, sf::Color target, double p } namespace QuickMedia { - enum class HistoryType { - YOUTUBE, - MANGA - }; - - class HistoryPage : public Page { - public: - HistoryPage(Program *program, Page *search_page, SearchBar *search_bar, HistoryType history_type) : - Page(program), search_page(search_page), search_bar(search_bar), history_type(history_type) {} - const char* get_title() const override { return "History"; } - PluginResult submit(const std::string &title, const std::string &url, std::vector &result_tabs) override { - return search_page->submit(title, url, result_tabs); + // Returns index to item or -1 if not found + static int get_body_item_by_url(Body *body, const std::string &url) { + if(url.empty()) return -1; + for(size_t i = 0; i < body->items.size(); ++i) { + auto &body_item = body->items[i]; + if(body_item->url == url) + return i; } - void on_navigate_to_page(Body *body) override { - std::string selected_item_url = body->get_selected() ? body->get_selected()->url : ""; - body->clear_items(); - switch(history_type) { - case HistoryType::YOUTUBE: - program->youtube_get_watch_history(body->items); - break; - case HistoryType::MANGA: - program->manga_get_watch_history(program->get_plugin_name(), body->items); - break; - } - body->filter_search_fuzzy(search_bar->get_text()); - int item_to_revert_selection_to = get_body_item_by_url(body, selected_item_url); - if(item_to_revert_selection_to != -1) - body->set_selected_item(item_to_revert_selection_to, false); - } - - // Returns index to item or -1 if not found - int get_body_item_by_url(Body *body, const std::string &url) { - if(url.empty()) return -1; - for(size_t i = 0; i < body->items.size(); ++i) { - auto &body_item = body->items[i]; - if(body_item->url == url) - return i; - } - return -1; - } - private: - Page *search_page; - SearchBar *search_bar; - HistoryType history_type; - }; - - class RecommendedPage : public Page { - public: - RecommendedPage(Program *program, Page *search_page) : Page(program), search_page(search_page) {} - const char* get_title() const override { return "Recommended"; } - PluginResult submit(const std::string &title, const std::string &url, std::vector &result_tabs) override { - return search_page->submit(title, url, result_tabs); - } - private: - Page *search_page; - }; + return -1; + } static Path get_recommended_filepath(const char *plugin_name) { Path video_history_dir = get_storage_dir().join("recommended"); @@ -411,6 +365,63 @@ namespace QuickMedia { std::random_shuffle(body_items.begin(), body_items.end()); } + enum class HistoryType { + YOUTUBE, + MANGA + }; + + class HistoryPage : public Page { + public: + HistoryPage(Program *program, Page *search_page, SearchBar *search_bar, HistoryType history_type) : + Page(program), search_page(search_page), search_bar(search_bar), history_type(history_type) {} + const char* get_title() const override { return "History"; } + PluginResult submit(const std::string &title, const std::string &url, std::vector &result_tabs) override { + return search_page->submit(title, url, result_tabs); + } + void on_navigate_to_page(Body *body) override { + std::string selected_item_url = body->get_selected() ? body->get_selected()->url : ""; + body->clear_items(); + switch(history_type) { + case HistoryType::YOUTUBE: + program->youtube_get_watch_history(body->items); + break; + case HistoryType::MANGA: + program->manga_get_watch_history(program->get_plugin_name(), body->items); + break; + } + body->filter_search_fuzzy(search_bar->get_text()); + int item_to_revert_selection_to = get_body_item_by_url(body, selected_item_url); + if(item_to_revert_selection_to != -1) + body->set_selected_item(item_to_revert_selection_to, false); + } + private: + Page *search_page; + SearchBar *search_bar; + HistoryType history_type; + }; + + class RecommendedPage : public Page { + public: + RecommendedPage(Program *program, Page *search_page, SearchBar *search_bar, const char *plugin_name) : Page(program), search_page(search_page), search_bar(search_bar), plugin_name(plugin_name) {} + const char* get_title() const override { return "Recommended"; } + PluginResult submit(const std::string &title, const std::string &url, std::vector &result_tabs) override { + return search_page->submit(title, url, result_tabs); + } + void on_navigate_to_page(Body *body) override { + std::string selected_item_url = body->get_selected() ? body->get_selected()->url : ""; + body->clear_items(); + fill_recommended_items_from_json(plugin_name, program->load_recommended_json(), body->items); + body->filter_search_fuzzy(search_bar->get_text()); + int item_to_revert_selection_to = get_body_item_by_url(body, selected_item_url); + if(item_to_revert_selection_to != -1) + body->set_selected_item(item_to_revert_selection_to, false); + } + private: + Page *search_page; + SearchBar *search_bar; + const char *plugin_name; + }; + Program::Program() : disp(nullptr), window_size(1280, 720), @@ -911,14 +922,13 @@ namespace QuickMedia { tabs.push_back(Tab{std::move(search_body), std::make_unique(this), create_search_bar("Search...", 350)}); 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::YOUTUBE); - tabs.push_back(Tab{std::move(history_body), std::move(history_page), std::move(search_bar)}); - - auto recommended_body = create_body(); - fill_recommended_items_from_json(plugin_name, load_recommended_json(), recommended_body->items); - tabs.push_back(Tab{std::move(recommended_body), std::make_unique(this, tabs.front().page.get()), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); + auto history_search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER); + auto history_page = std::make_unique(this, tabs.front().page.get(), history_search_bar.get(), HistoryType::YOUTUBE); + tabs.push_back(Tab{std::move(history_body), std::move(history_page), std::move(history_search_bar)}); + auto recommended_search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER); + auto recommended_page = std::make_unique(this, tabs.front().page.get(), recommended_search_bar.get(), plugin_name); + tabs.push_back(Tab{create_body(), std::move(recommended_page), std::move(recommended_search_bar)}); tabs.push_back(Tab{create_body(), std::make_unique(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); } else if(strcmp(plugin_name, "pornhub") == 0) { auto search_body = create_body(); @@ -3917,8 +3927,10 @@ namespace QuickMedia { process_pinned_events(std::move(pinned_events)); tabs[PINNED_TAB_INDEX].body->select_last_item(); - room_name_text.setString(current_room->get_name()); - room_topic_text.setString(current_room->get_topic()); + std::string room_name = current_room->get_name(); + std::string room_topic = current_room->get_topic(); + room_name_text.setString(sf::String::fromUtf8(room_name.begin(), room_name.end())); + room_topic_text.setString(sf::String::fromUtf8(room_topic.begin(), room_topic.end())); room_avatar_thumbnail_data = std::make_shared(); read_marker_timeout_ms = 0; diff --git a/src/plugins/Pleroma.cpp b/src/plugins/Pleroma.cpp index 20d71c7..f0bb808 100644 --- a/src/plugins/Pleroma.cpp +++ b/src/plugins/Pleroma.cpp @@ -61,10 +61,7 @@ namespace QuickMedia { std::string content(content_json.GetString(), content_json.GetStringLength()); HtmlParseUserdata parse_userdata; - HtmlParser html_parser; - html_parser_init(&html_parser, content.data(), content.size(), html_parse_callback, &parse_userdata); - html_parser_parse(&html_parser); - html_parser_deinit(&html_parser); + html_parser_parse(content.data(), content.size(), html_parse_callback, &parse_userdata); while(!parse_userdata.result.empty() && parse_userdata.result.back() == '\n') parse_userdata.result.pop_back(); diff --git a/src/plugins/Pornhub.cpp b/src/plugins/Pornhub.cpp index 4d30001..1aa0851 100644 --- a/src/plugins/Pornhub.cpp +++ b/src/plugins/Pornhub.cpp @@ -59,14 +59,11 @@ namespace QuickMedia { } } - static HtmlElement* html_parse(char *source, size_t size) { + static HtmlElement* html_parse(const char *source, size_t size) { HtmlElement *html_element_root = new HtmlElement(); HtmlParseUserdata parse_userdata; parse_userdata.current_html_element = html_element_root; - HtmlParser html_parser; - html_parser_init(&html_parser, source, size, html_page_callback, &parse_userdata); - html_parser_parse(&html_parser); - html_parser_deinit(&html_parser); + html_parser_parse(source, size, html_page_callback, &parse_userdata); return html_element_root; } diff --git a/src/plugins/Spankbang.cpp b/src/plugins/Spankbang.cpp index cc35d39..ac0e371 100644 --- a/src/plugins/Spankbang.cpp +++ b/src/plugins/Spankbang.cpp @@ -21,10 +21,6 @@ namespace { } namespace QuickMedia { - static bool begins_with(const char *str, const char *begin_with) { - return strncmp(str, begin_with, strlen(begin_with)) == 0; - } - static void html_cleanup(HtmlElement *html_element_root) { for(HtmlElement *child_html_element : html_element_root->children) { html_cleanup(child_html_element); @@ -59,14 +55,11 @@ namespace QuickMedia { } } - static HtmlElement* html_parse(char *source, size_t size) { + static HtmlElement* html_parse(const char *source, size_t size) { HtmlElement *html_element_root = new HtmlElement(); HtmlParseUserdata parse_userdata; parse_userdata.current_html_element = html_element_root; - HtmlParser html_parser; - html_parser_init(&html_parser, source, size, html_page_callback, &parse_userdata); - html_parser_parse(&html_parser); - html_parser_deinit(&html_parser); + html_parser_parse(source, size, html_page_callback, &parse_userdata); return html_element_root; } diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp index 4c4372e..d03105c 100644 --- a/src/plugins/Youtube.cpp +++ b/src/plugins/Youtube.cpp @@ -1284,8 +1284,7 @@ namespace QuickMedia { std::vector subscription_data_list; - HtmlParser html_parser; - html_parser_init(&html_parser, website_data.data(), website_data.size(), [](HtmlParser *html_parser, HtmlParseType parse_type, void *userdata) { + html_parser_parse(website_data.data(), website_data.size(), [](HtmlParser *html_parser, HtmlParseType parse_type, void *userdata) { std::vector &subscription_data_list = *(std::vector*)userdata; if(parse_type == HTML_PARSE_TAG_START && string_view_equals(&html_parser->tag_name, "entry")) { @@ -1328,8 +1327,6 @@ namespace QuickMedia { subscription_data_list.back().subscription_entry.published = timegm(&time); } }, &subscription_data_list); - html_parser_parse(&html_parser); - html_parser_deinit(&html_parser); std::vector results; for(SubscriptionData &subscription_data : subscription_data_list) { -- cgit v1.2.3