#pragma once #include "Page.hpp" #include namespace QuickMedia { struct MediaSearchQuery { const char *search_template = nullptr; int page_start = 0; }; // If |url_contains| is null, then any matching query is added. If |title_field| is "text", then the inner text is used. // If |url_field| is null, then the current page is used instead. struct MediaTextQuery { const char *html_query = nullptr; const char *title_field = nullptr; const char *url_field = nullptr; const char *url_contains = nullptr; }; struct MediaThumbnailQuery { const char *html_query = nullptr; const char *field_name = nullptr; const char *field_contains = nullptr; }; struct MediaRelatedItem { std::string title; std::string url; std::string thumbnail_url; }; using MediaVideoUrlCustomHandler = std::function; using MediaRelatedCustomHandler = std::function(const std::string &html_source)>; class MediaGenericSearchPage : public Page { friend class MediaGenericVideoPage; public: MediaGenericSearchPage(Program *program, const char *website_url, mgl::vec2i thumbnail_max_size, bool cloudflare_bypass, std::vector extra_commands = {}); const char* get_title() const override { return "Search"; } bool search_is_filter() override { return false; } SearchResult search(const std::string &str, BodyItems &result_items) override; PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override; PluginResult submit(const SubmitArgs &args, std::vector &result_tabs) override; PluginResult get_related_media(const std::string &url, BodyItems &result_items); // Add a %s where the search query should be inserted into |search_template| and add a %p where the page number should be inserted, for example: // example.com/search?q=%s&page=%p // This is required. MediaGenericSearchPage& search_handler(const char *search_template, int page_start); // This is required. MediaGenericSearchPage& text_handler(std::vector queries); // This is optional. MediaGenericSearchPage& thumbnail_handler(std::vector queries); // This is optional. Youtube-dl (or yt-dlp) is used instead if this is not used. MediaGenericSearchPage& video_url_custom_handler(MediaVideoUrlCustomHandler handler); // This is optional. MediaGenericSearchPage& related_media_text_handler(std::vector queries); // This is optional. MediaGenericSearchPage& related_media_thumbnail_handler(std::vector queries); // This is optional. MediaGenericSearchPage& related_media_custom_handler(MediaRelatedCustomHandler handler); private: std::string website_url; mgl::vec2i thumbnail_max_size; MediaSearchQuery search_query; std::vector text_queries; std::vector thumbnail_queries; MediaVideoUrlCustomHandler video_custom_handler = nullptr; std::vector related_media_text_queries; std::vector related_media_thumbnail_queries; MediaRelatedCustomHandler related_custom_handler = nullptr; bool cloudflare_bypass = false; std::vector extra_commands; }; class MediaGenericRelatedPage : public RelatedVideosPage { public: MediaGenericRelatedPage(Program *program, MediaGenericSearchPage *search_page) : RelatedVideosPage(program), search_page(search_page) {} PluginResult submit(const SubmitArgs &args, std::vector &result_tabs) override; private: MediaGenericSearchPage *search_page; }; class MediaGenericVideoPage : public VideoPage { public: MediaGenericVideoPage(Program *program, MediaGenericSearchPage *search_page, const std::string &url) : VideoPage(program, url), search_page(search_page) {} const char* get_title() const override { return ""; } BodyItems get_related_media(const std::string &url) override; PluginResult get_related_pages(const BodyItems &related_videos, const std::string &channel_url, std::vector &result_tabs) override; std::string get_download_url(int max_height) override; std::string get_video_url(int max_height, bool &has_embedded_audio, std::string &ext) override; PluginResult load(std::string &title, std::string &channel_url, std::vector &chapters, std::string &err_str) override; private: MediaGenericSearchPage *search_page; std::string video_url; }; }