Some cleanup, refactoring & docs

This commit is contained in:
Gina Häußge 2017-11-29 15:55:33 +01:00
parent 5c20e264e2
commit ca7aa322c3
11 changed files with 284 additions and 169 deletions

View file

@ -1565,6 +1565,13 @@ class Plugin(object):
initialization of the implementation.
"""
def __init__(self):
self._identifier = None
self._plugin_name = None
self._plugin_version = None
self._basefolder = None
self._logger = None
def initialize(self):
"""
Called by the plugin core after performing all injections. Override this to initialize your implementation.

View file

@ -8,9 +8,11 @@ Please note that the plugin implementation types are documented in the section
.. autoclass:: OctoPrintPlugin
:show-inheritance:
:members:
.. autoclass:: ReloadNeedingPlugin
:show-inheritance:
:members:
"""
@ -23,6 +25,7 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms
from .core import (Plugin, RestartNeedingPlugin, SortablePlugin)
# noinspection PyCompatibility
from past.builtins import basestring
class OctoPrintPlugin(Plugin):
@ -74,16 +77,39 @@ class OctoPrintPlugin(Plugin):
The :class:`~octoprint.server.LifecycleManager` instance. Injected by the plugin core system upon initialization
of the implementation.
.. attribute:: _user_manager
The :class:`~octoprint.users.UserManager` instance. Injected by the plugin core system upon initialization
of the implementation.
.. attribute:: _connectivity_checker
The :class:`~octoprint.util.ConnectivityChecker` 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
"""
# noinspection PyMissingConstructor
def __init__(self):
self._plugin_manager = None
self._printer_profile_manager = None
self._event_bus = None
self._analysis_queue = None
self._slicing_manager = None
self._file_manager = None
self._printer = None
self._app_session_manager = None
self._plugin_lifecycle_manager = None
self._user_manager = None
self._connectivity_checker = None
self._data_folder = None
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
@ -107,10 +133,10 @@ class ReloadNeedingPlugin(Plugin):
class EnvironmentDetectionPlugin(OctoPrintPlugin, RestartNeedingPlugin):
def get_additional_environment(self):
pass
def on_environment_detected(self, environment, *args, **kwargs):
pass
@ -602,6 +628,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
See below for details on this.
"""
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def will_handle_ui(self, request):
"""
Called by OctoPrint to determine if the mixin implementation will be
@ -624,6 +651,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return False
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def on_ui_render(self, now, request, render_kwargs):
"""
Called by OctoPrint to retrieve the response to send to the client
@ -712,6 +740,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
return None
# noinspection PyMethodMayBeStatic
def get_ui_additional_key_data_for_cache(self):
"""
Allows to return additional data to use in the cache key.
@ -723,6 +752,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_ui_additional_tracked_files(self):
"""
Allows to return additional files to track for validating existing caches. By default OctoPrint
@ -735,6 +765,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_ui_custom_tracked_files(self):
"""
Allows to define a complete separate set of files to track for (in)validating the cache. If this
@ -747,6 +778,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_ui_custom_etag(self):
"""
Allows to use a custom way to calculate the ETag, instead of the default method (hashing
@ -757,6 +789,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_ui_additional_etag(self, default_additional):
"""
Allows to provide a list of additional fields to use for ETag generation.
@ -772,6 +805,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return default_additional
# noinspection PyMethodMayBeStatic
def get_ui_custom_lastmodified(self):
"""
Allows to calculate the LastModified differently than using the most recent modification
@ -782,6 +816,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_ui_preemptive_caching_enabled(self):
"""
Allows to control whether the view provided by the plugin should be preemptively
@ -794,6 +829,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return True
# noinspection PyMethodMayBeStatic
def get_ui_data_for_preemptive_caching(self):
"""
Allows defining additional data to be persisted in the preemptive cache configuration, on
@ -804,6 +840,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_ui_additional_request_data_for_preemptive_caching(self):
"""
Allows defining additional request data to persist in the preemptive cache configuration and
@ -819,6 +856,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_ui_preemptive_caching_additional_unless(self):
"""
Allows defining additional reasons for temporarily not adding a preemptive cache record for
@ -832,6 +870,7 @@ class UiPlugin(OctoPrintPlugin, SortablePlugin):
"""
return False
# noinspection PyMethodMayBeStatic
def get_ui_custom_template_filter(self, default_template_filter):
"""
Allows to specify a custom template filter to use for filtering the template contained in the
@ -916,6 +955,7 @@ class WizardPlugin(OctoPrintPlugin, ReloadNeedingPlugin):
``WizardPlugin`` is a :class:`~octoprint.plugin.core.ReloadNeedingPlugin`.
"""
# noinspection PyMethodMayBeStatic
def is_wizard_required(self):
"""
Allows the plugin to report whether it needs to display a wizard to the
@ -931,6 +971,7 @@ class WizardPlugin(OctoPrintPlugin, ReloadNeedingPlugin):
"""
return False
# noinspection PyMethodMayBeStatic
def get_wizard_version(self):
"""
The version of this plugin's wizard. OctoPrint will only display a wizard
@ -950,6 +991,7 @@ class WizardPlugin(OctoPrintPlugin, ReloadNeedingPlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_wizard_details(self):
"""
Called by OctoPrint when the wizard wrapper dialog is shown. Allows the plugin to return data
@ -964,6 +1006,7 @@ class WizardPlugin(OctoPrintPlugin, ReloadNeedingPlugin):
"""
return dict()
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def on_wizard_finish(self, handled):
"""
Called by OctoPrint whenever the user finishes a wizard session.
@ -982,6 +1025,7 @@ class WizardPlugin(OctoPrintPlugin, ReloadNeedingPlugin):
"""
pass
# noinspection PyProtectedMember
@classmethod
def is_wizard_ignored(cls, seen_wizards, implementation):
"""
@ -1132,6 +1176,7 @@ class SimpleApiPlugin(OctoPrintPlugin):
}
"""
# noinspection PyMethodMayBeStatic
def get_api_commands(self):
"""
Return a dictionary here with the keys representing the accepted commands and the values being lists of
@ -1139,12 +1184,14 @@ class SimpleApiPlugin(OctoPrintPlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def is_api_adminonly(self):
"""
Return True if the API is only available to users having the admin role.
"""
return False
# noinspection PyMethodMayBeStatic
def on_api_command(self, command, data):
"""
Called by OctoPrint upon a POST request to ``/api/plugin/<plugin identifier>``. ``command`` will contain one of
@ -1164,6 +1211,7 @@ class SimpleApiPlugin(OctoPrintPlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def on_api_get(self, request):
"""
Called by OctoPrint upon a GET request to ``/api/plugin/<plugin identifier>``. ``request`` will contain the
@ -1262,6 +1310,7 @@ class BlueprintPlugin(OctoPrintPlugin, RestartNeedingPlugin):
return f
return decorator
# noinspection PyProtectedMember
def get_blueprint(self):
"""
Creates and returns the blueprint for your plugin. Override this if you want to define and handle your blueprint yourself.
@ -1327,6 +1376,7 @@ class BlueprintPlugin(OctoPrintPlugin, RestartNeedingPlugin):
template_folder=template_folder
)
# noinspection PyMethodMayBeStatic
def is_blueprint_protected(self):
"""
Whether a valid API key is needed to access the blueprint (the default) or not. Note that this only restricts
@ -1395,16 +1445,19 @@ class SettingsPlugin(OctoPrintPlugin):
should have access to via :meth:`~octoprint.plugin.SettingsPlugin.get_settings_restricted_paths`. OctoPrint will
return its settings on the REST API even to anonymous clients, but will filter out fields it know are restricted,
therefore you **must** make sure that you specify sensitive information accordingly to limit access as required!
.. attribute:: _settings
The :class:`~octoprint.plugin.PluginSettings` instance to use for accessing the plugin's settings. Injected by
the plugin core system upon initialization of the implementation.
"""
config_version_key = "_config_version"
"""Key of the field in the settings that holds the configuration format version."""
# noinspection PyMissingConstructor
def __init__(self):
self._settings = None
"""
The :class:`~octoprint.plugin.PluginSettings` instance to use for accessing the plugin's settings. Injected by
the plugin core system upon initialization of the implementation.
"""
def on_settings_load(self):
"""
Loads the settings for the plugin, called by the Settings API view in order to retrieve all settings from
@ -1437,6 +1490,7 @@ class SettingsPlugin(OctoPrintPlugin):
restricted_paths = self.get_settings_restricted_paths()
# noinspection PyShadowingNames
def restrict_path_unless(data, path, condition):
if not path:
return
@ -1535,6 +1589,7 @@ class SettingsPlugin(OctoPrintPlugin):
return diff
# noinspection PyMethodMayBeStatic
def get_settings_defaults(self):
"""
Retrieves the plugin's default settings with which the plugin's settings manager will be initialized.
@ -1544,6 +1599,7 @@ class SettingsPlugin(OctoPrintPlugin):
"""
return dict()
# noinspection PyMethodMayBeStatic
def get_settings_restricted_paths(self):
"""
Retrieves the list of paths in the plugin's settings which be restricted on the REST API.
@ -1598,6 +1654,7 @@ class SettingsPlugin(OctoPrintPlugin):
"""
return dict()
# noinspection PyMethodMayBeStatic
def get_settings_preprocessors(self):
"""
Retrieves the plugin's preprocessors to use for preprocessing returned or set values prior to returning/setting
@ -1635,6 +1692,7 @@ class SettingsPlugin(OctoPrintPlugin):
"""
return dict(), dict()
# noinspection PyMethodMayBeStatic
def get_settings_version(self):
"""
Retrieves the settings format version of the plugin.
@ -1649,6 +1707,7 @@ class SettingsPlugin(OctoPrintPlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def on_settings_migrate(self, target, current):
"""
Called by OctoPrint if it detects that the installed version of the plugin necessitates a higher settings version
@ -1735,6 +1794,7 @@ class EventHandlerPlugin(OctoPrintPlugin):
videos rendering etc.
"""
# noinspection PyMethodMayBeStatic
def on_event(self, event, payload):
"""
Called by OctoPrint upon processing of a fired event on the platform.
@ -1753,6 +1813,7 @@ class SlicerPlugin(OctoPrintPlugin):
"""
# noinspection PyMethodMayBeStatic
def is_slicer_configured(self):
"""
Unless the return value of this method is ``True``, OctoPrint will not register the slicer within the slicing
@ -1762,6 +1823,7 @@ class SlicerPlugin(OctoPrintPlugin):
"""
return False
# noinspection PyMethodMayBeStatic
def get_slicer_properties(self):
"""
Plugins should override this method to return a ``dict`` containing a bunch of meta data about the implemented slicer.
@ -1799,6 +1861,7 @@ class SlicerPlugin(OctoPrintPlugin):
destination_extensions=["gco", "gcode", "g"]
)
# noinspection PyMethodMayBeStatic
def get_slicer_default_profile(self):
"""
Should return a :class:`~octoprint.slicing.SlicingProfile` containing the default slicing profile to use with
@ -1810,6 +1873,7 @@ class SlicerPlugin(OctoPrintPlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def get_slicer_profile(self, path):
"""
Should return a :class:`~octoprint.slicing.SlicingProfile` parsed from the slicing profile stored at the
@ -1823,6 +1887,7 @@ class SlicerPlugin(OctoPrintPlugin):
"""
return None
# noinspection PyMethodMayBeStatic
def save_slicer_profile(self, path, profile, allow_overwrite=True, overrides=None):
"""
Should save the provided :class:`~octoprint.slicing.SlicingProfile` to the indicated ``path``, after applying
@ -1839,6 +1904,7 @@ class SlicerPlugin(OctoPrintPlugin):
"""
pass
# noinspection PyMethodMayBeStatic
def do_slice(self, model_path, printer_profile, machinecode_path=None, profile_path=None, position=None, on_progress=None, on_progress_args=None, on_progress_kwargs=None):
"""
Called by OctoPrint to slice ``model_path`` for the indicated ``printer_profile``. If the ``machinecode_path`` is ``None``,
@ -1895,6 +1961,7 @@ class SlicerPlugin(OctoPrintPlugin):
"""
pass
# noinspection PyMethodMayBeStatic
def cancel_slicing(self, machinecode_path):
"""
Cancels the slicing to the indicated file.
@ -1911,16 +1978,18 @@ class ProgressPlugin(OctoPrintPlugin):
limited to minimally 1% steps.
"""
# noinspection PyMethodMayBeStatic
def on_print_progress(self, storage, path, progress):
"""
Called by OctoPrint on minimally 1% increments during a running print job.
:param string location: Location of the file
:param string storage: Location of the file
:param string path: Path of the file
:param int progress: Current progress as a value between 0 and 100
"""
pass
# noinspection PyMethodMayBeStatic
def on_slicing_progress(self, slicer, source_location, source_path, destination_location, destination_path, progress):
"""
Called by OctoPrint on minimally 1% increments during a running slicing job.
@ -1946,6 +2015,7 @@ class AppPlugin(OctoPrintPlugin):
"""
# noinspection PyMethodMayBeStatic
def get_additional_apps(self):
return []

View file

@ -33,6 +33,7 @@ class AnnouncementPlugin(octoprint.plugin.AssetPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.EventHandlerPlugin):
# noinspection PyMissingConstructor
def __init__(self):
self._cached_channel_configs = None
self._cached_channel_configs_mutex = threading.RLock()
@ -184,6 +185,7 @@ class AnnouncementPlugin(octoprint.plugin.AssetPlugin,
return hash.hexdigest()
# noinspection PyShadowingNames
def condition(lm, etag):
return check_etag(etag)

View file

@ -1,22 +1,21 @@
# coding=utf-8
from __future__ import absolute_import, division, print_function
__author__ = "Gina Häußge <osd@foosel.net>"
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms of the AGPLv3 License"
import octoprint.plugin
from flask.ext.babel import gettext
from .subwizards import Subwizards
class CoreWizardPlugin(octoprint.plugin.AssetPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.WizardPlugin,
octoprint.plugin.SettingsPlugin,
octoprint.plugin.BlueprintPlugin):
octoprint.plugin.BlueprintPlugin,
Subwizards):
#~~ TemplatePlugin API
@ -34,6 +33,9 @@ class CoreWizardPlugin(octoprint.plugin.AssetPlugin,
result = list()
for key, method in required.items():
if not callable(method):
continue
if not method():
continue
@ -92,135 +94,7 @@ class CoreWizardPlugin(octoprint.plugin.AssetPlugin,
return result
def get_wizard_version(self):
return 2
#~~ ACL subwizard
def _is_acl_wizard_firstrunonly(self):
return True
def _is_acl_wizard_required(self):
return self._user_manager.enabled and not self._user_manager.hasBeenCustomized()
def _get_acl_wizard_details(self):
return dict(required=self._is_acl_wizard_required())
def _get_acl_wizard_name(self):
return gettext("Access Control")
def _get_acl_additional_wizard_template_data(self):
return dict(mandatory=self._is_acl_wizard_required())
@octoprint.plugin.BlueprintPlugin.route("/acl", methods=["POST"])
def acl_wizard_api(self):
from flask import request
from octoprint.server.api import valid_boolean_trues, NO_CONTENT
data = request.values
if hasattr(request, "json") and request.json:
data = request.json
if "ac" in data and data["ac"] in valid_boolean_trues and \
"user" in data.keys() and "pass1" in data.keys() and \
"pass2" in data.keys() and data["pass1"] == data["pass2"]:
# configure access control
self._settings.global_set_boolean(["accessControl", "enabled"], True)
self._user_manager.enable()
self._user_manager.addUser(data["user"], data["pass1"], True, ["user", "admin"], overwrite=True)
elif "ac" in data.keys() and not data["ac"] in valid_boolean_trues:
# disable access control
self._settings.global_set_boolean(["accessControl", "enabled"], False)
octoprint.server.loginManager.anonymous_user = octoprint.users.DummyUser
octoprint.server.principals.identity_loaders.appendleft(octoprint.users.dummy_identity_loader)
self._user_manager.disable()
self._settings.save()
return NO_CONTENT
#~~ Webcam subwizard
def _is_webcam_wizard_firstrunonly(self):
return True
def _is_webcam_wizard_required(self):
webcam_snapshot_url = self._settings.global_get(["webcam", "snapshot"])
webcam_stream_url = self._settings.global_get(["webcam", "stream"])
ffmpeg_path = self._settings.global_get(["webcam", "ffmpeg"])
return not (webcam_snapshot_url and webcam_stream_url and ffmpeg_path)
def _get_webcam_wizard_details(self):
return dict(required=self._is_webcam_wizard_required())
def _get_webcam_wizard_name(self):
return gettext("Webcam & Timelapse")
#~~ Server commands subwizard
def _is_servercommands_wizard_firstrunonly(self):
return True
def _is_servercommands_wizard_required(self):
system_shutdown_command = self._settings.global_get(["server", "commands", "systemShutdownCommand"])
system_restart_command = self._settings.global_get(["server", "commands", "systemRestartCommand"])
server_restart_command = self._settings.global_get(["server", "commands", "serverRestartCommand"])
return not (system_shutdown_command and system_restart_command and server_restart_command)
def _get_servercommands_wizard_details(self):
return dict(required=self._is_servercommands_wizard_required())
def _get_servercommands_wizard_name(self):
return gettext("Server Commands")
#~~ Online check subwizard
def _is_onlinecheck_wizard_firstrunonly(self):
return False
def _is_onlinecheck_wizard_required(self):
return self._settings.global_get(["server", "onlineCheck", "enabled"]) is None
def _get_onlinecheck_wizard_details(self):
return dict(required=self._is_onlinecheck_wizard_required())
def _get_onlinecheck_wizard_name(self):
return gettext("Online connectivity check")
def _get_onlinecheck_additional_wizard_template_data(self):
return dict(mandatory=self._is_onlinecheck_wizard_required())
#~~ Plugin blacklist subwizard
def _is_pluginblacklist_wizard_firstrunonly(self):
return False
def _is_pluginblacklist_wizard_required(self):
return self._settings.global_get(["server", "pluginBlacklist", "enabled"]) is None
def _get_pluginblacklist_wizard_details(self):
return dict(required=self._is_pluginblacklist_wizard_required())
def _get_pluginblacklist_wizard_name(self):
return gettext("Plugin blacklist")
def _get_pluginblacklist_additional_wizard_template_data(self):
return dict(mandatory=self._is_pluginblacklist_wizard_required())
#~~ Printer profile subwizard
def _is_printerprofile_wizard_firstrunonly(self):
return True
def _is_printerprofile_wizard_required(self):
return self._printer_profile_manager.is_default_unmodified() and self._printer_profile_manager.profile_count == 1
def _get_printerprofile_wizard_details(self):
return dict(required=self._is_printerprofile_wizard_required())
def _get_printerprofile_wizard_name(self):
return gettext("Default Printer Profile")
return 3
#~~ helpers

View file

@ -0,0 +1,154 @@
# coding=utf-8
from __future__ import absolute_import, division, print_function
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
__copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms of the AGPLv3 License"
import octoprint.plugin
import sys
import inspect
from flask.ext.babel import gettext
# noinspection PyUnresolvedReferences,PyMethodMayBeStatic
class ServerCommandsSubwizard(object):
def _is_servercommands_wizard_firstrunonly(self):
return True
def _is_servercommands_wizard_required(self):
system_shutdown_command = self._settings.global_get(["server", "commands", "systemShutdownCommand"])
system_restart_command = self._settings.global_get(["server", "commands", "systemRestartCommand"])
server_restart_command = self._settings.global_get(["server", "commands", "serverRestartCommand"])
return not (system_shutdown_command and system_restart_command and server_restart_command)
def _get_servercommands_wizard_details(self):
return dict(required=self._is_servercommands_wizard_required())
def _get_servercommands_wizard_name(self):
return gettext("Server Commands")
# noinspection PyUnresolvedReferences,PyMethodMayBeStatic
class WebcamSubwizard(object):
def _is_webcam_wizard_firstrunonly(self):
return True
def _is_webcam_wizard_required(self):
webcam_snapshot_url = self._settings.global_get(["webcam", "snapshot"])
webcam_stream_url = self._settings.global_get(["webcam", "stream"])
ffmpeg_path = self._settings.global_get(["webcam", "ffmpeg"])
return not (webcam_snapshot_url and webcam_stream_url and ffmpeg_path)
def _get_webcam_wizard_details(self):
return dict(required=self._is_webcam_wizard_required())
def _get_webcam_wizard_name(self):
return gettext("Webcam & Timelapse")
# noinspection PyUnresolvedReferences,PyMethodMayBeStatic
class AclSubwizard(object):
def _is_acl_wizard_firstrunonly(self):
return True
def _is_acl_wizard_required(self):
return self._user_manager.enabled and not self._user_manager.hasBeenCustomized()
def _get_acl_wizard_details(self):
return dict(required=self._is_acl_wizard_required())
def _get_acl_wizard_name(self):
return gettext("Access Control")
def _get_acl_additional_wizard_template_data(self):
return dict(mandatory=self._is_acl_wizard_required())
@octoprint.plugin.BlueprintPlugin.route("/acl", methods=["POST"])
def acl_wizard_api(self):
from flask import request, abort
from octoprint.server.api import valid_boolean_trues, NO_CONTENT
if not self._settings.global_get(["server", "firstRun"]) or self._user_manager.hasBeenCustomized():
abort(404)
data = request.values
if hasattr(request, "json") and request.json:
data = request.json
if "ac" in data and data["ac"] in valid_boolean_trues and \
"user" in data.keys() and "pass1" in data.keys() and \
"pass2" in data.keys() and data["pass1"] == data["pass2"]:
# configure access control
self._settings.global_set_boolean(["accessControl", "enabled"], True)
self._user_manager.enable()
self._user_manager.addUser(data["user"], data["pass1"], True, ["user", "admin"], overwrite=True)
elif "ac" in data.keys() and not data["ac"] in valid_boolean_trues:
# disable access control
self._settings.global_set_boolean(["accessControl", "enabled"], False)
octoprint.server.loginManager.anonymous_user = octoprint.users.DummyUser
octoprint.server.principals.identity_loaders.appendleft(octoprint.users.dummy_identity_loader)
self._user_manager.disable()
self._settings.save()
return NO_CONTENT
# noinspection PyUnresolvedReferences,PyMethodMayBeStatic
class OnlineCheckSubwizard(object):
def _is_onlinecheck_wizard_firstrunonly(self):
return False
def _is_onlinecheck_wizard_required(self):
return self._settings.global_get(["server", "onlineCheck", "enabled"]) is None
def _get_onlinecheck_wizard_details(self):
return dict(required=self._is_onlinecheck_wizard_required())
def _get_onlinecheck_wizard_name(self):
return gettext("Online connectivity check")
def _get_onlinecheck_additional_wizard_template_data(self):
return dict(mandatory=self._is_onlinecheck_wizard_required())
# noinspection PyUnresolvedReferences,PyMethodMayBeStatic
class PluginBlacklistSubwizard(object):
def _is_pluginblacklist_wizard_firstrunonly(self):
return False
def _is_pluginblacklist_wizard_required(self):
return self._settings.global_get(["server", "pluginBlacklist", "enabled"]) is None
def _get_pluginblacklist_wizard_details(self):
return dict(required=self._is_pluginblacklist_wizard_required())
def _get_pluginblacklist_wizard_name(self):
return gettext("Plugin blacklist")
def _get_pluginblacklist_additional_wizard_template_data(self):
return dict(mandatory=self._is_pluginblacklist_wizard_required())
# noinspection PyUnresolvedReferences,PyMethodMayBeStatic
class PrinterProfileSubwizard(object):
def _is_printerprofile_wizard_firstrunonly(self):
return True
def _is_printerprofile_wizard_required(self):
return self._printer_profile_manager.is_default_unmodified() and self._printer_profile_manager.profile_count == 1
def _get_printerprofile_wizard_details(self):
return dict(required=self._is_printerprofile_wizard_required())
def _get_printerprofile_wizard_name(self):
return gettext("Default Printer Profile")
Subwizards = type("Subwizwards",
tuple(cls for clsname, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass)
if clsname.endswith("Subwizard")),
dict())

View file

@ -31,6 +31,7 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin,
octoprint.plugin.StartupPlugin,
octoprint.plugin.WizardPlugin):
# noinspection PyMissingConstructor
def __init__(self):
self._logger = logging.getLogger("octoprint.plugins.cura")
self._cura_logger = logging.getLogger("octoprint.plugins.cura.engine")
@ -79,7 +80,7 @@ class CuraPlugin(octoprint.plugin.SlicerPlugin,
self._cura_logger.addHandler(cura_logging_handler)
self._cura_logger.setLevel(logging.DEBUG if self._settings.get_boolean(["debug_logging"]) else logging.CRITICAL)
self._cura_logger.propagate = False
engine = self._settings.get(["cura_engine"])
if not self._is_engine_configured(cura_engine=engine):
self._logger.info("Path to CuraEngine has not been configured or does not exist (currently set to %r), "
@ -519,6 +520,7 @@ def _get_usage_from_length(filament_length, filament_diameter):
return usage
__plugin_name__ = "CuraEngine (<= 15.04)"
__plugin_author__ = "Gina Häußge"
__plugin_url__ = "http://docs.octoprint.org/en/master/bundledplugins/cura.html"

View file

@ -8,7 +8,9 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms
import re
# noinspection PyCompatibility
from builtins import range
# noinspection PyCompatibility
from past.builtins import basestring
class SupportLocationTypes(object):

View file

@ -10,9 +10,10 @@ The SSDP/UPNP implementations has been largely inspired by https://gist.github.c
"""
import logging
import os
import flask
from flask.ext.babel import gettext
# noinspection PyCompatibility
from builtins import range
import octoprint.plugin
@ -24,14 +25,6 @@ except:
pybonjour = False
__plugin_name__ = "Discovery"
__plugin_author__ = "Gina Häußge"
__plugin_url__ = "http://docs.octoprint.org/en/master/bundledplugins/discovery.html"
__plugin_description__ = "Makes the OctoPrint instance discoverable via Bonjour/Avahi/Zeroconf and uPnP"
__plugin_disabling_discouraged__ = gettext("Without this plugin your OctoPrint instance will no longer be "
"discoverable on the network via Bonjour and uPnP.")
__plugin_license__ = "AGPLv3"
def __plugin_load__():
if not pybonjour:
# no pybonjour available, we can't use that
@ -62,6 +55,7 @@ class DiscoveryPlugin(octoprint.plugin.StartupPlugin,
ssdp_multicast_port = 1900
# noinspection PyMissingConstructor
def __init__(self):
self.host = None
self.port = None
@ -685,3 +679,12 @@ class DiscoveryPlugin(octoprint.plugin.StartupPlugin,
else:
import socket
return u"OctoPrint instance on {}".format(socket.gethostname())
__plugin_name__ = "Discovery"
__plugin_author__ = "Gina Häußge"
__plugin_url__ = "http://docs.octoprint.org/en/master/bundledplugins/discovery.html"
__plugin_description__ = "Makes the OctoPrint instance discoverable via Bonjour/Avahi/Zeroconf and uPnP"
__plugin_disabling_discouraged__ = gettext("Without this plugin your OctoPrint instance will no longer be "
"discoverable on the network via Bonjour and uPnP.")
__plugin_license__ = "AGPLv3"

View file

@ -91,6 +91,7 @@ class OctoPiSupportPlugin(octoprint.plugin.EnvironmentDetectionPlugin,
octoprint.plugin.AssetPlugin,
octoprint.plugin.TemplatePlugin):
# noinspection PyMissingConstructor
def __init__(self):
self._version = None
self._cpuinfo = None

View file

@ -12,14 +12,13 @@ import octoprint.plugin.core
from octoprint.settings import valid_boolean_trues
from octoprint.server.util.flask import restricted_access, with_revalidation_checking, check_etag
from octoprint.server import admin_permission, VERSION
from octoprint.util.pip import LocalPipCaller, UnknownPip
from octoprint.server import admin_permission
from octoprint.util.pip import LocalPipCaller
from octoprint.util.version import get_octoprint_version_string, get_octoprint_version, is_octoprint_compatible
from octoprint.util.platform import get_os
from flask import jsonify, make_response
from flask.ext.babel import gettext
from collections import OrderedDict
import logging
import sarge
@ -27,7 +26,6 @@ import sys
import requests
import re
import os
import pkg_resources
import copy
import dateutil.parser
import time
@ -44,7 +42,7 @@ class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin,
octoprint.plugin.EventHandlerPlugin):
ARCHIVE_EXTENSIONS = (".zip", ".tar.gz", ".tgz", ".tar")
# valid pip install URL schemes according to https://pip.pypa.io/en/stable/reference/pip_install/
URL_SCHEMES = ("http", "https", "git",
"git+http", "git+https", "git+ssh", "git+git",
@ -61,6 +59,7 @@ class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin,
RECONNECT_HOOKS = ["octoprint.comm.protocol.*",]
# noinspection PyMissingConstructor
def __init__(self):
self._pending_enable = set()
self._pending_disable = set()
@ -313,7 +312,7 @@ class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin,
if url is not None:
if not any(map(lambda scheme: url.startswith(scheme + "://"), self.URL_SCHEMES)):
raise ValueError("Invalid URL to pip install from")
source = url
source_type = "url"
already_installed_check = lambda line: url in line

View file

@ -15,8 +15,8 @@ import time
import logging
import logging.handlers
import hashlib
import traceback
# noinspection PyCompatibility
from concurrent import futures
from . import version_checks, updaters, exceptions, util, cli
@ -41,9 +41,10 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
octoprint.plugin.EventHandlerPlugin):
COMMIT_TRACKING_TYPES = ("github_commit", "bitbucket_commit")
DATA_FORMAT_VERSION = "v2"
# noinspection PyMissingConstructor
def __init__(self):
self._update_in_progress = False
self._configured_checks_mutex = threading.Lock()
@ -343,7 +344,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
if "octoprint_type" in data:
octoprint_type = data["octoprint_type"]
if octoprint_type == "github_release":
self._settings.set(["checks", "octoprint", "type"], octoprint_type, defaults=defaults, force=True)
self._settings.set(["checks", "octoprint", "method"], "pip", defaults=defaults, force=True)
@ -364,7 +365,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
self._settings.set(["checks", "octoprint", "prerelease"], False, defaults=defaults, force=True)
self._settings.set(["checks", "octoprint", "prerelease_channel"], None, defaults=defaults, force=True)
updated_octoprint_check_config = True
if updated_octoprint_check_config:
self._refresh_configured_checks = True
try:
@ -381,11 +382,11 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
if current is None or current < 6:
# up until & including config version 5 we didn't set the method parameter for the octoprint check
# configuration
configured_checks = self._settings.get(["checks"], incl_defaults=False)
if configured_checks is not None and "octoprint" in configured_checks:
octoprint_check = dict(configured_checks["octoprint"])
if not "method" in octoprint_check and octoprint_check.get("type") == "git_commit":
defaults = dict(plugins=dict(softwareupdate=dict(checks=dict(octoprint=dict(method="pip")))))
self._settings.set(["checks", "octoprint", "method"], "update_script", defaults=defaults)
@ -698,7 +699,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
releaseNotes=release_notes,
online=target_online,
error=target_error)
if target == "octoprint" and "released_version" in populated_check:
information[target]["released_version"] = populated_check["released_version"]
@ -1023,7 +1024,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
# we compare versions fully, not just the base so that we see a difference
# between RCs + stable for the same version release
result["force_base"] = False
if check.get("prerelease", None):
# we are tracking prereleases => we want to be on the correct prerelease channel/branch
channel = check.get("prerelease_channel", None)
@ -1031,7 +1032,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
# if we have a release channel, we also set our update_branch here to our release channel
# in case it's not already set
result["update_branch"] = check.get("update_branch", channel)
else:
# we are not tracking prereleases, but aren't on the stable branch either => switch back
# to stable branch on update
@ -1049,7 +1050,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin,
# branch of the release channel - unequality means we might have to handle
# a downgrade
result["release_compare"] = "python_unequal"
elif check.get("pip", None):
# we force python unequality check for pip installs, to be able to downgrade
result["release_compare"] = "python_unequal"