Mercurial > minori
comparison src/core/anime_db.cc @ 83:d02fdf1d6708
*: huuuge update
1. make the now playing page function correctly
2. de-constructorfy many of our custom widgets,
allowing them to be changed on-the-fly from
the Now Playing page
3. ... :)
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Tue, 24 Oct 2023 22:01:02 -0400 |
parents | 9b2b41f83a5e |
children | de0a8d2f28b3 |
comparison
equal
deleted
inserted
replaced
82:8b65c417c225 | 83:d02fdf1d6708 |
---|---|
60 total += a.second.GetDuration() * (a.second.GetEpisodes() - a.second.GetUserProgress()); | 60 total += a.second.GetDuration() * (a.second.GetEpisodes() - a.second.GetUserProgress()); |
61 } | 61 } |
62 return total; | 62 return total; |
63 } | 63 } |
64 | 64 |
65 /* I'm sure many will appreciate this being called an | 65 /* In Taiga this is called a mean, but "average" is |
66 "average" instead of a "mean" */ | 66 what's primarily used in conversation, at least |
67 in the U.S. */ | |
67 double Database::GetAverageScore() { | 68 double Database::GetAverageScore() { |
68 double avg = 0; | 69 double avg = 0; |
69 int amt = 0; | 70 int amt = 0; |
70 for (const auto& a : items) { | 71 for (const auto& a : items) { |
71 if (a.second.IsInUserList() && a.second.GetUserScore()) { | 72 if (a.second.IsInUserList() && a.second.GetUserScore()) { |
86 } | 87 } |
87 } | 88 } |
88 return (amt > 0) ? std::sqrt(squares_sum / amt) : 0; | 89 return (amt > 0) ? std::sqrt(squares_sum / amt) : 0; |
89 } | 90 } |
90 | 91 |
91 int Database::GetAnimeFromTitle(std::string title) { | 92 template <typename T, typename U> |
93 static T get_lowest_in_map(const std::unordered_map<T, U>& map) { | |
94 if (map.size() <= 0) | |
95 return 0; | |
96 T id; | |
97 U ret = std::numeric_limits<U>::max(); | |
98 for (const auto& t : map) { | |
99 if (t.second < ret) { | |
100 ret = t.second; | |
101 id = t.first; | |
102 } | |
103 } | |
104 return id; | |
105 } | |
106 | |
107 /* This is really fugly but WHO CARES :P | |
108 | |
109 This sort of ""advanced"" algorithm is only in effect because | |
110 there are some special cases, e.g. Another and Re:ZERO, where | |
111 we get the wrong match, so we have to create Advanced Techniques | |
112 to solve this | |
113 | |
114 This algorithm: | |
115 1. searches each anime item for a match to the preferred title | |
116 AND all synonyms and marks those matches with | |
117 `synonym.length() - (synonym.find(needle) + needle.length());` | |
118 which, on a title that exactly matches, will be 0 | |
119 2. returns the id of the match that is the lowest, which will most | |
120 definitely match anything that exactly matches the title of the | |
121 filename */ | |
122 int Database::GetAnimeFromTitle(const std::string& title) { | |
92 if (title.empty()) | 123 if (title.empty()) |
93 return 0; | 124 return 0; |
125 std::unordered_map<int, long long> map; | |
94 for (const auto& a : items) { | 126 for (const auto& a : items) { |
95 if (a.second.GetUserPreferredTitle().find(title) != std::string::npos) | 127 long long ret = a.second.GetUserPreferredTitle().find(title); |
96 return a.second.GetId(); | 128 if (ret != static_cast<long long>(std::string::npos)) { |
97 for (const auto& t : a.second.GetTitleSynonyms()) { | 129 map[a.second.GetId()] = a.second.GetUserPreferredTitle().length() - (ret + title.length()); |
98 if (t.find(title) != std::string::npos) { | 130 continue; |
99 return a.second.GetId(); | 131 } |
132 for (const auto& synonym : a.second.GetTitleSynonyms()) { | |
133 ret = synonym.find(title); | |
134 if (ret != static_cast<long long>(std::string::npos)) { | |
135 map[a.second.GetId()] = synonym.length() - (ret + title.length()); | |
136 continue; | |
100 } | 137 } |
101 } | 138 } |
102 } | 139 } |
103 return 0; | 140 return get_lowest_in_map(map); |
104 } | 141 } |
105 | 142 |
106 Database db; | 143 Database db; |
107 | 144 |
108 } // namespace Anime | 145 } // namespace Anime |