Skip to content

Commit

Permalink
Merge branch 'maintenance' into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
foosel committed Nov 8, 2019
2 parents 8955b8e + 8173f8d commit 7f2eb47
Show file tree
Hide file tree
Showing 33 changed files with 308 additions and 141 deletions.
13 changes: 9 additions & 4 deletions docs/api/general.rst
Expand Up @@ -148,17 +148,22 @@ Login
via the ``passive`` flag.

Will return a :http:statuscode:`200` with a :ref:`login response <sec-api-general-datamodel-login>` on successful
login, whether active or passive. The active (username/password) login may also return a :http:statuscode:`401` in
case of a username/password mismatch or unknown user and a :http:statuscode:`403` in case of a deactivated account.
login, whether active or passive. The active (username/password) login may also return a :http:statuscode:`403` in
case of a username/password mismatch, unknown user or a deactivated account.

.. warning::

Previous versions of this API endpoint did return a :http:statuscode:`401` in case of a username/password
mismatch or an unknown user. That was incompatible with basic authentication since it was a wrong use of
the :http:statuscode:`401` code and got therefore changed as part of a bug fix.

:json passive: If present, performs a passive login only, returning information about the current user that's
active either through an existing session or the used API key
:json user: (active login only) Username
:json pass: (active login only) Password
:json remember: (active login only) Whether to set a "remember me" cookie on the session
:status 200: Successful login
:status 401: Username/password mismatch or unknown user
:status 403: Deactivated account
:status 403: Username/password mismatch, unknown user or deactivated account

.. _sec-api-general-logout:

Expand Down
2 changes: 1 addition & 1 deletion docs/bundledplugins/backup.rst
Expand Up @@ -27,7 +27,7 @@ Command line usage
------------------

The Backup Plugin implements a command line interface that allows creation and restoration of backups.
It adds two new commands, ``backup:backup`` and ``backup_restore``.
It adds two new commands, ``backup:backup`` and ``backup:restore``.

.. code-block:: none
Expand Down
2 changes: 1 addition & 1 deletion docs/bundledplugins/discovery.rst
Expand Up @@ -14,7 +14,7 @@ network running Microsoft Windows. You will be able to just double click on the
OctoPrint instance icon in "Networks > Other Devices" in your Windows Explorer,
which will take you directly to the web frontend.

The ZeroConf support allows OctoPrint to announce itself to Safari on MacOS X
The ZeroConf support allows OctoPrint to announce itself to Safari on macOS
on the same network.

Linux users should install `Avahi <http://avahi.org>`_ and can then use one
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration/config_yaml.rst
Expand Up @@ -5,7 +5,7 @@ config.yaml

If not specified via the command line, the main configuration file ``config.yaml`` for OctoPrint is expected in its
settings folder, which unless defined differently via the command line is located at ``~/.octoprint`` on Linux, at
``%APPDATA%/OctoPrint`` on Windows and at ``~/Library/Application Support/OctoPrint`` on MacOS. If the file is not there,
``%APPDATA%/OctoPrint`` on Windows and at ``~/Library/Application Support/OctoPrint`` on macOS. If the file is not there,
you can just create it - it will only get created by OctoPrint once you save settings that deviate from the default
settings.

Expand Down
2 changes: 1 addition & 1 deletion docs/configuration/logging_yaml.rst
Expand Up @@ -5,7 +5,7 @@ logging.yaml

The logging configuration file ``logging.yaml`` for OctoPrint is expected in its settings folder, which unless defined
differently on the command line is located at ``~/.octoprint`` on Linux, at ``%APPDATA%/OctoPrint`` on Windows and at
``~/Library/Application Support/OctoPrint`` on MacOS.
``~/Library/Application Support/OctoPrint`` on macOS.

You can use it to change the log levels of the individual components within OctoPrint, which might be necessary to help
in debugging issues you are experiencing, or to change the configuration of the logging handlers themselves, e.g. in
Expand Down
12 changes: 7 additions & 5 deletions docs/development/environment.rst
Expand Up @@ -17,7 +17,7 @@ below.
* `Python 3.7 <https://python.org>`_ including ``pip``, ``setuptools`` and ``virtualenv``
* `Git <https://git-scm.com>`_

