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 |
