def wizardState(): if (not s().getBoolean(["server", "firstRun"]) and octoprint.server.userManager.has_been_customized() and not Permissions.ADMIN.can()): abort(403) seen_wizards = s().get(["server", "seenWizards"]) result = {} wizard_plugins = octoprint.server.pluginManager.get_implementations( octoprint.plugin.WizardPlugin) for implementation in wizard_plugins: name = implementation._identifier try: required = implementation.is_wizard_required() details = implementation.get_wizard_details() version = implementation.get_wizard_version() ignored = octoprint.plugin.WizardPlugin.is_wizard_ignored( seen_wizards, implementation) except Exception: logging.getLogger(__name__).exception( "There was an error fetching wizard " "details for {}, ignoring".format(name), extra={"plugin": name}, ) else: result[name] = { "required": required, "details": details, "version": version, "ignored": ignored, } return jsonify(result)
def _get_core_command_specs(): def enable_safe_mode(): s().set(["server", "startOnceInSafeMode"], True) s().save() commands = collections.OrderedDict( shutdown=dict( command=s().get(["server", "commands", "systemShutdownCommand"]), name=gettext("Shutdown system"), confirm=gettext("You are about to shutdown the system.")), reboot=dict( command=s().get(["server", "commands", "systemRestartCommand"]), name=gettext("Reboot system"), confirm=gettext("You are about to reboot the system.")), restart=dict( command=s().get(["server", "commands", "serverRestartCommand"]), name=gettext("Restart OctoPrint"), confirm=gettext("You are about to restart the OctoPrint server.")), restart_safe=dict( command=s().get(["server", "commands", "serverRestartCommand"]), name=gettext("Restart OctoPrint in safe mode"), confirm=gettext("You are about to restart the OctoPrint server in safe mode."), before=enable_safe_mode) ) available_commands = collections.OrderedDict() for action, spec in commands.items(): if not spec["command"]: continue spec.update(dict(action=action, source="core", async=True, ignore=True))
def login(): if octoprint.server.userManager is not None and "user" in request.values.keys( ) and "pass" in request.values.keys(): username = request.values["user"] password = request.values["pass"] if "remember" in request.values.keys( ) and request.values["remember"] == "true": remember = True else: remember = False user = octoprint.server.userManager.findUser(username) if user is not None: if user.has_password(): if astroprintCloud().validatePassword(username, password): login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) else: try: if astroprintCloud().signin(username, password): return jsonify(current_user) except (AstroPrintCloudNoConnectionException, ConnectionError): return make_response( ("AstroPrint.com can't be reached", 503, [])) return make_response(("User unknown or password incorrect", 401, [])) elif "passive" in request.values.keys(): user = current_user if user is not None and not user.is_anonymous: identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) elif s().getBoolean(["accessControl", "autologinLocal"]) \ and s().get(["accessControl", "autologinAs"]) is not None \ and s().get(["accessControl", "localNetworks"]) is not None: autologinAs = s().get(["accessControl", "autologinAs"]) localNetworks = netaddr.IPSet([]) for ip in s().get(["accessControl", "localNetworks"]): localNetworks.add(ip) try: remoteAddr = util.getRemoteAddress(request) if netaddr.IPAddress(remoteAddr) in localNetworks: user = octoprint.server.userManager.findUser(autologinAs) if user is not None: login_user(user) identity_changed.send( current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) except: logger = logging.getLogger(__name__) logger.exception( "Could not autologin user %s for networks %r" % (autologinAs, localNetworks)) return NO_CONTENT
def beforeApiRequests(): """ All requests in this blueprint need to be made supplying an API key. This may be the UI_API_KEY, in which case the underlying request processing will directly take place, or it may be the global or a user specific case. In any case it has to be present and must be valid, so anything other than the above three types will result in denying the request. """ if request.method == 'OPTIONS' and s().getBoolean(["api", "allowCrossOrigin"]): return optionsAllowOrigin(request) apikey = getApiKey(request) if apikey is None: # no api key => 401 return make_response("No API key provided", 401) if apikey == UI_API_KEY: # ui api key => continue regular request processing return if not s().get(["api", "enabled"]): # api disabled => 401 return make_response("API disabled", 401) if apikey == s().get(["api", "key"]): # global api key => continue regular request processing return user = getUserForApiKey(apikey) if user is not None: # user specific api key => continue regular request processing return # invalid api key => 401 return make_response("Invalid API key", 401)
def _get_core_command_specs(): def enable_safe_mode(): s().set(["server", "startOnceInSafeMode"], True) s().save() commands = collections.OrderedDict( shutdown=dict( command=s().get(["server", "commands", "systemShutdownCommand"]), name=gettext("Shutdown system"), confirm=gettext("<strong>You are about to shutdown the system.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage).")), reboot=dict( command=s().get(["server", "commands", "systemRestartCommand"]), name=gettext("Reboot system"), confirm=gettext("<strong>You are about to reboot the system.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage).")), restart=dict( command=s().get(["server", "commands", "serverRestartCommand"]), name=gettext("Restart OctoPrint"), confirm=gettext("<strong>You are about to restart the OctoPrint server.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage).")), restart_safe=dict( command=s().get(["server", "commands", "serverRestartCommand"]), name=gettext("Restart OctoPrint in safe mode"), confirm=gettext("<strong>You are about to restart the OctoPrint server in safe mode.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage)."), before=enable_safe_mode) ) available_commands = collections.OrderedDict() for action, spec in commands.items(): if not spec["command"]: continue spec.update(dict(action=action, source="core", async=True, debug=True))
def beforeApiRequests(): """ All requests in this blueprint need to be made supplying an API key. This may be the UI_API_KEY, in which case the underlying request processing will directly take place, or it may be the global or a user specific case. In any case it has to be present and must be valid, so anything other than the above three types will result in denying the request. """ if request.method == "OPTIONS" and s().getBoolean(["api", "allowCrossOrigin"]): return optionsAllowOrigin(request) apikey = getApiKey(request) if apikey is None: # no api key => 401 return make_response("No API key provided", 401) if apikey == UI_API_KEY: # ui api key => continue regular request processing return if not s().get(["api", "enabled"]): # api disabled => 401 return make_response("API disabled", 401) if apikey == s().get(["api", "key"]): # global api key => continue regular request processing return user = getUserForApiKey(apikey) if user is not None: # user specific api key => continue regular request processing return # invalid api key => 401 return make_response("Invalid API key", 401)
def slicingPatchSlicerProfile(slicer, name): if not slicer in slicingManager.registered_slicers: return make_response("Unknown slicer {slicer}".format(**locals()), 404) if not "application/json" in request.headers["Content-Type"]: return None, None, make_response("Expected content-type JSON", 400) profile = slicingManager.load_profile(slicer, name) if not profile: return make_response("Profile not found", 404) json_data = request.json data = dict() display_name = None description = None if "data" in json_data: data = json_data["data"] if "displayName" in json_data: display_name = json_data["displayName"] if "description" in json_data: description = json_data["description"] from octoprint.server.api import valid_boolean_trues if "default" in json_data and json_data["default"] in valid_boolean_trues: default_profiles = s().get(["slicing", "defaultProfiles"]) if not default_profiles: default_profiles = dict() default_profiles[slicer] = name s().set(["slicing", "defaultProfiles"], default_profiles) s().save(force=True) slicingManager.save_profile(slicer, name, profile, overrides=data, display_name=display_name, description=description) return NO_CONTENT
def _get_subwizard_attrs(self, start, end, callback=None): #to avoid forcing the user through the wizard, set these values if they do not exist #TODO: set serial number to something here incase ? #check if the check plugin blacklist is enabled, if not set to true if s().get(["server", "pluginBlacklist", "enabled"]) is None: s().set(["server", "pluginBlacklist", "enabled"], True) s().save() #check if the check interent connectivity is enabled, if not set to true if s().get(["server", "onlineCheck", "enabled"]) is None: s().set(["server", "onlineCheck", "enabled"], True) s().save() result = dict() for item in dir(self): if not item.startswith(start) or not item.endswith(end): continue key = item[len(start):-len(end)] if not key: continue attr = getattr(self, item) if callable(callback): callback(key, attr) result[key] = attr return result
def wizardState(): if not s().getBoolean(["server", "firstRun" ]) and not admin_permission.can(): abort(403) seen_wizards = s().get(["server", "seenWizards"]) result = dict() wizard_plugins = octoprint.server.pluginManager.get_implementations( octoprint.plugin.WizardPlugin) for implementation in wizard_plugins: name = implementation._identifier try: required = implementation.is_wizard_required() details = implementation.get_wizard_details() version = implementation.get_wizard_version() ignored = octoprint.plugin.WizardPlugin.is_wizard_ignored( seen_wizards, implementation) except: logging.getLogger(__name__).exception( "There was an error fetching wizard details for {}, ignoring". format(name)) else: result[name] = dict(required=required, details=details, version=version, ignored=ignored) return jsonify(result)
def _get_core_command_specs(): def enable_safe_mode(): s().set(["server", "startOnceInSafeMode"], True) s().save() commands = collections.OrderedDict( shutdown=dict( command=s().get(["server", "commands", "systemShutdownCommand"]), name=gettext("Shutdown system"), confirm=gettext("You are about to shutdown the system.")), reboot=dict( command=s().get(["server", "commands", "systemRestartCommand"]), name=gettext("Reboot system"), confirm=gettext("You are about to reboot the system.")), restart=dict( command=s().get(["server", "commands", "serverRestartCommand"]), name=gettext("Restart OctoPrint"), confirm=gettext("You are about to restart the OctoPrint server.")), restart_safe=dict( command=s().get(["server", "commands", "serverRestartCommand"]), name=gettext("Restart OctoPrint in safe mode"), confirm=gettext("You are about to restart the OctoPrint server in safe mode."), before=enable_safe_mode) ) available_commands = collections.OrderedDict() for action, spec in commands.items(): if not spec["command"]: continue spec.update(dict(action=action, source="core", async=True, debug=True))
def performSystemAction(): #s().save(True) s().setFloat(["serial", "zpos"], sp._currentZ) s().save(True) logger = logging.getLogger(__name__) if "action" in request.values.keys(): action = request.values["action"] available_actions = s().get(["system", "actions"]) for availableAction in available_actions: if availableAction["action"] == action: logger.info("Performing command: %s" % availableAction["command"]) try: # Note: we put the command in brackets since sarge (up to the most recently released version) has # a bug concerning shell=True commands. Once sarge 0.1.4 we can upgrade to that and remove this # workaround again # # See https://bitbucket.org/vinay.sajip/sarge/issue/21/behavior-is-not-like-popen-using-shell p = sarge.run([availableAction["command"]], stderr=sarge.Capture(), shell=True) if p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text logger.warn("Command failed with return code %i: %s" % (returncode, stderr_text)) return make_response(("Command failed with return code %i: %s" % (returncode, stderr_text), 500, [])) except Exception, e: logger.warn("Command failed: %s" % e) return make_response(("Command failed: %s" % e, 500, []))
def _usageForFolders(): data = {} for folder_name in s().get(['folder']).keys(): path = s().getBaseFolder(folder_name, check_writable=False) if path is not None: usage = psutil.disk_usage(path) data[folder_name] = { 'free': usage.free, 'total': usage.total } return data
def _usageForFolders(): data = {} for folder_name in s().get(['folder']).keys(): path = s().getBaseFolder(folder_name, check_writable=False) if path is not None: usage = psutil.disk_usage(path) data[folder_name] = {'free': usage.free, 'total': usage.total} return data
def wizardFinish(): if not s().getBoolean(["server", "firstRun"]) and not admin_permission.can(): abort(403) data = dict() try: data = request.json except: abort(400) if not "handled" in data: abort(400) handled = data["handled"] if s().getBoolean(["server", "firstRun"]): s().setBoolean(["server", "firstRun"], False) seen_wizards = dict(s().get(["server", "seenWizards"])) wizard_plugins = octoprint.server.pluginManager.get_implementations(octoprint.plugin.WizardPlugin) for implementation in wizard_plugins: name = implementation._identifier try: implementation.on_wizard_finish(name in handled) if name in handled: seen_wizards[name] = implementation.get_wizard_version() except: logging.getLogger(__name__).exception("There was an error finishing the wizard for {}, ignoring".format(name)) s().set(["server", "seenWizards"], seen_wizards) s().save() return NO_CONTENT
def login(): if octoprint.server.userManager is not None and "user" in request.values.keys() and "pass" in request.values.keys(): username = request.values["user"] password = request.values["pass"] if "remember" in request.values.keys() and request.values["remember"] == "true": remember = True else: remember = False if "usersession.id" in session: _logout(current_user) user = octoprint.server.userManager.findUser(username) if user is not None: if octoprint.server.userManager.checkPassword(username, password): if octoprint.server.userManager is not None: user = octoprint.server.userManager.login_user(user) session["usersession.id"] = user.get_session() login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) return make_response(("User unknown or password incorrect", 401, [])) elif "passive" in request.values.keys(): if octoprint.server.userManager is not None: user = octoprint.server.userManager.login_user(current_user) else: user = current_user if user is not None and not user.is_anonymous(): identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) elif s().getBoolean(["accessControl", "autologinLocal"]) \ and s().get(["accessControl", "autologinAs"]) is not None \ and s().get(["accessControl", "localNetworks"]) is not None: autologinAs = s().get(["accessControl", "autologinAs"]) localNetworks = netaddr.IPSet([]) for ip in s().get(["accessControl", "localNetworks"]): localNetworks.add(ip) try: remoteAddr = util.getRemoteAddress(request) if netaddr.IPAddress(remoteAddr) in localNetworks: user = octoprint.server.userManager.findUser(autologinAs) if user is not None: login_user(user) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) except: logger = logging.getLogger(__name__) logger.exception("Could not autologin user %s for networks %r" % (autologinAs, localNetworks)) return NO_CONTENT
def login(): if octoprint.server.userManager is not None and "user" in request.values.keys( ) and "pass" in request.values.keys(): username = request.values["user"] password = request.values["pass"] if "remember" in request.values.keys( ) and request.values["remember"] == "true": remember = True else: remember = False user = octoprint.server.userManager.findUser(username) if user is not None: if octoprint.server.userManager.checkPassword(username, password): login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) return make_response(("User unknown or password incorrect", 401, [])) elif "passive" in request.values.keys(): user = current_user if user is not None and not user.is_anonymous(): identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) elif s().getBoolean(["accessControl", "autologinLocal"]) \ and s().get(["accessControl", "autologinAs"]) is not None \ and s().get(["accessControl", "localNetworks"]) is not None \ or s().getBoolean(["accessControl", "autologinWeb"]) is True: #modify by kevin, for auto login web autologinAs = s().get(["accessControl", "autologinAs"]) localNetworks = netaddr.IPSet([]) for ip in s().get(["accessControl", "localNetworks"]): localNetworks.add(ip) try: remoteAddr = util.getRemoteAddress(request) if netaddr.IPAddress(remoteAddr) in localNetworks \ or s().getBoolean(["accessControl", "autologinWeb"]) is True: #modify by kevin, for auto login web if netaddr.IPAddress(remoteAddr) in localNetworks: autologinAs = s().getBoolean([ "accessControl", "defaultUsers", "admin", "username" ]) user = octoprint.server.userManager.findUser(autologinAs) if user is not None: login_user( user, remember=True) #modify by kevin, for autoLogin identity_changed.send( current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) except: logger = logging.getLogger(__name__) logger.exception( "Could not autologin user %s for networks %r" % (autologinAs, localNetworks)) return NO_CONTENT
def getSystemInfo(): from octoprint.cli.systeminfo import get_systeminfo from octoprint.server import ( connectivityChecker, environmentDetector, printer, safe_mode, ) from octoprint.util import dict_flatten systeminfo = get_systeminfo( environmentDetector, connectivityChecker, s(), { "browser.user_agent": request.headers.get("User-Agent"), "octoprint.safe_mode": safe_mode is not None, "systeminfo.generator": "systemapi", }, ) if printer and printer.is_operational(): firmware_info = printer.firmware_info if firmware_info: systeminfo.update( dict_flatten({"firmware": firmware_info["name"]}, prefix="printer")) return jsonify(systeminfo=systeminfo)
def performSystemAction(): logger = logging.getLogger(__name__) if "action" in request.values.keys(): action = request.values["action"] available_actions = s().get(["system", "actions"]) for availableAction in available_actions: if availableAction["action"] == action: async = availableAction["async"] if "async" in availableAction else False ignore = availableAction["ignore"] if "ignore" in availableAction else False logger.info("Performing command: %s" % availableAction["command"]) try: # Note: we put the command in brackets since sarge (up to the most recently released version) has # a bug concerning shell=True commands. Once sarge 0.1.4 we can upgrade to that and remove this # workaround again # # See https://bitbucket.org/vinay.sajip/sarge/issue/21/behavior-is-not-like-popen-using-shell p = sarge.run([availableAction["command"]], stderr=sarge.Capture(), shell=True, async=async) if not async: if not ignore and p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text logger.warn("Command failed with return code %i: %s" % (returncode, stderr_text)) return make_response(("Command failed with return code %i: %s" % (returncode, stderr_text), 500, [])) except Exception, e: if not ignore: logger.warn("Command failed: %s" % e) return make_response(("Command failed: %s" % e, 500, [])) break
def getNozzlesAndFilament(): """ Returns the list of available nozzles, the current selected nozzle, the current selected filament and the amount of filament left in spool :return: """ nozzle_list = s().get(["nozzleTypes"]) if not printer.is_operational(): return jsonify({ "nozzle": '0.4', "nozzleList": nozzle_list, "filament": 'A023 - Black', "filamentInSpool": 0.0 }) filament = printer.getFilamentString() filamentInSpool = printer.getFilamentWeightInSpool() nozzle = printer.getNozzleSize() # converts the nozzle size to float nozzle = float(nozzle) / 1000.0 return jsonify({ "nozzle": nozzle, "nozzleList": nozzle_list, "filament": filament, "filamentInSpool": filamentInSpool })
def performSystemAction(): logger = logging.getLogger(__name__) if "action" in request.values.keys(): action = request.values["action"] available_actions = s().get(["system", "actions"]) for availableAction in available_actions: if availableAction["action"] == action: async = availableAction["async"] if "async" in availableAction else False ignore = availableAction["ignore"] if "ignore" in availableAction else False logger.info("Performing command: %s" % availableAction["command"]) try: # we run this with shell=True since we have to trust whatever # our admin configured as command and since we want to allow # shell-alike handling here... p = sarge.run(availableAction["command"], stderr=sarge.Capture(), shell=True, async=async) if not async: if not ignore and p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text logger.warn("Command failed with return code %i: %s" % (returncode, stderr_text)) return make_response(("Command failed with return code %i: %s" % (returncode, stderr_text), 500, [])) except Exception, e: if not ignore: logger.warn("Command failed: %s" % e) return make_response(("Command failed: %s" % e, 500, [])) break
def slicingListAll(): from octoprint.filemanager import get_extensions default_slicer = s().get(["slicing", "defaultSlicer"]) if "configured" in request.values and request.values["configured"] in valid_boolean_trues: slicers = slicingManager.configured_slicers else: slicers = slicingManager.registered_slicers result = dict() for slicer in slicers: try: slicer_impl = slicingManager.get_slicer(slicer, require_configured=False) extensions = set() for source_file_type in slicer_impl.get_slicer_properties().get("source_file_types", ["model"]): extensions = extensions.union(get_extensions(source_file_type)) result[slicer] = dict( key=slicer, displayName=slicer_impl.get_slicer_properties()["name"], default=default_slicer == slicer, configured=slicer_impl.is_slicer_configured(), profiles=_getSlicingProfilesData(slicer), extensions=dict( source=list(extensions), destination=slicer_impl.get_slicer_properties().get("destination_extensions", ["gco", "gcode", "g"]) ) ) except (UnknownSlicer, SlicerNotConfigured): # this should never happen pass return jsonify(result)
def performSystemAction(): if "action" in request.values.keys(): action = request.values["action"] available_actions = s().get(["system", "actions"]) for availableAction in available_actions: if availableAction["action"] == action: command = availableAction["command"] if command: logger = logging.getLogger(__name__) logger.info("Performing command: %s" % command) def executeCommand(command, logger): time.sleep(0.5) #add a small delay to make sure the response is sent try: p = sarge.run(command, stderr=sarge.Capture()) if p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text logger.warn("Command failed with return code %i: %s" % (returncode, stderr_text)) else: logger.info("Command executed sucessfully") except Exception, e: logger.warn("Command failed: %s" % e) executeThread = threading.Thread(target=executeCommand, args=(command, logger)) executeThread.start() return OK else: break
def slicingListAll(): default_slicer = s().get(["slicing", "defaultSlicer"]) if "configured" in request.values and request.values[ "configured"] in valid_boolean_trues: slicers = slicingManager.configured_slicers else: slicers = slicingManager.registered_slicers result = dict() for slicer in slicers: try: slicer_impl = slicingManager.get_slicer(slicer, require_configured=False) result[slicer] = dict( key=slicer, displayName=slicer_impl.get_slicer_properties()["name"], default=default_slicer == slicer, configured=slicer_impl.is_slicer_configured(), profiles=_getSlicingProfilesData(slicer)) except (UnknownSlicer, SlicerNotConfigured): # this should never happen pass return jsonify(result)
def _etag(configured, lm=None): if lm is None: lm = _lastmodified(configured) import hashlib hash = hashlib.sha1() def hash_update(value): value = value.encode("utf-8") hash.update(value) hash_update(str(lm)) if configured: slicers = slicingManager.configured_slicers else: slicers = slicingManager.registered_slicers default_slicer = s().get(["slicing", "defaultSlicer"]) for slicer in sorted(slicers): slicer_impl = slicingManager.get_slicer(slicer, require_configured=False) hash_update(slicer) hash_update(str(slicer_impl.is_slicer_configured())) hash_update(str(slicer == default_slicer)) hash_update( _DATA_FORMAT_VERSION) # increment version if we change the API format return hash.hexdigest()
def performSystemAction(): if "action" in request.values.keys(): action = request.values["action"] available_actions = s().get(["system", "actions"]) for availableAction in available_actions: if availableAction["action"] == action: command = availableAction["command"] if command: logger = logging.getLogger(__name__) logger.info("Performing command: %s" % command) try: p = sarge.run(command, stderr=sarge.Capture()) if p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text logger.warn( "Command failed with return code %i: %s" % (returncode, stderr_text)) return make_response( ("Command failed with return code %i: %s" % (returncode, stderr_text), 500, [])) else: return OK except Exception, e: logger.warn("Command failed: %s" % e) return make_response( ("Command failed: %s" % e, 500, [])) else: break
def plugin_settings(plugin_key, defaults=None, get_preprocessors=None, set_preprocessors=None, settings=None): """ Factory method for creating a :class:`PluginSettings` instance. Arguments: plugin_key (string): The plugin identifier for which to create the settings instance. defaults (dict): The default settings for the plugin, if different from get_settings_defaults. get_preprocessors (dict): The getter preprocessors for the plugin. set_preprocessors (dict): The setter preprocessors for the plugin. settings (octoprint.settings.Settings): The settings instance to use. Returns: PluginSettings: A fully initialized :class:`PluginSettings` instance to be used to access the plugin's settings """ if settings is None: settings = s() return PluginSettings(settings, plugin_key, defaults=defaults, get_preprocessors=get_preprocessors, set_preprocessors=set_preprocessors)
def slicingPatchSlicerProfile(slicer, name): if not "application/json" in request.headers["Content-Type"]: return make_response("Expected content-type JSON", 400) try: profile = slicingManager.load_profile(slicer, name, require_configured=False) except UnknownSlicer: return make_response("Unknown slicer {slicer}".format(**locals()), 404) except UnknownProfile: return make_response( "Profile {name} for slicer {slicer} not found".format(**locals()), 404) try: json_data = request.json except BadRequest: return make_response("Malformed JSON body in request", 400) data = dict() display_name = None description = None if "data" in json_data: data = json_data["data"] if "displayName" in json_data: display_name = json_data["displayName"] if "description" in json_data: description = json_data["description"] from octoprint.server.api import valid_boolean_trues if "default" in json_data and json_data["default"] in valid_boolean_trues: default_profiles = s().get(["slicing", "defaultProfiles"]) if not default_profiles: default_profiles = dict() default_profiles[slicer] = name s().set(["slicing", "defaultProfiles"], default_profiles) s().save(force=True) saved_profile = slicingManager.save_profile(slicer, name, profile, allow_overwrite=True, overrides=data, display_name=display_name, description=description) return jsonify(_getSlicingProfileData(slicer, name, saved_profile))
def afterApiRequests(resp): # Allow crossdomain allowCrossOrigin = s().getBoolean(["api", "allowCrossOrigin"]) if request.method != 'OPTIONS' and 'Origin' in request.headers and allowCrossOrigin: resp.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] return resp
def afterApiRequests(resp): # Allow crossdomain allowCrossOrigin = s().getBoolean(["api", "allowCrossOrigin"]) if request.method != "OPTIONS" and "Origin" in request.headers and allowCrossOrigin: resp.headers["Access-Control-Allow-Origin"] = request.headers["Origin"] return resp
def nozzleSizes(): """ Gets the nozzle sizes available :return: """ nozzles = s().get(["nozzleTypes"]) return jsonify(nozzles)
def login(): data = request.get_json() if not data: data = request.values if octoprint.server.userManager.enabled and "user" in data and "pass" in data: username = data["user"] password = data["pass"] if "remember" in data and data["remember"] in valid_boolean_trues: remember = True else: remember = False if "usersession.id" in session: _logout(current_user) user = octoprint.server.userManager.find_user(username) if user is not None: if octoprint.server.userManager.check_password(username, password): if not user.is_active: return make_response( ("Your account is deactivated", 403, [])) if octoprint.server.userManager.enabled: user = octoprint.server.userManager.login_user(user) session["usersession.id"] = user.session g.user = user login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) remote_addr = get_remote_address(request) logging.getLogger(__name__).info( "Actively logging in user {} from {}".format( user.get_id(), remote_addr)) response = user.as_dict() response["_is_external_client"] = s().getBoolean(["server", "ipCheck", "enabled"]) \ and not util_net.is_lan_address(remote_addr, additional_private=s().get(["server", "ipCheck", "trustedSubnets"])) r = make_response(jsonify(response)) r.delete_cookie("active_logout") eventManager().fire(Events.USER_LOGGED_IN, payload=dict(username=user.get_id())) return r return make_response(("User unknown or password incorrect", 403, [])) elif "passive" in data: return passive_login() return make_response( "Neither user and pass attributes nor passive flag present", 400)
def _get_core_command_specs(): def enable_safe_mode(): s().set(["server", "startOnceInSafeMode"], True) s().save() commands = collections.OrderedDict( shutdown={ "command": s().get(["server", "commands", "systemShutdownCommand"]), "name": gettext("Shutdown system"), "confirm": gettext( "<strong>You are about to shutdown the system.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage)." ), }, reboot={ "command": s().get(["server", "commands", "systemRestartCommand"]), "name": gettext("Reboot system"), "confirm": gettext( "<strong>You are about to reboot the system.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage)." ), }, restart={ "command": s().get(["server", "commands", "serverRestartCommand"]), "name": gettext("Restart OctoPrint"), "confirm": gettext( "<strong>You are about to restart the OctoPrint server.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage)." ), }, restart_safe={ "command": s().get(["server", "commands", "serverRestartCommand"]), "name": gettext("Restart OctoPrint in safe mode"), "confirm": gettext( "<strong>You are about to restart the OctoPrint server in safe mode.</strong></p><p>This action may disrupt any ongoing print jobs (depending on your printer's controller and general setup that might also apply to prints run directly from your printer's internal storage)." ), "before": enable_safe_mode, }, ) available_commands = collections.OrderedDict() for action, spec in commands.items(): if not spec["command"]: continue spec.update({"action": action, "source": "core", "async": True, "debug": True}) available_commands[action] = spec return available_commands
def filamentProfiles(): """ Gets the slicing profiles (Filament colors) configured for Cura engine :return: """ default_slicer = s().get(["slicing", "defaultSlicer"]) profiles = getSlicingProfilesData(default_slicer) return jsonify(profiles)
def performSystemAction(): if "action" in request.values.keys(): action = request.values["action"] available_actions = s().get(["system", "actions"]) logger = logging.getLogger(__name__) for availableAction in available_actions: if availableAction["action"] == action: command = availableAction["command"] if command: logger.info("Performing command: %s" % command) def executeCommand(command, logger): timeSleeping = 0.5 #if shutdown send message to plugin if action == "reboot" or action == "shutdown": eventManager().fire(Events.SHUTTING_DOWN, {'status': action}) timeSleeping = 1 time.sleep( timeSleeping ) #add a small delay to make sure the response is sent try: p = sarge.run(command, stderr=sarge.Capture()) if p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text logger.warn( "Command failed with return code %i: %s" % (returncode, stderr_text)) if action == "reboot" or action == "shutdown": eventManager().fire( Events.SHUTTING_DOWN, {'status': None}) else: logger.info("Command executed sucessfully") except Exception, e: logger.warn("Command failed: %s" % e) if command == "reboot" or command == "shutdown": eventManager().fire(Events.SHUTTING_DOWN, {'status': None}) executeThread = threading.Thread(target=executeCommand, args=(command, logger)) executeThread.start() return OK else: logger.warn("Action %s is misconfigured" % action) return ("Misconfigured action", 500) logger.warn("No suitable action in config for: %s" % action) return ("Command not found", 404)
def __init__(self, settings=None): self._logger = logging.getLogger(__name__) self._session_users_by_session = dict() self._sessionids_by_userid = dict() self._enabled = True if settings is None: settings = s() self._settings = settings self._callbacks = []
def wizardState(): if not s().getBoolean(["server", "firstRun"]) and not admin_permission.can(): abort(403) seen_wizards = s().get(["server", "seenWizards"]) result = dict() wizard_plugins = octoprint.server.pluginManager.get_implementations(octoprint.plugin.WizardPlugin) for implementation in wizard_plugins: name = implementation._identifier try: required = implementation.is_wizard_required() details = implementation.get_wizard_details() version = implementation.get_wizard_version() ignored = octoprint.plugin.WizardPlugin.is_wizard_ignored(seen_wizards, implementation) except: logging.getLogger(__name__).exception("There was an error fetching wizard details for {}, ignoring".format(name)) else: result[name] = dict(required=required, details=details, version=version, ignored=ignored) return jsonify(result)
def slicingListAll(): default_slicer = s().get(["slicing", "defaultSlicer"]) result = dict() for slicer in slicingManager.registered_slicers: result[slicer] = dict(key=slicer, displayName=slicingManager.get_slicer( slicer).get_slicer_properties()["name"], default=default_slicer == slicer, profiles=_getSlicingProfilesData(slicer)) return jsonify(result)
def _getSlicingProfileData(slicer, name, profile): defaultProfiles = s().get(["slicing", "defaultProfiles"]) result = dict( key=name, default=defaultProfiles and slicer in defaultProfiles and defaultProfiles[slicer] == name, resource=url_for(".slicingGetSlicerProfile", slicer=slicer, name=name, _external=True) ) if profile.display_name is not None: result["displayName"] = profile.display_name if profile.description is not None: result["description"] = profile.description return result
def _get_core_command_specs(): commands = collections.OrderedDict( shutdown=dict( command=s().get(["server", "commands", "systemShutdownCommand"]), name=gettext("Shutdown system"), confirm=gettext("You are about to shutdown the system.")), reboot=dict(command=s().get( ["server", "commands", "systemRestartCommand"]), name=gettext("Reboot system"), confirm=gettext("You are about to reboot the system.")), restart=dict( command=s().get(["server", "commands", "serverRestartCommand"]), name=gettext("Restart OctoPrint"), confirm=gettext("You are about to restart the OctoPrint server."))) available_commands = collections.OrderedDict() for action, spec in commands.items(): if not spec["command"]: continue spec.update(dict(action=action, source="core", async=True, ignore=True))
def slicingListAll(): default_slicer = s().get(["slicing", "defaultSlicer"]) result = dict() for slicer in slicingManager.registered_slicers: result[slicer] = dict( key=slicer, displayName=slicingManager.get_slicer(slicer).get_slicer_properties()["name"], default=default_slicer == slicer, profiles=_getSlicingProfilesData(slicer) ) return jsonify(result)
def slicingPatchSlicerProfile(slicer, name): if not "application/json" in request.headers["Content-Type"]: return make_response("Expected content-type JSON", 400) try: profile = slicingManager.load_profile(slicer, name, require_configured=False) except UnknownSlicer: return make_response("Unknown slicer {slicer}".format(**locals()), 404) except UnknownProfile: return make_response("Profile {name} for slicer {slicer} not found".format(**locals()), 404) try: json_data = request.json except BadRequest: return make_response("Malformed JSON body in request", 400) data = dict() display_name = None description = None if "data" in json_data: data = json_data["data"] if "displayName" in json_data: display_name = json_data["displayName"] if "description" in json_data: description = json_data["description"] from octoprint.server.api import valid_boolean_trues if "default" in json_data and json_data["default"] in valid_boolean_trues: default_profiles = s().get(["slicing", "defaultProfiles"]) if not default_profiles: default_profiles = dict() default_profiles[slicer] = name s().set(["slicing", "defaultProfiles"], default_profiles) s().save(force=True) saved_profile = slicingManager.save_profile(slicer, name, profile, allow_overwrite=True, overrides=data, display_name=display_name, description=description) return jsonify(_getSlicingProfileData(slicer, name, saved_profile))
def _get_registered_apps(): global __registered_apps if __registered_apps is not None: return __registered_apps apps = s().get(["api", "apps"], merged=True) for app, app_data in apps.items(): if not "enabled" in app_data: apps[app]["enabled"] = True hooks = octoprint.server.pluginManager.get_hooks("octoprint.accesscontrol.appkey") for name, hook in hooks.items(): try: additional_apps = hook() except: import logging logging.getLogger(__name__).exception("Error while retrieving additional appkeys from plugin {name}".format(**locals())) continue any_version_enabled = dict() for app_data in additional_apps: id, version, pubkey = app_data key = id + ":" + version if key in apps: continue if not id in any_version_enabled: any_version_enabled[id] = False if version == "any": any_version_enabled[id] = True apps[key] = dict( pubkey=pubkey, enabled=True ) for id, enabled in any_version_enabled.items(): if enabled: continue apps[id + ":any"] = dict( pubkey=None, enabled=False ) __registered_apps = apps return apps
def _get_custom_command_specs(): specs = collections.OrderedDict() dividers = 0 for spec in s().get(["system", "actions"]): if not "action" in spec: continue copied = dict(spec) copied["source"] = "custom" action = spec["action"] if action == "divider": dividers += 1 action = "divider_{}".format(dividers) specs[action] = copied return specs
def performSystemAction(): logger = logging.getLogger(__name__) if request.values.has_key("action"): action = request.values["action"] availableActions = s().get(["system", "actions"]) for availableAction in availableActions: if availableAction["action"] == action: logger.info("Performing command: %s" % availableAction["command"]) try: subprocess.check_output(availableAction["command"], shell=True) except subprocess.CalledProcessError, e: logger.warn("Command failed with return code %i: %s" % (e.returncode, e.message)) return make_response(("Command failed with return code %i: %s" % (e.returncode, e.message), 500, [])) except Exception, ex: logger.exception("Command failed") return make_response(("Command failed: %r" % ex, 500, []))
def login(): data = request.values if hasattr(request, "json") and request.json: data = request.json if octoprint.server.userManager.enabled and "user" in data and "pass" in data: username = data["user"] password = data["pass"] if "remember" in data and data["remember"] in valid_boolean_trues: remember = True else: remember = False if "usersession.id" in session: _logout(current_user) user = octoprint.server.userManager.findUser(username) if user is not None: if octoprint.server.userManager.checkPassword(username, password): if not user.is_active(): return make_response(("Your account is deactivated", 403, [])) if octoprint.server.userManager.enabled: user = octoprint.server.userManager.login_user(user) session["usersession.id"] = user.session g.user = user login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) remote_addr = get_remote_address(request) logging.getLogger(__name__).info("Actively logging in user {} from {}".format(user.get_id(), remote_addr)) response = user.asDict() response["_is_external_client"] = s().getBoolean(["server", "ipCheck", "enabled"]) \ and not util_net.is_lan_address(remote_addr, additional_private=s().get(["server", "ipCheck", "trustedSubnets"])) return jsonify(response) return make_response(("User unknown or password incorrect", 401, [])) elif "passive" in data: return passive_login() return NO_CONTENT
def performSystemAction(): logger = logging.getLogger(__name__) if "action" in request.values.keys(): action = request.values["action"] available_actions = s().get(["system", "actions"]) for availableAction in available_actions: if availableAction["action"] == action: logger.info("Performing command: %s" % availableAction["command"]) try: p = sarge.run(availableAction["command"], stderr=sarge.Capture()) if p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text logger.warn("Command failed with return code %i: %s" % (returncode, stderr_text)) return make_response(("Command failed with return code %i: %s" % (returncode, stderr_text), 500, [])) else: return OK except Exception, e: logger.warn("Command failed: %s" % e) return make_response(("Command failed: %s" % e, 500, []))
def _get_registered_apps(): global __registered_apps if __registered_apps is not None: return __registered_apps apps = s().get(["api", "apps"], merged=True) for app, app_data in apps.items(): if not "enabled" in app_data: apps[app]["enabled"] = True app_plugins = octoprint.server.pluginManager.get_implementations(octoprint.plugin.AppPlugin) for name, plugin in app_plugins.items(): additional_apps = plugin.get_additional_apps() any_version_enabled = dict() for app_data in additional_apps: id, version, pubkey = app_data key = id + ":" + version if key in apps: continue if not id in any_version_enabled: any_version_enabled[id] = False if version == "any": any_version_enabled[id] = True apps[key] = dict(pubkey=pubkey, enabled=True) for id, enabled in any_version_enabled.items(): if enabled: continue apps[id + ":any"] = dict(pubkey=None, enabled=False) __registered_apps = apps return apps
def _etag(configured, lm=None): if lm is None: lm = _lastmodified(configured) import hashlib hash = hashlib.sha1() hash.update(str(lm)) if configured: slicers = slicingManager.configured_slicers else: slicers = slicingManager.registered_slicers default_slicer = s().get(["slicing", "defaultSlicer"]) for slicer in sorted(slicers): slicer_impl = slicingManager.get_slicer(slicer, require_configured=False) hash.update(slicer) hash.update(str(slicer_impl.is_slicer_configured())) hash.update(str(slicer == default_slicer)) hash.update(_DATA_FORMAT_VERSION) # increment version if we change the API format return hash.hexdigest()
def slicingListAll(): default_slicer = s().get(["slicing", "defaultSlicer"]) if "configured" in request.values and request.values["configured"] in valid_boolean_trues: slicers = slicingManager.configured_slicers else: slicers = slicingManager.registered_slicers result = dict() for slicer in slicers: try: slicer_impl = slicingManager.get_slicer(slicer, require_configured=False) result[slicer] = dict( key=slicer, displayName=slicer_impl.get_slicer_properties()["name"], default=default_slicer == slicer, configured = slicer_impl.is_slicer_configured(), profiles=_getSlicingProfilesData(slicer) ) except (UnknownSlicer, SlicerNotConfigured): # this should never happen pass return jsonify(result)
def firstRunSetup(): if not s().getBoolean(["server", "firstRun"]): abort(403) if "ac" in request.values.keys() and request.values["ac"] in valid_boolean_trues and \ "user" in request.values.keys() and "pass1" in request.values.keys() and \ "pass2" in request.values.keys() and request.values["pass1"] == request.values["pass2"]: # configure access control s().setBoolean(["accessControl", "enabled"], True) octoprint.server.userManager.addUser(request.values["user"], request.values["pass1"], True, ["user", "admin"]) s().setBoolean(["server", "firstRun"], False) elif "ac" in request.values.keys() and not request.values["ac"] in valid_boolean_trues: # disable access control s().setBoolean(["accessControl", "enabled"], False) s().setBoolean(["server", "firstRun"], False) octoprint.server.loginManager.anonymous_user = octoprint.users.DummyUser octoprint.server.principals.identity_loaders.appendleft(octoprint.users.dummy_identity_loader) s().save() return NO_CONTENT
def enable_safe_mode(): s().set(["server", "startOnceInSafeMode"], True) s().save()