diff 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
line wrap: on
line diff
--- a/src/core/anime_db.cc	Tue Nov 28 13:53:54 2023 -0500
+++ b/src/core/anime_db.cc	Wed Nov 29 13:53:56 2023 -0500
@@ -2,8 +2,12 @@
 #include "core/anime.h"
 #include "core/strings.h"
 #include "core/json.h"
+#include "core/filesystem.h"
 
-#include <QDebug>
+#include "gui/translate/anime.h"
+#include "gui/translate/anilist.h"
+
+#include <fstream>
 
 namespace Anime {
 
@@ -158,14 +162,16 @@
 		{"status", Translate::ToString(anime.GetUserStatus())},
 		{"progress", anime.GetUserProgress()},
 		{"score", anime.GetUserScore()},
-		//{"started", anime.GetUserDateStarted()},
-		//{"completed", anime.GetUserDateCompleted()},
+		{"started", anime.GetUserDateStarted().GetAsAniListJson()},
+		{"completed", anime.GetUserDateCompleted().GetAsAniListJson()},
 		{"private", anime.GetUserIsPrivate()},
 		{"rewatched_times", anime.GetUserRewatchedTimes()},
 		{"rewatching", anime.GetUserIsRewatching()},
 		{"updated", anime.GetUserTimeUpdated()},
 		{"notes", anime.GetUserNotes()}
 	};
+
+	return true;
 }
 
 static bool GetAnimeAsJSON(const Anime& anime, nlohmann::json& json) {
@@ -178,17 +184,16 @@
 		}},
 		{"synonyms", anime.GetTitleSynonyms()},
 		{"episodes", anime.GetEpisodes()},
-		{"airing_status", anime.GetAiringStatus()},
-		{"air_date", anime.GetAirDate()},
+		{"airing_status", Translate::ToString(anime.GetAiringStatus())},
+		{"air_date", anime.GetAirDate().GetAsAniListJson()},
 		{"genres", anime.GetGenres()},
 		{"producers", anime.GetProducers()},
-		{"format", anime.GetFormat()},
-		{"season", anime.GetSeason()},
+		{"format", Translate::ToString(anime.GetFormat())},
+		{"season", Translate::ToString(anime.GetSeason())},
 		{"audience_score", anime.GetAudienceScore()},
 		{"synopsis", anime.GetSynopsis()},
 		{"duration", anime.GetDuration()},
-		{"poster_url", anime.GetPosterUrl()},
-		{"service_url", anime.GetServiceUrl()}
+		{"poster_url", anime.GetPosterUrl()}
 	};
 
 	nlohmann::json user;
