From 0aeb69a050e7d767cf4f9014e1b8d17a238404fa Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 1 Mar 2025 10:34:13 -0600 Subject: [PATCH] grab mount settings and status --- repertory/repertory/include/ui/handlers.hpp | 8 +- repertory/repertory/src/ui/handlers.cpp | 167 ++++++++++++-------- web/repertory/lib/models/mount.dart | 32 +++- web/repertory/lib/types/mount_config.dart | 9 +- 4 files changed, 141 insertions(+), 75 deletions(-) diff --git a/repertory/repertory/include/ui/handlers.hpp b/repertory/repertory/include/ui/handlers.hpp index 0fecf440..6f75b54f 100644 --- a/repertory/repertory/include/ui/handlers.hpp +++ b/repertory/repertory/include/ui/handlers.hpp @@ -58,7 +58,13 @@ private: console_consumer console; private: - [[nodiscard]] static auto read_process(provider_type type, + void handle_get_mount(auto &&req, auto &&res) const; + + void handle_get_mount_list(auto &&res) const; + + void handle_get_mount_status(auto &&req, auto &&res) const; + + [[nodiscard]] static auto read_process(provider_type prov, std::string_view name, std::string_view command) -> std::vector; diff --git a/repertory/repertory/src/ui/handlers.cpp b/repertory/repertory/src/ui/handlers.cpp index 7de39978..3d3496e9 100644 --- a/repertory/repertory/src/ui/handlers.cpp +++ b/repertory/repertory/src/ui/handlers.cpp @@ -25,7 +25,6 @@ #include "events/event_system.hpp" #include "rpc/common.hpp" #include "types/repertory.hpp" -#include "utils/collection.hpp" #include "utils/error_utils.hpp" #include "utils/file.hpp" #include "utils/path.hpp" @@ -72,72 +71,17 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) res.status = http_error_codes::internal_error; }); - server->Get("/api/v1/mount", [](const httplib::Request &req, auto &&res) { - auto prov = provider_type_from_string(req.get_param_value("type")); + server->Get("/api/v1/mount", + [this](auto &&req, auto &&res) { handle_get_mount(req, res); }); - auto lines = - handlers::read_process(prov, req.get_param_value("name"), "-dc"); - - if (lines.at(0U) != "0") { - throw utils::error::create_exception(function_name, { - "command failed", - lines.at(0U), - }); - } - - lines.erase(lines.begin()); - - auto result = nlohmann::json::parse(utils::string::join(lines, '\n')); - res.set_content(result.dump(), "application/json"); - res.status = http_error_codes::ok; + server->Get("/api/v1/mount_list", [this](auto && /* req */, auto &&res) { + handle_get_mount_list(res); }); - server->Get("/api/v1/mount_list", [](auto && /* req */, auto &&res) { - auto data_dir = - utils::file::directory{app_config::get_root_data_directory()}; - - nlohmann::json result; - - auto encrypt_dir = data_dir.get_directory("encrypt"); - if (encrypt_dir && encrypt_dir->get_file("config.json")) { - result["encrypt"].emplace_back("encrypt"); - } - - const auto process_dir = [&data_dir, &result](std::string_view name) { - auto name_dir = data_dir.get_directory(name); - if (not name_dir) { - return; - } - - for (const auto &dir : name_dir->get_directories()) { - if (not dir->get_file("config.json")) { - continue; - } - - result[name].emplace_back( - utils::path::strip_to_file_name(dir->get_path())); - } - }; - - process_dir("remote"); - process_dir("s3"); - process_dir("sia"); - - res.set_content(result.dump(), "application/json"); - res.status = http_error_codes::ok; - }); - - server->Get("/api/v1/mount_status", [](const httplib::Request &req, - auto &&res) { - auto prov = provider_type_from_string(req.get_param_value("type")); - - auto lines = - handlers::read_process(prov, req.get_param_value("name"), "-status"); - - auto result = nlohmann::json::parse(utils::string::join(lines, '\n')); - res.set_content(result.dump(), "application/json"); - res.status = http_error_codes::ok; - }); + server->Get("/api/v1/mount_status", + [this](const httplib::Request &req, auto &&res) { + handle_get_mount_status(req, res); + }); event_system::instance().start(); @@ -164,13 +108,104 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) handlers::~handlers() { event_system::instance().stop(); } -auto handlers::read_process(provider_type type, std::string_view name, +void handlers::handle_get_mount(auto &&req, auto &&res) const { + REPERTORY_USES_FUNCTION_NAME(); + + auto prov = provider_type_from_string(req.get_param_value("type")); + + auto lines = handlers::read_process(prov, req.get_param_value("name"), "-dc"); + + if (lines.at(0U) != "0") { + throw utils::error::create_exception(function_name, { + "command failed", + lines.at(0U), + }); + } + + lines.erase(lines.begin()); + + auto result = nlohmann::json::parse(utils::string::join(lines, '\n')); + res.set_content(result.dump(), "application/json"); + res.status = http_error_codes::ok; +} + +void handlers::handle_get_mount_list(auto &&res) const { + auto data_dir = utils::file::directory{app_config::get_root_data_directory()}; + + nlohmann::json result; + + auto encrypt_dir = data_dir.get_directory("encrypt"); + if (encrypt_dir && encrypt_dir->get_file("config.json")) { + result["encrypt"].emplace_back("encrypt"); + } + + const auto process_dir = [&data_dir, &result](std::string_view name) { + auto name_dir = data_dir.get_directory(name); + if (not name_dir) { + return; + } + + for (const auto &dir : name_dir->get_directories()) { + if (not dir->get_file("config.json")) { + continue; + } + + result[name].emplace_back( + utils::path::strip_to_file_name(dir->get_path())); + } + }; + + process_dir("remote"); + process_dir("s3"); + process_dir("sia"); + + res.set_content(result.dump(), "application/json"); + res.status = http_error_codes::ok; +} + +void handlers::handle_get_mount_status(auto &&req, auto &&res) const { + REPERTORY_USES_FUNCTION_NAME(); + + auto prov = provider_type_from_string(req.get_param_value("type")); + auto status_name = app_config::get_provider_display_name(prov); + auto name = req.get_param_value("name"); + + switch (prov) { + case provider_type::encrypt: + break; + + case provider_type::remote: { + auto parts = utils::string::split(name, '_', false); + status_name = fmt::format("{}{}:{}", status_name, parts[0U], parts[1U]); + } break; + + case provider_type::sia: + case provider_type::s3: + status_name = fmt::format("{}{}", status_name, name); + break; + + default: + throw utils::error::create_exception( + function_name, { + fmt::format("`{}` is not supported", name), + }); + } + + auto lines = handlers::read_process(prov, name, "-status"); + + auto result = + nlohmann::json::parse(utils::string::join(lines, '\n')).at(status_name); + res.set_content(result.dump(), "application/json"); + res.status = http_error_codes::ok; +} + +auto handlers::read_process(provider_type prov, std::string_view name, std::string_view command) -> std::vector { REPERTORY_USES_FUNCTION_NAME(); std::string str_type; - switch (type) { + switch (prov) { case provider_type::encrypt: str_type = "-en"; break; diff --git a/web/repertory/lib/models/mount.dart b/web/repertory/lib/models/mount.dart index fdbb9dbd..cadb1e28 100644 --- a/web/repertory/lib/models/mount.dart +++ b/web/repertory/lib/models/mount.dart @@ -7,7 +7,7 @@ import 'package:repertory/types/mount_config.dart'; class Mount with ChangeNotifier { final MountConfig mountConfig; Mount(this.mountConfig) { - _fetch(); + refresh(); } String get name => mountConfig.name; @@ -20,15 +20,33 @@ class Mount with ChangeNotifier { ), ); - if (response.statusCode == 200) { - mountConfig.updateSettings(jsonDecode(response.body)); - - notifyListeners(); + if (response.statusCode != 200) { return; } + + mountConfig.updateSettings(jsonDecode(response.body)); + + notifyListeners(); } - void refresh() { - _fetch(); + Future _fetchStatus() async { + final response = await http.get( + Uri.parse( + Uri.encodeFull( + '${Uri.base.origin}/api/v1/mount_status?name=$name&type=$type', + ), + ), + ); + + if (response.statusCode != 200) { + return; + } + + mountConfig.updateStatus(jsonDecode(response.body)); + } + + Future refresh() async { + await _fetch(); + return _fetchStatus(); } } diff --git a/web/repertory/lib/types/mount_config.dart b/web/repertory/lib/types/mount_config.dart index 62cfbb64..fc98f104 100644 --- a/web/repertory/lib/types/mount_config.dart +++ b/web/repertory/lib/types/mount_config.dart @@ -4,9 +4,12 @@ class MountConfig { final String _name; final String _type; Map _settings = {}; + Map _status = {}; MountConfig({required name, required type}) : _name = name, _type = type; - UnmodifiableMapView get items => UnmodifiableMapView(_settings); + UnmodifiableMapView get settings => UnmodifiableMapView(_settings); + UnmodifiableMapView get status => UnmodifiableMapView(_status); + String get name => _name; String get type => _type; @@ -17,4 +20,8 @@ class MountConfig { void updateSettings(Map settings) { _settings = settings; } + + void updateStatus(Map status) { + _status = status; + } }