Mercurial > minori
changeset 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 |
files | include/core/anime_db.h include/core/date.h include/core/json.h include/gui/translate/anime.h src/core/anime_db.cc src/core/date.cc src/core/json.cc src/gui/translate/anime.cc src/gui/window.cc |
diffstat | 9 files changed, 301 insertions(+), 77 deletions(-) [+] |
line wrap: on
line diff
--- a/include/core/anime_db.h Tue Nov 28 13:53:54 2023 -0500 +++ b/include/core/anime_db.h Wed Nov 29 13:53:56 2023 -0500 @@ -21,6 +21,13 @@ int GetAnimeFromTitle(const std::string& title); bool GetDatabaseAsJSON(nlohmann::json& json); + bool SaveDatabaseToDisk(); + + bool ParseDatabaseJSON(const nlohmann::json& json); + bool LoadDatabaseFromFile(); + + protected: + bool ParseAnimeInfoJSON(const nlohmann::json& json); }; extern Database db;
--- a/include/core/date.h Tue Nov 28 13:53:54 2023 -0500 +++ b/include/core/date.h Wed Nov 29 13:53:56 2023 -0500 @@ -1,7 +1,7 @@ #ifndef __core__date_h #define __core__date_h -#include "json.h" +#include "core/json.h" #include <QDate> #include <cstdint> @@ -11,6 +11,7 @@ Date(unsigned int y); Date(unsigned int y, unsigned int m, unsigned int d); Date(const QDate& date); + Date(const nlohmann::json& json); bool IsValid() const; void SetYear(unsigned int y); void SetMonth(unsigned int m); @@ -29,8 +30,7 @@ bool operator>=(const Date& other) const; private: - /* note: it might be worth it to change these all to int, as - large bit precisions aren't exactly useful here... */ + /* this implementation sucks and we should really use a struct instead */ std::shared_ptr<unsigned int> year; std::shared_ptr<unsigned int> month; std::shared_ptr<unsigned int> day;
--- a/include/core/json.h Tue Nov 28 13:53:54 2023 -0500 +++ b/include/core/json.h Wed Nov 29 13:53:56 2023 -0500 @@ -5,10 +5,32 @@ namespace JSON { -std::string GetString(nlohmann::json const& json, nlohmann::json::json_pointer const& ptr, std::string def = ""); -int GetInt(nlohmann::json const& json, nlohmann::json::json_pointer const& ptr, int def = 0); -bool GetBoolean(nlohmann::json const& json, nlohmann::json::json_pointer const& ptr, bool def = false); -double GetDouble(nlohmann::json const& json, nlohmann::json::json_pointer const& ptr, double def = 0); +template<typename T = std::string> +T GetString(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, T def) { + if (json.contains(ptr) && json[ptr].is_string()) + return json[ptr].get<T>(); + else + return def; +} + +template<typename T = int> +T GetNumber(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, T def = 0) { + if (json.contains(ptr) && json[ptr].is_number()) + return json[ptr].get<T>(); + else + return def; +} + +template<typename T = std::vector<std::string>> +T GetArray(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, T def = 0) { + if (json.contains(ptr) && json[ptr].is_array()) + return json[ptr].get<T>(); + else + return def; +} + +nlohmann::json GetValue(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr); +bool GetBoolean(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, bool def = false); } // namespace JSON
--- a/include/gui/translate/anime.h Tue Nov 28 13:53:54 2023 -0500 +++ b/include/gui/translate/anime.h Wed Nov 29 13:53:56 2023 -0500 @@ -7,8 +7,20 @@ std::string ToString(const Anime::SeriesSeason season); std::string ToString(const Anime::SeriesStatus status); std::string ToString(const Anime::Services service); +std::string ToString(const Anime::TitleLanguage language); + +std::string ToLocalString(const Anime::ListStatus status); +std::string ToLocalString(const Anime::SeriesFormat format); +std::string ToLocalString(const Anime::SeriesSeason season); +std::string ToLocalString(const Anime::SeriesStatus status); +std::string ToLocalString(const Anime::Services service); +std::string ToLocalString(const Anime::TitleLanguage language); + +Anime::ListStatus ToListStatus(const std::string& str); +Anime::SeriesFormat ToSeriesFormat(const std::string& str); +Anime::SeriesSeason ToSeriesSeason(const std::string& str); +Anime::SeriesStatus ToSeriesStatus(const std::string& str); Anime::Services ToService(const std::string& str); -std::string ToString(const Anime::TitleLanguage language); Anime::TitleLanguage ToLanguage(const std::string& str); } // namespace Translate
--- 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; }
--- a/src/core/date.cc Tue Nov 28 13:53:54 2023 -0500 +++ b/src/core/date.cc Wed Nov 29 13:53:56 2023 -0500 @@ -29,6 +29,15 @@ SetDay(date.day()); } +Date::Date(const nlohmann::json& json) { + if (json.contains("year") && json.at("year").is_number()) + SetYear(json.at("year").get<unsigned int>()); + if (json.contains("month") && json.at("month").is_number()) + SetMonth(json.at("month").get<unsigned int>()); + if (json.contains("day") && json.at("day").is_number()) + SetDay(json.at("day").get<unsigned int>()); +} + void Date::VoidYear() { year.reset(); }
--- a/src/core/json.cc Tue Nov 28 13:53:54 2023 -0500 +++ b/src/core/json.cc Wed Nov 29 13:53:56 2023 -0500 @@ -2,18 +2,11 @@ namespace JSON { -std::string GetString(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, std::string def) { - if (json.contains(ptr) && json[ptr].is_string()) - return json[ptr].get<std::string>(); +nlohmann::json GetValue(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr) { + if (json.contains(ptr)) + return json.at(ptr); else - return def; -} - -int GetInt(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, int def) { - if (json.contains(ptr) && json[ptr].is_number()) - return json[ptr].get<int>(); - else - return def; + return nlohmann::json(); } bool GetBoolean(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, bool def) { @@ -23,11 +16,4 @@ return def; } -double GetDouble(const nlohmann::json& json, const nlohmann::json::json_pointer& ptr, double def) { - if (json.contains(ptr) && json[ptr].is_number()) - return json[ptr].get<double>(); - else - return def; -} - } // namespace JSON
--- a/src/gui/translate/anime.cc Tue Nov 28 13:53:54 2023 -0500 +++ b/src/gui/translate/anime.cc Wed Nov 29 13:53:56 2023 -0500 @@ -7,64 +7,96 @@ std::string ToString(const Anime::ListStatus status) { switch (status) { - case Anime::ListStatus::CURRENT: return Strings::ToUtf8String(QCoreApplication::tr("Currently watching")); - case Anime::ListStatus::PLANNING: return Strings::ToUtf8String(QCoreApplication::tr("Plan to watch")); - case Anime::ListStatus::COMPLETED: return Strings::ToUtf8String(QCoreApplication::tr("Completed")); - case Anime::ListStatus::DROPPED: return Strings::ToUtf8String(QCoreApplication::tr("Dropped")); - case Anime::ListStatus::PAUSED: return Strings::ToUtf8String(QCoreApplication::tr("On hold")); + case Anime::ListStatus::CURRENT: return "Currently watching"; + case Anime::ListStatus::PLANNING: return "Plan to watch"; + case Anime::ListStatus::COMPLETED: return "Completed"; + case Anime::ListStatus::DROPPED: return "Dropped"; + case Anime::ListStatus::PAUSED: return "On hold"; default: - case Anime::ListStatus::NOT_IN_LIST: return Strings::ToUtf8String(QCoreApplication::tr("Not in list")); + case Anime::ListStatus::NOT_IN_LIST: return "Not in list"; } } std::string ToString(const Anime::SeriesFormat format) { switch (format) { - case Anime::SeriesFormat::TV: return Strings::ToUtf8String(QCoreApplication::tr("TV")); - case Anime::SeriesFormat::TV_SHORT: return Strings::ToUtf8String(QCoreApplication::tr("TV short")); - case Anime::SeriesFormat::OVA: return Strings::ToUtf8String(QCoreApplication::tr("OVA")); - case Anime::SeriesFormat::MOVIE: return Strings::ToUtf8String(QCoreApplication::tr("Movie")); - case Anime::SeriesFormat::SPECIAL: return Strings::ToUtf8String(QCoreApplication::tr("Special")); - case Anime::SeriesFormat::ONA: return Strings::ToUtf8String(QCoreApplication::tr("ONA")); - case Anime::SeriesFormat::MUSIC: return Strings::ToUtf8String(QCoreApplication::tr("Music")); + case Anime::SeriesFormat::TV: return "TV"; + case Anime::SeriesFormat::TV_SHORT: return "TV short"; + case Anime::SeriesFormat::OVA: return "OVA"; + case Anime::SeriesFormat::MOVIE: return "Movie"; + case Anime::SeriesFormat::SPECIAL: return "Special"; + case Anime::SeriesFormat::ONA: return "ONA"; + case Anime::SeriesFormat::MUSIC: return "Music"; default: - case Anime::SeriesFormat::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown")); + case Anime::SeriesFormat::UNKNOWN: return "Unknown"; } } std::string ToString(const Anime::SeriesSeason season) { switch (season) { - case Anime::SeriesSeason::WINTER: return Strings::ToUtf8String(QCoreApplication::tr("Winter")); - case Anime::SeriesSeason::SUMMER: return Strings::ToUtf8String(QCoreApplication::tr("Summer")); - case Anime::SeriesSeason::FALL: return Strings::ToUtf8String(QCoreApplication::tr("Fall")); - case Anime::SeriesSeason::SPRING: return Strings::ToUtf8String(QCoreApplication::tr("Spring")); + case Anime::SeriesSeason::WINTER: return "Winter"; + case Anime::SeriesSeason::SUMMER: return "Summer"; + case Anime::SeriesSeason::FALL: return "Fall"; + case Anime::SeriesSeason::SPRING: return "Spring"; default: - case Anime::SeriesSeason::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown")); + case Anime::SeriesSeason::UNKNOWN: return "Unknown"; } } std::string ToString(const Anime::SeriesStatus status) { switch (status) { - case Anime::SeriesStatus::RELEASING: return Strings::ToUtf8String(QCoreApplication::tr("Currently airing")); - case Anime::SeriesStatus::FINISHED: return Strings::ToUtf8String(QCoreApplication::tr("Finished airing")); - case Anime::SeriesStatus::NOT_YET_RELEASED: return Strings::ToUtf8String(QCoreApplication::tr("Not yet aired")); - case Anime::SeriesStatus::CANCELLED: return Strings::ToUtf8String(QCoreApplication::tr("Cancelled")); - case Anime::SeriesStatus::HIATUS: return Strings::ToUtf8String(QCoreApplication::tr("On hiatus")); + case Anime::SeriesStatus::RELEASING: return "Currently airing"; + case Anime::SeriesStatus::FINISHED: return "Finished airing"; + case Anime::SeriesStatus::NOT_YET_RELEASED: return "Not yet aired"; + case Anime::SeriesStatus::CANCELLED: return "Cancelled"; + case Anime::SeriesStatus::HIATUS: return "On hiatus"; default: - case Anime::SeriesStatus::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown")); + case Anime::SeriesStatus::UNKNOWN: "Unknown"; } } -std::string ToString(const Anime::Services service) { - switch (service) { - case Anime::Services::ANILIST: return Strings::ToUtf8String(QCoreApplication::tr("AniList")); - default: - case Anime::Services::NONE: return Strings::ToUtf8String(QCoreApplication::tr("None")); - } +Anime::SeriesStatus ToListStatus(const std::string& str) { + const std::unordered_map<std::string, Anime::SeriesStatus> map = { + {"Currently watching", Anime::SeriesSeason::CURRENT}, + {"Plan to watch", Anime::SeriesSeason::PLANNING}, + {"Completed", Anime::SeriesSeason::COMPLETED}, + {"Dropped", Anime::SeriesSeason::DROPPED}, + {"On hold", Anime::SeriesSeason::PAUSED} + }; + + if (map.find(str) == map.end()) + return Anime::SeriesStatus::NOT_IN_LIST; + return map.at(str); +} + +Anime::SeriesStatus ToSeriesStatus(const std::string& str) { + const std::unordered_map<std::string, Anime::SeriesStatus> map = { + {"Currently airing", Anime::SeriesSeason::RELEASING}, + {"Finished airing", Anime::SeriesSeason::FINISHED}, + {"Not yet aired", Anime::SeriesSeason::NOT_YET_RELEASED}, + {"Cancelled", Anime::SeriesSeason::CANCELLED}, + {"On hiatus", Anime::SeriesSeason::HIATUS} + }; + + if (map.find(str) == map.end()) + return Anime::SeriesStatus::UNKNOWN; + return map.at(str); +} + +Anime::SeriesSeason ToSeriesSeason(const std::string& str) { + const std::unordered_map<std::string, Anime::SeriesSeason> map = { + {"Winter", Anime::SeriesSeason::WINTER}, + {"Summer", Anime::SeriesSeason::SUMMER}, + {"Fall", Anime::SeriesSeason::FALL}, + {"Spring", Anime::SeriesSeason::SPRING} + }; + + if (map.find(str) == map.end()) + return Anime::SeriesSeason::UNKNOWN; + return map.at(str); } Anime::Services ToService(const std::string& str) { const std::unordered_map<std::string, Anime::Services> map = { - {"None", Anime::Services::NONE }, {"AniList", Anime::Services::ANILIST} }; @@ -73,15 +105,6 @@ return map.at(str); } -std::string ToString(const Anime::TitleLanguage language) { - switch (language) { - case Anime::TitleLanguage::NATIVE: return Strings::ToUtf8String(QCoreApplication::tr("Native")); - case Anime::TitleLanguage::ENGLISH: return Strings::ToUtf8String(QCoreApplication::tr("English")); - default: - case Anime::TitleLanguage::ROMAJI: return Strings::ToUtf8String(QCoreApplication::tr("Romaji")); - } -} - Anime::TitleLanguage ToLanguage(const std::string& str) { const std::unordered_map<std::string, Anime::TitleLanguage> map = { {"Romaji", Anime::TitleLanguage::ROMAJI}, @@ -94,4 +117,72 @@ return map.at(str); } +/* Localized versions of ToString() functions */ + +std::string ToLocalString(const Anime::ListStatus status) { + switch (status) { + case Anime::ListStatus::CURRENT: return Strings::ToUtf8String(QCoreApplication::tr("Currently watching")); + case Anime::ListStatus::PLANNING: return Strings::ToUtf8String(QCoreApplication::tr("Plan to watch")); + case Anime::ListStatus::COMPLETED: return Strings::ToUtf8String(QCoreApplication::tr("Completed")); + case Anime::ListStatus::DROPPED: return Strings::ToUtf8String(QCoreApplication::tr("Dropped")); + case Anime::ListStatus::PAUSED: return Strings::ToUtf8String(QCoreApplication::tr("On hold")); + default: + case Anime::ListStatus::NOT_IN_LIST: return Strings::ToUtf8String(QCoreApplication::tr("Not in list")); + } +} + +std::string ToLocalString(const Anime::SeriesFormat format) { + switch (format) { + case Anime::SeriesFormat::TV: return Strings::ToUtf8String(QCoreApplication::tr("TV")); + case Anime::SeriesFormat::TV_SHORT: return Strings::ToUtf8String(QCoreApplication::tr("TV short")); + case Anime::SeriesFormat::OVA: return Strings::ToUtf8String(QCoreApplication::tr("OVA")); + case Anime::SeriesFormat::MOVIE: return Strings::ToUtf8String(QCoreApplication::tr("Movie")); + case Anime::SeriesFormat::SPECIAL: return Strings::ToUtf8String(QCoreApplication::tr("Special")); + case Anime::SeriesFormat::ONA: return Strings::ToUtf8String(QCoreApplication::tr("ONA")); + case Anime::SeriesFormat::MUSIC: return Strings::ToUtf8String(QCoreApplication::tr("Music")); + default: + case Anime::SeriesFormat::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown")); + } +} + +std::string ToLocalString(const Anime::SeriesSeason season) { + switch (season) { + case Anime::SeriesSeason::WINTER: return Strings::ToUtf8String(QCoreApplication::tr("Winter")); + case Anime::SeriesSeason::SUMMER: return Strings::ToUtf8String(QCoreApplication::tr("Summer")); + case Anime::SeriesSeason::FALL: return Strings::ToUtf8String(QCoreApplication::tr("Fall")); + case Anime::SeriesSeason::SPRING: return Strings::ToUtf8String(QCoreApplication::tr("Spring")); + default: + case Anime::SeriesSeason::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown")); + } +} + +std::string ToLocalString(const Anime::SeriesStatus status) { + switch (status) { + case Anime::SeriesStatus::RELEASING: return Strings::ToUtf8String(QCoreApplication::tr("Currently airing")); + case Anime::SeriesStatus::FINISHED: return Strings::ToUtf8String(QCoreApplication::tr("Finished airing")); + case Anime::SeriesStatus::NOT_YET_RELEASED: return Strings::ToUtf8String(QCoreApplication::tr("Not yet aired")); + case Anime::SeriesStatus::CANCELLED: return Strings::ToUtf8String(QCoreApplication::tr("Cancelled")); + case Anime::SeriesStatus::HIATUS: return Strings::ToUtf8String(QCoreApplication::tr("On hiatus")); + default: + case Anime::SeriesStatus::UNKNOWN: return Strings::ToUtf8String(QCoreApplication::tr("Unknown")); + } +} + +std::string ToLocalString(const Anime::Services service) { + switch (service) { + case Anime::Services::ANILIST: return Strings::ToUtf8String(QCoreApplication::tr("AniList")); + default: + case Anime::Services::NONE: return Strings::ToUtf8String(QCoreApplication::tr("None")); + } +} + +std::string ToLocalString(const Anime::TitleLanguage language) { + switch (language) { + case Anime::TitleLanguage::NATIVE: return Strings::ToUtf8String(QCoreApplication::tr("Native")); + case Anime::TitleLanguage::ENGLISH: return Strings::ToUtf8String(QCoreApplication::tr("English")); + default: + case Anime::TitleLanguage::ROMAJI: return Strings::ToUtf8String(QCoreApplication::tr("Romaji")); + } +} + } // namespace Translate