From e3a151d5d2a71126c275567862a0cd2d471b42bc Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 4 Sep 2022 22:35:17 +0200 Subject: Dramacool: watch progress --- src/plugins/utils/EpisodeNameParser.cpp | 112 ++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/plugins/utils/EpisodeNameParser.cpp (limited to 'src/plugins/utils/EpisodeNameParser.cpp') diff --git a/src/plugins/utils/EpisodeNameParser.cpp b/src/plugins/utils/EpisodeNameParser.cpp new file mode 100644 index 0000000..de2b8ac --- /dev/null +++ b/src/plugins/utils/EpisodeNameParser.cpp @@ -0,0 +1,112 @@ +#include "../../../plugins/utils/EpisodeNameParser.hpp" + +namespace QuickMedia { + static bool has_season_in_name(std::string_view episode_name) { + size_t sep_count = 0; + size_t index = 0; + while(true) { + size_t next_index = episode_name.find(" - ", index); + if(next_index == std::string_view::npos) + break; + + index = next_index + 3; + ++sep_count; + } + return sep_count >= 2; + } + + static bool is_whitespace(char c) { + return c == ' ' || c == '\n' || c == '\t' || c == '\v'; + } + + static std::string_view strip_left(std::string_view str) { + size_t i = 0; + for(; i < str.size(); ++i) { + if(!is_whitespace(str[i])) + break; + } + return str.substr(i); + } + + static std::string_view strip_right(std::string_view str) { + long i = (long)str.size() - 1; + for(; i >= 0; --i) { + if(!is_whitespace(str[i])) + break; + } + return str.substr(0, i + 1); + } + + static std::string_view episode_name_extract_group(std::string_view &episode_name) { + episode_name = strip_left(episode_name); + if(episode_name[0] == '[') { + size_t group_end_index = episode_name.find(']', 1); + if(group_end_index == std::string_view::npos) + return {}; + + std::string_view group = episode_name.substr(1, group_end_index - 1); + episode_name.remove_prefix(group_end_index + 1); + return group; + } + return {}; + } + + static std::string_view episode_name_extract_anime(std::string_view &episode_name) { + episode_name = strip_left(episode_name); + size_t episode_or_season_sep_index = episode_name.find(" - "); + if(episode_or_season_sep_index == std::string_view::npos) + episode_or_season_sep_index = episode_name.size(); + + std::string_view anime = episode_name.substr(0, episode_or_season_sep_index); + anime = strip_right(anime); + if(episode_or_season_sep_index + 3 > episode_name.size()) + episode_name = {}; + else + episode_name.remove_prefix(episode_or_season_sep_index + 3); + + return anime; + } + + static std::string_view episode_name_extract_season(std::string_view &episode_name) { + return episode_name_extract_anime(episode_name); + } + + static bool is_num_real_char(char c) { + return (c >= '0' && c <= '9') || c == '.'; + } + + static std::string_view episode_name_extract_episode(std::string_view &episode_name) { + episode_name = strip_left(episode_name); + size_t i = 0; + for(; i < episode_name.size(); ++i) { + if(!is_num_real_char(episode_name[i])) + break; + } + + if(i == 0) + return {}; + + std::string_view episode = episode_name.substr(0, i); + episode_name.remove_prefix(i + 1); + return episode; + } + + std::optional episode_name_extract_parts(std::string_view episode_name) { + EpisodeNameParts name_parts; + const bool has_season = has_season_in_name(episode_name); + + name_parts.group = episode_name_extract_group(episode_name); + name_parts.anime = episode_name_extract_anime(episode_name); + if(name_parts.anime.empty()) + return std::nullopt; + + if(has_season) + name_parts.season = episode_name_extract_season(episode_name); + + name_parts.episode = episode_name_extract_episode(episode_name); + if(name_parts.episode.empty()) + return std::nullopt; + + return name_parts; + } +} \ No newline at end of file -- cgit v1.2.3