Mercurial > minori
comparison 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 |
comparison
equal
deleted
inserted
replaced
172:45a0967485f1 | 173:de0a8d2f28b3 |
---|---|
1 #include "core/anime_db.h" | 1 #include "core/anime_db.h" |
2 #include "core/anime.h" | 2 #include "core/anime.h" |
3 #include "core/strings.h" | 3 #include "core/strings.h" |
4 #include "core/json.h" | |
5 | |
4 #include <QDebug> | 6 #include <QDebug> |
5 | 7 |
6 namespace Anime { | 8 namespace Anime { |
7 | 9 |
8 int Database::GetTotalAnimeAmount() { | 10 int Database::GetTotalAnimeAmount() { |
91 | 93 |
92 template <typename T, typename U> | 94 template <typename T, typename U> |
93 static T get_lowest_in_map(const std::unordered_map<T, U>& map) { | 95 static T get_lowest_in_map(const std::unordered_map<T, U>& map) { |
94 if (map.size() <= 0) | 96 if (map.size() <= 0) |
95 return 0; | 97 return 0; |
96 T id; | 98 |
99 T id = 0; | |
97 U ret = std::numeric_limits<U>::max(); | 100 U ret = std::numeric_limits<U>::max(); |
98 for (const auto& t : map) { | 101 for (const auto& t : map) { |
99 if (t.second < ret) { | 102 if (t.second < ret) { |
100 ret = t.second; | 103 ret = t.second; |
101 id = t.first; | 104 id = t.first; |
104 return id; | 107 return id; |
105 } | 108 } |
106 | 109 |
107 /* This is really fugly but WHO CARES :P | 110 /* This is really fugly but WHO CARES :P |
108 | 111 |
109 This sort of ""advanced"" algorithm is only in effect because | 112 This fairly basic algorithm is only in effect because |
110 there are some special cases, e.g. Another and Re:ZERO, where | 113 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 | 114 we get the wrong match, so we have to create Advanced Techniques |
112 to solve this | 115 to solve this |
113 | 116 |
114 This algorithm: | 117 This algorithm: |
115 1. searches each anime item for a match to the preferred title | 118 1. searches each anime item for a match to the preferred title |
116 AND all synonyms and marks those matches with | 119 AND all synonyms and marks those matches with |
117 `synonym.length() - (synonym.find(needle) + needle.length());` | 120 `synonym.length() - (synonym.find(needle) + needle.length());` |
118 which, on a title that exactly matches, will be 0 | 121 which should never be less than zero and will be zero if, and only if |
122 the titles match exactly. | |
119 2. returns the id of the match that is the lowest, which will most | 123 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 | 124 definitely match anything that exactly matches the title of the |
121 filename */ | 125 filename */ |
122 int Database::GetAnimeFromTitle(const std::string& title) { | 126 int Database::GetAnimeFromTitle(const std::string& title) { |
123 if (title.empty()) | 127 if (title.empty()) |
124 return 0; | 128 return 0; |
125 std::unordered_map<int, long long> map; | 129 |
126 for (const auto& a : items) { | 130 std::unordered_map<int, size_t> map; |
127 long long ret = a.second.GetUserPreferredTitle().find(title); | 131 |
128 if (ret != static_cast<long long>(std::string::npos)) { | 132 auto process_title = [&map](const Anime& anime, const std::string& title, const std::string& needle) -> bool { |
129 map[a.second.GetId()] = a.second.GetUserPreferredTitle().length() - (ret + title.length()); | 133 size_t ret = title.find(needle); |
134 if (ret == std::string::npos) | |
135 return false; | |
136 | |
137 map[anime.GetId()] = title.length() - (ret + needle.length()); | |
138 return true; | |
139 }; | |
140 | |
141 for (const auto& [id, anime] : items) { | |
142 if (process_title(anime, anime.GetUserPreferredTitle(), title)) | |
130 continue; | 143 continue; |
131 } | 144 |
132 for (const auto& synonym : a.second.GetTitleSynonyms()) { | 145 for (const auto& synonym : anime.GetTitleSynonyms()) |
133 ret = synonym.find(title); | 146 if (process_title(anime, synonym, title)) |
134 if (ret != static_cast<long long>(std::string::npos)) { | |
135 map[a.second.GetId()] = synonym.length() - (ret + title.length()); | |
136 continue; | 147 continue; |
137 } | 148 } |
138 } | 149 |
139 } | |
140 return get_lowest_in_map(map); | 150 return get_lowest_in_map(map); |
141 } | 151 } |
142 | 152 |
153 static bool GetListDataAsJSON(const Anime& anime, nlohmann::json& json) { | |
154 if (!anime.IsInUserList()) | |
155 return false; | |
156 | |
157 json = { | |
158 {"status", Translate::ToString(anime.GetUserStatus())}, | |
159 {"progress", anime.GetUserProgress()}, | |
160 {"score", anime.GetUserScore()}, | |
161 //{"started", anime.GetUserDateStarted()}, | |
162 //{"completed", anime.GetUserDateCompleted()}, | |
163 {"private", anime.GetUserIsPrivate()}, | |
164 {"rewatched_times", anime.GetUserRewatchedTimes()}, | |
165 {"rewatching", anime.GetUserIsRewatching()}, | |
166 {"updated", anime.GetUserTimeUpdated()}, | |
167 {"notes", anime.GetUserNotes()} | |
168 }; | |
169 } | |
170 | |
171 static bool GetAnimeAsJSON(const Anime& anime, nlohmann::json& json) { | |
172 json = { | |
173 {"id", anime.GetId()}, | |
174 {"title", { | |
175 {"native", anime.GetNativeTitle()}, | |
176 {"romaji", anime.GetRomajiTitle()}, | |
177 {"english", anime.GetEnglishTitle()} | |
178 }}, | |
179 {"synonyms", anime.GetTitleSynonyms()}, | |
180 {"episodes", anime.GetEpisodes()}, | |
181 {"airing_status", anime.GetAiringStatus()}, | |
182 {"air_date", anime.GetAirDate()}, | |
183 {"genres", anime.GetGenres()}, | |
184 {"producers", anime.GetProducers()}, | |
185 {"format", anime.GetFormat()}, | |
186 {"season", anime.GetSeason()}, | |
187 {"audience_score", anime.GetAudienceScore()}, | |
188 {"synopsis", anime.GetSynopsis()}, | |
189 {"duration", anime.GetDuration()}, | |
190 {"poster_url", anime.GetPosterUrl()}, | |
191 {"service_url", anime.GetServiceUrl()} | |
192 }; | |
193 | |
194 nlohmann::json user; | |
195 if (GetListDataAsJSON(anime, user)) | |
196 json.push_back({"list_data", user}); | |
197 | |
198 return true; | |
199 } | |
200 | |
201 bool Database::GetDatabaseAsJSON(nlohmann::json& json) { | |
202 for (const auto& [id, anime] : items) { | |
203 nlohmann::json anime_json; | |
204 GetAnimeAsJSON(anime, anime_json); | |
205 json.push_back(anime_json); | |
206 } | |
207 return true; | |
208 } | |
209 | |
143 Database db; | 210 Database db; |
144 | 211 |
145 } // namespace Anime | 212 } // namespace Anime |