Overall better gcode file handling
See #182 and https://groups.google.com/forum/#!topic/octoprint/YnOzyToxfkImaster
parent
c6a749c684
commit
22ea55746c
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -181,7 +181,7 @@
|
|||
<td class="gcode_files_name" data-bind="text: name"></td>
|
||||
<td class="gcode_files_size" data-bind="text: size"></td>
|
||||
<td class="gcode_files_action">
|
||||
<a href="#" class="icon-trash" title="Remove" data-bind="click: function() { if ($root.loginState.isUser() && !$root.listHelper.isSelected($data)) { $root.removeFile($data.name); } else { return; } }, css: {disabled: !$root.loginState.isUser() || $root.listHelper.isSelected($data)}"></a> | <a href="#" class="icon-folder-open" title="Load" data-bind="click: function() { if ($root.isLoadActionPossible() && !$root.listHelper.isSelected($data)) { $root.loadFile($data.name, false); } else { return; } }, css: {disabled: !$root.isLoadActionPossible() || $root.listHelper.isSelected($data)}"></a> | <a href="#" class="icon-print" title="Load and Print" data-bind="click: function() { if ($root.isLoadAndPrintActionPossible() && !$root.listHelper.isSelected($data)) { $root.loadFile($data.name, true); } else { return; } }, css: {disabled: !$root.isLoadAndPrintActionPossible() || $root.listHelper.isSelected($data)}"></a>
|
||||
<a href="#" class="icon-trash" title="Remove" data-bind="click: function() { if ($root.enableRemove($data)) { $root.removeFile($data.name); } else { return; } }, css: {disabled: !$root.enableRemove($data)}"></a> | <a href="#" class="icon-folder-open" title="Load" data-bind="click: function() { if ($root.enableSelect($data)) { $root.loadFile($data.name, false); } else { return; } }, css: {disabled: !$root.enableSelect($data)}"></a> | <a href="#" class="icon-print" title="Load and Print" data-bind="click: function() { if ($root.enableSelect($data)) { $root.loadFile($data.name, true); } else { return; } }, css: {disabled: !$root.enableSelect($data)}"></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue