From d203aba86d89c8dd6184146454396e48d39a8fb5 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 17 Jan 2023 19:05:15 +0100 Subject: NyaaSi: add ctrl+t to track anime with automedia --- src/plugins/NyaaSi.cpp | 83 ++++++++++++++++++++++++++++++++- src/plugins/utils/EpisodeNameParser.cpp | 19 +++++++- 2 files changed, 98 insertions(+), 4 deletions(-) (limited to 'src/plugins') 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 namespace QuickMedia { + static std::string combine_strings(const std::initializer_list 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 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("set_items(std::move(result_items)); - result_tabs.push_back(Tab{std::move(body), std::make_unique(program), nullptr}); + result_tabs.push_back(Tab{std::move(body), std::make_unique(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 -- cgit v1.2.3