diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/QuickMedia.cpp | 9 | ||||
-rw-r--r-- | src/plugins/NyaaSi.cpp | 83 | ||||
-rw-r--r-- | src/plugins/utils/EpisodeNameParser.cpp | 19 |
3 files changed, 103 insertions, 8 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index c2b2b95..447b863 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -699,6 +699,10 @@ namespace QuickMedia { XSetErrorHandler(x_error_handler); XSetIOErrorHandler(x_io_error_handler); + // Initialize config and theme early to prevent possible race condition on initialize + get_config(); + get_theme(); + mgl::vec2i monitor_size; mgl::vec2i focused_monitor_center = get_focused_monitor_center(disp, monitor_size); @@ -719,6 +723,7 @@ namespace QuickMedia { } window_create_params.hidden = no_dialog; window_create_params.parent_window = parent_window; + window_create_params.background_color = get_theme().background_color; if(!window.create("QuickMedia", std::move(window_create_params))) { show_notification("QuickMedia", "Failed to create opengl window", Urgency::CRITICAL); abort(); @@ -732,10 +737,6 @@ namespace QuickMedia { resources_root = program_path + "../../../"; } - // Initialize config and theme early to prevent possible race condition on initialize - get_config(); - get_theme(); - set_resource_loader_root_path(resources_root.c_str()); init_body_themes(); diff --git a/src/plugins/NyaaSi.cpp b/src/plugins/NyaaSi.cpp index cd80997..739032b 100644 --- a/src/plugins/NyaaSi.cpp +++ b/src/plugins/NyaaSi.cpp @@ -5,9 +5,80 @@ #include "../../include/StringUtils.hpp" #include "../../include/NetUtils.hpp" #include "../../include/Utils.hpp" +#include "../../plugins/utils/EpisodeNameParser.hpp" #include <quickmedia/HtmlSearch.h> namespace QuickMedia { + static std::string combine_strings(const std::initializer_list<std::string_view> items, char divider) { + std::string result; + for(const auto &item : items) { + if(item.empty()) + continue; + + if(!result.empty()) + result += divider; + + result += item; + } + return result; + } + + static TrackResult track(const std::string &str) { + std::optional<EpisodeNameParts> episode_parts = episode_name_extract_parts(str); + if(!episode_parts) { + show_notification("QuickMedia", "Failed to extract episode name from torrent name. Please add the rss manually with automedia", Urgency::CRITICAL); + return TrackResult::ERR; + } + + const std::string track_name = combine_strings({ episode_parts->group, episode_parts->anime, episode_parts->episode, episode_parts->season, episode_parts->resolution }, ' '); + + std::string url = "https://nyaa.si/?page=rss&q=" + url_param_encode(track_name) + "&c=0_0&f=0"; + if(!episode_parts->group.empty()) + url += "&u=" + url_param_decode(std::string(episode_parts->group)); + + std::string website_data; + if(download_to_string(url, website_data, {}, true) != DownloadResult::OK) { + show_notification("QuickMedia", "Invalid rss. Please add the rss manually with automedia", Urgency::CRITICAL); + return TrackResult::ERR; + } + struct HtmlFindUserdata { + const std::string &str; + bool found_title = false; + }; + HtmlFindUserdata userdata{ str, false }; + + QuickMediaHtmlSearch html_search; + int result = quickmedia_html_search_init(&html_search, website_data.c_str(), website_data.size()); + if(result != 0) + goto cleanup; + + result = quickmedia_html_find_nodes_xpath(&html_search, "//channel/item/title", + [](QuickMediaMatchNode *node, void *userdata) { + HtmlFindUserdata &userdata_typed = *(HtmlFindUserdata*)userdata; + QuickMediaStringView text = quickmedia_html_node_get_text(node); + if(text.data && text.size == userdata_typed.str.size() && memcmp(text.data, userdata_typed.str.data(), text.size) == 0) { + userdata_typed.found_title = true; + } + return 0; + }, &userdata); + + cleanup: + quickmedia_html_search_deinit(&html_search); + if(result != 0 || !userdata.found_title) { + show_notification("QuickMedia", "The item you tried to track was not found in the rss feed. Please add the rss manually with automedia", Urgency::CRITICAL); + return TrackResult::ERR; + } + + const char *args[] = { "automedia", "add", "rss", url.c_str(), "--start-after", str.c_str(), "--name", track_name.c_str(), nullptr }; + if(exec_program(args, nullptr, nullptr) == 0) { + show_notification("QuickMedia", "You are now tracking \"" + track_name + "\" after \"" + str + "\"", Urgency::LOW); + return TrackResult::OK; + } else { + show_notification("QuickMedia", "Failed to track media \"" + track_name + "\", episode: \"" + str + "\"", Urgency::CRITICAL); + return TrackResult::ERR; + } + } + // Return end of td tag, or std::string::npos static size_t find_td_get_value(const std::string &str, size_t start_index, size_t end_index, std::string &result) { size_t td_begin = str.find("<td", start_index); @@ -310,7 +381,7 @@ namespace QuickMedia { } NyaaSiSearchPage::NyaaSiSearchPage(Program *program, std::string category_name, std::string category_id, std::string domain) : - Page(program), category_name(std::move(category_name)), category_id(std::move(category_id)), domain(std::move(domain)) + Page(program), TrackablePage("", ""), category_name(std::move(category_name)), category_id(std::move(category_id)), domain(std::move(domain)) { set_sort_type(NyaaSiSortType::UPLOAD_DATE_DESC); } @@ -493,10 +564,14 @@ namespace QuickMedia { auto body = create_body(); body->set_items(std::move(result_items)); - result_tabs.push_back(Tab{std::move(body), std::make_unique<NyaaSiTorrentPage>(program), nullptr}); + result_tabs.push_back(Tab{std::move(body), std::make_unique<NyaaSiTorrentPage>(program, args.title), nullptr}); return PluginResult::OK; } + TrackResult NyaaSiSearchPage::track(const std::string &str) { + return QuickMedia::track(str); + } + void NyaaSiSearchPage::set_sort_type(NyaaSiSortType sort_type) { this->sort_type = sort_type; title = category_name + " | " + sort_type_names[(size_t)sort_type]; @@ -524,4 +599,8 @@ namespace QuickMedia { } return PluginResult::OK; } + + TrackResult NyaaSiTorrentPage::track(const std::string&) { + return QuickMedia::track(content_title); + } }
\ No newline at end of file diff --git a/src/plugins/utils/EpisodeNameParser.cpp b/src/plugins/utils/EpisodeNameParser.cpp index de2b8ac..a381cca 100644 --- a/src/plugins/utils/EpisodeNameParser.cpp +++ b/src/plugins/utils/EpisodeNameParser.cpp @@ -71,7 +71,7 @@ namespace QuickMedia { return episode_name_extract_anime(episode_name); } - static bool is_num_real_char(char c) { + static bool is_real_num(char c) { return (c >= '0' && c <= '9') || c == '.'; } @@ -79,7 +79,7 @@ namespace QuickMedia { episode_name = strip_left(episode_name); size_t i = 0; for(; i < episode_name.size(); ++i) { - if(!is_num_real_char(episode_name[i])) + if(!is_real_num(episode_name[i])) break; } @@ -107,6 +107,21 @@ namespace QuickMedia { if(name_parts.episode.empty()) return std::nullopt; + if(episode_name.find("480p") != std::string_view::npos) + name_parts.resolution = "480p"; + else if(episode_name.find("720p") != std::string_view::npos) + name_parts.resolution = "720p"; + else if(episode_name.find("1080p") != std::string_view::npos) + name_parts.resolution = "1080p"; + else if(episode_name.find("2160p") != std::string_view::npos) + name_parts.resolution = "2160p"; + else if(episode_name.find("1280x720") != std::string_view::npos) + name_parts.resolution = "1280x720"; + else if(episode_name.find("1920x1080") != std::string_view::npos) + name_parts.resolution = "1920x1080"; + else if(episode_name.find("3840x2160") != std::string_view::npos) + name_parts.resolution = "3840x2160"; + return name_parts; } }
\ No newline at end of file |