* Checkout the OctoPrint sources from their Git repository:
* Checkout the OctoPrint sources from their Git repository:
* ``git clone -b devel https://github.com/foosel/OctoPrint.git``
* Enter the checked out source folder: ``cd OctoPrint``
* Create virtual environments in the checked out source folder for both Python 2.7 and Python 3.7 to use for
Expand All @@ -26,12 +26,12 @@ below.
* PY2: ``virtualenv --python=python2 venv2``
* PY3: ``virtualenv --python=python3 venv3``
* Activate one of the virtual environments:
* PY2: ``source venv2/bin/activate`` (Linux, MacOS) or ``source venv2/Scripts/activate`` (Git Bash under Windows, see below)
* PY3: ``source venv3/bin/activate`` (Linux, MacOS) or ``source venv3/Scripts/activate`` (Git Bash under Windows, see below)
* PY2: ``source venv2/bin/activate`` (Linux, macOS) or ``source venv2/Scripts/activate`` (Git Bash under Windows, see below)
* PY3: ``source venv3/bin/activate`` (Linux, macOS) or ``source venv3/Scripts/activate`` (Git Bash under Windows, see below)
* Update ``pip`` in the virtual environment:
* ``pip install --upgrade pip``
* Install OctoPrint in `"editable" mode <https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs>`_,
including its regular *and* development and plugin development dependencies:
including its regular *and* development and plugin development dependencies:
* ``pip install -e .[develop,plugins]``

When the virtual environment is activated you can then:
Expand Down Expand Up @@ -197,8 +197,10 @@ PyCharm
.......

- "File" > "Open ...", select OctoPrint checkout folder (e.g. ``~/devel/OctoPrint`` or ``C:\Devel\OctoPrint``)
- "File" > "Settings ..." > "Project: OctoPrint" > "Project Interpreter" > "Add local ...", select OctoPrint venv
- **(Linux, Windows)** "File" > "Settings ..." > "Project: OctoPrint" > "Project Interpreter" > "Add local ...", select OctoPrint venv
folder (e.g. ``~/devel/OctoPrint/venv`` or ``C:\Devel\OctoPrint\venv``)
- **(macOS)** "PyCharm" > "Preferences ..." > "Project: OctoPrint" > "Project Interpreter" > "Add ..." >
"Virtualenv Environment > "Existing Environment", select OctoPrint venv folder (e.g. ``~/devel/OctoPrint/venv``)
- Right click "src" in project tree, mark as source folder
- Add Run/Debug Configuration, select "Python":

