Mercurial > minori
annotate src/core/anime_db.cc @ 173:de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
| author | Paper <mrpapersonic@gmail.com> |
|---|---|
| date | Tue, 28 Nov 2023 13:53:54 -0500 |
| parents | d02fdf1d6708 |
| children | f88eda79c60a |
| rev | line source |
|---|---|
| 10 | 1 #include "core/anime_db.h" |
| 2 #include "core/anime.h" | |
| 64 | 3 #include "core/strings.h" |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
4 #include "core/json.h" |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
5 |
| 64 | 6 #include <QDebug> |
| 10 | 7 |
| 8 namespace Anime { | |
| 9 | |
| 10 int Database::GetTotalAnimeAmount() { | |
| 11 int total = 0; | |
| 11 | 12 for (const auto& a : items) { |
| 13 if (a.second.IsInUserList()) | |
| 10 | 14 total++; |
| 15 } | |
| 16 return total; | |
| 17 } | |
| 18 | |
| 19 int Database::GetListsAnimeAmount(ListStatus status) { | |
| 20 if (status == ListStatus::NOT_IN_LIST) | |
| 21 return 0; | |
| 22 int total = 0; | |
| 11 | 23 for (const auto& a : items) { |
| 24 if (a.second.IsInUserList() && a.second.GetUserStatus() == status) | |
| 10 | 25 total++; |
| 26 } | |
| 27 return total; | |
| 28 } | |
| 29 | |
| 30 int Database::GetTotalEpisodeAmount() { | |
| 31 int total = 0; | |
| 11 | 32 for (const auto& a : items) { |
| 33 if (a.second.IsInUserList()) { | |
| 34 total += a.second.GetUserRewatchedTimes() * a.second.GetEpisodes(); | |
| 35 total += a.second.GetUserProgress(); | |
| 10 | 36 } |
| 37 } | |
| 38 return total; | |
| 39 } | |
| 40 | |
| 41 /* Returns the total watched amount in minutes. */ | |
| 42 int Database::GetTotalWatchedAmount() { | |
| 43 int total = 0; | |
| 11 | 44 for (const auto& a : items) { |
| 45 if (a.second.IsInUserList()) { | |
| 46 total += a.second.GetDuration() * a.second.GetUserProgress(); | |
| 47 total += a.second.GetEpisodes() * a.second.GetDuration() * a.second.GetUserRewatchedTimes(); | |
| 10 | 48 } |
| 49 } | |
| 50 return total; | |
| 51 } | |
| 52 | |
| 53 /* Returns the total planned amount in minutes. | |
| 54 Note that we should probably limit progress to the | |
| 55 amount of episodes, as AniList will let you | |
| 56 set episode counts up to 32768. But that should | |
| 57 rather be handled elsewhere. */ | |
| 58 int Database::GetTotalPlannedAmount() { | |
| 59 int total = 0; | |
| 11 | 60 for (const auto& a : items) { |
| 61 if (a.second.IsInUserList()) | |
| 62 total += a.second.GetDuration() * (a.second.GetEpisodes() - a.second.GetUserProgress()); | |
| 10 | 63 } |
| 64 return total; | |
| 65 } | |
| 66 | |
| 83 | 67 /* In Taiga this is called a mean, but "average" is |
| 68 what's primarily used in conversation, at least | |
| 69 in the U.S. */ | |
| 10 | 70 double Database::GetAverageScore() { |
| 71 double avg = 0; | |
| 72 int amt = 0; | |
| 11 | 73 for (const auto& a : items) { |
| 74 if (a.second.IsInUserList() && a.second.GetUserScore()) { | |
| 75 avg += a.second.GetUserScore(); | |
| 10 | 76 amt++; |
| 77 } | |
| 78 } | |
| 79 return avg / amt; | |
| 80 } | |
| 81 | |
| 82 double Database::GetScoreDeviation() { | |
| 83 double squares_sum = 0, avg = GetAverageScore(); | |
| 84 int amt = 0; | |
| 11 | 85 for (const auto& a : items) { |
| 86 if (a.second.IsInUserList() && a.second.GetUserScore()) { | |
| 64 | 87 squares_sum += std::pow(static_cast<double>(a.second.GetUserScore()) - avg, 2); |
| 10 | 88 amt++; |
| 89 } | |
| 90 } | |
| 91 return (amt > 0) ? std::sqrt(squares_sum / amt) : 0; | |
| 92 } | |
| 93 | |
| 83 | 94 template <typename T, typename U> |
| 95 static T get_lowest_in_map(const std::unordered_map<T, U>& map) { | |
| 96 if (map.size() <= 0) | |
| 97 return 0; | |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
98 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
99 T id = 0; |
| 83 | 100 U ret = std::numeric_limits<U>::max(); |
| 101 for (const auto& t : map) { | |
| 102 if (t.second < ret) { | |
| 103 ret = t.second; | |
| 104 id = t.first; | |
| 105 } | |
| 106 } | |
| 107 return id; | |
| 108 } | |
| 109 | |
| 110 /* This is really fugly but WHO CARES :P | |
| 111 | |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
112 This fairly basic algorithm is only in effect because |
| 83 | 113 there are some special cases, e.g. Another and Re:ZERO, where |
| 114 we get the wrong match, so we have to create Advanced Techniques | |
| 115 to solve this | |
| 116 | |
| 117 This algorithm: | |
| 118 1. searches each anime item for a match to the preferred title | |
| 119 AND all synonyms and marks those matches with | |
| 120 `synonym.length() - (synonym.find(needle) + needle.length());` | |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
121 which should never be less than zero and will be zero if, and only if |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
122 the titles match exactly. |
| 83 | 123 2. returns the id of the match that is the lowest, which will most |
| 124 definitely match anything that exactly matches the title of the | |
| 125 filename */ | |
| 126 int Database::GetAnimeFromTitle(const std::string& title) { | |
| 64 | 127 if (title.empty()) |
| 128 return 0; | |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
129 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
130 std::unordered_map<int, size_t> map; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
131 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
132 auto process_title = [&map](const Anime& anime, const std::string& title, const std::string& needle) -> bool { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
133 size_t ret = title.find(needle); |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
134 if (ret == std::string::npos) |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
135 return false; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
136 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
137 map[anime.GetId()] = title.length() - (ret + needle.length()); |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
138 return true; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
139 }; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
140 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
141 for (const auto& [id, anime] : items) { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
142 if (process_title(anime, anime.GetUserPreferredTitle(), title)) |
| 83 | 143 continue; |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
144 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
145 for (const auto& synonym : anime.GetTitleSynonyms()) |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
146 if (process_title(anime, synonym, title)) |
| 83 | 147 continue; |
| 64 | 148 } |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
149 |
| 83 | 150 return get_lowest_in_map(map); |
| 64 | 151 } |
| 152 | |
|
173
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
153 static bool GetListDataAsJSON(const Anime& anime, nlohmann::json& json) { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
154 if (!anime.IsInUserList()) |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
155 return false; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
156 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
157 json = { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
158 {"status", Translate::ToString(anime.GetUserStatus())}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
159 {"progress", anime.GetUserProgress()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
160 {"score", anime.GetUserScore()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
161 //{"started", anime.GetUserDateStarted()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
162 //{"completed", anime.GetUserDateCompleted()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
163 {"private", anime.GetUserIsPrivate()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
164 {"rewatched_times", anime.GetUserRewatchedTimes()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
165 {"rewatching", anime.GetUserIsRewatching()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
166 {"updated", anime.GetUserTimeUpdated()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
167 {"notes", anime.GetUserNotes()} |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
168 }; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
169 } |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
170 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
171 static bool GetAnimeAsJSON(const Anime& anime, nlohmann::json& json) { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
172 json = { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
173 {"id", anime.GetId()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
174 {"title", { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
175 {"native", anime.GetNativeTitle()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
176 {"romaji", anime.GetRomajiTitle()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
177 {"english", anime.GetEnglishTitle()} |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
178 }}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
179 {"synonyms", anime.GetTitleSynonyms()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
180 {"episodes", anime.GetEpisodes()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
181 {"airing_status", anime.GetAiringStatus()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
182 {"air_date", anime.GetAirDate()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
183 {"genres", anime.GetGenres()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
184 {"producers", anime.GetProducers()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
185 {"format", anime.GetFormat()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
186 {"season", anime.GetSeason()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
187 {"audience_score", anime.GetAudienceScore()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
188 {"synopsis", anime.GetSynopsis()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
189 {"duration", anime.GetDuration()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
190 {"poster_url", anime.GetPosterUrl()}, |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
191 {"service_url", anime.GetServiceUrl()} |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
192 }; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
193 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
194 nlohmann::json user; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
195 if (GetListDataAsJSON(anime, user)) |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
196 json.push_back({"list_data", user}); |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
197 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
198 return true; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
199 } |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
200 |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
201 bool Database::GetDatabaseAsJSON(nlohmann::json& json) { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
202 for (const auto& [id, anime] : items) { |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
203 nlohmann::json anime_json; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
204 GetAnimeAsJSON(anime, anime_json); |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
205 json.push_back(anime_json); |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
206 } |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
207 return true; |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
208 } |
|
de0a8d2f28b3
WILL NOT COMPILE: sample export ability for anime db
Paper <mrpapersonic@gmail.com>
parents:
83
diff
changeset
|
209 |
| 11 | 210 Database db; |
| 211 | |
| 9 | 212 } // namespace Anime |
