From bbd728c51bad7e24a2adca424030fc3281ac4285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Fri, 25 Sep 2015 13:53:42 +0200 Subject: [PATCH] Migrated existing javascript application files to use client lib TODO: Testing & Debugging --- .../corewizard/static/js/corewizard.js | 18 +- src/octoprint/plugins/cura/static/js/cura.js | 45 +- .../pluginmanager/static/js/pluginmanager.js | 203 +++++---- .../static/js/softwareupdate.js | 70 +-- src/octoprint/server/__init__.py | 22 + src/octoprint/server/api/__init__.py | 8 +- src/octoprint/server/views.py | 1 - src/octoprint/static/js/app/client.js | 79 ---- src/octoprint/static/js/app/dataupdater.js | 415 ++++++++---------- src/octoprint/static/js/app/main.js | 16 + .../static/js/app/viewmodels/connection.js | 33 +- .../static/js/app/viewmodels/control.js | 121 ++--- .../static/js/app/viewmodels/files.js | 67 ++- .../static/js/app/viewmodels/gcode.js | 14 +- src/octoprint/static/js/app/viewmodels/log.js | 18 +- .../static/js/app/viewmodels/loginstate.js | 41 +- .../static/js/app/viewmodels/navigation.js | 17 +- .../js/app/viewmodels/printerprofiles.js | 70 ++- .../static/js/app/viewmodels/printerstate.js | 30 +- .../static/js/app/viewmodels/settings.js | 103 ++--- .../static/js/app/viewmodels/slicing.js | 32 +- .../static/js/app/viewmodels/temperature.js | 123 +++--- .../static/js/app/viewmodels/terminal.js | 29 +- .../static/js/app/viewmodels/timelapse.js | 39 +- .../static/js/app/viewmodels/users.js | 181 +++----- .../static/js/app/viewmodels/usersettings.js | 25 +- .../static/js/app/viewmodels/wizard.js | 74 ++-- src/octoprint/templates/javascripts.jinja2 | 4 + 28 files changed, 779 insertions(+), 1119 deletions(-) delete mode 100644 src/octoprint/static/js/app/client.js diff --git a/src/octoprint/plugins/corewizard/static/js/corewizard.js b/src/octoprint/plugins/corewizard/static/js/corewizard.js index f909057e..c4b587ed 100644 --- a/src/octoprint/plugins/corewizard/static/js/corewizard.js +++ b/src/octoprint/plugins/corewizard/static/js/corewizard.js @@ -53,26 +53,22 @@ $(function() { }; self._sendData = function(data, callback) { - $.ajax({ - url: BASEURL + "plugin/corewizard/acl", - type: "POST", - dataType: "json", - data: data, - success: function() { + OctoPrint.postJson("plugin/corewizard/acl", data) + .done(function() { self.setup(true); self.decision(data.ac); if (data.ac) { // we now log the user in var user = data.user; var pass = data.pass1; - self.loginStateViewModel.login(user, pass, true, function() { - if (callback) callback(); - }); + self.loginStateViewModel.login(user, pass, true) + .done(function() { + if (callback) callback(); + }); } else { if (callback) callback(); } - } - }); + }); }; self.onWizardTabChange = function(current, next) { diff --git a/src/octoprint/plugins/cura/static/js/cura.js b/src/octoprint/plugins/cura/static/js/cura.js index fb551689..fb8fb62a 100644 --- a/src/octoprint/plugins/cura/static/js/cura.js +++ b/src/octoprint/plugins/cura/static/js/cura.js @@ -70,6 +70,7 @@ $(function() { dataType: "json", maxNumberOfFiles: 1, autoUpload: false, + headers: OctoPrint.getRequestHeaders(), add: function(e, data) { if (data.files.length == 0) { return false; @@ -131,14 +132,11 @@ $(function() { return (item.key == data.key); }); - $.ajax({ - url: data.resource(), - type: "DELETE", - success: function() { + OctoPrint.slicing.deleteProfileForSlicer("cura", data.key, {url: data.resource}) + .done(function() { self.requestData(); self.slicingViewModel.requestData(); - } - }); + }); }; self.makeProfileDefault = function(data) { @@ -156,16 +154,10 @@ $(function() { item.isdefault(true); } - $.ajax({ - url: data.resource(), - type: "PATCH", - dataType: "json", - data: JSON.stringify({default: true}), - contentType: "application/json; charset=UTF-8", - success: function() { + OctoPrint.slicing.updateProfileForSlicer("cura", data.key, {default: true}, {url: data.resource()}) + .done(function() { self.requestData(); - } - }); + }); }; self.showImportProfileDialog = function(makeDefault) { @@ -199,28 +191,13 @@ $(function() { } } - $.ajax({ - url: API_BASEURL + "util/test", - type: "POST", - dataType: "json", - data: JSON.stringify({ - command: "path", - path: enginePath, - check_type: "file", - check_access: "x" - }), - contentType: "application/json; charset=UTF-8", - success: successCallback - }) + OctoPrint.util.test("path", {path: enginePath, check_type: "file", check_access: "x"}) + .done(successCallback); }; self.requestData = function() { - $.ajax({ - url: API_BASEURL + "slicing/cura/profiles", - type: "GET", - dataType: "json", - success: self.fromResponse - }); + OctoPrint.slicing.listProfilesForSlicer("cura") + .done(self.fromResponse); }; self.fromResponse = function(data) { diff --git a/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js b/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js index 7c5265ff..d75c7d24 100644 --- a/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js +++ b/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js @@ -1,4 +1,66 @@ $(function() { + + OctoPrint.plugins.pluginmanager = (function($, _) { + var exports = {}; + + exports.get = function(refresh, opts) { + return OctoPrint.get(OctoPrint.getSimpleApiUrl("pluginmanager") + ((refresh) ? "?refresh_repository=true" : ""), opts); + }; + + exports.getWithRefresh = function(opts) { + return exports.get(true, opts); + }; + + exports.getWithoutRefresh = function(opts) { + return exports.get(false, opts); + }; + + exports.install = function(pluginUrl, dependencyLinks, opts) { + var data = { + url: pluginUrl, + dependency_links: !!dependencyLinks + }; + return OctoPrint.simpleApiCommand(plugin, "install", data, opts); + }; + + exports.reinstall = function(plugin, pluginUrl, dependencyLinks, opts) { + var data = { + url: pluginUrl, + dependency_links: !!dependencyLinks, + reinstall: plugin, + force: true + }; + return OctoPrint.simpleApiCommand(plugin, "install", data, opts); + }; + + exports.uninstall = function(plugin, opts) { + var data = { + plugin: plugin + }; + return OctoPrint.simpleApiCommand(plugin, "uninstall", data, opts); + }; + + exports.enable = function(plugin, opts) { + var data = { + plugin: plugin + }; + return OctoPrint.simpleApiCommand(plugin, "enable", data, opts); + }; + + exports.disable = function(plugin, opts) { + var data = { + plugin: plugin + }; + return OctoPrint.simpleApiCommand(plugin, "disable", data, opts); + }; + + exports.upload = function(file) { + return OctoPrint.upload(OctoPrint.getBlueprintUrl("pluginmanager") + "upload_archive", file); + }; + + return exports; + })($, _); + function PluginManagerViewModel(parameters) { var self = this; @@ -193,12 +255,8 @@ $(function() { return; } - $.ajax({ - url: API_BASEURL + "plugin/pluginmanager" + ((includeRepo) ? "?refresh_repository=true" : ""), - type: "GET", - dataType: "json", - success: self.fromResponse - }); + OctoPrint.plugins.pluginmanager.get(includeRepo) + .done(self.fromResponse); }; self.togglePlugin = function(data) { @@ -212,19 +270,25 @@ $(function() { if (data.key == "pluginmanager") return; - var command = self._getToggleCommand(data); + var onSuccess = self.requestData, + onError = function() { + new PNotify({ + title: gettext("Something went wrong"), + text: gettext("Please consult octoprint.log for details"), + type: "error", + hide: false + }) + }; - var payload = {plugin: data.key}; - self._postCommand(command, payload, function(response) { - self.requestData(); - }, function() { - new PNotify({ - title: gettext("Something went wrong"), - text: gettext("Please consult octoprint.log for details"), - type: "error", - hide: false - }) - }); + if (self._getToggleCommand(data) == "enable") { + OctoPrint.plugins.pluginmanager.enable(data.key) + .done(onSuccess) + .fail(onError); + } else { + OctoPrint.plugins.pluginmanager.disable(data.key) + .done(onSuccess) + .fail(onError); + } }; self.showRepository = function() { @@ -244,11 +308,7 @@ $(function() { return; } - if (self.installed(data)) { - self.installPlugin(data.archive, data.title, data.id, data.follow_dependency_links || self.followDependencyLinks()); - } else { - self.installPlugin(data.archive, data.title, undefined, data.follow_dependency_links || self.followDependencyLinks()); - } + self.installPlugin(data.archive, data.title, (self.installed(data) ? data.id : undefined), data.follow_dependency_links || self.followDependencyLinks()); }; self.installPlugin = function(url, name, reinstall, followDependencyLinks) { @@ -283,26 +343,33 @@ $(function() { } self._markWorking(workTitle, workText); - var command = "install"; - var payload = {url: url, dependency_links: followDependencyLinks}; - if (reinstall) { - payload["plugin"] = reinstall; - payload["force"] = true; - } + var onSuccess = function() { + self.requestData(); + self.installUrl(""); + }, + onError = function() { + new PNotify({ + title: gettext("Something went wrong"), + text: gettext("Please consult octoprint.log for details"), + type: "error", + hide: false + }); + }, + onAlways = function() { + self._markDone(); + }; - self._postCommand(command, payload, function(response) { - self.requestData(); - self._markDone(); - self.installUrl(""); - }, function() { - new PNotify({ - title: gettext("Something went wrong"), - text: gettext("Please consult octoprint.log for details"), - type: "error", - hide: false - }); - self._markDone(); - }); + if (reinstall) { + OctoPrint.plugins.pluginmanager.reinstall(reinstall, url, followDependencyLinks) + .done(onSuccess) + .fail(onError) + .always(onAlways); + } else { + OctoPrint.plugins.pluginmanager.install(url, followDependencyLinks) + .done(onSuccess) + .fail(onError) + .always(onAlways); + } }; self.uninstallPlugin = function(data) { @@ -319,20 +386,19 @@ $(function() { self._markWorking(gettext("Uninstalling plugin..."), _.sprintf(gettext("Uninstalling plugin \"%(name)s\""), {name: data.name})); - var command = "uninstall"; - var payload = {plugin: data.key}; - self._postCommand(command, payload, function(response) { - self.requestData(); - self._markDone(); - }, function() { - new PNotify({ - title: gettext("Something went wrong"), - text: gettext("Please consult octoprint.log for details"), - type: "error", - hide: false + OctoPrint.plugins.pluginmanager.uninstall(data.key) + .done(self.requestData) + .fail(function() { + new PNotify({ + title: gettext("Something went wrong"), + text: gettext("Please consult octoprint.log for details"), + type: "error", + hide: false + }); + }) + .always(function() { + self._markDone(); }); - self._markDone(); - }); }; self.refreshRepository = function() { @@ -400,33 +466,6 @@ $(function() { } }; - self._postCommand = function (command, data, successCallback, failureCallback, alwaysCallback, timeout) { - var payload = _.extend(data, {command: command}); - - var params = { - url: API_BASEURL + "plugin/pluginmanager", - type: "POST", - dataType: "json", - data: JSON.stringify(payload), - contentType: "application/json; charset=UTF-8", - success: function(response) { - if (successCallback) successCallback(response); - }, - error: function() { - if (failureCallback) failureCallback(); - }, - complete: function() { - if (alwaysCallback) alwaysCallback(); - } - }; - - if (timeout != undefined) { - params.timeout = timeout; - } - - $.ajax(params); - }; - self._markWorking = function(title, line) { self.working(true); self.workingTitle(title); diff --git a/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js b/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js index b9223ddf..4be1e147 100644 --- a/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js +++ b/src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js @@ -1,4 +1,38 @@ $(function() { + OctoPrint.plugins.softwareupdate = (function($, _) { + var exports = {}; + + var url = OctoPrint.getBlueprintUrl("softwareupdate"); + var checkUrl = url + "check"; + var updateUrl = url + "update"; + + exports.check = function(force, opts) { + return OctoPrint.get(checkUrl + ((!!force) ? "?force=true" : ""), opts); + }; + + exports.update = function(entries, force, opts) { + entries = entries || []; + if (typeof entries == "string") { + entries = [entries]; + } + + var data = { + entries: entries, + force: !!force + }; + return OctoPrint.postJson(updateUrl, data, opts); + }; + + exports.updateAll = function(force, opts) { + var data = { + force: !!force + }; + return OctoPrint.postJson(updateUrl, data, opts); + }; + + return exports; + })($, _); + function SoftwareUpdateViewModel(parameters) { var self = this; @@ -221,20 +255,10 @@ $(function() { self.performCheck = function(showIfNothingNew, force, ignoreSeen) { if (!self.loginState.isUser()) return; - - var url = PLUGIN_BASEURL + "softwareupdate/check"; - if (force) { - url += "?force=true"; - } - - $.ajax({ - url: url, - type: "GET", - dataType: "json", - success: function(data) { + OctoPrint.plugins.softwareupdate.check(force) + .done(function(data) { self.fromCheckResponse(data, ignoreSeen, showIfNothingNew); - } - }); + }); }; self._markNotificationAsSeen = function(data) { @@ -285,13 +309,12 @@ $(function() { }; self._showPopup(options); - $.ajax({ - url: PLUGIN_BASEURL + "softwareupdate/update", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({force: (force == true)}), - error: function() { + OctoPrint.plugins.softwareupdate.updateAll(force) + .done(function(data) { + self.currentlyBeingUpdated = data.checks; + self._markWorking(gettext("Updating..."), gettext("Updating, please wait.")); + }) + .fail(function() { self.updateInProgress = false; self._showPopup({ title: gettext("Update not started!"), @@ -302,12 +325,7 @@ $(function() { sticker: false } }); - }, - success: function(data) { - self.currentlyBeingUpdated = data.checks; - self._markWorking(gettext("Updating..."), gettext("Updating, please wait.")); - } - }); + }); }; self.update = function(force) { diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index a64b5109..77ddcf78 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -912,6 +912,25 @@ class Server(object): "js/lib/loglevel.min.js", "js/lib/sockjs-0.3.4.min.js" ] + js_client = [ + "js/app/client/octoprint.js", + "js/app/client/socket.js", + "js/app/client/browser.js", + "js/app/client/connection.js", + "js/app/client/control.js", + "js/app/client/files.js", + "js/app/client/job.js", + "js/app/client/languages.js", + "js/app/client/logs.js", + "js/app/client/printer.js", + "js/app/client/printerprofiles.js", + "js/app/client/settings.js", + "js/app/client/slicing.js", + "js/app/client/timelapse.js", + "js/app/client/users.js", + "js/app/client/util.js", + "js/app/client/wizard.js" + ] js_app = dynamic_assets["js"] + [ "js/app/dataupdater.js", "js/app/helpers.js", @@ -966,8 +985,10 @@ class Server(object): js_libs_bundle = Bundle(*js_libs, output="webassets/packed_libs.js", filters="js_delimiter_bundler") if minify: + js_client_bundle = Bundle(*js_client, output="webassets/packed_client.js", filters="rjsmin, js_delimiter_bundler") js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="rjsmin, js_delimiter_bundler") else: + js_client_bundle = Bundle(*js_client, output="webassets/packed_client.js", filters="js_delimiter_bundler") js_app_bundle = Bundle(*js_app, output="webassets/packed_app.js", filters="js_delimiter_bundler") css_libs_bundle = Bundle(*css_libs, output="webassets/packed_libs.css") @@ -976,6 +997,7 @@ class Server(object): all_less_bundle = Bundle(*less_app, output="webassets/packed_app.less", filters="cssrewrite, less_importrewrite") assets.register("js_libs", js_libs_bundle) + assets.register("js_client", js_client_bundle) assets.register("js_app", js_app_bundle) assets.register("css_libs", css_libs_bundle) assets.register("css_app", css_app_bundle) diff --git a/src/octoprint/server/api/__init__.py b/src/octoprint/server/api/__init__.py index 7bb87bc4..9d953edf 100644 --- a/src/octoprint/server/api/__init__.py +++ b/src/octoprint/server/api/__init__.py @@ -217,7 +217,11 @@ def performSystemAction(): @api.route("/login", methods=["POST"]) def login(): - if octoprint.server.userManager is not None and "user" in request.values.keys() and "pass" in request.values.keys(): + data = request.values + if hasattr(request, "json") and request.json: + data = request.json + + if octoprint.server.userManager is not None and "user" in data and "pass" in data: username = request.values["user"] password = request.values["pass"] @@ -241,7 +245,7 @@ def login(): return jsonify(user.asDict()) return make_response(("User unknown or password incorrect", 401, [])) - elif "passive" in request.values: + elif "passive" in data: return passive_login() return NO_CONTENT diff --git a/src/octoprint/server/views.py b/src/octoprint/server/views.py index 961ba445..0f1b8c70 100644 --- a/src/octoprint/server/views.py +++ b/src/octoprint/server/views.py @@ -573,4 +573,3 @@ def localeJs(locale, domain): def plugin_assets(name, filename): return redirect(url_for("plugin." + name + ".static", filename=filename)) - diff --git a/src/octoprint/static/js/app/client.js b/src/octoprint/static/js/app/client.js deleted file mode 100644 index 803635af..00000000 --- a/src/octoprint/static/js/app/client.js +++ /dev/null @@ -1,79 +0,0 @@ -var OctoPrint = (function($, _, SockJS) { - var self = { - options: { - socketReconnectTimeouts: [0, 1, 1, 2, 3, 5, 8, 13, 20, 40, 100], - socketDebug: false, - socketNormalClose: 1000 - } - }; - - var _socket = undefined; - var _socketAddress = undefined; - var _socketReconnecting = false; - var _socketReconnectTrial = 0; - var _socketIgnoreReconnects = 1; - - function callCallback(callback, arguments) { - if (!_.isFunction(self.options[callback])) { - throw Error("No such callback: " + callback); - } - - self.options[callback].bind(arguments); - } - - function connect(socketAddress) { - var address = socketAddress || _socketAddress; - if (address == undefined) { - return; - } - - var socketOptions = { - debug: options.socketDebug || false - }; - - if (_socket != undefined) { - self._socket.close(); - delete self._socket; - } - - _socketAddress = address; - _socket = new SockJS(address, undefined, socketOptions); - _socket.onopen = onSocketOpen; - _socket.onclose = onSocketClose; - _socket.onmessage = onSocketMessage; - } - - function onSocketOpen() { - _socketReconnecting = false; - _socketReconnectTrial = 0; - } - - function onSocketClose(error) { - if (error.code == options.socketNormalClose) { - return; - } - - if (_socketReconnectTrial >= _socketIgnoreReconnects) { - if (options.onAttemptingReconnect) { - options.onAttemptingReconnect(_socketReconnectTrial); - } - } - - if (_socketReconnectTrial < options.socketReconnectTimeouts.length) { - var timeout = options.socketReconnectTimeouts[_socketReconnectTrial]; - log.info("Reconnect trial #" + self._autoReconnectTrial + ", waiting " + timeout + "s"); - setTimeout(connect, timeout * 1000); - _socketReconnectTrial++; - } else { - if (options.onReconnectFailed) { - options.onReconnectFailed(); - } - } - } - - function onSocketMessage(data) { - } - - return self; - -}(jQuery, _, SockJS)); diff --git a/src/octoprint/static/js/app/dataupdater.js b/src/octoprint/static/js/app/dataupdater.js index 52293417..fa42e519 100644 --- a/src/octoprint/static/js/app/dataupdater.js +++ b/src/octoprint/static/js/app/dataupdater.js @@ -3,12 +3,6 @@ function DataUpdater(allViewModels) { self.allViewModels = allViewModels; - self._socket = undefined; - self._autoReconnecting = false; - self._autoReconnectTrial = 0; - self._autoReconnectTimeouts = [0, 1, 1, 2, 3, 5, 8, 13, 20, 40, 100]; - self._autoReconnectDialogIndex = 1; - self._pluginHash = undefined; self._configHash = undefined; @@ -16,65 +10,39 @@ function DataUpdater(allViewModels) { $("#reloadui_overlay_reload").click(function() { location.reload(true); }); self.connect = function() { - var options = {}; - if (SOCKJS_DEBUG) { - options["debug"] = true; - } - - self._socket = new SockJS(SOCKJS_URI, undefined, options); - self._socket.onopen = self._onconnect; - self._socket.onclose = self._onclose; - self._socket.onmessage = self._onmessage; + OctoPrint.socket.connect({debug: !!SOCKJS_DEBUG}); }; self.reconnect = function() { - self._socket.close(); - delete self._socket; - self.connect(); + OctoPrint.socket.reconnect(); }; - self._onconnect = function() { - self._autoReconnecting = false; - self._autoReconnectTrial = 0; - }; - - self._onclose = function(e) { - if (e.code == SOCKJS_CLOSE_NORMAL) { + self._onReconnectAttempt = function(trial) { + if (trial <= 0) { + // Only consider it a real disconnect if the trial number has exceeded our threshold. return; } - if (self._autoReconnectTrial >= self._autoReconnectDialogIndex) { - // Only consider it a real disconnect if the trial number has exceeded our threshold. - var handled = false; - callViewModelsIf( - self.allViewModels, - "onServerDisconnect", - function() { return !handled; }, - function(method) { handled = !method() || handled; } - ); + var handled = false; + callViewModelsIf( + self.allViewModels, + "onServerDisconnect", + function() { return !handled; }, + function(method) { handled = !method() || handled; } + ); - if (handled) { - return; - } - - showOfflineOverlay( - gettext("Server is offline"), - gettext("The server appears to be offline, at least I'm not getting any response from it. I'll try to reconnect automatically over the next couple of minutes, however you are welcome to try a manual reconnect anytime using the button below."), - self.reconnect - ); + if (handled) { + return true; } - if (self._autoReconnectTrial < self._autoReconnectTimeouts.length) { - var timeout = self._autoReconnectTimeouts[self._autoReconnectTrial]; - log.info("Reconnect trial #" + self._autoReconnectTrial + ", waiting " + timeout + "s"); - setTimeout(self.reconnect, timeout * 1000); - self._autoReconnectTrial++; - } else { - self._onreconnectfailed(); - } + showOfflineOverlay( + gettext("Server is offline"), + gettext("The server appears to be offline, at least I'm not getting any response from it. I'll try to reconnect automatically over the next couple of minutes, however you are welcome to try a manual reconnect anytime using the button below."), + self.reconnect + ); }; - self._onreconnectfailed = function() { + self._onReconnectFailed = function() { var handled = false; callViewModelsIf( self.allViewModels, @@ -91,182 +59,181 @@ function DataUpdater(allViewModels) { $("#offline_overlay_message").html(gettext("The server appears to be offline, at least I'm not getting any response from it. I could not reconnect automatically, but you may try a manual reconnect using the button below.")); }; - self._onmessage = function(e) { - for (var prop in e.data) { - if (!e.data.hasOwnProperty(prop)) { - continue; + self._onConnected = function(event) { + var data = event.data; + + // update version information + var oldVersion = VERSION; + VERSION = data["version"]; + DISPLAY_VERSION = data["display_version"]; + BRANCH = data["branch"]; + $("span.version").text(DISPLAY_VERSION); + + // update plugin hash + var oldPluginHash = self._pluginHash; + self._pluginHash = data["plugin_hash"]; + + // update config hash + var oldConfigHash = self._configHash; + self._configHash = data["config_hash"]; + + // if the offline overlay is still showing, now's a good time to + // hide it, plus reload the camera feed if it's currently displayed + if ($("#offline_overlay").is(":visible")) { + hideOfflineOverlay(); + callViewModels(self.allViewModels, "onDataUpdaterReconnect"); + + if ($('#tabs li[class="active"] a').attr("href") == "#control") { + $("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime()); } + } - var data = e.data[prop]; - - var gcodeUploadProgress = $("#gcode_upload_progress"); - var gcodeUploadProgressBar = $(".bar", gcodeUploadProgress); - - switch (prop) { - case "connected": { - // update the current UI API key and send it with any request - UI_API_KEY = data["apikey"]; - $.ajaxSetup({ - headers: {"X-Api-Key": UI_API_KEY} - }); - - var oldVersion = VERSION; - VERSION = data["version"]; - DISPLAY_VERSION = data["display_version"]; - BRANCH = data["branch"]; - $("span.version").text(DISPLAY_VERSION); - - var oldPluginHash = self._pluginHash; - self._pluginHash = data["plugin_hash"]; - - var oldConfigHash = self._configHash; - self._configHash = data["config_hash"]; - - if ($("#offline_overlay").is(":visible")) { - hideOfflineOverlay(); - callViewModels(self.allViewModels, "onDataUpdaterReconnect"); - - if ($('#tabs li[class="active"] a').attr("href") == "#control") { - $("#webcam_image").attr("src", CONFIG_WEBCAM_STREAM + "?" + new Date().getTime()); - } - } - - var versionChanged = oldVersion != VERSION; - var pluginsChanged = oldPluginHash != undefined && oldPluginHash != self._pluginHash; - var configChanged = oldConfigHash != undefined && oldConfigHash != self._configHash; - if (versionChanged || pluginsChanged || configChanged) { - self.reloadOverlay.show(); - } - - break; - } - case "history": { - callViewModels(self.allViewModels, "fromHistoryData", [data]); - break; - } - case "current": { - callViewModels(self.allViewModels, "fromCurrentData", [data]); - break; - } - case "slicingProgress": { - gcodeUploadProgressBar.text(_.sprintf(gettext("Slicing ... (%(percentage)d%%)"), {percentage: Math.round(data["progress"])})); - - callViewModels(self.allViewModels, "onSlicingProgress", [ - data["slicer"], - data["model_path"], - data["machinecode_path"], - data["progress"] - ]); - break; - } - case "event": { - var type = data["type"]; - var payload = data["payload"]; - var html = ""; - var format = {}; - - log.debug("Got event " + type + " with payload: " + JSON.stringify(payload)); - - if (type == "SettingsUpdated") { - if (payload && payload.hasOwnProperty("config_hash")) { - self._configHash = payload.config_hash; - } - } else if (type == "MovieRendering") { - new PNotify({title: gettext("Rendering timelapse"), text: _.sprintf(gettext("Now rendering timelapse %(movie_basename)s"), payload)}); - } else if (type == "MovieDone") { - new PNotify({title: gettext("Timelapse ready"), text: _.sprintf(gettext("New timelapse %(movie_basename)s is done rendering."), payload)}); - } else if (type == "MovieFailed") { - html = "

" + _.sprintf(gettext("Rendering of timelapse %(movie_basename)s failed with return code %(returncode)s"), payload) + "

"; - html += pnotifyAdditionalInfo('
' + payload.error + '
'); - new PNotify({ - title: gettext("Rendering failed"), - text: html, - type: "error", - hide: false - }); - } else if (type == "PostRollStart") { - if (payload.postroll_duration > 60) { - format = {duration: _.sprintf(gettext("%(minutes)d min"), {minutes: payload.postroll_duration / 60})}; - } else { - format = {duration: _.sprintf(gettext("%(seconds)d sec"), {seconds: payload.postroll_duration})}; - } - - new PNotify({ - title: gettext("Capturing timelapse postroll"), - text: _.sprintf(gettext("Now capturing timelapse post roll, this will take approximately %(duration)s..."), format) - }); - } else if (type == "SlicingStarted") { - gcodeUploadProgress.addClass("progress-striped").addClass("active"); - gcodeUploadProgressBar.css("width", "100%"); - if (payload.progressAvailable) { - gcodeUploadProgressBar.text(_.sprintf(gettext("Slicing ... (%(percentage)d%%)"), {percentage: 0})); - } else { - gcodeUploadProgressBar.text(gettext("Slicing ...")); - } - } else if (type == "SlicingDone") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - new PNotify({title: gettext("Slicing done"), text: _.sprintf(gettext("Sliced %(stl)s to %(gcode)s, took %(time).2f seconds"), payload), type: "success"}); - } else if (type == "SlicingCancelled") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - } else if (type == "SlicingFailed") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - - html = _.sprintf(gettext("Could not slice %(stl)s to %(gcode)s: %(reason)s"), payload); - new PNotify({title: gettext("Slicing failed"), text: html, type: "error", hide: false}); - } else if (type == "TransferStarted") { - gcodeUploadProgress.addClass("progress-striped").addClass("active"); - gcodeUploadProgressBar.css("width", "100%"); - gcodeUploadProgressBar.text(gettext("Streaming ...")); - } else if (type == "TransferDone") { - gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); - gcodeUploadProgressBar.css("width", "0%"); - gcodeUploadProgressBar.text(""); - new PNotify({ - title: gettext("Streaming done"), - text: _.sprintf(gettext("Streamed %(local)s to %(remote)s on SD, took %(time).2f seconds"), payload), - type: "success" - }); - gcodeFilesViewModel.requestData(payload.remote, "sdcard"); - } - - var legacyEventHandlers = { - "UpdatedFiles": "onUpdatedFiles", - "MetadataStatisticsUpdated": "onMetadataStatisticsUpdated", - "MetadataAnalysisFinished": "onMetadataAnalysisFinished", - "SlicingDone": "onSlicingDone", - "SlicingCancelled": "onSlicingCancelled", - "SlicingFailed": "onSlicingFailed" - }; - _.each(self.allViewModels, function(viewModel) { - if (viewModel.hasOwnProperty("onEvent" + type)) { - viewModel["onEvent" + type](payload); - } else if (legacyEventHandlers.hasOwnProperty(type) && viewModel.hasOwnProperty(legacyEventHandlers[type])) { - // there might still be code that uses the old callbacks, make sure those still get called - // but log a warning - log.warn("View model " + viewModel.name + " is using legacy event handler " + legacyEventHandlers[type] + ", new handler is called " + legacyEventHandlers[type]); - viewModel[legacyEventHandlers[type]](payload); - } - }); - - break; - } - case "timelapse": { - callViewModels(self.allViewModels, "fromTimelapseData", [data]); - break; - } - case "plugin": { - callViewModels(self.allViewModels, "onDataUpdaterPluginMessage", [data.plugin, data.data]); - break; - } - } + // if the version, the plugin hash or the config hash changed, we + // want the user to reload the UI since it might be stale now + var versionChanged = oldVersion != VERSION; + var pluginsChanged = oldPluginHash != undefined && oldPluginHash != self._pluginHash; + var configChanged = oldConfigHash != undefined && oldConfigHash != self._configHash; + if (versionChanged || pluginsChanged || configChanged) { + self.reloadOverlay.show(); } }; + self._onHistoryData = function(event) { + callViewModels(self.allViewModels, "fromHistoryData", [event.data]); + }; + + self._onCurrentData = function(event) { + callViewModels(self.allViewModels, "fromCurrentData", [event.data]); + }; + + self._onSlicingProgress = function(event) { + $("#gcode_upload_progress").find(".bar").text(_.sprintf(gettext("Slicing ... (%(percentage)d%%)"), {percentage: Math.round(event.data["progress"])})); + + callViewModels(self.allViewModels, "onSlicingProgress", [ + data["slicer"], + data["model_path"], + data["machinecode_path"], + data["progress"] + ]); + }; + + self._onEvent = function(event) { + var gcodeUploadProgress = $("#gcode_upload_progress"); + var gcodeUploadProgressBar = $(".bar", gcodeUploadProgress); + + var type = event.data["type"]; + var payload = event.data["payload"]; + var html = ""; + var format = {}; + + log.debug("Got event " + type + " with payload: " + JSON.stringify(payload)); + + if (type == "SettingsUpdated") { + if (payload && payload.hasOwnProperty("config_hash")) { + self._configHash = payload.config_hash; + } + } else if (type == "MovieRendering") { + new PNotify({title: gettext("Rendering timelapse"), text: _.sprintf(gettext("Now rendering timelapse %(movie_basename)s"), payload)}); + } else if (type == "MovieDone") { + new PNotify({title: gettext("Timelapse ready"), text: _.sprintf(gettext("New timelapse %(movie_basename)s is done rendering."), payload)}); + } else if (type == "MovieFailed") { + html = "

" + _.sprintf(gettext("Rendering of timelapse %(movie_basename)s failed with return code %(returncode)s"), payload) + "

"; + html += pnotifyAdditionalInfo('
' + payload.error + '
'); + new PNotify({ + title: gettext("Rendering failed"), + text: html, + type: "error", + hide: false + }); + } else if (type == "PostRollStart") { + if (payload.postroll_duration > 60) { + format = {duration: _.sprintf(gettext("%(minutes)d min"), {minutes: payload.postroll_duration / 60})}; + } else { + format = {duration: _.sprintf(gettext("%(seconds)d sec"), {seconds: payload.postroll_duration})}; + } + + new PNotify({ + title: gettext("Capturing timelapse postroll"), + text: _.sprintf(gettext("Now capturing timelapse post roll, this will take approximately %(duration)s..."), format) + }); + } else if (type == "SlicingStarted") { + gcodeUploadProgress.addClass("progress-striped").addClass("active"); + gcodeUploadProgressBar.css("width", "100%"); + if (payload.progressAvailable) { + gcodeUploadProgressBar.text(_.sprintf(gettext("Slicing ... (%(percentage)d%%)"), {percentage: 0})); + } else { + gcodeUploadProgressBar.text(gettext("Slicing ...")); + } + } else if (type == "SlicingDone") { + gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); + gcodeUploadProgressBar.css("width", "0%"); + gcodeUploadProgressBar.text(""); + new PNotify({title: gettext("Slicing done"), text: _.sprintf(gettext("Sliced %(stl)s to %(gcode)s, took %(time).2f seconds"), payload), type: "success"}); + } else if (type == "SlicingCancelled") { + gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); + gcodeUploadProgressBar.css("width", "0%"); + gcodeUploadProgressBar.text(""); + } else if (type == "SlicingFailed") { + gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); + gcodeUploadProgressBar.css("width", "0%"); + gcodeUploadProgressBar.text(""); + + html = _.sprintf(gettext("Could not slice %(stl)s to %(gcode)s: %(reason)s"), payload); + new PNotify({title: gettext("Slicing failed"), text: html, type: "error", hide: false}); + } else if (type == "TransferStarted") { + gcodeUploadProgress.addClass("progress-striped").addClass("active"); + gcodeUploadProgressBar.css("width", "100%"); + gcodeUploadProgressBar.text(gettext("Streaming ...")); + } else if (type == "TransferDone") { + gcodeUploadProgress.removeClass("progress-striped").removeClass("active"); + gcodeUploadProgressBar.css("width", "0%"); + gcodeUploadProgressBar.text(""); + new PNotify({ + title: gettext("Streaming done"), + text: _.sprintf(gettext("Streamed %(local)s to %(remote)s on SD, took %(time).2f seconds"), payload), + type: "success" + }); + gcodeFilesViewModel.requestData(payload.remote, "sdcard"); + } + + var legacyEventHandlers = { + "UpdatedFiles": "onUpdatedFiles", + "MetadataStatisticsUpdated": "onMetadataStatisticsUpdated", + "MetadataAnalysisFinished": "onMetadataAnalysisFinished", + "SlicingDone": "onSlicingDone", + "SlicingCancelled": "onSlicingCancelled", + "SlicingFailed": "onSlicingFailed" + }; + _.each(self.allViewModels, function(viewModel) { + if (viewModel.hasOwnProperty("onEvent" + type)) { + viewModel["onEvent" + type](payload); + } else if (legacyEventHandlers.hasOwnProperty(type) && viewModel.hasOwnProperty(legacyEventHandlers[type])) { + // there might still be code that uses the old callbacks, make sure those still get called + // but log a warning + log.warn("View model " + viewModel.name + " is using legacy event handler " + legacyEventHandlers[type] + ", new handler is called " + legacyEventHandlers[type]); + viewModel[legacyEventHandlers[type]](payload); + } + }); + }; + + self._onTimelapse = function(event) { + callViewModels(self.allViewModels, "fromTimelapseData", [event.data]); + }; + + self._onPluginMessage = function(event) { + callViewModels(self.allViewModels, "onDataUpdaterPluginMessage", [event.data.plugin, event.data.data]); + }; + + OctoPrint.socket.onReconnectAttempt = self._onReconnectAttempt; + OctoPrint.socket.onReconnectFailed = self._onReconnectFailed; + OctoPrint.socket + .onMessage("connected", self._onConnected) + .onMessage("history", self._onHistoryData) + .onMessage("current", self._onCurrentData) + .onMessage("slicingProgress", self._onSlicingProgress) + .onMessage("event", self._onEvent) + .onMessage("timelapse", self._onTimelapse) + .onMessage("plugin", self._onPluginMessage); + self.connect(); } diff --git a/src/octoprint/static/js/app/main.js b/src/octoprint/static/js/app/main.js index c1237505..ebbede84 100644 --- a/src/octoprint/static/js/app/main.js +++ b/src/octoprint/static/js/app/main.js @@ -7,6 +7,22 @@ $(function() { log.setLevel(CONFIG_DEBUG ? "debug" : "info"); + //~~ OctoPrint client setup + OctoPrint.options.baseurl = BASEURL; + OctoPrint.options.apikey = UI_API_KEY; + + OctoPrint.socket.onMessage("connected", function(data) { + OctoPrint.options.apikey = data.apikey; + + // update the API key directly in jquery's ajax options too, + // to ensure the fileupload plugin and any plugins still using + // $.ajax directly still work fine too + UI_API_KEY = data["apikey"]; + $.ajaxSetup({ + headers: {"X-Api-Key": UI_API_KEY} + }); + }); + //~~ AJAX setup // work around a stupid iOS6 bug where ajax requests get cached and only work once, as described at diff --git a/src/octoprint/static/js/app/viewmodels/connection.js b/src/octoprint/static/js/app/viewmodels/connection.js index 7f55d607..d501e7ec 100644 --- a/src/octoprint/static/js/app/viewmodels/connection.js +++ b/src/octoprint/static/js/app/viewmodels/connection.js @@ -47,14 +47,8 @@ $(function() { self.previousIsOperational = undefined; self.requestData = function() { - $.ajax({ - url: API_BASEURL + "connection", - method: "GET", - dataType: "json", - success: function(response) { - self.fromResponse(response); - } - }) + OctoPrint.connection.getSettings() + .done(self.fromResponse); }; self.fromResponse = function(response) { @@ -93,7 +87,7 @@ $(function() { } else if (!self.isOperational() && !connectionTab.hasClass("in")) { connectionTab.collapse("show"); } - } + }; self._processStateData = function(data) { self.previousIsOperational = self.isOperational(); @@ -116,7 +110,6 @@ $(function() { self.connect = function() { if (self.isErrorOrClosed()) { var data = { - "command": "connect", "port": self.selectedPort() || "AUTO", "baudrate": self.selectedBaudrate() || 0, "printerProfile": self.selectedPrinter(), @@ -126,26 +119,14 @@ $(function() { if (self.saveSettings()) data["save"] = true; - $.ajax({ - url: API_BASEURL + "connection", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data), - success: function(response) { + OctoPrint.connection.connect(data) + .done(function() { self.settings.requestData(); self.settings.printerProfiles.requestData(); - } - }); + }); } else { self.requestData(); - $.ajax({ - url: API_BASEURL + "connection", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({"command": "disconnect"}) - }) + OctoPrint.connection.disconnect(); } }; diff --git a/src/octoprint/static/js/app/viewmodels/control.js b/src/octoprint/static/js/app/viewmodels/control.js index d8ab3457..a8680e87 100644 --- a/src/octoprint/static/js/app/viewmodels/control.js +++ b/src/octoprint/static/js/app/viewmodels/control.js @@ -108,14 +108,10 @@ $(function() { }; self.requestData = function () { - $.ajax({ - url: API_BASEURL + "printer/command/custom", - method: "GET", - dataType: "json", - success: function (response) { + OctoPrint.control.getCustomControls() + .done(function(response) { self._fromResponse(response); - } - }); + }); }; self._fromResponse = function (response) { @@ -254,26 +250,17 @@ $(function() { multiplier *= -1; } - var data = { - "command": "jog" - }; + var data = {}; data[axis] = distance * multiplier; - - self.sendPrintHeadCommand(data); + OctoPrint.printer.jog(data); }; self.sendHomeCommand = function (axis) { - self.sendPrintHeadCommand({ - "command": "home", - "axes": axis - }); + OctoPrint.printer.home(axis); }; self.sendFeedRateCommand = function () { - self.sendPrintHeadCommand({ - "command": "feedrate", - "factor": self.feedRate() - }); + OctoPrint.printer.setFeedrate(self.feedRate()); }; self.sendExtrudeCommand = function () { @@ -285,90 +272,46 @@ $(function() { }; self.sendFlowRateCommand = function () { - self.sendToolCommand({ - "command": "flowrate", - "factor": self.flowRate() - }); + OctoPrint.printer.setFlowrate(self.flowRate()); }; self._sendECommand = function (dir) { - var length = self.extrusionAmount(); - if (!length) length = self.settings.printer_defaultExtrusionLength(); - - self.sendToolCommand({ - command: "extrude", - amount: length * dir - }); + var length = self.extrusionAmount() || self.settings.printer_defaultExtrusionLength(); + OctoPrint.printer.extrude(length * dir); }; self.sendSelectToolCommand = function (data) { if (!data || !data.key()) return; - self.sendToolCommand({ - command: "select", - tool: data.key() - }); - }; - - self.sendPrintHeadCommand = function (data) { - $.ajax({ - url: API_BASEURL + "printer/printhead", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data) - }); - }; - - self.sendToolCommand = function (data) { - $.ajax({ - url: API_BASEURL + "printer/tool", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data) - }); + OctoPrint.printer.selectTool(data.key()); }; self.sendCustomCommand = function (command) { if (!command) return; - var data = undefined; - if (command.hasOwnProperty("command")) { - // single command - data = {"command": command.command}; - } else if (command.hasOwnProperty("commands")) { - // multi command - data = {"commands": command.commands}; - } else if (command.hasOwnProperty("script")) { - data = {"script": command.script}; - if (command.hasOwnProperty("context")) { - data["context"] = command.context; + if (command.hasOwnProperty("command") || command.hasOwnProperty("commands")) { + var commands = command.commands || [command.command]; + + if (commands.hasOwnProperty("input")) { + var parameters = {}; + _.each(command.input, function(input) { + if (!input.hasOwnProperty("parameter") || !input.hasOwnProperty("value")) { + return; + } + + parameters[input.parameter] = input.value(); + }); + OctoPrint.control.sendGcodeWithParameters(commands, parameters); + } else { + OctoPrint.control.sendGcode(commands); } - } else { - return; + } else if (command.hasOwnProperty("script")) { + var script = command.script; + var context = command.context || {}; + + OctoPrint.control.sendGcodeScript(script, context); } - - if (command.hasOwnProperty("input")) { - // parametric command(s) - data["parameters"] = {}; - _.each(command.input, function(input) { - if (!input.hasOwnProperty("parameter") || !input.hasOwnProperty("value")) { - return; - } - - data["parameters"][input.parameter] = input.value(); - }); - } - - $.ajax({ - url: API_BASEURL + "printer/command", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data) - }) }; self.displayMode = function (customControl) { @@ -414,7 +357,7 @@ $(function() { } else { $("#webcam_rotator").css("height", ""); } - } + }; self.onSettingsBeforeSave = self.updateRotatorWidth; diff --git a/src/octoprint/static/js/app/viewmodels/files.js b/src/octoprint/static/js/app/viewmodels/files.js index 885f5a40..3b752773 100644 --- a/src/octoprint/static/js/app/viewmodels/files.js +++ b/src/octoprint/static/js/app/viewmodels/files.js @@ -146,18 +146,13 @@ $(function() { if (self._otherRequestInProgress) return; self._otherRequestInProgress = true; - $.ajax({ - url: API_BASEURL + "files", - method: "GET", - dataType: "json", - success: function(response) { + OctoPrint.files.list() + .done(function(response) { self.fromResponse(response, filenameToFocus, locationToFocus); + }) + .always(function() { self._otherRequestInProgress = false; - }, - error: function() { - self._otherRequestInProgress = false; - } - }); + }); }; self.fromResponse = function(response, filenameToFocus, locationToFocus) { @@ -192,55 +187,45 @@ $(function() { }; self.loadFile = function(file, printAfterLoad) { - if (!file || !file.refs || !file.refs.hasOwnProperty("resource")) return; - - $.ajax({ - url: file.refs.resource, - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({command: "select", print: printAfterLoad}) - }); + if (!file) { + return; + } + OctoPrint.files.select(file.origin, file.name) + .done(function() { + if (printAfterLoad) { + OctoPrint.job.start(); + } + }); }; self.removeFile = function(file) { - if (!file || !file.refs || !file.refs.hasOwnProperty("resource")) return; - - $.ajax({ - url: file.refs.resource, - type: "DELETE", - success: function() { + if (!file) { + return; + } + OctoPrint.files.delete(file.origin, file.name) + .done(function() { self.requestData(); - } - }); + }) }; self.sliceFile = function(file) { - if (!file) return; + if (!file) { + return; + } self.slicing.show(file.origin, file.name, true); }; self.initSdCard = function() { - self._sendSdCommand("init"); + OctoPrint.printer.initSd(); }; self.releaseSdCard = function() { - self._sendSdCommand("release"); + OctoPrint.printer.releaseSd(); }; self.refreshSdFiles = function() { - self._sendSdCommand("refresh"); - }; - - self._sendSdCommand = function(command) { - $.ajax({ - url: API_BASEURL + "printer/sd", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({command: command}) - }); + OctoPrint.printer.refreshSd(); }; self.downloadLink = function(data) { diff --git a/src/octoprint/static/js/app/viewmodels/gcode.js b/src/octoprint/static/js/app/viewmodels/gcode.js index eb8c358d..5b032b3e 100644 --- a/src/octoprint/static/js/app/viewmodels/gcode.js +++ b/src/octoprint/static/js/app/viewmodels/gcode.js @@ -289,11 +289,8 @@ $(function() { self.enableReload(false); if (self.status == "idle" && self.errorCount < 3) { self.status = "request"; - $.ajax({ - url: BASEURL + "downloads/files/local/" + filename, - data: { "ctime": date }, - type: "GET", - success: function(response, rstatus) { + OctoPrint.files.download("local", filename) + .done(function(response, rstatus) { if(rstatus === 'success'){ self.showGCodeViewer(response, rstatus); self.loadedFilename = filename; @@ -301,12 +298,11 @@ $(function() { self.status = "idle"; self.enableReload(true); } - }, - error: function() { + }) + .fail(function() { self.status = "idle"; self.errorCount++; - } - }); + }); } }; diff --git a/src/octoprint/static/js/app/viewmodels/log.js b/src/octoprint/static/js/app/viewmodels/log.js index fa42aeed..872eb288 100644 --- a/src/octoprint/static/js/app/viewmodels/log.js +++ b/src/octoprint/static/js/app/viewmodels/log.js @@ -36,12 +36,8 @@ $(function() { ); self.requestData = function() { - $.ajax({ - url: API_BASEURL + "logs", - type: "GET", - dataType: "json", - success: self.fromResponse - }); + OctoPrint.logs.list() + .done(self.fromResponse); }; self.fromResponse = function(response) { @@ -53,12 +49,8 @@ $(function() { }; self.removeFile = function(filename) { - $.ajax({ - url: API_BASEURL + "logs/" + filename, - type: "DELETE", - dataType: "json", - success: self.requestData - }); + OctoPrint.logs.delete(filename) + .done(self.requestData); }; self.onUserLoggedIn = function(user) { @@ -73,4 +65,4 @@ $(function() { ["loginStateViewModel"], "#logs" ]); -}); \ No newline at end of file +}); diff --git a/src/octoprint/static/js/app/viewmodels/loginstate.js b/src/octoprint/static/js/app/viewmodels/loginstate.js index 661b1549..a5dfaf38 100644 --- a/src/octoprint/static/js/app/viewmodels/loginstate.js +++ b/src/octoprint/static/js/app/viewmodels/loginstate.js @@ -32,20 +32,13 @@ $(function() { return; } - $.ajax({ - url: API_BASEURL + "users/" + self.currentUser().name, - type: "GET", - success: self.fromResponse - }) + OctoPrint.users.get(self.currentUser().name) + .done(self.fromResponse); }; self.requestData = function() { - $.ajax({ - url: API_BASEURL + "login", - type: "POST", - data: {"passive": true}, - success: self.fromResponse - }) + OctoPrint.browser.passiveLogin() + .done(self.fromResponse); }; self.fromResponse = function(response) { @@ -70,7 +63,7 @@ $(function() { } }; - self.login = function(u, p, r, callback) { + self.login = function(u, p, r) { var username = u || self.loginUser(); var password = p || self.loginPass(); var remember = (r != undefined ? r : self.loginRemember()); @@ -79,30 +72,22 @@ $(function() { self.loginPass(""); self.loginRemember(false); - $.ajax({ - url: API_BASEURL + "login", - type: "POST", - data: {"user": username, "pass": password, "remember": remember}, - success: function(response) { + return OctoPrint.browser.login(username, password, remember) + .done(function(response) { new PNotify({title: gettext("Login successful"), text: _.sprintf(gettext('You are now logged in as "%(username)s"'), {username: response.name}), type: "success"}); self.fromResponse(response); - if (callback) callback(response); - }, - error: function(jqXHR, textStatus, errorThrown) { + }) + .fail(function() { new PNotify({title: gettext("Login failed"), text: gettext("User unknown or wrong password"), type: "error"}); - } - }) + }); }; self.logout = function() { - $.ajax({ - url: API_BASEURL + "logout", - type: "POST", - success: function(response) { + OctoPrint.browser.logout() + .done(function(response) { new PNotify({title: gettext("Logout successful"), text: gettext("You are now logged out"), type: "success"}); self.fromResponse(response); - } - }) + }); }; self.onLoginUserKeyup = function(data, event) { diff --git a/src/octoprint/static/js/app/viewmodels/navigation.js b/src/octoprint/static/js/app/viewmodels/navigation.js index 736fc949..1c9851fa 100644 --- a/src/octoprint/static/js/app/viewmodels/navigation.js +++ b/src/octoprint/static/js/app/viewmodels/navigation.js @@ -19,22 +19,17 @@ $(function() { self.triggerAction = function(action) { var callback = function() { - $.ajax({ - url: API_BASEURL + "system", - type: "POST", - dataType: "json", - data: "action=" + action.action, - success: function() { - new PNotify({title: "Success", text: _.sprintf(gettext("The command \"%(command)s\" executed successfully"), {command: action.name}), type: "success"}); - }, - error: function(jqXHR, textStatus, errorThrown) { + OctoPrint.control.executeSystemCommand(action.action) + .done(function() { + new PNotify({title: gettext("Success"), text: _.sprintf(gettext("The command \"%(command)s\" executed successfully"), {command: action.name}), type: "success"}); + }) + .fail(function() { if (!action.hasOwnProperty("ignore") || !action.ignore) { var error = "

" + _.sprintf(gettext("The command \"%(command)s\" could not be executed."), {command: action.name}) + "

"; error += pnotifyAdditionalInfo("
" + jqXHR.responseText + "
"); new PNotify({title: gettext("Error"), text: error, type: "error", hide: false}); } - } - }) + }); }; if (action.confirm) { showConfirmationDialog({ diff --git a/src/octoprint/static/js/app/viewmodels/printerprofiles.js b/src/octoprint/static/js/app/viewmodels/printerprofiles.js index 79612465..922ddd8f 100644 --- a/src/octoprint/static/js/app/viewmodels/printerprofiles.js +++ b/src/octoprint/static/js/app/viewmodels/printerprofiles.js @@ -194,12 +194,8 @@ $(function() { }; self.requestData = function() { - $.ajax({ - url: API_BASEURL + "printerprofiles", - type: "GET", - dataType: "json", - success: self.fromResponse - }) + OctoPrint.printerprofiles.get() + .done(self.fromResponse); }; self.fromResponse = function(data) { @@ -228,43 +224,35 @@ $(function() { self.addProfile = function(callback) { var profile = self._editorData(); self.requestInProgress(true); - $.ajax({ - url: API_BASEURL + "printerprofiles", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({profile: profile}), - success: function() { - self.requestInProgress(false); + OctoPrint.printerprofiles.add(profile) + .done(function() { if (callback !== undefined) { callback(); } self.requestData(); - }, - error: function() { - self.requestInProgress(false); + }) + .fail(function() { var text = gettext("There was unexpected error while saving the printer profile, please consult the logs."); new PNotify({title: gettext("Saving failed"), text: text, type: "error", hide: false}); - } - }); + }) + .always(function() { + self.requestInProgress(false); + }); }; self.removeProfile = function(data) { self.requestInProgress(true); - $.ajax({ - url: data.resource, - type: "DELETE", - dataType: "json", - success: function() { - self.requestInProgress(false); + OctoPrint.printerprofiles.delete(data.id, {url: data.resource}) + .done(function() { self.requestData(); - }, - error: function() { - self.requestInProgress(false); + }) + .fail(function() { var text = gettext("There was unexpected error while removing the printer profile, please consult the logs."); new PNotify({title: gettext("Saving failed"), text: text, type: "error", hide: false}); - } - }) + }) + .always(function() { + self.requestInProgress(false); + }); }; self.updateProfile = function(profile, callback) { @@ -273,26 +261,20 @@ $(function() { } self.requestInProgress(true); - - $.ajax({ - url: API_BASEURL + "printerprofiles/" + profile.id, - type: "PATCH", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({profile: profile}), - success: function() { - self.requestInProgress(false); + OctoPrint.printerprofiles.update(profile.key, profile) + .done(function() { if (callback !== undefined) { callback(); } self.requestData(); - }, - error: function() { - self.requestInProgress(false); + }) + .fail(function() { var text = gettext("There was unexpected error while updating the printer profile, please consult the logs."); new PNotify({title: gettext("Saving failed"), text: text, type: "error", hide: false}); - } - }); + }) + .always(function() { + self.requestInProgress(false); + }); }; self.showEditProfileDialog = function(data) { diff --git a/src/octoprint/static/js/app/viewmodels/printerstate.js b/src/octoprint/static/js/app/viewmodels/printerstate.js index e764a003..d1bfa10a 100644 --- a/src/octoprint/static/js/app/viewmodels/printerstate.js +++ b/src/octoprint/static/js/app/viewmodels/printerstate.js @@ -198,45 +198,25 @@ $(function() { }; self.print = function() { - var restartCommand = function() { - self._jobCommand("restart"); - }; - if (self.isPaused()) { showConfirmationDialog({ message: gettext("This will restart the print job from the beginning."), - onproceed: function(e) { - restartCommand(); + onproceed: function() { + OctoPrint.job.restart(); } }); } else { - self._jobCommand("start"); + OctoPrint.job.start(); } - }; self.pause = function() { - self._jobCommand("pause"); + OctoPrint.job.pause(); }; self.cancel = function() { - self._jobCommand("cancel"); + OctoPrint.job.cancel(); }; - - self._jobCommand = function(command, callback) { - $.ajax({ - url: API_BASEURL + "job", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({command: command}), - success: function(response) { - if (callback != undefined) { - callback(); - } - } - }); - } } OCTOPRINT_VIEWMODELS.push([ diff --git a/src/octoprint/static/js/app/viewmodels/settings.js b/src/octoprint/static/js/app/viewmodels/settings.js index 39b58432..f5c97ea2 100644 --- a/src/octoprint/static/js/app/viewmodels/settings.js +++ b/src/octoprint/static/js/app/viewmodels/settings.js @@ -225,18 +225,14 @@ $(function() { var errorText = gettext("Could not retrieve snapshot URL, please double check the URL"); var errorTitle = gettext("Snapshot test failed"); - $.ajax({ - url: API_BASEURL + "util/test", - type: "POST", - dataType: "json", - data: JSON.stringify({ - command: "url", - url: self.webcam_snapshotUrl(), - method: "GET", - response: true - }), - contentType: "application/json; charset=UTF-8", - success: function(response) { + + var data = { + url: self.webcam_snapshotUrl(), + method: "GET", + response: true + }; + OctoPrint.util.test("url", data) + .done(function(response) { $("i.icon-spinner", target).remove(); if (!response.result) { @@ -260,15 +256,14 @@ $(function() { title: gettext("Snapshot test"), message: $('

' + text + '

') }); - }, - error: function() { + }) + .fail(function() { $("i.icon-spinner", target).remove(); showMessageDialog({ title: errorTitle, message: errorText }); - } - }); + }); }; self.testWebcamFfmpegPath = function() { @@ -293,19 +288,13 @@ $(function() { }; var path = self.webcam_ffmpegPath(); - $.ajax({ - url: API_BASEURL + "util/test", - type: "POST", - dataType: "json", - data: JSON.stringify({ - command: "path", - path: path, - check_type: "file", - check_access: "x" - }), - contentType: "application/json; charset=UTF-8", - success: successCallback - }) + var data = { + path: path, + check_type: "file", + check_access: "x" + }; + OctoPrint.util.test("path", data) + .done(successCallback); }; self.onSettingsShown = function() { @@ -331,6 +320,7 @@ $(function() { dataType: "json", maxNumberOfFiles: 1, autoUpload: false, + headers: OctoPrint.getRequestHeaders(), add: function(e, data) { if (data.files.length == 0) { return false; @@ -418,11 +408,8 @@ $(function() { } self.receiving(true); - $.ajax({ - url: API_BASEURL + "settings", - type: "GET", - dataType: "json", - success: function(response) { + OctoPrint.settings.get() + .done(function(response) { if (callback) { self.callbacks.push(callback); } @@ -443,23 +430,15 @@ $(function() { self.receiving(false); self.callbacks = []; } - }, - error: function(xhr) { + }) + .fail(function() { self.receiving(false); - } - }); + }); }; self.requestTranslationData = function(callback) { - $.ajax({ - url: API_BASEURL + "languages", - type: "GET", - dataType: "json", - success: function(response) { - self.fromTranslationResponse(response); - if (callback) callback(); - } - }) + return OctoPrint.languages.list() + .done(self.fromTranslationResponse); }; self.fromTranslationResponse = function(response) { @@ -509,14 +488,8 @@ $(function() { }); self.deleteLanguagePack = function(locale, pack) { - $.ajax({ - url: API_BASEURL + "languages/" + locale + "/" + pack, - type: "DELETE", - dataType: "json", - success: function(response) { - self.fromTranslationResponse(response); - } - }) + OctoPrint.languages.delete(locale, pack) + .done(self.fromTranslationResponse); }; /** @@ -690,13 +663,8 @@ $(function() { data = getOnlyChangedData(self.getLocalData(), self.lastReceivedSettings); } - $.ajax({ - url: API_BASEURL + "settings", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data), - success: function(data, status, xhr) { + OctoPrint.settings.save(data) + .done(function(data, status, xhr) { self.receiving(true); self.sending(false); try { @@ -705,15 +673,14 @@ $(function() { } finally { self.receiving(false); } - }, - error: function(xhr, status, error) { + }) + .fail(function(xhr, status, error) { self.sending(false); if (options.error) options.error(xhr, status, error); - }, - complete: function(xhr, status) { + }) + .always(function(xhr, status) { if (options.complete) options.complete(xhr, status); - } - }); + }); }; self.onEventSettingsUpdated = function() { diff --git a/src/octoprint/static/js/app/viewmodels/slicing.js b/src/octoprint/static/js/app/viewmodels/slicing.js index eba0581a..c361b826 100644 --- a/src/octoprint/static/js/app/viewmodels/slicing.js +++ b/src/octoprint/static/js/app/viewmodels/slicing.js @@ -65,17 +65,13 @@ $(function() { }); self.requestData = function(callback) { - $.ajax({ - url: API_BASEURL + "slicing", - type: "GET", - dataType: "json", - success: function(data) { + OctoPrint.slicing.listAllSlicersAndProfiles() + .done(function(data) { self.fromResponse(data); if (callback !== undefined) { callback(); } - } - }); + }); }; self.fromResponse = function(data) { @@ -150,7 +146,6 @@ $(function() { } var data = { - command: "slice", slicer: self.slicer(), profile: self.profile(), printerProfile: self.printerProfile(), @@ -163,19 +158,14 @@ $(function() { data["select"] = true; } - $.ajax({ - url: API_BASEURL + "files/" + self.target + "/" + self.file, - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data) - }); + OctoPrint.files.slice(self.target, self.file, data) + .done(function() { + $("#slicing_configuration_dialog").modal("hide"); - $("#slicing_configuration_dialog").modal("hide"); - - self.gcodeFilename(undefined); - self.slicer(self.defaultSlicer); - self.profile(self.defaultProfile); + self.gcodeFilename(undefined); + self.slicer(self.defaultSlicer); + self.profile(self.defaultProfile); + }); }; self._sanitize = function(name) { @@ -196,4 +186,4 @@ $(function() { ["loginStateViewModel", "printerProfilesViewModel"], "#slicing_configuration_dialog" ]); -}); \ No newline at end of file +}); diff --git a/src/octoprint/static/js/app/viewmodels/temperature.js b/src/octoprint/static/js/app/viewmodels/temperature.js index 9b58d2ec..e9f51ece 100644 --- a/src/octoprint/static/js/app/viewmodels/temperature.js +++ b/src/octoprint/static/js/app/viewmodels/temperature.js @@ -268,87 +268,84 @@ $(function() { var value = item.newTarget(); if (!value) return; - self._sendToolCommand("target", - item.key(), - item.newTarget(), - function() {item.newTarget("");} - ); + var onSuccess = function() { + item.newTarget(""); + }; + + if (item.key() == "bed") { + self._setBedTemperature(value) + .done(onSuccess); + } else { + self._setToolTemperature(item.key(), value) + .done(onSuccess); + } }; self.setTargetFromProfile = function(item, profile) { if (!profile) return; - var value = undefined; - if (item.key() == "bed") { - value = profile.bed; - } else { - value = profile.extruder; - } + var onSuccess = function() { + item.newTarget(""); + }; - self._sendToolCommand("target", - item.key(), - value, - function() {item.newTarget("");} - ); + if (item.key() == "bed") { + self._setBedTemperature(profile.bed) + .done(onSuccess); + } else { + self._setToolTemperature(item.key(), profile.extruder) + .done(onSuccess); + } }; self.setTargetToZero = function(item) { - self._sendToolCommand("target", - item.key(), - 0, - function() {item.newTarget("");} - ); + var onSuccess = function() { + item.newTarget(""); + }; + + if (item.key() == "bed") { + self._setBedTemperature(0) + .done(onSuccess); + } else { + self._setToolTemperature(item.key(), 0) + .done(onSuccess); + } }; self.setOffset = function(item) { - self._sendToolCommand("offset", - item.key(), - item.newOffset(), - function() {item.newOffset("");} - ); - }; + var value = item.newOffset(); + if (!value) return; - self._sendToolCommand = function(command, type, temp, successCb, errorCb) { - var data = { - command: command + var onSuccess = function() { + item.newOffset(""); }; - var endpoint; - if (type == "bed") { - if ("target" == command) { - data["target"] = parseInt(temp); - } else if ("offset" == command) { - data["offset"] = parseInt(temp); - } else { - return; - } - - endpoint = "bed"; + if (item.key() == "bed") { + self._setBedOffset(value) + .done(onSuccess); } else { - var group; - if ("target" == command) { - group = "targets"; - } else if ("offset" == command) { - group = "offsets"; - } else { - return; - } - data[group] = {}; - data[group][type] = parseInt(temp); - - endpoint = "tool"; + self._setToolOffset(item.key(), value) + .done(onSuccess); } + }; - $.ajax({ - url: API_BASEURL + "printer/" + endpoint, - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(data), - success: function() { if (successCb !== undefined) successCb(); }, - error: function() { if (errorCb !== undefined) errorCb(); } - }); + self._setToolTemperature = function(tool, temperature) { + var data = {}; + data[tool] = parseInt(temperature); + return OctoPrint.printer.setToolTargetTemperatures(data); + }; + self._setToolOffset = function(tool, offset) { + var data = {}; + data[tool] = parseInt(offset); + return OctoPrint.printer.setToolTemperatureOffsets(data); + }; + + self._setBedTemperature = function(temperature) { + return OctoPrint.printer.setBedTargetTemperature(parseInt(temperature)); + }; + + self._setBedOffset = function(offset) { + return OctoPrint.printer.setBedTemperatureOffset(parseInt(offset)); }; self.handleEnter = function(event, type, item) { @@ -375,4 +372,4 @@ $(function() { ["loginStateViewModel", "settingsViewModel"], "#temp" ]); -}); \ No newline at end of file +}); diff --git a/src/octoprint/static/js/app/viewmodels/terminal.js b/src/octoprint/static/js/app/viewmodels/terminal.js index d7ec494d..3da817a0 100644 --- a/src/octoprint/static/js/app/viewmodels/terminal.js +++ b/src/octoprint/static/js/app/viewmodels/terminal.js @@ -158,29 +158,18 @@ $(function() { } if (command) { - $.ajax({ - url: API_BASEURL + "printer/command", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({"command": command}) - }); - - self.cmdHistory.push(command); - self.cmdHistory.slice(-300); // just to set a sane limit to how many manually entered commands will be saved... - self.cmdHistoryIdx = self.cmdHistory.length; - self.command(""); + OctoPrint.control.sendGcode(command) + .done(function() { + self.cmdHistory.push(command); + self.cmdHistory.slice(-300); // just to set a sane limit to how many manually entered commands will be saved... + self.cmdHistoryIdx = self.cmdHistory.length; + self.command(""); + }); } }; self.fakeAck = function() { - $.ajax({ - url: API_BASEURL + "connection", - type: "POST", - dataType: "json", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({"command": "fake_ack"}) - }); + OctoPrint.printer.fakeAck(); }; self.handleKeyDown = function(event) { @@ -232,4 +221,4 @@ $(function() { ["loginStateViewModel", "settingsViewModel"], "#term" ]); -}); \ No newline at end of file +}); diff --git a/src/octoprint/static/js/app/viewmodels/timelapse.js b/src/octoprint/static/js/app/viewmodels/timelapse.js index ed4188b5..0b3a0950 100644 --- a/src/octoprint/static/js/app/viewmodels/timelapse.js +++ b/src/octoprint/static/js/app/viewmodels/timelapse.js @@ -34,20 +34,20 @@ $(function() { return self.isDirty() && self.isOperational() && !self.isPrinting() && self.loginState.isUser(); }); - self.isOperational.subscribe(function(newValue) { + self.isOperational.subscribe(function() { self.requestData(); }); - self.timelapseType.subscribe(function(newValue) { + self.timelapseType.subscribe(function() { self.isDirty(true); }); - self.timelapseTimedInterval.subscribe(function(newValue) { + self.timelapseTimedInterval.subscribe(function() { self.isDirty(true); }); - self.timelapsePostRoll.subscribe(function(newValue) { + self.timelapsePostRoll.subscribe(function() { self.isDirty(true); }); - self.timelapseFps.subscribe(function(newValue) { + self.timelapseFps.subscribe(function() { self.isDirty(true); }); @@ -83,12 +83,8 @@ $(function() { ); self.requestData = function() { - $.ajax({ - url: API_BASEURL + "timelapse", - type: "GET", - dataType: "json", - success: self.fromResponse - }); + OctoPrint.timelapse.get() + .done(self.fromResponse); }; self.fromResponse = function(response) { @@ -141,15 +137,11 @@ $(function() { }; self.removeFile = function(filename) { - $.ajax({ - url: API_BASEURL + "timelapse/" + filename, - type: "DELETE", - dataType: "json", - success: self.requestData - }); + OctoPrint.timelapse.delete(filename) + .done(self.requestData); }; - self.save = function(data, event) { + self.save = function() { var payload = { "type": self.timelapseType(), "postRoll": self.timelapsePostRoll(), @@ -161,20 +153,15 @@ $(function() { payload["interval"] = self.timelapseTimedInterval(); } - $.ajax({ - url: API_BASEURL + "timelapse", - type: "POST", - dataType: "json", - data: payload, - success: self.fromResponse - }); + OctoPrint.timelapse.saveConfig(payload) + .done(self.fromResponse); }; self.onDataUpdaterReconnect = function() { self.requestData(); }; - self.onEventMovieDone = function(payload) { + self.onEventMovieDone = function() { self.requestData(); }; diff --git a/src/octoprint/static/js/app/viewmodels/users.js b/src/octoprint/static/js/app/viewmodels/users.js index c341a067..235dd28d 100644 --- a/src/octoprint/static/js/app/viewmodels/users.js +++ b/src/octoprint/static/js/app/viewmodels/users.js @@ -60,12 +60,8 @@ $(function() { self.requestData = function() { if (!CONFIG_ACCESS_CONTROL) return; - $.ajax({ - url: API_BASEURL + "users", - type: "GET", - dataType: "json", - success: self.fromResponse - }); + OctoPrint.users.list() + .done(self.fromResponse); }; self.fromResponse = function(response) { @@ -83,12 +79,19 @@ $(function() { self.confirmAddUser = function() { if (!CONFIG_ACCESS_CONTROL) return; - var user = {name: self.editorUsername(), password: self.editorPassword(), admin: self.editorAdmin(), active: self.editorActive()}; - self.addUser(user, function() { - // close dialog - self.currentUser(undefined); - self.addUserDialog.modal("hide"); - }); + var user = { + name: self.editorUsername(), + password: self.editorPassword(), + admin: self.editorAdmin(), + active: self.editorActive() + }; + + self.addUser(user) + .done(function() { + // close dialog + self.currentUser(undefined); + self.addUserDialog.modal("hide"); + }); }; self.showEditUserDialog = function(user) { @@ -105,12 +108,12 @@ $(function() { user.active = self.editorActive(); user.admin = self.editorAdmin(); - // make AJAX call - self.updateUser(user, function() { - // close dialog - self.currentUser(undefined); - self.editUserDialog.modal("hide"); - }); + self.updateUser(user) + .done(function() { + // close dialog + self.currentUser(undefined); + self.editUserDialog.modal("hide"); + }); }; self.showChangePasswordDialog = function(user) { @@ -123,27 +126,30 @@ $(function() { self.confirmChangePassword = function() { if (!CONFIG_ACCESS_CONTROL) return; - self.updatePassword(self.currentUser().name, self.editorPassword(), function() { - // close dialog - self.currentUser(undefined); - self.changePasswordDialog.modal("hide"); - }); + self.updatePassword(self.currentUser().name, self.editorPassword()) + .done(function() { + // close dialog + self.currentUser(undefined); + self.changePasswordDialog.modal("hide"); + }); }; self.confirmGenerateApikey = function() { if (!CONFIG_ACCESS_CONTROL) return; - self.generateApikey(self.currentUser().name, function(response) { - self._updateApikey(response.apikey); - }) + self.generateApikey(self.currentUser().name) + .done(function(response) { + self._updateApikey(response.apikey); + }); }; self.confirmDeleteApikey = function() { if (!CONFIG_ACCESS_CONTROL) return; - self.deleteApikey(self.currentUser().name, function() { - self._updateApikey(undefined); - }) + self.deleteApikey(self.currentUser().name) + .done(function() { + self._updateApikey(undefined); + }); }; self._updateApikey = function(apikey) { @@ -159,108 +165,55 @@ $(function() { self.changePasswordDialog = $("#settings-usersDialogChangePassword"); }; - //~~ AJAX calls + //~~ API calls - self.addUser = function(user, callback) { - if (!CONFIG_ACCESS_CONTROL) return; - if (user === undefined) return; + self.addUser = function(user) { + if (!user) { + throw OctoPrint.InvalidArgumentError("user must be set"); + } - $.ajax({ - url: API_BASEURL + "users", - type: "POST", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(user), - success: function(response) { - self.fromResponse(response); - if (callback) { - callback(response); - } - } - }); + return OctoPrint.users.add(user) + .done(self.fromResponse); }; - self.removeUser = function(user, callback) { - if (!CONFIG_ACCESS_CONTROL) return; - if (user === undefined) return; + self.removeUser = function(user) { + if (!user) { + throw OctoPrint.InvalidArgumentError("user must be set"); + } if (user.name == self.loginState.username()) { // we do not allow to delete ourselves - new PNotify({title: "Not possible", text: "You may not delete your own account.", type: "error"}); - return; + new PNotify({ + title: gettext("Not possible"), + text: gettext("You may not delete your own account."), + type: "error" + }); + return $.Deferred().reject("You may not delete your own account").promise(); } - $.ajax({ - url: API_BASEURL + "users/" + user.name, - type: "DELETE", - success: function(response) { - self.fromResponse(response); - if (callback) { - callback(response); - } - } - }); + return OctoPrint.users.delete(user.name) + .done(self.fromResponse); }; - self.updateUser = function(user, callback) { - if (!CONFIG_ACCESS_CONTROL) return; - if (user === undefined) return; + self.updateUser = function(user) { + if (!user) { + throw OctoPrint.InvalidArgumentError("user must be set"); + } - $.ajax({ - url: API_BASEURL + "users/" + user.name, - type: "PUT", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(user), - success: function(response) { - self.fromResponse(response); - if (callback) { - callback(response); - } - } - }); + return OctoPrint.users.update(user.name, user.active, user.admin) + .done(self.fromResponse); }; - self.updatePassword = function(username, password, callback) { - if (!CONFIG_ACCESS_CONTROL) return; - - $.ajax({ - url: API_BASEURL + "users/" + username + "/password", - type: "PUT", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify({password: password}), - success: function(response) { - if (callback) { - callback(response); - } - } - }); + self.updatePassword = function(username, password) { + return OctoPrint.users.changePassword(username, password); }; - self.generateApikey = function(username, callback) { - if (!CONFIG_ACCESS_CONTROL) return; - - $.ajax({ - url: API_BASEURL + "users/" + username + "/apikey", - type: "POST", - success: function(response) { - if (callback) { - callback(response); - } - } - }); + self.generateApikey = function(username) { + return OctoPrint.users.generateApiKey(username); }; - self.deleteApikey = function(username, callback) { - if (!CONFIG_ACCESS_CONTROL) return; - - $.ajax({ - url: API_BASEURL + "users/" + username + "/apikey", - type: "DELETE", - success: function(response) { - if (callback) { - callback(response); - } - } - }); + self.deleteApikey = function(username) { + return OctoPrint.users.resetApiKey(username); }; self.onUserLoggedIn = function(user) { @@ -275,4 +228,4 @@ $(function() { ["loginStateViewModel"], [] ]); -}); \ No newline at end of file +}); diff --git a/src/octoprint/static/js/app/viewmodels/usersettings.js b/src/octoprint/static/js/app/viewmodels/usersettings.js index ed8d0a6a..99b79631 100644 --- a/src/octoprint/static/js/app/viewmodels/usersettings.js +++ b/src/octoprint/static/js/app/viewmodels/usersettings.js @@ -60,24 +60,17 @@ $(function() { "language": self.interface_language() } }; - self.updateSettings(self.currentUser().name, settings, function() { - // close dialog - self.currentUser(undefined); - self.userSettingsDialog.modal("hide"); - self.loginState.reloadUser(); - }); + self.updateSettings(self.currentUser().name, settings) + .done(function() { + // close dialog + self.currentUser(undefined); + self.userSettingsDialog.modal("hide"); + self.loginState.reloadUser(); + }); }; - self.updateSettings = function(username, settings, callback) { - if (!CONFIG_ACCESS_CONTROL) return; - - $.ajax({ - url: API_BASEURL + "users/" + username + "/settings", - type: "PATCH", - contentType: "application/json; charset=UTF-8", - data: JSON.stringify(settings), - success: callback - }); + self.updateSettings = function(username, settings) { + return OctoPrint.users.saveSettings(username, settings); }; self.saveEnabled = function() { diff --git a/src/octoprint/static/js/app/viewmodels/wizard.js b/src/octoprint/static/js/app/viewmodels/wizard.js index c15b11a3..54ca62e4 100644 --- a/src/octoprint/static/js/app/viewmodels/wizard.js +++ b/src/octoprint/static/js/app/viewmodels/wizard.js @@ -19,18 +19,19 @@ $(function() { self.showDialog = function() { if (!CONFIG_WIZARD || !(CONFIG_FIRST_RUN || self.loginState.isAdmin())) return; - self.getWizardDetails(function(response) { - callViewModels(self.allViewModels, "onWizardDetails", [response]); + self.getWizardDetails() + .done(function(response) { + callViewModels(self.allViewModels, "onWizardDetails", [response]); - if (!self.isDialogActive()) { - self.wizardDialog.modal({ - minHeight: function() { return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); } - }).css({ - width: 'auto', - 'margin-left': function() { return -($(this).width() /2); } - }); - } - }); + if (!self.isDialogActive()) { + self.wizardDialog.modal({ + minHeight: function() { return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); } + }).css({ + width: 'auto', + 'margin-left': function() { return -($(this).width() /2); } + }); + } + }); }; self.closeDialog = function() { @@ -121,53 +122,34 @@ $(function() { // then reload = (method() == "reload") || reload; }); - self.finishWizard(function() { - self.closeDialog(); - if (reload) { - log.info("Wizard requested reloading"); - location.reload(true); - } - }); + self.finishWizard() + .done(function() { + self.closeDialog(); + if (reload) { + log.info("Wizard requested reloading"); + location.reload(true); + } + }); } } }); self.showDialog(); }; - self.getWizardDetails = function(callback) { - if (!callback) return; - - $.ajax({ - url: API_BASEURL + "setup/wizard", - type: "GET", - dataType: "json", - success: function(response) { + self.getWizardDetails = function() { + return OctoPrint.wizard.get() + .done(function(response) { self.wizards = _.filter(_.keys(response), function(key) { return response[key] && response[key]["required"] && !response[key]["ignored"]; }); - if (callback) { - callback(response); - } - } - }); + }); }; - self.finishWizard = function(callback) { + self.finishWizard = function() { self.finishing = true; - self.settingsViewModel.saveData(); - $.ajax({ - url: API_BASEURL + "setup/wizard", - type: "POST", - dataType: "json", - data: JSON.stringify({handled: self.wizards}), - contentType: "application/json; charset=UTF-8", - success: function() { + return OctoPrint.wizard.finish(self.wizards) + .always(function() { self.finishing = false; - callback(); - }, - failure: function() { - self.finishing = false; - } - }) + }); }; self.onSettingsPreventRefresh = function() { diff --git a/src/octoprint/templates/javascripts.jinja2 b/src/octoprint/templates/javascripts.jinja2 index acad1952..f69b158c 100644 --- a/src/octoprint/templates/javascripts.jinja2 +++ b/src/octoprint/templates/javascripts.jinja2 @@ -2,6 +2,10 @@ {% endassets %} +{% assets "js_client" %} + +{% endassets %} + {% assets "js_app" %} {% endassets %}