diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2024-05-17 17:58:38 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2024-05-17 17:58:38 +0200 |
| commit | 577fc0845718ed8ad5bebf02a277c0579a817f77 (patch) | |
| tree | 3d1cdc53c426a0ba60a7996619a7b787850bb3b3 /source/lib/include/wanda/system | |
| parent | de5bf7ca3b7a2bf6be35b86486b00dc6a071b950 (diff) | |
| download | wanda-577fc0845718ed8ad5bebf02a277c0579a817f77.tar.xz wanda-577fc0845718ed8ad5bebf02a277c0579a817f77.zip | |
Diffstat (limited to 'source/lib/include/wanda/system')
| -rw-r--r-- | source/lib/include/wanda/system/environment.hpp | 61 | ||||
| -rw-r--r-- | source/lib/include/wanda/system/filesystem.hpp | 39 | ||||
| -rw-r--r-- | source/lib/include/wanda/system/logging.hpp | 35 | ||||
| -rw-r--r-- | source/lib/include/wanda/system/magic.hpp | 58 | ||||
| -rw-r--r-- | source/lib/include/wanda/system/setting.hpp | 156 | ||||
| -rw-r--r-- | source/lib/include/wanda/system/wallpaper.hpp | 24 | ||||
| -rw-r--r-- | source/lib/include/wanda/system/xdg.hpp | 40 |
7 files changed, 413 insertions, 0 deletions
diff --git a/source/lib/include/wanda/system/environment.hpp b/source/lib/include/wanda/system/environment.hpp new file mode 100644 index 0000000..8cd9ecf --- /dev/null +++ b/source/lib/include/wanda/system/environment.hpp @@ -0,0 +1,61 @@ +/** + * @file environment.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + +#ifndef WANDA_SYSTEM_ENVIRONMENT_HPP +#define WANDA_SYSTEM_ENVIRONMENT_HPP + +#include <unistd.h> + +#include <map> +#include <string> + +namespace wanda::system +{ + /** + * @brief A type to provide access to the runtime environment + */ + struct environment + { + using map_type = std::map<std::string, std::string>; + using iterator = map_type::iterator; + using const_iterator = map_type::const_iterator; + using reference = map_type::reference; + using const_reference = map_type::const_reference; + + /** + * @brief Construct a new environment from the given string array + */ + explicit environment(char const * const * env = ::environ); + + /** + * @brief Get the value of the given variable + * + * @return A mutable reference to the value of the given environment variable + */ + std::string & operator[](std::string const & variable); + + /** + * @brief Get the value of the given variable + * + * @return An immutable reference to the value of the given environment variable + */ + std::string const & operator[](std::string const & variable) const; + + iterator begin(); + const_iterator begin() const; + const_iterator cbegin() const; + + iterator end(); + const_iterator end() const; + const_iterator cend() const; + + private: + map_type m_cache{}; + }; + +} // namespace wanda::system + +#endif
\ No newline at end of file diff --git a/source/lib/include/wanda/system/filesystem.hpp b/source/lib/include/wanda/system/filesystem.hpp new file mode 100644 index 0000000..971db90 --- /dev/null +++ b/source/lib/include/wanda/system/filesystem.hpp @@ -0,0 +1,39 @@ +/** + * @file filesystem.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + +#ifndef WANDA_SYSTEM_FILESYSTEM_HPP +#define WANDA_SYSTEM_FILESYSTEM_HPP + +#include <filesystem> +#include <optional> +#include <vector> + +namespace wanda::system +{ + /** + * @brief Covenience alias for path lists + */ + using path_list = std::vector<std::filesystem::path>; + + /** + * @brief The default scan filter, allowing only regular files to pass + */ + constexpr inline auto default_filter = [](std::filesystem::path const & path) { + return is_regular_file(path); + }; + + /** + * @brief Scan the given folder for files + */ + std::optional<path_list> scan(std::filesystem::path folder, bool(filter)(std::filesystem::path const &) = default_filter); + + /** + * @brief Pick a random path from the given list + */ + std::filesystem::path random_pick(path_list const & paths); +} // namespace wanda::system + +#endif
\ No newline at end of file diff --git a/source/lib/include/wanda/system/logging.hpp b/source/lib/include/wanda/system/logging.hpp new file mode 100644 index 0000000..8a9a90e --- /dev/null +++ b/source/lib/include/wanda/system/logging.hpp @@ -0,0 +1,35 @@ +/** + * @file logging.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + +#ifndef WANDA_SYSTEM_LOGGING_HPP +#define WANDA_SYSTEM_LOGGING_HPP + +#include <spdlog/sinks/null_sink.h> +#include <spdlog/spdlog.h> + +#include <memory> + +namespace wanda::system +{ + /** + * @brief A covenience alias to represent a handle for a logger + */ + using logger_ptr = std::shared_ptr<spdlog::logger>; + + /** + * @brief Initialize the shared logger + * + * @note The logger will only ever be initialized once, even if this function is called multiple times + */ + void initialize_logger(spdlog::sink_ptr sink = std::make_shared<spdlog::sinks::null_sink_st>()); + + /** + * @brief Get the shared logger + */ + logger_ptr get_logger(); +} // namespace wanda::system + +#endif
\ No newline at end of file diff --git a/source/lib/include/wanda/system/magic.hpp b/source/lib/include/wanda/system/magic.hpp new file mode 100644 index 0000000..a8ea1ba --- /dev/null +++ b/source/lib/include/wanda/system/magic.hpp @@ -0,0 +1,58 @@ +#ifndef WANDA_SYSTEM_MAGIC_HPP +#define WANDA_SYSTEM_MAGIC_HPP + +#include <magic.h> + +#include <filesystem> +#include <memory> +#include <string> +#include <type_traits> + +namespace wanda::system +{ + struct magic + { + struct closer + { + auto operator()(magic_t handle) const noexcept -> void + { + magic_close(handle); + } + }; + + enum struct mime_type + { + unknown, + image_jpeg, + image_png, + }; + + magic() + : m_handle{magic_open(MAGIC_MIME_TYPE)} + { + magic_load(m_handle.get(), nullptr); + } + + auto type(std::filesystem::path path) -> mime_type + { + auto magic_type = std::string{magic_file(m_handle.get(), path.native().c_str())}; + + if (magic_type == "image/jpeg") + { + return mime_type::image_jpeg; + } + else if (magic_type == "image/png") + { + return mime_type::image_png; + } + + return mime_type::unknown; + } + + private: + std::unique_ptr<std::remove_pointer_t<magic_t>, closer> m_handle; + }; + +} // namespace wanda::system + +#endif
\ No newline at end of file diff --git a/source/lib/include/wanda/system/setting.hpp b/source/lib/include/wanda/system/setting.hpp new file mode 100644 index 0000000..e0be3f4 --- /dev/null +++ b/source/lib/include/wanda/system/setting.hpp @@ -0,0 +1,156 @@ +/** + * @file setting.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + +#ifndef WANDA_SYSTEM_SETTING_HPP +#define WANDA_SYSTEM_SETTING_HPP + +#include "wanda/meta/deferred_failure.hpp" +#include "wanda/meta/type_wrapper.hpp" + +#include <gio/gio.h> + +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <memory> +#include <optional> +#include <string> +#include <variant> +#include <vector> + +namespace wanda::system +{ + struct setting; + + /** + * @brief A convenience type to represent setting keys + */ + using key = meta::type_wrapper<std::string, struct KeyTag>; + + namespace literals + { + /** + * @brief UDL to create setting keys + */ + key operator""_key(char const * str, std::size_t len); + + /** + * @brief UDL to create setting schemas + */ + std::optional<setting> operator""_setting(char const * str, std::size_t lent); + } // namespace literals + + /** + * @brief A simple wrapper for GSettings Schemas + */ + struct setting + { + struct entry + { + using value_type = std::variant<std::monostate, bool, std::int32_t, std::int64_t, std::uint32_t, std::uint64_t, double, std::string, std::vector<std::string>>; + + /** + * @brief Get the value of the settings entry + */ + value_type operator*() const; + + /** + * @brief Assign the given @p value to the settings entry + * + * @returns @p true iff. the value could be successfully assigned + */ + template<typename Type> + bool operator=(Type value) + { + struct setting_applier + { + setting_applier(GSettings * setting, gchar const * key, Type value) noexcept + : m_result{[&] { + if constexpr (std::is_same_v<Type, bool>) + { + return g_settings_set_boolean(setting, key, value); + } + else if constexpr (std::is_same_v<Type, std::int32_t>) + { + return g_settings_set_int(setting, key, value); + } + else if constexpr (std::is_same_v<Type, std::int64_t>) + { + return g_settings_set_int64(setting, key, value); + } + else if constexpr (std::is_same_v<Type, std::uint32_t>) + { + return g_settings_set_uint(setting, key, value); + } + else if constexpr (std::is_same_v<Type, std::uint64_t>) + { + return g_settings_set_uint64(setting, key, value); + } + else if constexpr (std::is_same_v<Type, double>) + { + return g_settings_set_double(setting, key, value); + } + else if constexpr (std::is_same_v<Type, std::string>) + { + return g_settings_set_string(setting, key, value.c_str()); + } + else if constexpr (std::is_same_v<Type, std::vector<std::string>>) + { + auto temp = std::vector<gchar const *>{value.size() + 1}; + std::transform(value.begin(), value.end(), temp.begin(), [](auto const & str) { return str.c_str(); }); + return g_settings_set_strv(setting, key, temp.data()); + } + }()} + { + } + + ~setting_applier() + { + g_settings_sync(); + } + + operator bool() const + { + return m_result; + } + + private: + gboolean const m_result; + }; + + return setting_applier{m_settings.get(), m_key.get().c_str(), value}; + } + + private: + entry(setting const & schema, key key); + + std::unique_ptr<GSettings, decltype(&g_object_unref)> m_settings; + + key m_key; + + friend setting; + }; + + /** + * @brief Get the entry for the given key + * + * @return An <code>std::optional</code> wrapping the entry associated with + * the given key, or an empty <code>std::optional</code> if the desired key + * does not exist in the setting's schema. + */ + std::optional<entry> operator[](key key) const; + + private: + explicit setting(GSettingsSchema * schema); + + std::unique_ptr<GSettingsSchema, decltype(&g_settings_schema_unref)> m_schema; + + friend std::optional<setting> literals::operator""_setting(char const *, std::size_t); + }; + +} // namespace wanda::system + +#endif
\ No newline at end of file diff --git a/source/lib/include/wanda/system/wallpaper.hpp b/source/lib/include/wanda/system/wallpaper.hpp new file mode 100644 index 0000000..7965fb0 --- /dev/null +++ b/source/lib/include/wanda/system/wallpaper.hpp @@ -0,0 +1,24 @@ +/** + * @file wallpaper.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + +#ifndef WANDA_SYSTEM_WALLPAPER_HPP +#define WANDA_SYSTEM_WALLPAPER_HPP + +#include <spdlog/sinks/null_sink.h> +#include <spdlog/spdlog.h> + +#include <filesystem> +#include <memory> + +namespace wanda::system +{ + /** + * @brief Set the wallpaper to the file specified by the given path + */ + void set_wallpaper(std::filesystem::path wallpaper); +} // namespace wanda::system + +#endif
\ No newline at end of file diff --git a/source/lib/include/wanda/system/xdg.hpp b/source/lib/include/wanda/system/xdg.hpp new file mode 100644 index 0000000..ae01feb --- /dev/null +++ b/source/lib/include/wanda/system/xdg.hpp @@ -0,0 +1,40 @@ +/** + * @file xdg.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + +#ifndef WANDA_SYSTEM_XDG_HPP +#define WANDA_SYSTEM_XDG_HPP + +#include "wanda/system/environment.hpp" + +#include <cstddef> +#include <filesystem> +#include <type_traits> + +namespace wanda::system +{ + /** + * @brief An @p enum to represet the standardized XDG directories + */ + enum struct xdg_directory : std::underlying_type_t<std::byte> + { + data_home, + config_home, + cache_home, + runtime_dir, + }; + + /** + * @brief Get the name of the environment variable associated with the given XDG directory + */ + std::string xdg_variable(xdg_directory directory); + + /** + * @brief Get the path to the given @p directory given the provided @p environment + */ + std::filesystem::path xdg_path_for(xdg_directory directory, environment const & environment); +} // namespace wanda::system + +#endif
\ No newline at end of file |
