Skip to content

Commit

Permalink
config: rework + add pkg managers specific paths
Browse files Browse the repository at this point in the history
  • Loading branch information
Toni500github committed Aug 25, 2024
1 parent 00f9be8 commit d104819
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 79 deletions.
44 changes: 30 additions & 14 deletions include/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,31 @@ class Config
Config(const std::string_view configFile, const std::string_view configDir, colors_t& colors);

// config file
std::string source_path;
std::string font;
std::string data_dir;
std::string sep_reset;
std::string gui_bg_image;
std::string ascii_logo_type;
std::uint16_t offset = 0;
std::uint16_t logo_padding_left = 0;
std::uint16_t logo_padding_top = 0;
std::uint16_t layout_padding_top = 0;

bool gui = false;
std::vector<std::string> layouts;
std::vector<std::string> pkgs_managers;
std::string source_path;
std::string font;
std::string data_dir;
std::string sep_reset;
std::string gui_bg_image;
std::string ascii_logo_type;
std::uint16_t offset = 0;
std::uint16_t logo_padding_left = 0;
std::uint16_t logo_padding_top = 0;
std::uint16_t layout_padding_top = 0;
bool gui = false;

// modules specific config
std::string uptime_d_fmt;
std::string uptime_h_fmt;
std::string uptime_m_fmt;
std::string uptime_s_fmt;

std::vector<std::string> pkgs_managers;
std::vector<std::string> pacman_dirs;
std::vector<std::string> flatpak_dirs;
std::vector<std::string> dpkg_files;
std::vector<std::string> apk_files;

// inner management
std::string m_custom_distro;
bool m_disable_source = false;
Expand All @@ -67,8 +71,10 @@ class Config
std::string getThemeValue(const std::string& value, const std::string& fallback) const;
void generateConfig(const std::string_view filename);

std::vector<std::string> getValueArrayStr(const std::string& value);

template <typename T>
T getConfigValue(const std::string& value, const T&& fallback) const
T getValue(const std::string& value, const T&& fallback) const
{
std::optional<T> ret = this->tbl.at_path(value).value<T>();
if constexpr (toml::is_string<T>) // if we want to get a value that's a string
Expand Down Expand Up @@ -201,6 +207,16 @@ secs = " seconds"
# e.g "Packages: $(pacman -Q | wc -l) (pacman)"
pkg-managers = ["pacman", "dpkg", "flatpak"]
# Distros and package manager specific
# package manager paths for getting the packages count from path.
# They are arrayies so you can add multiple paths.
#
# If you don't know what these ares, leave them by default settings
pacman-dirs = ["/var/lib/pacman/local/"]
dpkg-files = ["/var/lib/dpkg/status"]
flatpak-dirs = ["/var/lib/flatpak/app/", "~/.local/share/flatpak/app/"]
apk-files = ["/var/lib/apk/db/installed"]
# GUI options
# note: customfetch needs to be compiled with GUI_MODE=1 (check with "cufetch --version")
[gui]
Expand Down
29 changes: 29 additions & 0 deletions include/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <dlfcn.h>
#include <sys/types.h>

#include <iostream>
#include <string>
#include <vector>

Expand Down Expand Up @@ -104,4 +105,32 @@ void warn(const std::string_view fmt, Args&&... args) noexcept
fmt::format(fmt::runtime(fmt), std::forward<Args>(args)...));
}

/** Ask the user a yes or no question.
* @param def The default result
* @param fmt The format string
* @param args Arguments in the format
* @returns the result, y = true, f = false, only returns def if the result is def
*/
template <typename... Args>
bool askUserYorN(bool def, const std::string_view fmt, Args&&... args)
{
const std::string& inputs_str = fmt::format("[{}/{}]: ", (def ? 'Y' : 'y'), (!def ? 'N' : 'n'));
std::string result;
fmt::print(fmt::runtime(fmt), std::forward<Args>(args)...);
fmt::print(" {}", inputs_str);

while (std::getline(std::cin, result) && (result.length() > 1))
fmt::print(BOLD_COLOR(fmt::rgb(fmt::color::yellow)), "Please answear y or n, {}", inputs_str);

ctrl_d_handler(std::cin);

if (result.empty())
return def;

if (def ? tolower(result[0]) != 'n' : tolower(result[0]) != 'y')
return def;

return !def;
}

