Mercurial > minori
changeset 120:275da698697d
config: template-ify INI
now it's... slightly less ugly :')
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 08 Nov 2023 18:13:37 -0500 |
parents | 4eae379cb1ff |
children | a66c47c1ba3c |
files | CMakeLists.txt include/core/config.h include/core/ini.h src/core/config.cc src/core/strings.cc src/gui/dialog/settings/recognition.cc src/gui/dialog/settings/services.cc src/services/anilist.cc |
diffstat | 8 files changed, 123 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Wed Nov 08 13:50:00 2023 -0500 +++ b/CMakeLists.txt Wed Nov 08 18:13:37 2023 -0500 @@ -57,7 +57,6 @@ src/core/config.cc src/core/date.cc src/core/filesystem.cc - src/core/ini.cc src/core/http.cc src/core/json.cc src/core/strings.cc
--- a/include/core/config.h Wed Nov 08 13:50:00 2023 -0500 +++ b/include/core/config.h Wed Nov 08 18:13:37 2023 -0500 @@ -29,10 +29,19 @@ "auth" struct... */ struct { public: - std::string auth_token; - std::string username; - int user_id; - } anilist; + struct { + public: + std::string auth_token; + std::string username; + int user_id; + } anilist; + } auth; + + struct { + public: + bool detect_media_players; + //bool detect_streaming_media; + } recognition; struct { public:
--- a/include/core/ini.h Wed Nov 08 13:50:00 2023 -0500 +++ b/include/core/ini.h Wed Nov 08 18:13:37 2023 -0500 @@ -3,12 +3,75 @@ #define MINI_CASE_SENSITIVE #include "mini/ini.h" +#include "core/strings.h" +#include "gui/translate/anime.h" +#include "gui/translate/config.h" +#include <type_traits> +#include <string> namespace INI { -std::string GetIniString(const mINI::INIStructure& ini, const std::string& section, - const std::string& value, const std::string& def = ""); +/* very simple tutorial on how to give anyone who reads + your code an aneurysm */ +template< class... > +using void_t = void; + +template <typename T, typename = void> +struct is_toutf8string_available : std::false_type {}; + +template<typename T> +struct is_toutf8string_available<T, + void_t<decltype(Strings::ToUtf8String(std::declval<T>()))>> : std::true_type {}; + +template <typename T, typename = void> +struct is_translation_available : std::false_type {}; + +template<typename T> +struct is_translation_available<T, + void_t<decltype(Translate::ToString(std::declval<T>()))>> : std::true_type {}; + +template<typename T> +T GetIniValue(const mINI::INIStructure& ini, const std::string& section, + const std::string& value, const T& def) { + if (!ini.has(section) || !ini.get(section).has(value)) + return def; + + const std::string val = ini.get(section).get(value); + + if constexpr (std::is_arithmetic<T>::value) { + /* Integer? */ + if constexpr (std::is_same<T, bool>::value) { + /* Boolean? */ + return Strings::ToBool(val); + } else if constexpr (std::is_unsigned<T>::value) { + /* Unsigned? */ + return Strings::ToUnsignedInt(val); + } else { + /* Always fall back to long long */ + return Strings::ToInt(val); + } + } else { + return val; + } +} + +/* this should be able to handle most of our custom types */ +template<typename T> +void SetIniValue(mINI::INIStructure& ini, const std::string& section, + const std::string& key, const T& value) { + auto& ini_key = ini[section][key]; + + if constexpr (is_translation_available<T>::value) { + ini_key = Translate::ToString(value); + } else if constexpr (std::is_same<T, std::string>::value) { + ini_key = value; + } else if constexpr (std::is_arithmetic<T>::value && !std::is_same<T, bool>::value) { + ini_key = std::to_string(value); + } else if constexpr (is_toutf8string_available<T>::value) { + ini_key = Strings::ToUtf8String(value); + } +} } -#endif \ No newline at end of file +#endif
--- a/src/core/config.cc Wed Nov 08 13:50:00 2023 -0500 +++ b/src/core/config.cc Wed Nov 08 18:13:37 2023 -0500 @@ -17,6 +17,9 @@ #include <fstream> #include <limits.h> +/* I'll use an INI-based config file instead of using an + XML file like Taiga. */ + int Config::Load() { Filesystem::Path cfg_path = Filesystem::GetConfigPath(); @@ -24,22 +27,23 @@ mINI::INIStructure ini; file.read(ini); - service = Translate::ToService(INI::GetIniString(ini, "General", "Service", "None")); - /* ew */ - locale.SetActiveLocale(QLocale(Strings::ToQString(INI::GetIniString(ini, "General", "Locale", "en_US")))); + service = Translate::ToService(INI::GetIniValue<std::string>(ini, "General", "Service", "None")); + + anime_list.language = Translate::ToLanguage(INI::GetIniValue<std::string>(ini, "Anime List", "Title language", "Romaji")); + anime_list.display_aired_episodes = INI::GetIniValue<bool>(ini, "Anime List", "Display only aired episodes", true); + anime_list.display_available_episodes = INI::GetIniValue<bool>(ini, "Anime List", "Display only available episodes in library", true); + anime_list.highlight_anime_if_available = INI::GetIniValue<bool>(ini, "Anime List", "Highlight anime if available", true); + anime_list.highlighted_anime_above_others = INI::GetIniValue<bool>(ini, "Anime List", "Display highlighted anime above others", false); - anime_list.language = Translate::ToLanguage(INI::GetIniString(ini, "Anime List", "Title language", "Romaji")); - anime_list.display_aired_episodes = Strings::ToBool(INI::GetIniString(ini, "Anime List", "Display only aired episodes", ""), true); - anime_list.display_available_episodes = Strings::ToBool(INI::GetIniString(ini, "Anime List", "Display only available episodes in library", ""), true); - anime_list.highlight_anime_if_available = Strings::ToBool(INI::GetIniString(ini, "Anime List", "Highlight anime if available", ""), true); - anime_list.highlighted_anime_above_others = Strings::ToBool(INI::GetIniString(ini, "Anime List", "Display highlighted anime above others", ""), false); + auth.anilist.auth_token = INI::GetIniValue<std::string>(ini, "Authentication/AniList", "Auth Token", ""); + auth.anilist.user_id = INI::GetIniValue<int>(ini, "Authentication/AniList", "User ID", 0); + + torrents.feed_link = INI::GetIniValue<std::string>(ini, "Torrents", "RSS feed", "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0"); - anilist.auth_token = INI::GetIniString(ini, "AniList", "Auth Token", ""); - anilist.user_id = Strings::ToInt(INI::GetIniString(ini, "AniList", "User ID", ""), 0); + /* ew */ + locale.SetActiveLocale(QLocale(Strings::ToQString(INI::GetIniValue<std::string>(ini, "General", "Locale", "en_US")))); - torrents.feed_link = INI::GetIniString(ini, "Torrents", "RSS feed", "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0"); - - theme.SetTheme(Translate::ToTheme(INI::GetIniString(ini, "Appearance", "Theme", "Default"))); + theme.SetTheme(Translate::ToTheme(INI::GetIniValue<std::string>(ini, "Appearance", "Theme", "Default"))); return 0; } @@ -52,17 +56,24 @@ mINI::INIFile file(cfg_path.GetPath()); mINI::INIStructure ini; - ini["General"]["Service"] = Translate::ToString(service); - ini["General"]["Locale"] = Strings::ToUtf8String(locale.GetLocale().name()); - ini["Anime List"]["Title language"] = Translate::ToString(anime_list.language); - ini["Anime List"]["Display only aired episodes"] = Strings::ToUtf8String(anime_list.display_aired_episodes); - ini["Anime List"]["Display only available episodes in library"] = Strings::ToUtf8String(anime_list.display_available_episodes); - ini["Anime List"]["Highlight anime if available"] = Strings::ToUtf8String(anime_list.highlight_anime_if_available); - ini["Anime List"]["Display highlighted anime above others"] = Strings::ToUtf8String(anime_list.highlighted_anime_above_others); - ini["AniList"]["Auth Token"] = anilist.auth_token; - ini["AniList"]["User ID"] = std::to_string(anilist.user_id); - ini["Appearance"]["Theme"] = Translate::ToString(theme.GetTheme()); - ini["Torrents"]["RSS feed"] = torrents.feed_link; + INI::SetIniValue(ini, "General", "Service", service); + INI::SetIniValue(ini, "General", "Locale", locale.GetLocale().name()); + + INI::SetIniValue(ini, "Anime List", "Title language", anime_list.language); + INI::SetIniValue(ini, "Anime List", "Display only aired episodes", anime_list.display_aired_episodes); + INI::SetIniValue(ini, "Anime List", "Display only available episodes in library", anime_list.display_available_episodes); + INI::SetIniValue(ini, "Anime List", "Highlight anime if available", anime_list.highlight_anime_if_available); + INI::SetIniValue(ini, "Anime List", "Display highlighted anime above others", anime_list.highlighted_anime_above_others); + + INI::SetIniValue(ini, "Authentication/AniList", "Auth Token", auth.anilist.auth_token); + INI::SetIniValue(ini, "Authentication/AniList", "User ID", auth.anilist.user_id); + + INI::SetIniValue(ini, "Appearance", "Theme", theme.GetTheme()); + + INI::SetIniValue(ini, "Torrents", "RSS feed", torrents.feed_link); + + INI::SetIniValue(ini, "Recognition", "Detect media players", recognition.detect_media_players); + //ini["Recognition"]["Detect streaming media"] = Strings::ToUtf8String(recognition.detect_streaming_media); file.write(ini);
--- a/src/core/strings.cc Wed Nov 08 13:50:00 2023 -0500 +++ b/src/core/strings.cc Wed Nov 08 18:13:37 2023 -0500 @@ -158,6 +158,7 @@ return QString::fromWCharArray(wstring.c_str(), wstring.length()); } +/* not really an "int"... but who cares? */ int ToInt(const std::string& str, int def) { int tmp = 0; try {
--- a/src/gui/dialog/settings/recognition.cc Wed Nov 08 13:50:00 2023 -0500 +++ b/src/gui/dialog/settings/recognition.cc Wed Nov 08 18:13:37 2023 -0500 @@ -66,5 +66,5 @@ } SettingsPageRecognition::SettingsPageRecognition(QWidget* parent) : SettingsPage(parent, tr("Recognition")) { - AddTab(CreatePlayersWidget(), tr("Players")); + AddTab(CreatePlayersWidget(), tr("Media players")); }
--- a/src/gui/dialog/settings/services.cc Wed Nov 08 13:50:00 2023 -0500 +++ b/src/gui/dialog/settings/services.cc Wed Nov 08 18:13:37 2023 -0500 @@ -87,7 +87,7 @@ /* The actual auth button */ QPushButton* auth_button = new QPushButton(auth_widget); connect(auth_button, &QPushButton::clicked, this, [] { Services::AniList::AuthorizeUser(); }); - auth_button->setText(session.config.anilist.auth_token.empty() ? tr("Authorize...") : tr("Re-authorize...")); + auth_button->setText(session.config.auth.anilist.auth_token.empty() ? tr("Authorize...") : tr("Re-authorize...")); auth_layout->addWidget(auth_button); }
--- a/src/services/anilist.cc Wed Nov 08 13:50:00 2023 -0500 +++ b/src/services/anilist.cc Wed Nov 08 18:13:37 2023 -0500 @@ -24,14 +24,14 @@ class Account { public: - std::string Username() const { return session.config.anilist.username; } - void SetUsername(std::string const& username) { session.config.anilist.username = username; } + std::string Username() const { return session.config.auth.anilist.username; } + void SetUsername(std::string const& username) { session.config.auth.anilist.username = username; } - int UserId() const { return session.config.anilist.user_id; } - void SetUserId(const int id) { session.config.anilist.user_id = id; } + int UserId() const { return session.config.auth.anilist.user_id; } + void SetUserId(const int id) { session.config.auth.anilist.user_id = id; } - std::string AuthToken() const { return session.config.anilist.auth_token; } - void SetAuthToken(std::string const& auth_token) { session.config.anilist.auth_token = auth_token; } + 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; } bool Authenticated() const { return !AuthToken().empty(); } };