diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2018-11-26 23:19:40 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2018-11-26 23:19:40 +0100 |
| commit | 97390d565eca8004edb1d262c282aaf9e47c3b7b (patch) | |
| tree | 7590e094e17a9e8732fc48b76b8f38c4ba866e9b | |
| parent | bae92cea3bcbacd7883499da61a0e54f13da6d23 (diff) | |
| download | wanda-97390d565eca8004edb1d262c282aaf9e47c3b7b.tar.xz wanda-97390d565eca8004edb1d262c282aaf9e47c3b7b.zip | |
fs: implement filesystem access
| -rw-r--r-- | .vscode/settings.json | 3 | ||||
| -rw-r--r-- | CMakeLists.txt | 3 | ||||
| -rw-r--r-- | cmake/Modules/SystemDependencies.cmake | 9 | ||||
| -rw-r--r-- | conanfile.py | 1 | ||||
| -rw-r--r-- | src/filesystem.cpp | 30 | ||||
| -rw-r--r-- | src/filesystem.hpp | 35 | ||||
| -rw-r--r-- | src/main.cpp | 48 |
7 files changed, 114 insertions, 15 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json index 3974147..7192bf1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,7 @@ "utility": "cpp", "string": "cpp", "variant": "cpp", - "string_view": "cpp" + "string_view": "cpp", + "ostream": "cpp" } }
\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f9b4906..e82b59e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,8 @@ add_executable("wanda" # Components "src/deferred_failure.hpp" + "src/filesystem.cpp" + "src/filesystem.hpp" "src/optional.hpp" "src/setting.cpp" "src/setting.hpp" @@ -33,5 +35,6 @@ add_executable("wanda" target_link_libraries("wanda" "CONAN_PKG::boost_config" + "SYSTEM::C++FS" "SYSTEM::GIO" ) diff --git a/cmake/Modules/SystemDependencies.cmake b/cmake/Modules/SystemDependencies.cmake index 0b1321f..8200824 100644 --- a/cmake/Modules/SystemDependencies.cmake +++ b/cmake/Modules/SystemDependencies.cmake @@ -1,7 +1,14 @@ find_package("PkgConfig" REQUIRED) +find_library(C++FS_LIBRARIES "stdc++fs" DOC "The C++ Standard Library Filesystem implementation") +if(NOT C++FS_LIBRARIES) + message(FATAL_ERROR "Failed to find libstdc++fs") +endif() +add_library("SYSTEM::C++FS" INTERFACE IMPORTED) +set_property(TARGET "SYSTEM::C++FS" PROPERTY INTERFACE_LINK_LIBRARIES ${C++FS_LIBRARIES}) + pkg_check_modules("GIO" "gio-2.0" REQUIRED) add_library("SYSTEM::GIO" INTERFACE IMPORTED) set_property(TARGET "SYSTEM::GIO" PROPERTY INTERFACE_LINK_LIBRARIES ${GIO_LIBRARIES}) set_property(TARGET "SYSTEM::GIO" PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${GIO_INCLUDE_DIRS}) -set_property(TARGET "SYSTEM::GIO" PROPERTY INTERFACE_COMPILE_OPTIONS ${GIO_CFLAGS} ${GIO_CFLAGS_OTHER}) +set_property(TARGET "SYSTEM::GIO" PROPERTY INTERFACE_COMPILE_OPTIONS ${GIO_CFLAGS} ${GIO_CFLAGS_OTHER})
\ No newline at end of file diff --git a/conanfile.py b/conanfile.py index ddb17e8..e084427 100644 --- a/conanfile.py +++ b/conanfile.py @@ -14,6 +14,7 @@ class Wanda(ConanFile): ) requires = ( "boost_program_options/1.67.0@bincrafters/stable", + "boost_iterator/1.67.0@bincrafters/stable", ) def build(self): diff --git a/src/filesystem.cpp b/src/filesystem.cpp new file mode 100644 index 0000000..4dfa183 --- /dev/null +++ b/src/filesystem.cpp @@ -0,0 +1,30 @@ +#include "filesystem.hpp" + +#include <boost/iterator/filter_iterator.hpp> + +#include <random> + +namespace wanda +{ + +std::optional<path_list> scan(std::filesystem::path source, bool(filter)(std::filesystem::path const &)) +{ + if (!std::filesystem::is_directory(source)) + { + return std::nullopt; + } + + auto first = boost::make_filter_iterator(filter, std::filesystem::recursive_directory_iterator{source}); + auto last = boost::make_filter_iterator(filter, std::filesystem::recursive_directory_iterator{}); + return path_list{first, last}; +} + +std::filesystem::path random_pick(path_list const &paths) +{ + static auto generator = std::mt19937{std::random_device{}()}; + auto distribution = std::uniform_int_distribution<std::size_t>{0, paths.size() - 1}; + + return paths[distribution(generator)]; +} + +} // namespace wanda
\ No newline at end of file diff --git a/src/filesystem.hpp b/src/filesystem.hpp new file mode 100644 index 0000000..bcc9e5e --- /dev/null +++ b/src/filesystem.hpp @@ -0,0 +1,35 @@ +#ifndef WANDA_FILESYSTEM_HPP +#define WANDA_FILESYSTEM_HPP + +#include <filesystem> +#include <optional> +#include <vector> + +namespace wanda +{ + +/** + * @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 + +#endif
\ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 38fdf7f..6d1353d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,28 +1,50 @@ +#include "filesystem.hpp" #include "setting.hpp" #include "optional.hpp" #include <iostream> +#include <set> #include <string> -#include <typeinfo> +namespace +{ -int main() +void set_wallpaper(std::filesystem::path wallpaper) { using namespace wanda::literals; using namespace wanda::std_ext; using namespace std::string_literals; - with("org.gnome.desktop.background"_setting, [](auto &setting) { - with(setting["picture-uri"_key], [](auto &value) { - std::visit([](auto &&value) { - using ValueType = std::decay_t<decltype(value)>; - if constexpr (std::is_same_v<ValueType, std::string>) - { - std::cout << value << '\n'; - } - }, - *value); - std::cout << (value = "file:///"s) << '\n'; + with("org.gnome.desktop.background"_setting, [&](auto &setting) { + with(setting["picture-uri"_key], [&](auto &value) { + value = "file://" + wallpaper.native(); }) || [] { std::cerr << "No such key!\n"; }; }) || [] { std::cerr << "No such setting!\n"; }; } + +constexpr auto image_filter = [](auto const &path) { + static auto const extensions = std::set<std::filesystem::path>{ + std::filesystem::path{".jpg"}, + std::filesystem::path{".png"}, + }; + + if (!std::filesystem::is_regular_file(path)) + { + return false; + } + + return extensions.find(path.extension()) != extensions.cend(); +}; + +} // namespace + +int main() +{ + using namespace wanda::std_ext; + + with(wanda::scan({"/usr/share/backgrounds"}, image_filter), [](auto const &list) { + auto wallpaper = wanda::random_pick(list); + std::cout << "changing wallpaper to " << wallpaper << '\n'; + set_wallpaper(wallpaper); + }) || [] { std::cerr << "Directory does not exist\n"; }; +} |
