Revamped the events slightly
Payload data can now be properly injected into event handlers such as command triggers. Added a couple of new events to use for update triggers to the frontend instead of custom code, further decoupling the application. Movie rendering now also causes a frontend notification.
This commit is contained in:
parent
9f7fc73441
commit
0b662b7211
22 changed files with 118 additions and 104 deletions
|
|
@ -135,7 +135,8 @@ class DebugEventListener(GenericEventListener):
|
|||
events = ["Startup", "Connected", "Disconnected", "ClientOpen", "ClientClosed", "PowerOn", "PowerOff", "Upload",
|
||||
"FileSelected", "TransferStarted", "TransferDone", "PrintStarted", "PrintDone", "PrintFailed",
|
||||
"Cancelled", "Home", "ZChange", "Paused", "Waiting", "Cooling", "Alert", "Conveyor", "Eject",
|
||||
"CaptureStart", "CaptureDone", "MovieDone", "EStop", "Error"]
|
||||
"CaptureStart", "CaptureDone", "MovieRendering", "MovieDone", "MovieFailed", "EStop", "Error",
|
||||
"SlicingStarted", "SlicingDone", "SlicingFailed", "UpdatedFiles"]
|
||||
self.subscribe(events)
|
||||
|
||||
def eventCallback(self, event, payload):
|
||||
|
|
@ -191,8 +192,11 @@ class CommandTrigger(GenericEventListener):
|
|||
return
|
||||
|
||||
for command in self._subscriptions[event]:
|
||||
processedCommand = self._processCommand(command, payload)
|
||||
self.executeCommand(processedCommand)
|
||||
try:
|
||||
processedCommand = self._processCommand(command, payload)
|
||||
self.executeCommand(processedCommand)
|
||||
except KeyError:
|
||||
self._logger.warn("There was an error processing one or more placeholders in the following command: %s" % command)
|
||||
|
||||
def executeCommand(self, command):
|
||||
"""
|
||||
|
|
@ -206,33 +210,39 @@ class CommandTrigger(GenericEventListener):
|
|||
|
||||
The following substitutions are currently supported:
|
||||
|
||||
- %(currentZ)s : current Z position of the print head, or -1 if not available
|
||||
- %(filename)s : current selected filename, or "NO FILE" if no file is selected
|
||||
- %(progress)s : current print progress in percent, 0 if no print is in progress
|
||||
- %(data)s : the string representation of the event's payload
|
||||
- %(now)s : ISO 8601 representation of the current date and time
|
||||
- {__currentZ} : current Z position of the print head, or -1 if not available
|
||||
- {__filename} : current selected filename, or "NO FILE" if no file is selected
|
||||
- {__progress} : current print progress in percent, 0 if no print is in progress
|
||||
- {__data} : the string representation of the event's payload
|
||||
- {__now} : ISO 8601 representation of the current date and time
|
||||
|
||||
Additionally, the keys of the event's payload can also be used as placeholder.
|
||||
"""
|
||||
|
||||
params = {
|
||||
"currentZ": "-1",
|
||||
"filename": "NO FILE",
|
||||
"progress": "0",
|
||||
"data": str(payload),
|
||||
"now": datetime.datetime.now().isoformat()
|
||||
"__currentZ": "-1",
|
||||
"__filename": "NO FILE",
|
||||
"__progress": "0",
|
||||
"__data": str(payload),
|
||||
"__now": datetime.datetime.now().isoformat()
|
||||
}
|
||||
|
||||
currentData = self._printer.getCurrentData()
|
||||
|
||||
if "currentZ" in currentData.keys() and currentData["currentZ"] is not None:
|
||||
params["currentZ"] = str(currentData["currentZ"])
|
||||
params["__currentZ"] = str(currentData["currentZ"])
|
||||
|
||||
if "job" in currentData.keys() and currentData["job"] is not None:
|
||||
params["filename"] = currentData["job"]["filename"]
|
||||
params["__filename"] = currentData["job"]["filename"]
|
||||
if "progress" in currentData.keys() and currentData["progress"] is not None \
|
||||
and "progress" in currentData["progress"].keys() and currentData["progress"]["progress"] is not None:
|
||||
params["progress"] = str(round(currentData["progress"]["progress"] * 100))
|
||||
params["__progress"] = str(round(currentData["progress"]["progress"] * 100))
|
||||
|
||||
return command % params
|
||||
# now add the payload keys as well
|
||||
if isinstance(payload, dict):
|
||||
params.update(payload)
|
||||
|
||||
return command.format(**params)
|
||||
|
||||
class SystemCommandTrigger(CommandTrigger):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ class GcodeManager:
|
|||
self._metadata[basename] = metadata
|
||||
self._metadataDirty = True
|
||||
self._saveMetadata()
|
||||
eventManager().fire("MetadataAnalysisFinished", {"filename": basename, "result": analysisResult})
|
||||
|
||||
def _loadMetadata(self):
|
||||
if os.path.exists(self._metadataFile) and os.path.isfile(self._metadataFile):
|
||||
|
|
@ -141,7 +142,6 @@ class GcodeManager:
|
|||
util.safeRename(self._metadataTempFile, self._metadataFile)
|
||||
|
||||
self._loadMetadata()
|
||||
self._sendUpdateTrigger("gcodeFiles")
|
||||
|
||||
def _getBasicFilename(self, filename):
|
||||
if filename.startswith(self._uploadFolder):
|
||||
|
|
@ -160,7 +160,7 @@ class GcodeManager:
|
|||
|
||||
def _sendUpdateTrigger(self, type):
|
||||
for callback in self._callbacks:
|
||||
try: callback.sendUpdateTrigger(type)
|
||||
try: callback.sendEvent(type)
|
||||
except: pass
|
||||
|
||||
#~~ file handling
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class Printer():
|
|||
|
||||
def _sendTriggerUpdateCallbacks(self, type):
|
||||
for callback in self._callbacks:
|
||||
try: callback.sendUpdateTrigger(type)
|
||||
try: callback.sendEvent(type)
|
||||
except: pass
|
||||
|
||||
def _sendFeedbackCommandOutput(self, name, output):
|
||||
|
|
@ -436,7 +436,7 @@ class Printer():
|
|||
self._stateMonitor.setState({"state": self._state, "stateString": self.getStateString(), "flags": self._getStateFlags()})
|
||||
|
||||
def mcSdFiles(self, files):
|
||||
self._sendTriggerUpdateCallbacks("gcodeFiles")
|
||||
eventManager().fire("UpdatedFiles", {"type": "gcode", "files": files})
|
||||
self._sdFilelistAvailable.set()
|
||||
|
||||
def mcFileSelected(self, filename, filesize, sd):
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agp
|
|||
|
||||
from flask import request, jsonify, make_response
|
||||
|
||||
from octoprint.settings import settings, valid_boolean_trues
|
||||
from octoprint.settings import settings
|
||||
from octoprint.printer import getConnectionOptions
|
||||
from octoprint.server import printer, restricted_access, SUCCESS
|
||||
from octoprint.server.ajax import ajax
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ def api_access(func):
|
|||
|
||||
|
||||
class PrinterStateConnection(SockJSConnection):
|
||||
EVENTS = ["UpdatedFiles", "MetadataAnalysisFinished", "MovieRendering", "MovieDone",
|
||||
"MovieFailed", "SlicingStarted", "SlicingDone", "SlicingFailed"]
|
||||
|
||||
def __init__(self, printer, gcodeManager, userManager, eventManager, session):
|
||||
SockJSConnection.__init__(self, session)
|
||||
|
||||
|
|
@ -113,10 +116,8 @@ class PrinterStateConnection(SockJSConnection):
|
|||
octoprint.timelapse.registerCallback(self)
|
||||
|
||||
self._eventManager.fire("ClientOpened")
|
||||
self._eventManager.subscribe("MovieDone", self._onMovieDone)
|
||||
self._eventManager.subscribe("SlicingStarted", self._onSlicingStarted)
|
||||
self._eventManager.subscribe("SlicingDone", self._onSlicingDone)
|
||||
self._eventManager.subscribe("SlicingFailed", self._onSlicingFailed)
|
||||
for event in PrinterStateConnection.EVENTS:
|
||||
self._eventManager.subscribe(event, self._onEvent)
|
||||
|
||||
octoprint.timelapse.notifyCallbacks(octoprint.timelapse.current)
|
||||
|
||||
|
|
@ -127,10 +128,8 @@ class PrinterStateConnection(SockJSConnection):
|
|||
octoprint.timelapse.unregisterCallback(self)
|
||||
|
||||
self._eventManager.fire("ClientClosed")
|
||||
self._eventManager.unsubscribe("MovieDone", self._onMovieDone)
|
||||
self._eventManager.unsubscribe("SlicingStarted", self._onSlicingStarted)
|
||||
self._eventManager.unsubscribe("SlicingDone", self._onSlicingDone)
|
||||
self._eventManager.unsubscribe("SlicingFailed", self._onSlicingFailed)
|
||||
for event in PrinterStateConnection.EVENTS:
|
||||
self._eventManager.unsubscribe(event, self._onEvent)
|
||||
|
||||
def on_message(self, message):
|
||||
pass
|
||||
|
|
@ -150,17 +149,17 @@ class PrinterStateConnection(SockJSConnection):
|
|||
self._messageBacklog = []
|
||||
|
||||
data.update({
|
||||
"temperatures": temperatures,
|
||||
"logs": logs,
|
||||
"messages": messages
|
||||
"temperatures": temperatures,
|
||||
"logs": logs,
|
||||
"messages": messages
|
||||
})
|
||||
self._emit("current", data)
|
||||
|
||||
def sendHistoryData(self, data):
|
||||
self._emit("history", data)
|
||||
|
||||
def sendUpdateTrigger(self, type, payload=None):
|
||||
self._emit("updateTrigger", {"type": type, "payload": payload})
|
||||
def sendEvent(self, type, payload=None):
|
||||
self._emit("event", {"type": type, "payload": payload})
|
||||
|
||||
def sendFeedbackCommandOutput(self, name, output):
|
||||
self._emit("feedbackCommandOutput", {"name": name, "output": output})
|
||||
|
|
@ -180,17 +179,8 @@ class PrinterStateConnection(SockJSConnection):
|
|||
with self._temperatureBacklogMutex:
|
||||
self._temperatureBacklog.append(data)
|
||||
|
||||
def _onMovieDone(self, event, payload):
|
||||
self.sendUpdateTrigger("timelapseFiles")
|
||||
|
||||
def _onSlicingStarted(self, event, payload):
|
||||
self.sendUpdateTrigger("slicingStarted", payload)
|
||||
|
||||
def _onSlicingDone(self, event, payload):
|
||||
self.sendUpdateTrigger("slicingDone", payload)
|
||||
|
||||
def _onSlicingFailed(self, event, payload):
|
||||
self.sendUpdateTrigger("slicingFailed", payload)
|
||||
def _onEvent(self, event, payload):
|
||||
self.sendEvent(event, payload)
|
||||
|
||||
def _emit(self, type, payload):
|
||||
self.send({type: payload})
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ default_settings = {
|
|||
}
|
||||
}
|
||||
|
||||
valid_boolean_trues = ["true", "yes", "y", "1"]
|
||||
valid_boolean_trues = [True, "true", "yes", "y", "1"]
|
||||
|
||||
class Settings(object):
|
||||
|
||||
|
|
|
|||
|
|
@ -102,27 +102,36 @@ function DataUpdater(loginStateViewModel, connectionViewModel, printerStateViewM
|
|||
self.gcodeFilesViewModel.fromCurrentData(data);
|
||||
break;
|
||||
}
|
||||
case "updateTrigger": {
|
||||
case "event": {
|
||||
var type = data["type"];
|
||||
var payload = data["payload"];
|
||||
if (type == "gcodeFiles") {
|
||||
|
||||
var gcodeUploadProgress = $("#gcode_upload_progress");
|
||||
var gcodeUploadProgressBar = $(".bar", gcodeUploadProgress);
|
||||
|
||||
if ((type == "UpdatedFiles" && payload.type == "gcode") || type == "MetadataAnalysisFinished") {
|
||||
gcodeFilesViewModel.requestData();
|
||||
} else if (type == "timelapseFiles") {
|
||||
} else if (type == "MovieRendering") {
|
||||
$.pnotify({title: "Rendering timelapse", text: "Now rendering timelapse " + payload.movie_basename});
|
||||
} else if (type == "MovieDone") {
|
||||
$.pnotify({title: "Timelapse ready", text: "New timelapse " + payload.movie_basename + " is done rendering."});
|
||||
timelapseViewModel.requestData();
|
||||
} else if (type == "slicingStarted") {
|
||||
$("#gcode_upload_progress .bar").css("width", "100%");
|
||||
$("#gcode_upload_progress").addClass("progress-striped").addClass("active");
|
||||
$("#gcode_upload_progress .bar").text("Slicing ...");
|
||||
} else if (type == "slicingDone") {
|
||||
$("#gcode_upload_progress .bar").css("width", "0%");
|
||||
$("#gcode_upload_progress").removeClass("progress-striped").removeClass("active");
|
||||
$("#gcode_upload_progress .bar").text("");
|
||||
} else if (type == "MovieFailed") {
|
||||
$.pnotify({title: "Rendering failed", text: "Rendering of timelapse " + payload.movie_basename + " failed, return code " + payload.returncode, type: "error"});
|
||||
} else if (type == "SlicingStarted") {
|
||||
gcodeUploadProgress.addClass("progress-striped").addClass("active");
|
||||
gcodeUploadProgressBar.css("width", "100%");
|
||||
gcodeUploadProgressBar.text("Slicing ...");
|
||||
} else if (type == "SlicingDone") {
|
||||
gcodeUploadProgress.removeClass("progress-striped").removeClass("active");
|
||||
gcodeUploadProgressBar.css("width", "0%");
|
||||
gcodeUploadProgressBar.text("");
|
||||
$.pnotify({title: "Slicing done", text: "Sliced " + payload.stl + " to " + payload.gcode + ", took " + payload.time + " seconds"});
|
||||
gcodeFilesViewModel.requestData(payload.gcode);
|
||||
} else if (type == "slicingFailed") {
|
||||
$("#gcode_upload_progress .bar").css("width", "0%");
|
||||
$("#gcode_upload_progress").removeClass("progress-striped").removeClass("active");
|
||||
$("#gcode_upload_progress .bar").text("");
|
||||
} else if (type == "SlicingFailed") {
|
||||
gcodeUploadProgress.removeClass("progress-striped").removeClass("active");
|
||||
gcodeUploadProgressBar.css("width", "0%");
|
||||
gcodeUploadProgressBar.text("");
|
||||
$.pnotify({title: "Slicing failed", text: "Could not slice " + payload.stl + " to " + payload.gcode + ": " + payload.reason, type: "error"});
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ $(function() {
|
|||
|
||||
function enable_local_dropzone() {
|
||||
$("#gcode_upload").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/local",
|
||||
url: API_BASEURL + "gcodefiles/local",
|
||||
dataType: "json",
|
||||
dropZone: localTarget,
|
||||
done: gcode_upload_done,
|
||||
|
|
@ -118,7 +118,7 @@ $(function() {
|
|||
|
||||
function disable_local_dropzone() {
|
||||
$("#gcode_upload").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/local",
|
||||
url: API_BASEURL + "gcodefiles/local",
|
||||
dataType: "json",
|
||||
dropZone: null,
|
||||
done: gcode_upload_done,
|
||||
|
|
@ -129,7 +129,7 @@ $(function() {
|
|||
|
||||
function enable_sd_dropzone() {
|
||||
$("#gcode_upload_sd").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/sdcard",
|
||||
url: API_BASEURL + "gcodefiles/sdcard",
|
||||
dataType: "json",
|
||||
dropZone: $("#drop_sd"),
|
||||
done: gcode_upload_done,
|
||||
|
|
@ -140,7 +140,7 @@ $(function() {
|
|||
|
||||
function disable_sd_dropzone() {
|
||||
$("#gcode_upload_sd").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/sdcard",
|
||||
url: API_BASEURL + "gcodefiles/sdcard",
|
||||
dataType: "json",
|
||||
dropZone: null,
|
||||
formData: {target: "sd"},
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ function ConnectionViewModel(loginStateViewModel, settingsViewModel) {
|
|||
|
||||
self.requestData = function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/connection",
|
||||
url: API_BASEURL + "control/connection",
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
success: function(response) {
|
||||
|
|
@ -100,7 +100,7 @@ function ConnectionViewModel(loginStateViewModel, settingsViewModel) {
|
|||
data["save"] = true;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/connection",
|
||||
url: API_BASEURL + "control/connection",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
@ -112,7 +112,7 @@ function ConnectionViewModel(loginStateViewModel, settingsViewModel) {
|
|||
} else {
|
||||
self.requestData();
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/connection",
|
||||
url: API_BASEURL + "control/connection",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
|
|||
|
||||
self.requestData = function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/custom",
|
||||
url: API_BASEURL + "control/custom",
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
success: function(response) {
|
||||
|
|
@ -90,7 +90,7 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
|
|||
data[axis] = distance * multiplier;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/printer/printhead",
|
||||
url: API_BASEURL + "control/printer/printhead",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
@ -105,7 +105,7 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/printer/printhead",
|
||||
url: API_BASEURL + "control/printer/printhead",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
@ -127,7 +127,7 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
|
|||
length = 5;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/printer/feeder",
|
||||
url: API_BASEURL + "control/printer/feeder",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
@ -160,7 +160,7 @@ function ControlViewModel(loginStateViewModel, settingsViewModel) {
|
|||
return;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/printer/command",
|
||||
url: API_BASEURL + "control/printer/command",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ function FirstRunViewModel() {
|
|||
|
||||
self._sendData = function(data, callback) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "setup",
|
||||
url: API_BASEURL + "setup",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: data,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel) {
|
|||
|
||||
self.requestData = function(filenameOverride) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "gcodefiles",
|
||||
url: API_BASEURL + "gcodefiles",
|
||||
method: "GET",
|
||||
dataType: "json",
|
||||
success: function(response) {
|
||||
|
|
@ -135,7 +135,7 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel) {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "gcodefiles/" + origin + "/" + filename,
|
||||
url: API_BASEURL + "gcodefiles/" + origin + "/" + filename,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
@ -155,7 +155,7 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel) {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "gcodefiles/" + origin + "/" + filename,
|
||||
url: API_BASEURL + "gcodefiles/" + origin + "/" + filename,
|
||||
type: "DELETE",
|
||||
success: self.fromResponse
|
||||
})
|
||||
|
|
@ -175,7 +175,7 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel) {
|
|||
|
||||
self._sendSdCommand = function(command) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/sd",
|
||||
url: API_BASEURL + "control/sd",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: {command: command}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ function LoginStateViewModel() {
|
|||
|
||||
self.requestData = function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "login",
|
||||
url: API_BASEURL + "login",
|
||||
type: "POST",
|
||||
data: {"passive": true},
|
||||
success: self.fromResponse
|
||||
|
|
@ -63,7 +63,7 @@ function LoginStateViewModel() {
|
|||
$("#login_remember").prop("checked", false);
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "login",
|
||||
url: API_BASEURL + "login",
|
||||
type: "POST",
|
||||
data: {"user": username, "pass": password, "remember": remember},
|
||||
success: function(response) {
|
||||
|
|
@ -78,7 +78,7 @@ function LoginStateViewModel() {
|
|||
|
||||
self.logout = function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "logout",
|
||||
url: API_BASEURL + "logout",
|
||||
type: "POST",
|
||||
success: function(response) {
|
||||
$.pnotify({title: "Logout successful", text: "You are now logged out", type: "success"});
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ function NavigationViewModel(loginStateViewModel, appearanceViewModel, settingsV
|
|||
self.triggerAction = function(action) {
|
||||
var callback = function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "system",
|
||||
url: API_BASEURL + "system",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: "action=" + action.action,
|
||||
|
|
@ -22,14 +22,17 @@ function NavigationViewModel(loginStateViewModel, appearanceViewModel, settingsV
|
|||
})
|
||||
}
|
||||
if (action.confirm) {
|
||||
$("#confirmation_dialog .confirmation_dialog_message").text(action.confirm);
|
||||
$("#confirmation_dialog .confirmation_dialog_acknowledge").unbind("click");
|
||||
$("#confirmation_dialog .confirmation_dialog_acknowledge").bind("click", function(e) {
|
||||
var confirmationDialog = $("#confirmation_dialog");
|
||||
var confirmationDialogAck = $(".confirmation_dialog_acknowledge", confirmationDialog);
|
||||
|
||||
$(".confirmation_dialog_message", confirmationDialog).text(action.confirm);
|
||||
confirmationDialogAck.unbind("click");
|
||||
confirmationDialogAck.bind("click", function(e) {
|
||||
e.preventDefault();
|
||||
$("#confirmation_dialog").modal("hide");
|
||||
callback();
|
||||
});
|
||||
$("#confirmation_dialog").modal("show");
|
||||
confirmationDialog.modal("show");
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ function PrinterStateViewModel(loginStateViewModel) {
|
|||
|
||||
self._jobCommand = function(command) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/job",
|
||||
url: API_BASEURL + "control/job",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
|
|||
|
||||
self.requestData = function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "settings",
|
||||
url: API_BASEURL + "settings",
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: self.fromResponse
|
||||
|
|
@ -227,7 +227,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "settings",
|
||||
url: API_BASEURL + "settings",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ function TemperatureViewModel(loginStateViewModel, settingsViewModel) {
|
|||
data[group][type] = parseInt(temp);
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/printer/hotend",
|
||||
url: API_BASEURL + "control/printer/hotend",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ function TerminalViewModel(loginStateViewModel, settingsViewModel) {
|
|||
|
||||
if (command) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "control/printer/command",
|
||||
url: API_BASEURL + "control/printer/command",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ function TimelapseViewModel(loginStateViewModel) {
|
|||
|
||||
self.requestData = function() {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "timelapse",
|
||||
url: API_BASEURL + "timelapse",
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: self.fromResponse
|
||||
|
|
@ -109,7 +109,7 @@ function TimelapseViewModel(loginStateViewModel) {
|
|||
|
||||
self.removeFile = function(filename) {
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "timelapse/" + filename,
|
||||
url: API_BASEURL + "timelapse/" + filename,
|
||||
type: "DELETE",
|
||||
dataType: "json",
|
||||
success: self.requestData
|
||||
|
|
@ -127,7 +127,7 @@ function TimelapseViewModel(loginStateViewModel) {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "timelapse",
|
||||
url: API_BASEURL + "timelapse",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: data,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ function UsersViewModel(loginStateViewModel) {
|
|||
if (!CONFIG_ACCESS_CONTROL) return;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "users",
|
||||
url: API_BASEURL + "users",
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: self.fromResponse
|
||||
|
|
@ -153,7 +153,7 @@ function UsersViewModel(loginStateViewModel) {
|
|||
if (user === undefined) return;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "users",
|
||||
url: API_BASEURL + "users",
|
||||
type: "POST",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
data: JSON.stringify(user),
|
||||
|
|
@ -175,7 +175,7 @@ function UsersViewModel(loginStateViewModel) {
|
|||
}
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "users/" + user.name,
|
||||
url: API_BASEURL + "users/" + user.name,
|
||||
type: "DELETE",
|
||||
success: function(response) {
|
||||
self.fromResponse(response);
|
||||
|
|
@ -189,7 +189,7 @@ function UsersViewModel(loginStateViewModel) {
|
|||
if (user === undefined) return;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "users/" + user.name,
|
||||
url: API_BASEURL + "users/" + user.name,
|
||||
type: "PUT",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
data: JSON.stringify(user),
|
||||
|
|
@ -204,7 +204,7 @@ function UsersViewModel(loginStateViewModel) {
|
|||
if (!CONFIG_ACCESS_CONTROL) return;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "users/" + username + "/password",
|
||||
url: API_BASEURL + "users/" + username + "/password",
|
||||
type: "PUT",
|
||||
contentType: "application/json; charset=UTF-8",
|
||||
data: JSON.stringify({password: password}),
|
||||
|
|
@ -216,7 +216,7 @@ function UsersViewModel(loginStateViewModel) {
|
|||
if (!CONFIG_ACCESS_CONTROL) return;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "users/" + username + "/apikey",
|
||||
url: API_BASEURL + "users/" + username + "/apikey",
|
||||
type: "POST",
|
||||
success: callback
|
||||
});
|
||||
|
|
@ -226,7 +226,7 @@ function UsersViewModel(loginStateViewModel) {
|
|||
if (!CONFIG_ACCESS_CONTROL) return;
|
||||
|
||||
$.ajax({
|
||||
url: AJAX_BASEURL + "users/" + username + "/apikey",
|
||||
url: API_BASEURL + "users/" + username + "/apikey",
|
||||
type: "DELETE",
|
||||
success: callback
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<script lang="javascript">
|
||||
var BASEURL = "{{ url_for('index') }}";
|
||||
var AJAX_BASEURL = BASEURL + "ajax/";
|
||||
var API_BASEURL = BASEURL + "ajax/";
|
||||
|
||||
var CONFIG_GCODEFILESPERPAGE = 5;
|
||||
var CONFIG_TIMELAPSEFILESPERPAGE = 10;
|
||||
|
|
|
|||
|
|
@ -252,11 +252,13 @@ class Timelapse(object):
|
|||
# finalize command with output file
|
||||
self._logger.debug("Rendering movie to %s" % output)
|
||||
command.append(output)
|
||||
eventManager().fire("MovieRendering", {"gcode": self._gcodeFile, "movie": output, "movie_basename": os.path.basename(output)})
|
||||
try:
|
||||
subprocess.check_call(command)
|
||||
eventManager().fire("MovieDone", output)
|
||||
eventManager().fire("MovieDone", {"gcode": self._gcodeFile, "movie": output, "movie_basename": os.path.basename(output)})
|
||||
except subprocess.CalledProcessError as (e):
|
||||
self._logger.warn("Could not render movie, got return code %r" % e.returncode)
|
||||
eventManager().fire("MovieFailed", {"gcode": self._gcodeFile, "movie": output, "movie_basename": os.path.basename(output), "returncode": e.returncode})
|
||||
|
||||
def cleanCaptureDir(self):
|
||||
if not os.path.isdir(self._captureDir):
|
||||
|
|
|
|||
Loading…
Reference in a new issue