From 88ab085846b55624e6aa25a96514f78b60f12e96 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 6 Sep 2025 19:30:44 -0500 Subject: [PATCH] [ui] Add auto-mount on first launch functionality #52 --- repertory/repertory/include/ui/handlers.hpp | 3 + .../repertory/include/ui/mgmt_app_config.hpp | 4 + repertory/repertory/src/ui/handlers.cpp | 99 +++++++++++++++---- .../repertory/src/ui/mgmt_app_config.cpp | 16 +++ 4 files changed, 102 insertions(+), 20 deletions(-) diff --git a/repertory/repertory/include/ui/handlers.hpp b/repertory/repertory/include/ui/handlers.hpp index 8fa2d76b..810028aa 100644 --- a/repertory/repertory/include/ui/handlers.hpp +++ b/repertory/repertory/include/ui/handlers.hpp @@ -124,6 +124,9 @@ private: bool background = false) const -> std::vector; + [[nodiscard]] auto mount(provider_type prov, std::string_view name, + const std::string &location) -> bool; + void removed_expired_nonces(); void set_key_value(provider_type prov, std::string_view name, diff --git a/repertory/repertory/include/ui/mgmt_app_config.hpp b/repertory/repertory/include/ui/mgmt_app_config.hpp index 250bdfaa..6276d321 100644 --- a/repertory/repertory/include/ui/mgmt_app_config.hpp +++ b/repertory/repertory/include/ui/mgmt_app_config.hpp @@ -24,6 +24,7 @@ #include "types/repertory.hpp" #include "utils/atomic.hpp" +#include namespace repertory::ui { class mgmt_app_config final { @@ -65,6 +66,9 @@ public: [[nodiscard]] auto get_auto_start(provider_type prov, std::string_view name) const -> bool; + [[nodiscard]] auto get_auto_start_list() const + -> std::unordered_map>; + [[nodiscard]] auto get_hidden() const -> bool { return hidden_; } [[nodiscard]] auto get_launch_only() const -> bool { return launch_only_; } diff --git a/repertory/repertory/src/ui/handlers.cpp b/repertory/repertory/src/ui/handlers.cpp index 3694c3ed..8c2e6ed6 100644 --- a/repertory/repertory/src/ui/handlers.cpp +++ b/repertory/repertory/src/ui/handlers.cpp @@ -293,6 +293,55 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) event_system::instance().start(); + std::jthread auto_mount([this]() { + for (const auto &[prov, names] : config_->get_auto_start_list()) { + for (const auto &name : names) { + try { + auto location = config_->get_mount_location(prov, name); + if (location.empty()) { + utils::error::raise_error(function_name, + utils::error::create_error_message({ + "failed to auto-mount", + "provider", + provider_type_to_string(prov), + "name", + name, + "location is empty", + })); + } else if (not mount(prov, name, location)) { + utils::error::raise_error(function_name, + utils::error::create_error_message({ + "failed to auto-mount", + "provider", + provider_type_to_string(prov), + "name", + name, + "mount failed", + })); + } + } catch (const std::exception &e) { + utils::error::raise_error(function_name, e, + utils::error::create_error_message({ + "failed to auto-mount", + "provider", + provider_type_to_string(prov), + "name", + name, + })); + } catch (...) { + utils::error::raise_error(function_name, "unknown error", + utils::error::create_error_message({ + "failed to auto-mount", + "provider", + provider_type_to_string(prov), + "name", + name, + })); + } + } + } + }); + nonce_thread_ = std::make_unique([this]() { removed_expired_nonces(); }); @@ -625,32 +674,21 @@ void handlers::handle_post_mount(const httplib::Request &req, return; } + res.status = http_error_codes::ok; + auto location = utils::path::absolute(req.get_param_value("location")); auto unmount = utils::string::to_bool(req.get_param_value("unmount")); - if (unmount) { launch_process(prov, name, {"-unmount"}); - } else { -#if defined(_WIN32) - if (utils::file::directory{location}.exists()) { -#else // !defined(_WIN32) - if (not utils::file::directory{location}.exists()) { -#endif // defined(_WIN32) - config_->set_mount_location(prov, name, ""); - res.status = http_error_codes::internal_error; - return; - } - - config_->set_mount_location(prov, name, location); - - static std::mutex mount_mtx; - mutex_lock lock(mount_mtx); - - launch_process(prov, name, {location}, true); - launch_process(prov, name, {"-status"}); + return; } - res.status = http_error_codes::ok; + if (mount(prov, name, location)) { + launch_process(prov, name, {"-status"}); + return; + } + + res.status = http_error_codes::internal_error; } void handlers::handle_put_set_value_by_name(const httplib::Request &req, @@ -821,6 +859,27 @@ auto handlers::launch_process(provider_type prov, std::string_view name, false); } +auto handlers::mount(provider_type prov, std::string_view name, + const std::string &location) -> bool { +#if defined(_WIN32) + if (utils::file::directory{location}.exists()) { +#else // !defined(_WIN32) + if (not utils::file::directory{location}.exists()) { +#endif // defined(_WIN32) + + config_->set_mount_location(prov, name, ""); + return false; + } + + config_->set_mount_location(prov, name, location); + + static std::mutex mount_mtx; + mutex_lock lock(mount_mtx); + + launch_process(prov, name, {location}, true); + return true; +} + void handlers::removed_expired_nonces() { unique_mutex_lock lock(nonce_mtx_); lock.unlock(); diff --git a/repertory/repertory/src/ui/mgmt_app_config.cpp b/repertory/repertory/src/ui/mgmt_app_config.cpp index 6f201119..81e4c73e 100644 --- a/repertory/repertory/src/ui/mgmt_app_config.cpp +++ b/repertory/repertory/src/ui/mgmt_app_config.cpp @@ -142,6 +142,22 @@ auto mgmt_app_config::get_auto_start(provider_type prov, return false; } +auto mgmt_app_config::get_auto_start_list() const + -> std::unordered_map> { + std::unordered_map> ret; + + recur_mutex_lock lock(mtx_); + for (const auto &prov_pair : mount_auto_start_) { + for (const auto &pair : prov_pair.second) { + if (pair.second) { + ret[prov_pair.first].emplace_back(pair.first); + } + } + } + + return ret; +} + auto mgmt_app_config::get_mount_location(provider_type prov, std::string_view name) const -> std::string {