diff --git a/octoprint/gcodefiles.py b/octoprint/gcodefiles.py index 6f64284..b44f2a3 100644 --- a/octoprint/gcodefiles.py +++ b/octoprint/gcodefiles.py @@ -116,28 +116,43 @@ class GcodeManager: #~~ file handling def addFile(self, file): - if file: - absolutePath = self.getAbsolutePath(file.filename, mustExist=False) - if absolutePath is not None: - if file.filename in self._metadata.keys(): - # delete existing metadata entry, since the file is going to get overwritten - del self._metadata[file.filename] - self._metadataDirty = True - self._saveMetadata() - file.save(absolutePath) - self._metadataAnalyzer.addFileToQueue(os.path.basename(absolutePath)) - return self._getBasicFilename(absolutePath) - return None + if not file: + return None + + absolutePath = self.getAbsolutePath(file.filename, mustExist=False) + if absolutePath is None: + return None + + if file.filename in self._metadata.keys(): + # delete existing metadata entry, since the file is going to get overwritten + del self._metadata[file.filename] + self._metadataDirty = True + self._saveMetadata() + file.save(absolutePath) + self._metadataAnalyzer.addFileToQueue(os.path.basename(absolutePath)) + return self._getBasicFilename(absolutePath) + + def getFutureFilename(self, file): + if not file: + return None + + absolutePath = self.getAbsolutePath(file.filename, mustExist=False) + if absolutePath is None: + return None + + return self._getBasicFilename(absolutePath) def removeFile(self, filename): filename = self._getBasicFilename(filename) absolutePath = self.getAbsolutePath(filename) - if absolutePath is not None: - os.remove(absolutePath) - if filename in self._metadata.keys(): - del self._metadata[filename] - self._metadataDirty = True - self._saveMetadata() + if absolutePath is None: + return + + os.remove(absolutePath) + if filename in self._metadata.keys(): + del self._metadata[filename] + self._metadataDirty = True + self._saveMetadata() def getAbsolutePath(self, filename, mustExist=True): """ diff --git a/octoprint/printer.py b/octoprint/printer.py index 7899d23..fecc841 100644 --- a/octoprint/printer.py +++ b/octoprint/printer.py @@ -171,6 +171,16 @@ class Printer(): self._printAfterSelect = printAfterSelect self._comm.selectFile(filename, sd) + self._setProgressData(0, None, None, None) + self._setCurrentZ(None) + + def unselectFile(self): + if self._comm is not None and (self._comm.isBusy() or self._comm.isStreaming()): + return + + self._comm.unselectFile() + self._setProgressData(0, None, None, None) + self._setCurrentZ(None) def startPrint(self): """ diff --git a/octoprint/server.py b/octoprint/server.py index ab1ba0f..88b553b 100644 --- a/octoprint/server.py +++ b/octoprint/server.py @@ -4,7 +4,7 @@ __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agp from werkzeug.utils import secure_filename import tornadio2 -from flask import Flask, request, render_template, jsonify, send_from_directory, url_for, current_app, session, abort +from flask import Flask, request, render_template, jsonify, send_from_directory, url_for, current_app, session, abort, make_response from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user from flask.ext.principal import Principal, Permission, RoleNeed, Identity, identity_changed, AnonymousIdentity, identity_loaded, UserNeed @@ -310,12 +310,39 @@ def readGcodeFile(filename): @app.route(BASEURL + "gcodefiles/upload", methods=["POST"]) @login_required def uploadGcodeFile(): - filename = None if "gcode_file" in request.files.keys(): file = request.files["gcode_file"] + sd = "target" in request.values.keys() and request.values["target"] == "sd"; + + currentFilename = None + currentSd = None + currentJob = printer.getCurrentJob() + if currentJob is not None and "filename" in currentJob.keys() and "sd" in currentJob.keys(): + currentFilename = currentJob["filename"] + currentSd = currentJob["sd"] + + futureFilename = gcodeManager.getFutureFilename(file) + if futureFilename is None: + return make_response("Can not upload file %s, wrong format?" % file.filename, 400) + + if futureFilename == currentFilename and sd == currentSd and printer.isPrinting() or printer.isPaused(): + # trying to overwrite currently selected file, but it is being printed + return make_response("Trying to overwrite file that is currently being printed: %s" % currentFilename, 403) + filename = gcodeManager.addFile(file) - if filename and "target" in request.values.keys() and request.values["target"] == "sd": - printer.addSdFile(filename, gcodeManager.getAbsolutePath(filename)) + if filename is None: + return make_response("Could not upload the file %s" % file.filename, 500) + + absFilename = gcodeManager.getAbsolutePath(filename) + if sd: + printer.addSdFile(filename, absFilename) + + if currentFilename == filename and currentSd == sd: + # reload file as it was updated + if sd: + printer.selectFile(filename, sd, False) + else: + printer.selectFile(absFilename, sd, False) global eventManager eventManager.fire("Upload", filename) @@ -331,7 +358,6 @@ def loadGcodeFile(): printAfterLoading = True sd = False - filename = None if "target" in request.values.keys() and request.values["target"] == "sd": filename = request.values["filename"] sd = True @@ -345,18 +371,23 @@ def loadGcodeFile(): def deleteGcodeFile(): if "filename" in request.values.keys(): filename = request.values["filename"] - currentJob = printer.getCurrentJob() + sd = "target" in request.values.keys() and request.values["target"] == "sd" + currentJob = printer.getCurrentJob() currentFilename = None currentSd = None if currentJob is not None and "filename" in currentJob.keys() and "sd" in currentJob.keys(): currentFilename = currentJob["filename"] currentSd = currentJob["sd"] - if "target" in request.values.keys() and request.values["target"] == "sd" and not (currentFilename == filename and currentSd is True): - printer.deleteSdFile(filename) - elif not (currentFilename == filename and currentSd is False): - gcodeManager.removeFile(filename) + if currentFilename is not None and filename == currentFilename and not (printer.isPrinting() or printer.isPaused()): + printer.unselectFile() + + if not (currentFilename == filename and currentSd == sd and (printer.isPrinting() or printer.isPaused())): + if currentSd: + printer.deleteSdFile(filename) + else: + gcodeManager.removeFile(filename) return readGcodeFiles() @app.route(BASEURL + "gcodefiles/refresh", methods=["POST"]) diff --git a/octoprint/static/js/ui.js b/octoprint/static/js/ui.js index b1403c8..4040f32 100644 --- a/octoprint/static/js/ui.js +++ b/octoprint/static/js/ui.js @@ -956,6 +956,15 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel) { return data["prints"]["last"]["success"] ? "text-success" : "text-error"; } + self.enableRemove = function(data) { + return self.loginState.isUser() && !(self.listHelper.isSelected(data) && (self.isPrinting() || self.isPaused())); + } + + self.enableSelect = function(data, printAfterSelect) { + var isLoadActionPossible = self.loginState.isUser() && !(self.isPrinting() || self.isPaused() || self.isLoading()); + return isLoadActionPossible && !self.listHelper.isSelected(data); + } + } function TimelapseViewModel(loginStateViewModel) { diff --git a/octoprint/templates/index.jinja2 b/octoprint/templates/index.jinja2 index 2516bfa..3cfa071 100644 --- a/octoprint/templates/index.jinja2 +++ b/octoprint/templates/index.jinja2 @@ -181,7 +181,7 @@ -  |  |  +  |  |  diff --git a/octoprint/util/comm.py b/octoprint/util/comm.py index ea8d8ab..32f66c7 100644 --- a/octoprint/util/comm.py +++ b/octoprint/util/comm.py @@ -356,6 +356,14 @@ class MachineCom(object): eventManager().fire("FileSelected", filename) self._callback.mcFileSelected(filename, self._currentFile.getFilesize(), False) + def unselectFile(self): + if self.isBusy(): + return + + self._currentFile = None + eventManager().fire("FileSelected", None) + self._callback.mcFileSelected(None, None, False) + def cancelPrint(self): if not self.isOperational() or self.isStreaming(): return