Mercurial > minori
diff src/core/config.cc @ 318:3b355fa948c7
config: use TOML instead of INI
unfortunately, INI is not enough, and causes some paths including
semicolons to break with our current storage of the library folders.
so, I decided to switch to TOML which does support real arrays...
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 12 Jun 2024 05:25:41 -0400 |
parents | b1f4d1867ab1 |
children | 1b5c04268d6a |
line wrap: on
line diff
--- a/src/core/config.cc Wed Jun 12 04:07:10 2024 -0400 +++ b/src/core/config.cc Wed Jun 12 05:25:41 2024 -0400 @@ -1,11 +1,6 @@ -/** - * config.cpp: - * parses the config... lol - **/ #include "core/config.h" #include "core/anime.h" #include "core/filesystem.h" -#include "core/ini.h" #include "core/json.h" #include "core/strings.h" #include "gui/translate/anime.h" @@ -20,59 +15,60 @@ #include <fstream> #include <limits.h> +#include <toml11/toml.hpp> + #include <QFile> #include <QTextStream> #include <iostream> -/* I'll use an INI-based config file instead of using an - * XML file like Taiga. - * - * It technically isn't to spec, because I'm making these case-sensitive. - * Boohoo. - */ +/* NOTE: This config file is prone to breakage, as Minori is alpha software and + * as such nothing is constant. */ int Config::Load() { std::filesystem::path cfg_path = Filesystem::GetConfigPath(); - mINI::INIFile file(cfg_path.u8string()); - mINI::INIStructure ini; - file.read(ini); + std::ifstream ifs(cfg_path, std::ios_base::binary); + if (!ifs.good()) + return 0; - service = Translate::ToService(INI::GetIniString(ini, "General", "Service", "None")); + toml::value data; - anime_list.score_format = - Translate::ToScoreFormat(INI::GetIniString(ini, "Anime List", "Score format", "POINT_100")); - anime_list.language = - Translate::ToLanguage(INI::GetIniString(ini, "Anime List", "Title language", "Romaji")); - anime_list.display_aired_episodes = INI::GetIniBool(ini, "Anime List", "Display only aired episodes", true); - anime_list.display_available_episodes = - INI::GetIniBool(ini, "Anime List", "Display only available episodes in library", true); - anime_list.highlight_anime_if_available = - INI::GetIniBool(ini, "Anime List", "Highlight anime if available", true); + try { + data = toml::parse(ifs); + } catch (const std::exception& ex) { + std::cerr << "config: failed to parse toml with error " << ex.what() << std::endl; + return 0; + } + + service = Translate::ToService(toml::find_or(data, "General", "Service", "None")); + locale.RefreshAvailableLocales(); + locale.SetActiveLocale(QLocale(Strings::ToQString(toml::find_or(data, "General", "Locale", "en_US")))); + - if (anime_list.highlight_anime_if_available) // sanity check - anime_list.highlighted_anime_above_others = - INI::GetIniBool(ini, "Anime List", "Display highlighted anime above others", false); - else - anime_list.highlighted_anime_above_others = false; - - auth.anilist.auth_token = INI::GetIniString(ini, "Authentication/AniList", "Auth Token", ""); - auth.anilist.user_id = INI::GetIniInteger<int>(ini, "Authentication/AniList", "User ID", 0); + anime_list.score_format = Translate::ToScoreFormat(toml::find_or(data, "Anime List", "Score format", "100-point")); + anime_list.language = Translate::ToLanguage(toml::find_or(data, "Anime List", "Title language", "Romaji")); + anime_list.display_aired_episodes = toml::find_or<bool>(data, "Anime List", "Display only aired episodes", true); + anime_list.display_available_episodes = toml::find_or<bool>(data, "Anime List", "Display only available episodes in library", true); + anime_list.highlight_anime_if_available = toml::find_or<bool>(data, "Anime List", "Highlight anime if available", true); + anime_list.highlighted_anime_above_others = + (anime_list.highlight_anime_if_available) + ? toml::find_or<bool>(data, "Anime List", "Display highlighted anime above others", false) + : false; - auth.kitsu.access_token = INI::GetIniString(ini, "Authentication/Kitsu", "Access Token", ""); - auth.kitsu.access_token_expiration = INI::GetIniInteger<Time::Timestamp>(ini, "Authentication/Kitsu", "Access Token Expiration", 0); - auth.kitsu.refresh_token = INI::GetIniString(ini, "Authentication/Kitsu", "Refresh Token", ""); - auth.kitsu.user_id = INI::GetIniString(ini, "Authentication/Kitsu", "User ID", ""); + auth.anilist.auth_token = toml::find_or(data, "Authentication/AniList", "Auth Token", ""); + auth.anilist.user_id = toml::find_or<int>(data, "Authentication/AniList", "User ID", 0); - torrents.feed_link = INI::GetIniString(ini, "Torrents", "RSS feed", - "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0"); + auth.kitsu.access_token = toml::find_or(data, "Authentication/Kitsu", "Access Token", ""); + auth.kitsu.access_token_expiration = toml::find_or(data, "Authentication/Kitsu", "Access Token Expiration", 0LL); + auth.kitsu.refresh_token = toml::find_or(data, "Authentication/Kitsu", "Refresh Token", ""); + auth.kitsu.user_id = toml::find_or(data, "Authentication/Kitsu", "User ID", ""); - recognition.detect_media_players = INI::GetIniBool(ini, "Recognition", "Detect media players", true); + torrents.feed_link = toml::find_or(data, "Torrents", "RSS feed", "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0"); - /* lots of dumb logic to import the player data */ + recognition.detect_media_players = toml::find_or(data, "Recognition", "Detect media players", true); + { - /* load the player data */ QFile f(":/players.anisthesia"); if (!f.exists()) return false; @@ -94,28 +90,26 @@ switch (player.type) { default: case animone::PlayerType::Default: - enabled = INI::GetIniBool(ini, "Recognition/Players", player.name, true); + enabled = toml::find_or<bool>(data, "Recognition/Players", player.name, true); break; case animone::PlayerType::WebBrowser: - enabled = INI::GetIniBool(ini, "Recognition/Browsers", player.name, true); + enabled = toml::find_or<bool>(data, "Recognition/Browsers", player.name, true); break; } } - locale.RefreshAvailableLocales(); - locale.SetActiveLocale( - QLocale(Strings::ToQString(INI::GetIniString(ini, "General", "Locale", "en_US")))); + + theme.SetTheme(Translate::ToTheme(toml::find_or(data, "Appearance", "Theme", "Default"))); - theme.SetTheme(Translate::ToTheme(INI::GetIniString(ini, "Appearance", "Theme", "Default"))); - - { - std::vector<std::string> v = Strings::Split(INI::GetIniString(ini, "Library", "Folders", ""), ";"); + if (data.contains("Library") && data["Library"].contains("Folders")) { + const toml::value& folders = toml::find(data, "Library", "Folders"); + std::vector<std::string> v = toml::get_or<std::vector<std::string>>(folders, {}); for (const auto& s : v) if (!library.paths.count(s)) library.paths.insert(s); } - library.real_time_monitor = INI::GetIniBool(ini, "Library", "Real-time monitor", true); + library.real_time_monitor = toml::find_or(data, "Library", "Real-time monitor", true); return 0; } @@ -124,42 +118,45 @@ std::filesystem::path cfg_path = Filesystem::GetConfigPath(); Filesystem::CreateDirectories(cfg_path); - mINI::INIFile file(cfg_path.string()); - mINI::INIStructure ini; - - ini["General"]["Service"] = Translate::ToString(service); - ini["General"]["Locale"] = Strings::ToUtf8String(locale.GetLocale().name()); - - ini["Anime List"]["Score format"] = Translate::ToString(anime_list.score_format); - 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); + std::ofstream file(cfg_path); + if (!file.good()) + return 0; - ini["Authentication/AniList"]["Auth Token"] = auth.anilist.auth_token; - ini["Authentication/AniList"]["User ID"] = Strings::ToUtf8String(auth.anilist.user_id); + toml::value data; - ini["Authentication/Kitsu"]["Access Token"] = auth.kitsu.access_token; - ini["Authentication/Kitsu"]["Access Token Expiration"] = Strings::ToUtf8String(auth.kitsu.access_token_expiration); - ini["Authentication/Kitsu"]["Refresh Token"] = auth.kitsu.refresh_token; - ini["Authentication/Kitsu"]["User ID"] = auth.kitsu.user_id; - - ini["Appearance"]["Theme"] = Translate::ToString(theme.GetTheme()); - - ini["Torrents"]["RSS feed"] = torrents.feed_link; - - ini["Recognition"]["Detect media players"] = Strings::ToUtf8String(recognition.detect_media_players); + data["Library"]["Folders"] = library.paths; + data["Library"]["Real-time monitor"] = library.real_time_monitor; for (const auto& [enabled, player] : recognition.players) { const std::string section = (player.type == animone::PlayerType::WebBrowser) ? "Recognition/Players" : "Recognition/Browsers"; - ini[section][player.name] = Strings::ToUtf8String(enabled); + data[section][player.name] = enabled; } - ini["Library"]["Folders"] = Strings::Implode(library.paths, ";"); - ini["Library"]["Real-time monitor"] = Strings::ToUtf8String(library.real_time_monitor); + data["Recognition"]["Detect media players"] = recognition.detect_media_players; + + data["Torrents"]["RSS feed"] = torrents.feed_link; + + data["Authentication/Kitsu"]["Access Token"] = auth.kitsu.access_token; + data["Authentication/Kitsu"]["Access Token Expiration"] = auth.kitsu.access_token_expiration; + data["Authentication/Kitsu"]["Refresh Token"] = auth.kitsu.refresh_token; + data["Authentication/Kitsu"]["User ID"] = auth.kitsu.user_id; + + data["Authentication/AniList"]["Auth Token"] = auth.anilist.auth_token; + data["Authentication/AniList"]["User ID"] = auth.anilist.user_id; - file.write(ini); + data["Anime List"]["Score format"] = Translate::ToString(anime_list.score_format); + data["Anime List"]["Title language"] = Translate::ToString(anime_list.language); + data["Anime List"]["Display only aired episodes"] = anime_list.display_aired_episodes; + data["Anime List"]["Display only available episodes in library"] = anime_list.display_available_episodes; + data["Anime List"]["Highlight anime if available"] = anime_list.highlight_anime_if_available; + data["Anime List"]["Display highlighted anime above others"] = anime_list.highlighted_anime_above_others; + + data["Appearance"]["Theme"] = Translate::ToString(theme.GetTheme()); + + data["General"]["Service"] = Translate::ToString(service); + data["General"]["Locale"] = Strings::ToUtf8String(locale.GetLocale().name()); + + file << std::setw(0) << data; return 0; }