Expand Down
2 changes: 1 addition & 1 deletion docs/development/virtual_printer.rst
Expand Up @@ -17,7 +17,7 @@ be found in the full :ref:`config.yaml documentation <sec-configuration-config_y

The steps to take are as follows:

* Find config.yaml in the OctoPrint settings folder. Usually in ``~/.octoprint`` on Linux, in ``%APPDATA%/OctoPrint`` on Windows and in ``~/Library/Application Support/OctoPrint`` on MacOS.
* Find config.yaml in the OctoPrint settings folder. Usually in ``~/.octoprint`` on Linux, in ``%APPDATA%/OctoPrint`` on Windows and in ``~/Library/Application Support/OctoPrint`` on macOS.
* Add or extend the ``devel`` section with:

.. code-block:: yaml
Expand Down
3 changes: 3 additions & 0 deletions docs/events/index.rst
Expand Up @@ -165,6 +165,9 @@ Error
An unrecoverable error has been encountered, either as reported by the firmware (e.g. a thermal runaway) or
on the connection.

Note that this event will not fire for error messages from the firmware that are handled (and as such recovered from)
either by OctoPrint or a plugin.

Payload:

* ``error``: the error string
Expand Down
2 changes: 1 addition & 1 deletion docs/features/gcode_scripts.rst
Expand Up @@ -11,7 +11,7 @@ is clicked.

Unless :ref:`configured otherwise <sec-configuration-config_yaml-folder>`, OctoPrint expects scripts to be located in
the ``scripts/gcode`` folder in OctoPrint configuration directory (per default ``~/.octoprint`` on Linux, ``%APPDATA%\OctoPrint``
on Windows and ``~/Library/Application Support/OctoPrint`` on MacOS).
on Windows and ``~/Library/Application Support/OctoPrint`` on macOS).

These GCODE scripts are backed by the templating engine Jinja2, allowing more than just
simple "send-as-is" scripts but making use of a full blown templating language in order to create your scripts. To
Expand Down
4 changes: 2 additions & 2 deletions docs/features/safemode.rst
Expand Up @@ -75,12 +75,12 @@ When OctoPrint is running in safe mode the following changes to its normal opera
* OctoPrint will not enable any of the installed third party plugins. OctoPrint considers all plugins third
party plugins that do not ship with OctoPrint's sources, so any plugins installed either via `pip` or
into OctoPrint's plugin folder at ``~/.octoprint/plugins`` (Linux), ``%APPDATA%/OctoPrint/plugins`` (Windows) and
``~/Library/Application Support/OctoPrint/plugins`` (MacOS).
``~/Library/Application Support/OctoPrint/plugins`` (macOS).
* OctoPrint will not enable any of the installed third party language packs. OctoPrint considers all language packs
third party language packs that do not ship with OctoPrint's sources, so any language plugins installed
through the language pack manager within settings and/or stored in the language pack folder at
``~/.octoprint/translations`` (Linux), ``%APPDATA%/OctoPrint/translations`` (Windows) or
``~/Library/Application Support/OctoPrint/translations`` (MacOS).
``~/Library/Application Support/OctoPrint/translations`` (macOS).
* OctoPrint will still allow to uninstall third party plugins through the built-in Plugin Manager.
* OctoPrint will still allow to disable (bundled) plugins that are still enabled.
* OctoPrint will not allow to enable third party plugins.
Expand Down
2 changes: 1 addition & 1 deletion docs/jsclientlib/socket.rst
Expand Up @@ -42,7 +42,7 @@
To register for all message types, provide ``*`` as the type to register for.

``handler`` is expected to be a function accepting one object parameter ``eventObj``, consisting
of the received message as property ``key`` and the received payload (if any) as property ``data``.
of the received message as property ``event`` and the received payload (if any) as property ``data``.

.. code-block:: javascript
Expand Down
2 changes: 1 addition & 1 deletion src/octoprint/plugin/core.py
Expand Up @@ -447,7 +447,7 @@ def pythoncompat(self):
@property
def hooks(self):
"""
Hooks provided by the plugin. Will be taken from the hooks attribute of the plugin module as defiend in
Hooks provided by the plugin. Will be taken from the hooks attribute of the plugin module as defined in
:attr:`attr_hooks` if available, otherwise an empty dictionary is returned.
Returns:
Expand Down
2 changes: 1 addition & 1 deletion src/octoprint/plugins/discovery/__init__.py
Expand Up @@ -212,7 +212,7 @@ def zeroconf_register(self, reg_type, name=None, port=None, txt_record=None):

def zeroconf_unregister(self, reg_type, port=None):
"""
Unregisteres a previously registered Zeroconf/Bonjour/Avahi service identified by service and port.
Unregisters a previously registered Zeroconf/Bonjour/Avahi service identified by service and port.
:param reg_type: the type of the service to be unregistered
:param port: the port of the service to be unregistered, defaults to OctoPrint's (public) port if not given
Expand Down
55 changes: 51 additions & 4 deletions src/octoprint/plugins/pluginmanager/__init__.py
Expand Up @@ -197,7 +197,6 @@ def get_settings_defaults(self):
notices_ttl=6*60,
pip_args=None,
pip_force_user=False,
confirm_uninstall=True,
confirm_disable=False,
dependency_links=False,
hidden=[],
Expand Down Expand Up @@ -298,6 +297,7 @@ def get_api_commands(self):
"uninstall": ["plugin"],
"enable": ["plugin"],
"disable": ["plugin"],
"cleanup": ["plugin"],
"refresh_repository": []
}

Expand Down Expand Up @@ -384,7 +384,15 @@ def on_api_command(self, command, data):
return make_response("Unknown plugin: %s" % plugin_name, 404)

plugin = self._plugin_manager.plugins[plugin_name]
return self.command_uninstall(plugin)
return self.command_uninstall(plugin, cleanup=data.get("cleanup", False))

elif command == "cleanup":
plugin_name = data["plugin"]
if not plugin_name in self._plugin_manager.plugins:
return make_response("Unknown plugin: %s" % plugin_name, 404)

plugin = self._plugin_manager.plugins[plugin_name]
return self.command_cleanup(plugin)

elif command == "enable" or command == "disable":
plugin_name = data["plugin"]
Expand Down Expand Up @@ -565,7 +573,7 @@ def command_install(self, url=None, path=None, force=False, reinstall=None, depe
self._send_result_notification("install", result)
return jsonify(result)

def command_uninstall(self, plugin):
def command_uninstall(self, plugin, cleanup=False):
if plugin.key == "pluginmanager":
return make_response("Can't uninstall Plugin Manager", 403)

Expand Down Expand Up @@ -614,7 +622,7 @@ def command_uninstall(self, plugin):
self._logger.warning("Trying to uninstall plugin {plugin} but origin is unknown ({plugin.origin.type})".format(**locals()))
return make_response("Could not uninstall plugin, its origin is unknown")

needs_restart = self._plugin_manager.is_restart_needing_plugin(plugin)
needs_restart = self._plugin_manager.is_restart_needing_plugin(plugin) or cleanup
needs_refresh = plugin.implementation and isinstance(plugin.implementation, octoprint.plugin.ReloadNeedingPlugin)
needs_reconnect = self._plugin_manager.has_any_of_hooks(plugin, self._reconnect_hooks) and self._printer.is_operational()

Expand Down Expand Up @@ -654,6 +662,45 @@ def command_uninstall(self, plugin):
needs_reconnect=needs_reconnect,
plugin=self._to_external_plugin(plugin))
self._send_result_notification("uninstall", result)
self._logger.info("Plugin {} uninstalled".format(plugin.key))

if cleanup:
self.command_cleanup(plugin)

return jsonify(result)

def command_cleanup(self, plugin):
# delete plugin settings
self._settings.global_set(["plugins", plugin.key], None)
self._settings.save()
message = "Cleaned up settings of plugin {}".format(plugin.key)
self._log_stdout(message)
self._logger.info(message)

# delete plugin data folder
import os
import shutil

result_data = True
data_folder = os.path.join(self._settings.getBaseFolder("data"), plugin.key)
if os.path.exists(data_folder):
try:
shutil.rmtree(data_folder)
message = "Cleaned up data folder of plugin {}".format(plugin.key)
self._log_stdout(message)
self._logger.info(message)
except:
message = "Could not delete data folder of plugin {} at {}".format(plugin.key, data_folder)
self._log_stderr(message)
self._logger.exception(message)
result_data = False

result = dict(result=result_data,
needs_restart=True,
plugin=self._to_external_plugin(plugin))
self._send_result_notification("cleanup", result)
self._logger.info("Plugin {} cleaned up".format(plugin.key))

return jsonify(result)

def command_toggle(self, plugin, command):
Expand Down
Expand Up @@ -52,13 +52,27 @@
return this.base.simpleApiCommand("pluginmanager", "install", data, opts);
};

OctoPrintPluginManagerClient.prototype.uninstall = function(plugin, opts) {
OctoPrintPluginManagerClient.prototype.uninstall = function(plugin, cleanup, opts) {
// backwards compatibility to former argument list (plugin, opts)
if (arguments.length === 2 && typeof cleanup === "object") {
opts = cleanup;
cleanup = false;
}

var data = {
plugin: plugin
plugin: plugin,
cleanup: !!cleanup
};
return this.base.simpleApiCommand("pluginmanager", "uninstall", data, opts);
};

OctoPrintPluginManagerClient.prototype.cleanup = function(plugin, opts) {
var data = {
plugin: plugin
};
return this.base.simpleApiCommand("pluginmanager", "cleanup", data, opts);
};

OctoPrintPluginManagerClient.prototype.enable = function(plugin, opts) {
var data = {
plugin: plugin
Expand Down

0 comments on commit 7f2eb47

Please sign in to comment.