view src/core/config.cc @ 337:a7d4e5107531

dep/animone: REFACTOR ALL THE THINGS 1: animone now has its own syntax divergent from anisthesia, making different platforms actually have their own sections 2: process names in animone are now called `comm' (this will probably break things). this is what its called in bsd/linux so I'm just going to use it everywhere 3: the X11 code now checks for the existence of a UTF-8 window title and passes it if available 4: ANYTHING THATS NOT LINUX IS 100% UNTESTED AND CAN AND WILL BREAK! I still actually need to test the bsd code. to be honest I'm probably going to move all of the bsds into separate files because they're all essentially different operating systems at this point
author Paper <paper@paper.us.eu.org>
date Wed, 19 Jun 2024 12:51:15 -0400
parents 1b5c04268d6a
children
line wrap: on
line source

#include "core/config.h"
#include "core/anime.h"
#include "core/filesystem.h"
#include "core/json.h"
#include "core/strings.h"
#include "gui/translate/anime.h"
#include "gui/translate/config.h"

#include "animone/player.h"

#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <limits.h>

#include <toml11/toml.hpp>

#include <QFile>
#include <QTextStream>

#include <iostream>

/* 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();

	std::ifstream ifs(cfg_path, std::ios_base::binary);
	if (!ifs.good())
		return 0;

	toml::value data;

	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"))));


	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(data, "Anime List", "Display only aired episodes", true);
	anime_list.display_available_episodes = toml::find_or(data, "Anime List", "Display only available episodes in library", true);
	anime_list.highlight_anime_if_available = toml::find_or(data, "Anime List", "Highlight anime if available", true);
	anime_list.highlighted_anime_above_others =
		(anime_list.highlight_anime_if_available)
		? toml::find_or(data, "Anime List", "Display highlighted anime above others", false)
		: false;

	auth.anilist.auth_token = toml::find_or(data, "Authentication/AniList", "Auth Token", "");
	auth.anilist.user_id = toml::find_or(data, "Authentication/AniList", "User ID", 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", static_cast<Time::Timestamp>(0));
	auth.kitsu.refresh_token = toml::find_or(data, "Authentication/Kitsu", "Refresh Token", "");
	auth.kitsu.user_id = toml::find_or(data, "Authentication/Kitsu", "User ID", "");

	torrents.feed_link = toml::find_or(data, "Torrents", "RSS feed", "https://www.tokyotosho.info/rss.php?filter=1,11&zwnj=0");

	recognition.detect_media_players = toml::find_or(data, "Recognition", "Detect media players", true);

	{
		QFile f(":/players.animone");
		if (!f.exists())
			return false;

		f.open(QFile::ReadOnly | QFile::Text);
		QTextStream ts(&f);

		std::vector<animone::Player> players;

		if (!animone::ParsePlayersData(Strings::ToUtf8String(ts.readAll()), players))
			return false;

		recognition.players.reserve(players.size());
		for (const auto& player : players)
			recognition.players.push_back({true, player});
	}

	for (auto& [enabled, player] : recognition.players) {
		switch (player.type) {
			default:
			case animone::PlayerType::Default:
				enabled = toml::find_or(data, "Recognition/Players", player.name, true);
				break;
			case animone::PlayerType::WebBrowser:
				enabled = toml::find_or(data, "Recognition/Browsers", player.name, true);
				break;
		}
	}


	theme.SetTheme(Translate::ToTheme(toml::find_or(data, "Appearance", "Theme", "Default")));

	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 = toml::find_or(data, "Library", "Real-time monitor", true);

	return 0;
}

int Config::Save() {
	std::filesystem::path cfg_path = Filesystem::GetConfigPath();
	Filesystem::CreateDirectories(cfg_path);

	std::ofstream file(cfg_path);
	if (!file.good())
		return 0;

	toml::value data;

	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";
		data[section][player.name] = enabled;
	}

	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;

	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;
}