Compare commits

...

3 Commits

Author SHA1 Message Date
Ian Chua
2e246341d1 move the storage directory outside the actual plugin code folder 2026-07-24 18:57:46 +08:00
Ian Chua
9513300835 Merge branch 'main' into feat/plugin-storage-api 2026-07-24 13:09:39 +08:00
Ian Chua
f7caf0db07 feat(plugin): storage API 2026-07-23 21:04:08 +08:00
6 changed files with 62 additions and 2 deletions

View File

@@ -632,7 +632,7 @@ void parse_metadata_rfc822(const std::string& content,
bool is_ignored_plugin_directory(const boost::filesystem::path& path)
{
const std::string name = path.filename().string();
return name.empty() || name[0] == '.' || name.rfind("__", 0) == 0 || name == PLUGIN_SUBSCRIBED_DIR;
return name.empty() || name[0] == '.' || name.rfind("__", 0) == 0 || name == PLUGIN_SUBSCRIBED_DIR || name == PLUGIN_DATA_DIR;
}
bool is_safe_relative_path(const boost::filesystem::path& path)

View File

@@ -12,6 +12,7 @@
#include <vector>
#define PLUGIN_SUBSCRIBED_DIR "_subscribed"
#define PLUGIN_DATA_DIR "plugin_data"
namespace Slic3r {

View File

@@ -486,6 +486,38 @@ bool PluginManager::try_get_plugin_descriptor_for_capability(const std::string&
return false;
}
std::string PluginManager::get_storage_dir(const std::string& plugin_key) const
{
namespace fs = boost::filesystem;
PluginDescriptor descriptor;
if (!try_get_plugin_descriptor(plugin_key, descriptor))
throw std::runtime_error("The current plugin is not registered");
const fs::path base_storage_dir = fs::path(get_orca_plugins_dir()) / PLUGIN_DATA_DIR;
if (!descriptor.is_cloud_plugin()) {
const fs::path local_storage_dir = base_storage_dir / plugin_key;
fs::create_directories(local_storage_dir);
return local_storage_dir.string();
}
auto agent = m_cloud_service.get_cloud_agent();
if (!agent)
throw std::runtime_error("Cloud plugin storage is unavailable before networking is initialized");
const std::string user_id = agent->get_user_id();
if (user_id.empty())
throw std::runtime_error("Cloud plugin storage is unavailable without a logged-in user");
if (!is_valid_plugin_id(plugin_key))
throw std::runtime_error("The current cloud plugin key is not a valid folder name");
const fs::path cloud_storage_dir = base_storage_dir / PLUGIN_SUBSCRIBED_DIR / user_id / plugin_key;
fs::create_directories(cloud_storage_dir);
return cloud_storage_dir.string();
}
// ── Capability instances ────────────────────────────────────────────────────────────────────
std::vector<std::shared_ptr<PluginCapabilityInterface>> PluginManager::get_plugin_capabilities(const std::string& plugin_key,

View File

@@ -138,6 +138,10 @@ public:
bool try_get_plugin_descriptor_for_capability(const std::string& capability_name,
PluginCapabilityType type,
PluginDescriptor& out) const;
// Per-plugin storage directory under orca_plugins/plugin_data, created if missing. Throws
// std::runtime_error if the plugin is unregistered, the key is invalid, or (cloud plugins)
// no user is logged in yet.
std::string get_storage_dir(const std::string& plugin_key) const;
std::vector<std::shared_ptr<PluginCapabilityInterface>> get_plugin_capabilities(
const std::string& plugin_key = "", // "" => all plugins

View File

@@ -1,9 +1,31 @@
#include "PluginHost.hpp"
#include "PluginHostBindings.hpp"
#include "PluginHostUi.hpp"
#include <slic3r/plugin/PluginAuditManager.hpp>
#include <slic3r/plugin/PluginManager.hpp>
#include <stdexcept>
namespace Slic3r {
namespace host_bindings {
void register_plugin(pybind11::module_& host)
{
auto plugin_host = host.def_submodule("plugin", "Plugin host API");
plugin_host.def(
"storage",
[]() -> std::string {
const std::string plugin_key = PluginAuditManager::instance().current_plugin();
if (plugin_key.empty())
throw std::runtime_error("plugin.storage() must be called from a plugin callback");
return PluginManager::instance().get_storage_dir(plugin_key);
},
"Return the installed folder of the current plugin.");
}
} // namespace host_bindings
void PluginHost::RegisterBindings(pybind11::module_& module)
{
auto host = module.def_submodule("host", "Host application API");
@@ -15,6 +37,7 @@ void PluginHost::RegisterBindings(pybind11::module_& module)
host_bindings::register_presets(host);
host_bindings::register_model(host);
host_bindings::register_app(host);
host_bindings::register_plugin(host);
// UI: native dialogs and interactive HTML windows for plugins.
PluginHostUi::RegisterBindings(host);

View File

@@ -12,5 +12,5 @@ void register_presets(pybind11::module_& host); // PluginHostPresets.cpp
void register_model(pybind11::module_& host); // PluginHostModel.cpp
void register_app(pybind11::module_& host); // PluginHostApp.cpp
void register_slicing(pybind11::module_& host); // PluginHostSlicing.cpp
void register_plugin(pybind11::module_& host); // PluginHost.cpp
} // namespace Slic3r::host_bindings