#endif
111 changes: 51 additions & 60 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,53 +36,31 @@ void Config::loadConfigFile(const std::string_view filename, colors_t& colors)
exit(-1);
}

// https://stackoverflow.com/a/78266628
// changed instead of vector<int> to vector<string>
const auto& layout_array = tbl.at_path("config.layout");
if (toml::array* arr = layout_array.as_array())
arr->for_each(
[this, filename](auto&& el)
{
if (const auto* str_elem = el.as_string())
{
auto v = *str_elem;
this->layouts.push_back(v->data()); // here's the thing
}
else
warn("An element of the layout variable in {} is not a string", filename);
});

const auto& pkg_managers_array = tbl.at_path("os.pkgs.pkg-managers");
if (toml::array* arr = pkg_managers_array.as_array())
arr->for_each(
[this, filename](auto&& element)
{
if (const auto* str_element = element.as_string())
{
auto element_value = *str_element;
this->pkgs_managers.push_back(str_tolower(element_value->data()));
}
else
warn("An element of the pkg-managers variable in {} is not a string", filename);
});

// clang-format off
this->gui = this->getConfigValue<bool>("gui.enable", false);
this->ascii_logo_type = this->getConfigValue<std::string>("config.ascii-logo-type", "");
this->source_path = this->getConfigValue<std::string>("config.source-path", "os");
this->data_dir = this->getConfigValue<std::string>("config.data-dir", "/usr/share/customfetch");
this->sep_reset = this->getConfigValue<std::string>("config.sep-reset", ":");
this->offset = this->getConfigValue<std::uint16_t>("config.offset", 5);
this->logo_padding_left = this->getConfigValue<std::uint16_t>("config.logo-padding-left", 0);
this->layout_padding_top = this->getConfigValue<std::uint16_t>("config.layout-padding-top", 0);
this->font = this->getConfigValue<std::string>("gui.font", "Liberation Mono Normal 12");
this->gui_bg_image = this->getConfigValue<std::string>("gui.bg-image", "disable");
this->logo_padding_top = this->getConfigValue<std::uint16_t>("config.logo-padding-top", 0);

this->uptime_d_fmt = this->getConfigValue<std::string>("os.uptime.days", " days");
this->uptime_h_fmt = this->getConfigValue<std::string>("os.uptime.hours", " hours");
this->uptime_m_fmt = this->getConfigValue<std::string>("os.uptime.mins", " mins");
this->uptime_s_fmt = this->getConfigValue<std::string>("os.uptime.secs", " secs");
// Idk but with `this->` looks more readable
this->layouts = this->getValueArrayStr("config.layout");
this->gui = this->getValue<bool>("gui.enable", false);
this->ascii_logo_type = this->getValue<std::string>("config.ascii-logo-type", "");
this->source_path = this->getValue<std::string>("config.source-path", "os");
this->data_dir = this->getValue<std::string>("config.data-dir", "/usr/share/customfetch");
this->sep_reset = this->getValue<std::string>("config.sep-reset", ":");
this->offset = this->getValue<std::uint16_t>("config.offset", 5);
this->logo_padding_left = this->getValue<std::uint16_t>("config.logo-padding-left", 0);
this->layout_padding_top = this->getValue<std::uint16_t>("config.layout-padding-top", 0);
this->font = this->getValue<std::string>("gui.font", "Liberation Mono Normal 12");
this->gui_bg_image = this->getValue<std::string>("gui.bg-image", "disable");
this->logo_padding_top = this->getValue<std::uint16_t>("config.logo-padding-top", 0);

