aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/utils')
-rw-r--r--src/plugins/utils/EpisodeNameParser.cpp65
1 files changed, 54 insertions, 11 deletions
diff --git a/src/plugins/utils/EpisodeNameParser.cpp b/src/plugins/utils/EpisodeNameParser.cpp
index e314953..8610ab0 100644
--- a/src/plugins/utils/EpisodeNameParser.cpp
+++ b/src/plugins/utils/EpisodeNameParser.cpp
@@ -1,6 +1,39 @@
#include "../../../plugins/utils/EpisodeNameParser.hpp"
namespace QuickMedia {
+ static bool is_num(char c) {
+ return c >= '0' && c <= '9';
+ }
+
+ static bool char_to_num(char c) {
+ return c - '0';
+ }
+
+ // Finds and parses SXXEXX where X is a number, returns the index to after the pattern or std::string_view::npos
+ static size_t parse_season_episode_pattern(std::string_view episode_name, int *season, int *episode) {
+ *season = 0;
+ *episode = 0;
+
+ size_t index = 0;
+ while(true) {
+ index = episode_name.find('S', index);
+ if(index == std::string_view::npos)
+ return std::string_view::npos;
+
+ if(index + 6 >= episode_name.size())
+ return std::string_view::npos;
+
+ if(is_num(episode_name[index + 1]) && is_num(episode_name[index + 2]) && episode_name[index + 3] == 'E'
+ && is_num(episode_name[index + 4]) && is_num(episode_name[index + 5]))
+ {
+ *season = char_to_num(episode_name[index + 1]) * 10 + char_to_num(episode_name[index + 2]);
+ *episode = char_to_num(episode_name[index + 4]) * 10 + char_to_num(episode_name[index + 5]);
+ return index + 6;
+ }
+ ++index;
+ }
+ }
+
static bool has_season_in_name(std::string_view episode_name) {
size_t sep_count = 0;
size_t index = 0;
@@ -96,20 +129,30 @@ namespace QuickMedia {
}
std::optional<EpisodeNameParts> episode_name_extract_parts(std::string_view episode_name) {
+ const std::string_view full_episode_name = episode_name;
EpisodeNameParts name_parts;
- const bool has_season = has_season_in_name(episode_name);
+
+ int season = 0;
+ int episode = 0;
+ size_t after_season_episode_pattern = parse_season_episode_pattern(episode_name, &season, &episode);
+ const bool has_season = after_season_episode_pattern != std::string_view::npos || 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;
+ if(after_season_episode_pattern == std::string_view::npos) {
+ 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;
+ } else {
+ name_parts.season = full_episode_name.substr(after_season_episode_pattern - 5, 2);
+ name_parts.episode = full_episode_name.substr(after_season_episode_pattern - 2, 2);
+ }
if(episode_name.find("480p") != std::string_view::npos)
name_parts.resolution = "480p";
@@ -118,13 +161,13 @@ namespace QuickMedia {
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";
+ name_parts.resolution = "4k";
else if(episode_name.find("1280x720") != std::string_view::npos)
- name_parts.resolution = "1280x720";
+ name_parts.resolution = "720p";
else if(episode_name.find("1920x1080") != std::string_view::npos)
- name_parts.resolution = "1920x1080";
+ name_parts.resolution = "1080p";
else if(episode_name.find("3840x2160") != std::string_view::npos)
- name_parts.resolution = "3840x2160";
+ name_parts.resolution = "4k";
if(ends_with(episode_name, ".mkv"))
name_parts.file_ext = ".mkv";