Mercurial > minori
comparison src/core/anime_db.cc @ 174:f88eda79c60a
anime/db: add some more json functionality, still doesn't compile :/
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 29 Nov 2023 13:53:56 -0500 |
parents | de0a8d2f28b3 |
children | 9b10175be389 |
comparison
equal
deleted
inserted
replaced
173:de0a8d2f28b3 | 174:f88eda79c60a |
---|---|
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" | 4 #include "core/json.h" |
5 | 5 #include "core/filesystem.h" |
6 #include <QDebug> | 6 |
7 #include "gui/translate/anime.h" | |
8 #include "gui/translate/anilist.h" | |
9 | |
10 #include <fstream> | |
7 | 11 |
8 namespace Anime { | 12 namespace Anime { |
9 | 13 |
10 int Database::GetTotalAnimeAmount() { | 14 int Database::GetTotalAnimeAmount() { |
11 int total = 0; | 15 int total = 0; |
156 | 160 |
157 json = { | 161 json = { |
158 {"status", Translate::ToString(anime.GetUserStatus())}, | 162 {"status", Translate::ToString(anime.GetUserStatus())}, |
159 {"progress", anime.GetUserProgress()}, | 163 {"progress", anime.GetUserProgress()}, |
160 {"score", anime.GetUserScore()}, | 164 {"score", anime.GetUserScore()}, |
161 //{"started", anime.GetUserDateStarted()}, | 165 {"started", anime.GetUserDateStarted().GetAsAniListJson()}, |
162 //{"completed", anime.GetUserDateCompleted()}, | 166 {"completed", anime.GetUserDateCompleted().GetAsAniListJson()}, |
163 {"private", anime.GetUserIsPrivate()}, | 167 {"private", anime.GetUserIsPrivate()}, |
164 {"rewatched_times", anime.GetUserRewatchedTimes()}, | 168 {"rewatched_times", anime.GetUserRewatchedTimes()}, |
165 {"rewatching", anime.GetUserIsRewatching()}, | 169 {"rewatching", anime.GetUserIsRewatching()}, |
166 {"updated", anime.GetUserTimeUpdated()}, | 170 {"updated", anime.GetUserTimeUpdated()}, |
167 {"notes", anime.GetUserNotes()} | 171 {"notes", anime.GetUserNotes()} |
168 }; | 172 }; |
173 | |
174 return true; | |
169 } | 175 } |
170 | 176 |
171 static bool GetAnimeAsJSON(const Anime& anime, nlohmann::json& json) { | 177 static bool GetAnimeAsJSON(const Anime& anime, nlohmann::json& json) { |
172 json = { | 178 json = { |
173 {"id", anime.GetId()}, | 179 {"id", anime.GetId()}, |
176 {"romaji", anime.GetRomajiTitle()}, | 182 {"romaji", anime.GetRomajiTitle()}, |
177 {"english", anime.GetEnglishTitle()} | 183 {"english", anime.GetEnglishTitle()} |
178 }}, | 184 }}, |
179 {"synonyms", anime.GetTitleSynonyms()}, | 185 {"synonyms", anime.GetTitleSynonyms()}, |
180 {"episodes", anime.GetEpisodes()}, | 186 {"episodes", anime.GetEpisodes()}, |
181 {"airing_status", anime.GetAiringStatus()}, | 187 {"airing_status", Translate::ToString(anime.GetAiringStatus())}, |
182 {"air_date", anime.GetAirDate()}, | 188 {"air_date", anime.GetAirDate().GetAsAniListJson()}, |
183 {"genres", anime.GetGenres()}, | 189 {"genres", anime.GetGenres()}, |
184 {"producers", anime.GetProducers()}, | 190 {"producers", anime.GetProducers()}, |
185 {"format", anime.GetFormat()}, | 191 {"format", Translate::ToString(anime.GetFormat())}, |
186 {"season", anime.GetSeason()}, | 192 {"season", Translate::ToString(anime.GetSeason())}, |
187 {"audience_score", anime.GetAudienceScore()}, | 193 {"audience_score", anime.GetAudienceScore()}, |
188 {"synopsis", anime.GetSynopsis()}, | 194 {"synopsis", anime.GetSynopsis()}, |
189 {"duration", anime.GetDuration()}, | 195 {"duration", anime.GetDuration()}, |
190 {"poster_url", anime.GetPosterUrl()}, | 196 {"poster_url", anime.GetPosterUrl()} |
191 {"service_url", anime.GetServiceUrl()} | |
192 }; | 197 }; |
193 | 198 |
194 nlohmann::json user; | 199 nlohmann::json user; |
195 if (GetListDataAsJSON(anime, user)) | 200 if (GetListDataAsJSON(anime, user)) |
196 json.push_back({"list_data", user}); | 201 json.push_back({"list_data", user}); |
198 return true; | 203 return true; |
199 } | 204 } |
200 | 205 |
201 bool Database::GetDatabaseAsJSON(nlohmann::json& json) { | 206 bool Database::GetDatabaseAsJSON(nlohmann::json& json) { |
202 for (const auto& [id, anime] : items) { | 207 for (const auto& [id, anime] : items) { |
203 nlohmann::json anime_json; | 208 nlohmann::json anime_json = {}; |
204 GetAnimeAsJSON(anime, anime_json); | 209 GetAnimeAsJSON(anime, anime_json); |
205 json.push_back(anime_json); | 210 json.push_back(anime_json); |
206 } | 211 } |
212 | |
213 return true; | |
214 } | |
215 | |
216 bool Database::SaveDatabaseToDisk() { | |
217 std::filesystem::path db_path = Filesystem::GetAnimeDBPath(); | |
218 Filesystem::CreateDirectories(db_path); | |
219 | |
220 std::ofstream db_file(db_path); | |
221 if (!db_file) | |
222 return false; | |
223 | |
224 nlohmann::json json = {}; | |
225 if (!GetDatabaseAsJSON(json)) | |
226 return false; | |
227 | |
228 db_file << std::setw(4) << json << std::endl; | |
229 return true; | |
230 } | |
231 | |
232 static bool ParseAnimeUserInfoJSON(const nlohmann::json& json, Anime& anime) { | |
233 if (!anime.IsInUserList()) | |
234 anime.AddToUserList(); | |
235 | |
236 anime.SetUserStatus(Translate::ToListStatus(JSON::GetString<std::string>(json, "/status"_json_pointer, ""))); | |
237 anime.SetUserStatus(JSON::GetNumber(json, "/progress"_json_pointer, 0)); | |
238 anime.SetUserScore(JSON::GetNumber(json, "/score"_json_pointer, 0)); | |
239 anime.SetUserDateStarted(Date(JSON::GetValue(json, "/started"_json_pointer))); | |
240 anime.SetUserDateStarted(Date(JSON::GetValue(json, "/completed"_json_pointer))); | |
241 anime.SetUserIsPrivate(JSON::GetBoolean(json, "/private"_json_pointer, false)); | |
242 anime.SetUserRewatchedTimes(JSON::GetNumber(json, "/rewatched_times"_json_pointer, "")); | |
243 anime.SetUserIsRewatching(JSON::GetBoolean(json, "/rewatching"_json_pointer, false)); | |
244 anime.SetUserTimeUpdated(JSON::GetNumber(json, "/updated"_json_pointer, 0)); | |
245 anime.SetUserNotes(JSON::GetString<std::string>(json, "/notes"_json_pointer, "")); | |
246 | |
247 return true; | |
248 } | |
249 | |
250 bool Database::ParseAnimeInfoJSON(const nlohmann::json& json) { | |
251 int id = JSON::GetNumber(json, "/id"_json_pointer, 0); | |
252 if (!id) | |
253 return false; | |
254 | |
255 Anime& anime = items[id]; | |
256 | |
257 anime.SetId(id); | |
258 anime.SetNativeTitle(JSON::GetString<std::string>(json, "/title/native"_json_pointer, "")); | |
259 anime.SetRomajiTitle(JSON::GetString<std::string>(json, "/title/romaji"_json_pointer, "")); | |
260 anime.SetEnglishTitle(JSON::GetString<std::string>(json, "/title/english"_json_pointer, "")); | |
261 anime.SetTitleSynonyms(JSON::GetArray<std::vector<std::string>>(json, "/synonyms"_json_pointer, {})); | |
262 anime.SetEpisodes(JSON::GetNumber(json, "/episodes"_json_pointer, 0)); | |
263 anime.SetAiringStatus(Translate::AniList::ToSeriesStatus(JSON::GetString<std::string>(json, "/airing_status"_json_pointer, ""))); | |
264 anime.SetAirDate(Date(JSON::GetValue(json, "/air_date"_json_pointer))); | |
265 anime.SetGenres(JSON::GetArray<std::vector<std::string>>(json, "/genres"_json_pointer, {})); | |
266 anime.SetProducers(JSON::GetArray<std::vector<std::string>>(json, "/producers"_json_pointer, {})); | |
267 anime.SetFormat(Translate::AniList::ToSeriesFormat(JSON::GetString<std::string>(json, "/format"_json_pointer, ""))); | |
268 anime.SetSeason(Translate::AniList::ToSeriesSeason(JSON::GetString<std::string>(json, "/season"_json_pointer, ""))); | |
269 anime.SetAudienceScore(JSON::GetNumber(json, "/audience_score"_json_pointer, 0)); | |
270 anime.SetSynopsis(JSON::GetString<std::string>(json, "/synopsis"_json_pointer, "")); | |
271 anime.SetDuration(JSON::GetNumber(json, "/duration"_json_pointer, 0)); | |
272 anime.SetPosterUrl(JSON::GetString<std::string>(json, "/poster_url"_json_pointer, "")); | |
273 | |
274 if (json.contains("/list_data") && json.at("/list_data").is_dictionary()) | |
275 ParseAnimeUserInfoJSON(json, anime); | |
276 | |
277 return true; | |
278 } | |
279 | |
280 bool Database::ParseDatabaseJSON(const nlohmann::json& json) { | |
281 for (const auto& anime_json : json) | |
282 ParseAnimeInfoJSON(anime_json); | |
283 | |
284 return true; | |
285 } | |
286 | |
287 bool Database::LoadDatabaseFromFile() { | |
288 std::filesystem::path db_path = Filesystem::GetAnimeDBPath(); | |
289 Filesystem::CreateDirectories(db_path); | |
290 | |
291 std::ifstream db_file(db_path); | |
292 if (!db_file) | |
293 return false; | |
294 | |
295 /* When parsing, do NOT throw exceptions */ | |
296 nlohmann::json json = json.parse(db_file, nullptr, false); | |
297 if (json.is_discarded()) | |
298 return false; /* Give up */ | |
299 | |
300 if (!ParseDatabaseJSON(json)) /* How */ | |
301 return false; | |
302 | |
207 return true; | 303 return true; |
208 } | 304 } |
209 | 305 |
210 Database db; | 306 Database db; |
211 | 307 |