@@ -200,10 +205,101 @@
 
 bool Database::GetDatabaseAsJSON(nlohmann::json& json) {
 	for (const auto& [id, anime] : items) {
-		nlohmann::json anime_json;
+		nlohmann::json anime_json = {};
 		GetAnimeAsJSON(anime, anime_json);
 		json.push_back(anime_json);
 	}
+
+	return true;
+}
+
+bool Database::SaveDatabaseToDisk() {
+	std::filesystem::path db_path = Filesystem::GetAnimeDBPath();
+	Filesystem::CreateDirectories(db_path);
+
+	std::ofstream db_file(db_path);
+	if (!db_file)
+		return false;
+
+	nlohmann::json json = {};
+	if (!GetDatabaseAsJSON(json))
+		return false;
+
+	db_file << std::setw(4) << json << std::endl;
+	return true;
+}
+
+static bool ParseAnimeUserInfoJSON(const nlohmann::json& json, Anime& anime) {
+	if (!anime.IsInUserList())
+		anime.AddToUserList();
+
+	anime.SetUserStatus(Translate::ToListStatus(JSON::GetString<std::string>(json, "/status"_json_pointer, "")));
+	anime.SetUserStatus(JSON::GetNumber(json, "/progress"_json_pointer, 0));
+	anime.SetUserScore(JSON::GetNumber(json, "/score"_json_pointer, 0));
+	anime.SetUserDateStarted(Date(JSON::GetValue(json, "/started"_json_pointer)));
+	anime.SetUserDateStarted(Date(JSON::GetValue(json, "/completed"_json_pointer)));
+	anime.SetUserIsPrivate(JSON::GetBoolean(json, "/private"_json_pointer, false));
+	anime.SetUserRewatchedTimes(JSON::GetNumber(json, "/rewatched_times"_json_pointer, ""));
+	anime.SetUserIsRewatching(JSON::GetBoolean(json, "/rewatching"_json_pointer, false));
+	anime.SetUserTimeUpdated(JSON::GetNumber(json, "/updated"_json_pointer, 0));
+	anime.SetUserNotes(JSON::GetString<std::string>(json, "/notes"_json_pointer, ""));
+
+	return true;
+}
+
+bool Database::ParseAnimeInfoJSON(const nlohmann::json& json) {
+	int id = JSON::GetNumber(json, "/id"_json_pointer, 0);
+	if (!id)
+		return false;
+
+	Anime& anime = items[id];
+
+	anime.SetId(id);
+	anime.SetNativeTitle(JSON::GetString<std::string>(json, "/title/native"_json_pointer, ""));
+	anime.SetRomajiTitle(JSON::GetString<std::string>(json, "/title/romaji"_json_pointer, ""));
+	anime.SetEnglishTitle(JSON::GetString<std::string>(json, "/title/english"_json_pointer, ""));
+	anime.SetTitleSynonyms(JSON::GetArray<std::vector<std::string>>(json, "/synonyms"_json_pointer, {}));
+	anime.SetEpisodes(JSON::GetNumber(json, "/episodes"_json_pointer, 0));
+	anime.SetAiringStatus(Translate::AniList::ToSeriesStatus(JSON::GetString<std::string>(json, "/airing_status"_json_pointer, "")));
+	anime.SetAirDate(Date(JSON::GetValue(json, "/air_date"_json_pointer)));
+	anime.SetGenres(JSON::GetArray<std::vector<std::string>>(json, "/genres"_json_pointer, {}));
+	anime.SetProducers(JSON::GetArray<std::vector<std::string>>(json, "/producers"_json_pointer, {}));
+	anime.SetFormat(Translate::AniList::ToSeriesFormat(JSON::GetString<std::string>(json, "/format"_json_pointer, "")));
+	anime.SetSeason(Translate::AniList::ToSeriesSeason(JSON::GetString<std::string>(json, "/season"_json_pointer, "")));
+	anime.SetAudienceScore(JSON::GetNumber(json, "/audience_score"_json_pointer, 0));
+	anime.SetSynopsis(JSON::GetString<std::string>(json, "/synopsis"_json_pointer, ""));
+	anime.SetDuration(JSON::GetNumber(json, "/duration"_json_pointer, 0));
+	anime.SetPosterUrl(JSON::GetString<std::string>(json, "/poster_url"_json_pointer, ""));
+
+	if (json.contains("/list_data") && json.at("/list_data").is_dictionary())
+		ParseAnimeUserInfoJSON(json, anime);
+
+	return true;
+}
+
+bool Database::ParseDatabaseJSON(const nlohmann::json& json) {
+	for (const auto& anime_json : json)
+		ParseAnimeInfoJSON(anime_json);
+
+	return true;
+}
+
+bool Database::LoadDatabaseFromFile() {
+	std::filesystem::path db_path = Filesystem::GetAnimeDBPath();
+	Filesystem::CreateDirectories(db_path);
+
+	std::ifstream db_file(db_path);
+	if (!db_file)
+		return false;
+
+	/* When parsing, do NOT throw exceptions */
+	nlohmann::json json = json.parse(db_file, nullptr, false);
+	if (json.is_discarded())
+		return false; /* Give up */
+
+	if (!ParseDatabaseJSON(json)) /* How */
+		return false;
+
 	return true;
 }