Mercurial > minori
changeset 286:53e3c015a973
anime: initial cross-service support
currently the Kitsu and MAL services don't work when chosen in the
GUI. This is because they haven't been implemented yet :)
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 08 May 2024 16:44:27 -0400 |
parents | 65df2813d0de |
children | 8535eb5fb836 |
files | include/core/anime.h src/core/anime.cc src/core/anime_db.cc src/core/config.cc src/gui/translate/anime.cc src/gui/widgets/poster.cc src/services/anilist.cc |
diffstat | 7 files changed, 58 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/include/core/anime.h Wed May 08 16:43:32 2024 -0400 +++ b/include/core/anime.h Wed May 08 16:44:27 2024 -0400 @@ -86,10 +86,18 @@ enum class Service { None, - AniList + AniList, + MyAnimeList, + Kitsu }; -constexpr std::array<Service, 1> Services{Service::AniList}; +/* this doesn't include MAL and Kitsu because they aren't really + * "valid" services yet. */ +constexpr std::array<Service, 3> Services{ + Service::AniList, + Service::MyAnimeList, + Service::Kitsu +}; enum class ScoreFormat { Point100, // 0-100 @@ -118,6 +126,7 @@ struct SeriesInformation { int id; + std::map<Service, std::string> ids; std::map<TitleLanguage, std::string> titles; std::vector<std::string> synonyms; int episodes = 0; @@ -160,6 +169,7 @@ /* Series data */ int GetId() const; + std::optional<std::string> GetServiceId(Service service) const; std::optional<std::string> GetTitle(TitleLanguage language) const; std::vector<std::string> GetTitleSynonyms() const; int GetEpisodes() const; @@ -173,9 +183,10 @@ std::string GetSynopsis() const; int GetDuration() const; std::string GetPosterUrl() const; - std::string GetServiceUrl() const; + std::optional<std::string> GetServiceUrl(Service service) const; void SetId(int id); + void SetServiceId(Service service, const std::string& id); void SetTitle(TitleLanguage language, const std::string& title); void SetTitleSynonyms(std::vector<std::string> const& synonyms); void AddTitleSynonym(std::string const& synonym);
--- a/src/core/anime.cc Wed May 08 16:43:32 2024 -0400 +++ b/src/core/anime.cc Wed May 08 16:44:27 2024 -0400 @@ -170,6 +170,13 @@ return info_.id; } +std::optional<std::string> Anime::GetServiceId(Service service) const { + if (info_.ids.find(service) == info_.ids.end()) + return std::nullopt; + + return info_.ids.at(service); +} + /* note: this should use std::optional */ std::optional<std::string> Anime::GetTitle(TitleLanguage language) const { if (info_.titles.find(language) == info_.titles.end()) @@ -239,13 +246,21 @@ } std::string Anime::GetPosterUrl() const { + /* this isn't really service-specific. this could use + * kitsu, MAL, or anilist, and would achieve basically + * the same effect. */ return info_.poster_url; } -std::string Anime::GetServiceUrl() const { +std::optional<std::string> Anime::GetServiceUrl(Service service) const { /* todo: add support for other services... */ - switch (session.config.service) { - case Service::AniList: return "https://anilist.co/anime/" + Strings::ToUtf8String(GetId()); + std::optional<std::string> id = GetServiceId(service); + if (!id.has_value()) + return std::nullopt; + + switch (service) { + case Service::AniList: + return "https://anilist.co/anime/" + id.value(); default: return ""; } } @@ -254,6 +269,10 @@ info_.id = id; } +void Anime::SetServiceId(Service service, const std::string& id) { + info_.ids[service] = id; +} + void Anime::SetTitle(TitleLanguage language, const std::string& title) { info_.titles[language] = title; }
--- a/src/core/anime_db.cc Wed May 08 16:43:32 2024 -0400 +++ b/src/core/anime_db.cc Wed May 08 16:44:27 2024 -0400 @@ -179,6 +179,12 @@ json["title"][Strings::ToLower(Translate::ToString(lang))] = title.value(); } + for (const auto& service : Services) { + std::optional<std::string> id = anime.GetServiceId(service); + if (id.has_value()) + json["ids"][Strings::ToLower(Translate::ToString(service))] = id.value(); + } + nlohmann::json user; if (GetListDataAsJSON(anime, user)) json.push_back({"list_data", user});
--- a/src/core/config.cc Wed May 08 16:43:32 2024 -0400 +++ b/src/core/config.cc Wed May 08 16:44:27 2024 -0400 @@ -133,7 +133,7 @@ ini["Anime List"]["Display highlighted anime above others"] = Strings::ToUtf8String(anime_list.highlighted_anime_above_others); ini["Authentication/AniList"]["Auth Token"] = auth.anilist.auth_token; - ini["Authentication/AniList"]["User ID"] = auth.anilist.user_id; + ini["Authentication/AniList"]["User ID"] = Strings::ToUtf8String(auth.anilist.user_id); ini["Appearance"]["Theme"] = Translate::ToString(theme.GetTheme());
--- a/src/gui/translate/anime.cc Wed May 08 16:43:32 2024 -0400 +++ b/src/gui/translate/anime.cc Wed May 08 16:44:27 2024 -0400 @@ -60,6 +60,8 @@ std::string ToString(const Anime::Service service) { switch (service) { case Anime::Service::AniList: return "AniList"; + case Anime::Service::MyAnimeList: return "MyAnimeList"; + case Anime::Service::Kitsu: return "Kitsu"; default: case Anime::Service::None: return "None"; } @@ -144,7 +146,9 @@ Anime::Service ToService(const std::string& str) { static const std::unordered_map<std::string, Anime::Service> map = { - {"AniList", Anime::Service::AniList} + {"AniList", Anime::Service::AniList}, + {"MyAnimeList", Anime::Service::MyAnimeList}, + {"Kitsu", Anime::Service::Kitsu} }; if (map.find(str) == map.end()) @@ -238,6 +242,8 @@ std::string ToLocalString(const Anime::Service service) { switch (service) { case Anime::Service::AniList: return Strings::ToUtf8String(QCoreApplication::tr("AniList")); + case Anime::Service::MyAnimeList: return Strings::ToUtf8String(QCoreApplication::tr("MyAnimeList")); + case Anime::Service::Kitsu: return Strings::ToUtf8String(QCoreApplication::tr("Kitsu")); default: case Anime::Service::None: return Strings::ToUtf8String(QCoreApplication::tr("None")); }
--- a/src/gui/widgets/poster.cc Wed May 08 16:43:32 2024 -0400 +++ b/src/gui/widgets/poster.cc Wed May 08 16:44:27 2024 -0400 @@ -44,7 +44,9 @@ thread->start(); } - service_url_ = Strings::ToQString(anime.GetServiceUrl()); + std::optional<std::string> url = anime.GetServiceUrl(session.config.service); + if (url) + service_url_ = Strings::ToQString(url.value()); if (clickable_) { label_.disconnect();
--- a/src/services/anilist.cc Wed May 08 16:43:32 2024 -0400 +++ b/src/services/anilist.cc Wed May 08 16:44:27 2024 -0400 @@ -26,7 +26,7 @@ namespace Services { namespace AniList { -constexpr int CLIENT_ID = 13706; +static constexpr int CLIENT_ID = 13706; class Account { public: @@ -34,7 +34,7 @@ void SetUserId(const int id) { session.config.auth.anilist.user_id = id; } std::string AuthToken() const { return session.config.auth.anilist.auth_token; } - void SetAuthToken(std::string const& auth_token) { session.config.auth.anilist.auth_token = auth_token; } + void SetAuthToken(const std::string& auth_token) { session.config.auth.anilist.auth_token = auth_token; } bool Authenticated() const { return !AuthToken().empty(); } bool IsValid() const { return UserId() && Authenticated(); } @@ -130,6 +130,8 @@ Anime::Anime& anime = Anime::db.items[id]; anime.SetId(id); + anime.SetServiceId(Anime::Service::AniList, Strings::ToUtf8String(id)); + anime.SetServiceId(Anime::Service::MyAnimeList, Strings::ToUtf8String(JSON::GetNumber(json, "/id_mal"_json_pointer))); ParseTitle(json.at("/title"_json_pointer), anime); @@ -266,6 +268,7 @@ " large\n" " }\n" " id\n" + " id_mal\n" " title {\n" " romaji\n" " english\n"