diff --git a/docs/plugins/concepts.rst b/docs/plugins/concepts.rst index ecc8ecbb..42b66d37 100644 --- a/docs/plugins/concepts.rst +++ b/docs/plugins/concepts.rst @@ -257,7 +257,7 @@ them as (hopefully) documented. :emphasize-lines: 6-8,20 :caption: Excerpt from the Growl Plugin showing utilization of the helpers published by the Discovery Plugin. :name: sec-plugin-concepts-helpers-example-usage - + def on_after_startup(self): host = self._settings.get(["hostname"]) port = self._settings.getInt(["port"]) @@ -270,7 +270,7 @@ them as (hopefully) documented. self.growl, _ = self._register_growl(host, port, password=password) # ... - + def on_api_get(self, request): if not self.zeroconf_browse: return flask.jsonify(dict( @@ -302,6 +302,10 @@ An overview of these properties follows. ``self._basefolder`` The plugin's base folder where it's installed. Can be used to refer to files relative to the plugin's installation location, e.g. included scripts, templates or assets. +``self._datafolder`` + The plugin's additional data folder path. Can be used to store additional files needed for the plugin's operation (cache, + data files etc). Plugins should not access this property directly but instead utilize :func:`~octoprint.plugin.types.OctoPrintPlugin.get_plugin_data_folder` + which will make sure the path actually does exist and if not create it before returning it. ``self._logger`` A `python logger instance `_ logging to the log target ``octoprint.plugin.``. @@ -340,4 +344,4 @@ Lifecycle .. image:: ../images/plugins_lifecycle.png :align: center - :alt: The lifecycle of OctoPrint plugins. \ No newline at end of file + :alt: The lifecycle of OctoPrint plugins. diff --git a/src/octoprint/plugin/__init__.py b/src/octoprint/plugin/__init__.py index ce7224b3..21976d08 100644 --- a/src/octoprint/plugin/__init__.py +++ b/src/octoprint/plugin/__init__.py @@ -426,12 +426,10 @@ class PluginSettings(object): filename += ".log" return os.path.join(self.settings.getBaseFolder("logs"), filename) + @deprecated("PluginSettings.get_plugin_data_folder has been replaced by OctoPrintPlugin.get_plugin_data_folder", + includedoc="Replaced by :func:`~octoprint.plugin.types.OctoPrintPlugin.get_plugin_data_folder`", + since="1.2.0") def get_plugin_data_folder(self): - """ - Retrieves the path to a data folder specifically for the plugin. - - Plugins may use this for storing additional data. - """ path = os.path.join(self.settings.getBaseFolder("data"), self.plugin_key) if not os.path.isdir(path): os.makedirs(path) diff --git a/src/octoprint/plugin/types.py b/src/octoprint/plugin/types.py index 578e117a..ad74364c 100644 --- a/src/octoprint/plugin/types.py +++ b/src/octoprint/plugin/types.py @@ -69,9 +69,32 @@ class OctoPrintPlugin(Plugin): The :class:`~octoprint.server.LifecycleManager` instance. Injected by the plugin core system upon initialization of the implementation. + + .. attribute:: _data_folder + + Path to the data folder for the plugin to use for any data it might have to persist. Should always be accessed + through :meth:`get_plugin_data_folder` since that function will also ensure that the data folder actually exists + and if not creating it before returning it. Injected by the plugin core system upon initialization of the + implementation. + + .. automethod:: get_plugin_data_folder """ - pass + def get_plugin_data_folder(self): + """ + Retrieves the path to a data folder specifically for the plugin, ensuring it exists and if not creating it + before returning it. + + Plugins may use this folder for storing additional data they need for their operation. + """ + if self._data_folder is None: + raise RuntimeError("self._plugin_data_folder is None, has the plugin been initialized yet?") + + import os + if not os.path.isdir(self._data_folder): + os.makedirs(self._data_folder) + return self._data_folder + class ReloadNeedingPlugin(Plugin): pass diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 811baaf6..8426628f 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -196,7 +196,8 @@ class Server(): file_manager=fileManager, printer=printer, app_session_manager=appSessionManager, - plugin_lifecycle_manager=pluginLifecycleManager + plugin_lifecycle_manager=pluginLifecycleManager, + data_folder=os.path.join(settings().getBaseFolder("data"), name) ) def settings_plugin_inject_factory(name, implementation):