From c33fcdb124d690161b1a959a43b8c0544fc50f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 19 Aug 2015 17:28:23 +0200 Subject: [PATCH] Track already seen wizards --- src/octoprint/plugin/types.py | 5 +++- src/octoprint/server/api/__init__.py | 21 +++++++++++-- src/octoprint/server/views.py | 9 ++++-- src/octoprint/settings.py | 1 + .../static/js/app/viewmodels/wizard.js | 30 +++++++++++++++++-- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/octoprint/plugin/types.py b/src/octoprint/plugin/types.py index dd8dddce..f47cfc0f 100644 --- a/src/octoprint/plugin/types.py +++ b/src/octoprint/plugin/types.py @@ -458,9 +458,12 @@ class WizardPlugin(OctoPrintPlugin, ReloadNeedingPlugin): def get_wizard_details(self): return dict() - def on_wizard_finish(self): + def on_wizard_finish(self, handled): pass + def get_wizard_version(self): + return None + class SimpleApiPlugin(OctoPrintPlugin): """ diff --git a/src/octoprint/server/api/__init__.py b/src/octoprint/server/api/__init__.py index 53cbdf83..c40501a8 100644 --- a/src/octoprint/server/api/__init__.py +++ b/src/octoprint/server/api/__init__.py @@ -100,7 +100,7 @@ def pluginCommand(name): @api.route("/setup/wizard", methods=["GET"]) def wizardState(): - if not admin_permission.can(): + if not s().getBoolean(["server", "firstRun"]) and not admin_permission.can(): abort(403) result = dict() @@ -120,20 +120,35 @@ def wizardState(): @api.route("/setup/wizard", methods=["POST"]) def wizardFinish(): - if not admin_permission.can(): + 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() + implementation.on_wizard_finish(name in handled) + if name in handled: + seen_wizards[name] = implementation.get_wizard_version() except: logging.getLogger(__name__).exceptino("There was an error finishing the wizard for {}, ignoring".format(name)) + s().set(["server", "seenWizards"], seen_wizards) s().save() return NO_CONTENT diff --git a/src/octoprint/server/views.py b/src/octoprint/server/views.py index b22e828e..e9953b85 100644 --- a/src/octoprint/server/views.py +++ b/src/octoprint/server/views.py @@ -29,13 +29,13 @@ def index(): #~~ a bunch of settings + first_run = settings().getBoolean(["server", "firstRun"]) enable_gcodeviewer = settings().getBoolean(["gcodeViewer", "enabled"]) enable_timelapse = (settings().get(["webcam", "snapshot"]) and settings().get(["webcam", "ffmpeg"])) enable_systemmenu = settings().get(["system"]) is not None and settings().get(["system", "actions"]) is not None and len(settings().get(["system", "actions"])) > 0 enable_accesscontrol = userManager is not None preferred_stylesheet = settings().get(["devel", "stylesheet"]) locales = dict((l.language, dict(language=l.language, display=l.display_name, english=l.english_name)) for l in LOCALES) - first_run = settings().getBoolean(["server", "firstRun"])# and (userManager is None or not userManager.hasBeenCustomized()) ##~~ prepare templates @@ -190,16 +190,19 @@ def index(): plugin_vars = dict() plugin_names = set() + seen_wizards = settings().get(["server", "seenWizards"]) for implementation in template_plugins: name = implementation._identifier plugin_names.add(name) wizard_required = False + wizard_ignored = False try: vars = implementation.get_template_vars() configs = implementation.get_template_configs() if isinstance(implementation, octoprint.plugin.WizardPlugin): wizard_required = implementation.is_wizard_required() + wizard_ignored = name in seen_wizards and seen_wizards[name] == implementation.get_wizard_version() except: _logger.exception("Error while retrieving template data for plugin {}, ignoring it".format(name)) continue @@ -214,7 +217,7 @@ def index(): includes = _process_template_configs(name, implementation, configs, template_rules) - if not wizard_required: + if not wizard_required or wizard_ignored: includes["wizard"] = list() for t in template_types: @@ -302,7 +305,7 @@ def index(): render_kwargs = dict( webcamStream=settings().get(["webcam", "stream"]), enableTemperatureGraph=settings().get(["feature", "temperatureGraph"]), - enableAccessControl=userManager is not None, + enableAccessControl=enable_accesscontrol, enableSdSupport=settings().get(["feature", "sdSupport"]), firstRun=first_run, debug=debug, diff --git a/src/octoprint/settings.py b/src/octoprint/settings.py index f10f5994..039e4ebe 100644 --- a/src/octoprint/settings.py +++ b/src/octoprint/settings.py @@ -92,6 +92,7 @@ default_settings = { "host": "0.0.0.0", "port": 5000, "firstRun": True, + "seenWizards": {}, "secretKey": None, "reverseProxy": { "prefixHeader": "X-Script-Name", diff --git a/src/octoprint/static/js/app/viewmodels/wizard.js b/src/octoprint/static/js/app/viewmodels/wizard.js index 8f03f42f..34081788 100644 --- a/src/octoprint/static/js/app/viewmodels/wizard.js +++ b/src/octoprint/static/js/app/viewmodels/wizard.js @@ -10,6 +10,7 @@ $(function() { self.allViewModels = undefined; self.finishing = false; + self.wizards = []; self.isDialogActive = function() { return self.wizardDialog.is(":visible"); @@ -100,13 +101,32 @@ $(function() { onFinish: function(tab, navigation, index) { var closeDialog = true; callViewModels(allViewModels, "onBeforeWizardFinish", function(method) { + // we don't need to call all methods here, one method saying that + // the dialog must not be closed yet is enough to stop + // + // we evaluate closeDialog first to make sure we don't call + // the method once it becomes false closeDialog = closeDialog && (method() !== false); }); if (closeDialog) { - callViewModels(allViewModels, "onWizardFinish"); + var reload = false; + callViewModels(allViewModels, "onWizardFinish", function(method) { + // if any of our methods returns that it wants to reload + // we'll need to set reload to true + // + // order is important here - the method call needs to happen + // first, or it won't happen after the reload flag has been + // set once due to the || making further evaluation unnecessary + // then + reload = (method() == "reload") || reload; + }); self.finishWizard(function() { self.closeDialog(); + if (reload) { + log.info("Wizard requested reloading"); + location.reload(true); + } }); } } @@ -121,7 +141,12 @@ $(function() { url: API_BASEURL + "setup/wizard", type: "GET", dataType: "json", - success: callback + success: function(response) { + self.wizards = _.filter(_.keys(response), function(key) { return response[key] && response[key]["required"]; }); + if (callback) { + callback(response); + } + } }); }; @@ -133,6 +158,7 @@ $(function() { url: API_BASEURL + "setup/wizard", type: "POST", dataType: "json", + data: JSON.stringify({handled: self.wizards}), contentType: "application/json; charset=UTF-8", success: function() { self.finishing = false;