this->uptime_d_fmt = this->getValue<std::string>("os.uptime.days", " days");
this->uptime_h_fmt = this->getValue<std::string>("os.uptime.hours", " hours");
this->uptime_m_fmt = this->getValue<std::string>("os.uptime.mins", " mins");
this->uptime_s_fmt = this->getValue<std::string>("os.uptime.secs", " secs");

this->pkgs_managers= this->getValueArrayStr("os.pkgs.pkg-managers");
this->pacman_dirs = this->getValueArrayStr("os.pkgs.pacman-dirs");
this->dpkg_files = this->getValueArrayStr("os.pkgs.dpkg-files");
this->flatpak_dirs = this->getValueArrayStr("os.pkgs.flatpak-dirs");
this->apk_files = this->getValueArrayStr("os.pkgs.apk-files");

colors.black = this->getThemeValue("config.black", "\033[1;30m");
colors.red = this->getThemeValue("config.red", "\033[1;31m");
Expand Down Expand Up @@ -110,24 +88,37 @@ std::string Config::getThemeValue(const std::string& value, const std::string& f
return this->tbl.at_path(value).value<std::string>().value_or(fallback);
}

std::vector<std::string> Config::getValueArrayStr(const std::string& value)
{
std::vector<std::string> ret;

// https://stackoverflow.com/a/78266628
const auto& array = tbl.at_path(value);
if (toml::array* array_it = array.as_array())
{
array_it->for_each(
[&ret, value](auto&& el)
{
if (toml::value<std::string>* str_elem = el.as_string())
{
toml::value<std::string> v = *str_elem;
ret.push_back(v->data());
}
else
warn("An element of the {} array variable is not a string", value);
}
);
}

return ret;
}

void Config::generateConfig(const std::string_view filename)
{
if (std::filesystem::exists(filename))
{
std::string result;
// warn() without new line
fmt::print(BOLD_COLOR((fmt::rgb(fmt::color::yellow))),
"WARNING: config file {} already exists. Do you want to overwrite it? [y/N]: ", filename);
while (std::getline(std::cin, result) && (result.length() > 1))
{
error("Please answear y or n");
fmt::print(BOLD_COLOR(fmt::rgb(fmt::color::yellow)), "[y/N]: ");
}

ctrl_d_handler(std::cin);

if (result.empty() || std::tolower(result[0]) != 'y')
exit(1);
if (!askUserYorN(false, "WARNING: config file {} already exists. Do you want to overwrite it?", filename))
std::exit(1);
}

std::ofstream f(filename.data(), std::ios::trunc);
Expand Down
13 changes: 8 additions & 5 deletions src/query/unix/utils/packages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,26 @@ std::string get_all_pkgs(const Config& config)
switch (fnv1a16::hash(name))
{
case "pacman"_fnv1a16:
pkgs_count.pacman = get_num_count_dir("/var/lib/pacman/local");
for (const std::string& str : config.pacman_dirs)
pkgs_count.pacman += get_num_count_dir(expandVar(str));
ADD_PKGS_COUNT(pacman);
break;

case "flatpak"_fnv1a16:
pkgs_count.flatpak += get_num_count_dir("/var/lib/flatpak/app");
pkgs_count.flatpak += get_num_count_dir(expandVar("~/.local/share/flatpak/app"));
for (const std::string& str : config.flatpak_dirs)
pkgs_count.flatpak += get_num_count_dir(expandVar(str));
ADD_PKGS_COUNT(flatpak);
break;

case "dpkg"_fnv1a16:
pkgs_count.dpkg = get_num_string_file("/var/lib/dpkg/status", "Status: install ok installed");
for (const std::string& str : config.dpkg_files)
pkgs_count.dpkg += get_num_string_file(expandVar(str), "Status: install ok installed");
ADD_PKGS_COUNT(dpkg);
break;

case "apk"_fnv1a16:
pkgs_count.apk = get_num_string_file("/var/lib/apk/db/installed", "C:Q");
for (const std::string& str : config.apk_files)
pkgs_count.apk += get_num_string_file(expandVar(str), "C:Q");
ADD_PKGS_COUNT(apk);
break;
}
Expand Down

0 comments on commit d104819

Please sign in to comment.