Overall better gcode file handling
See #182 and https://groups.google.com/forum/#!topic/octoprint/YnOzyToxfkImaster
parent
c6a749c684
commit
22ea55746c
|
@ -116,9 +116,13 @@ class GcodeManager:
|
||||||
#~~ file handling
|
#~~ file handling
|
||||||
|
|
||||||
def addFile(self, file):
|
def addFile(self, file):
|
||||||
if file:
|
if not file:
|
||||||
|
return None
|
||||||
|
|
||||||
absolutePath = self.getAbsolutePath(file.filename, mustExist=False)
|
absolutePath = self.getAbsolutePath(file.filename, mustExist=False)
|
||||||
if absolutePath is not None:
|
if absolutePath is None:
|
||||||
|
return None
|
||||||
|
|
||||||
if file.filename in self._metadata.keys():
|
if file.filename in self._metadata.keys():
|
||||||
# delete existing metadata entry, since the file is going to get overwritten
|
# delete existing metadata entry, since the file is going to get overwritten
|
||||||
del self._metadata[file.filename]
|
del self._metadata[file.filename]
|
||||||
|
@ -127,12 +131,23 @@ class GcodeManager:
|
||||||
file.save(absolutePath)
|
file.save(absolutePath)
|
||||||
self._metadataAnalyzer.addFileToQueue(os.path.basename(absolutePath))
|
self._metadataAnalyzer.addFileToQueue(os.path.basename(absolutePath))
|
||||||
return self._getBasicFilename(absolutePath)
|
return self._getBasicFilename(absolutePath)
|
||||||
|
|
||||||
|
def getFutureFilename(self, file):
|
||||||
|
if not file:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
absolutePath = self.getAbsolutePath(file.filename, mustExist=False)
|
||||||
|
if absolutePath is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self._getBasicFilename(absolutePath)
|
||||||
|
|
||||||
def removeFile(self, filename):
|
def removeFile(self, filename):
|
||||||
filename = self._getBasicFilename(filename)
|
filename = self._getBasicFilename(filename)
|
||||||
absolutePath = self.getAbsolutePath(filename)
|
absolutePath = self.getAbsolutePath(filename)
|
||||||
if absolutePath is not None:
|
if absolutePath is None:
|
||||||
|
return
|
||||||
|
|
||||||
os.remove(absolutePath)
|
os.remove(absolutePath)
|
||||||
if filename in self._metadata.keys():
|
if filename in self._metadata.keys():
|
||||||
del self._metadata[filename]
|
del self._metadata[filename]
|
||||||
|
|
|
@ -171,6 +171,16 @@ class Printer():
|
||||||
|
|
||||||
self._printAfterSelect = printAfterSelect
|
self._printAfterSelect = printAfterSelect
|
||||||
self._comm.selectFile(filename, sd)
|
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):
|
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
|
from werkzeug.utils import secure_filename
|
||||||
import tornadio2
|
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.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
|
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"])
|
@app.route(BASEURL + "gcodefiles/upload", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def uploadGcodeFile():
|
def uploadGcodeFile():
|
||||||
filename = None
|
|
||||||
if "gcode_file" in request.files.keys():
|
if "gcode_file" in request.files.keys():
|
||||||
file = request.files["gcode_file"]
|
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)
|
filename = gcodeManager.addFile(file)
|
||||||
if filename and "target" in request.values.keys() and request.values["target"] == "sd":
|
if filename is None:
|
||||||
printer.addSdFile(filename, gcodeManager.getAbsolutePath(filename))
|
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
|
global eventManager
|
||||||
eventManager.fire("Upload", filename)
|
eventManager.fire("Upload", filename)
|
||||||
|
@ -331,7 +358,6 @@ def loadGcodeFile():
|
||||||
printAfterLoading = True
|
printAfterLoading = True
|
||||||
|
|
||||||
sd = False
|
sd = False
|
||||||
filename = None
|
|
||||||
if "target" in request.values.keys() and request.values["target"] == "sd":
|
if "target" in request.values.keys() and request.values["target"] == "sd":
|
||||||
filename = request.values["filename"]
|
filename = request.values["filename"]
|
||||||
sd = True
|
sd = True
|
||||||
|
@ -345,17 +371,22 @@ def loadGcodeFile():
|
||||||
def deleteGcodeFile():
|
def deleteGcodeFile():
|
||||||
if "filename" in request.values.keys():
|
if "filename" in request.values.keys():
|
||||||
filename = request.values["filename"]
|
filename = request.values["filename"]
|
||||||
currentJob = printer.getCurrentJob()
|
sd = "target" in request.values.keys() and request.values["target"] == "sd"
|
||||||
|
|
||||||
|
currentJob = printer.getCurrentJob()
|
||||||
currentFilename = None
|
currentFilename = None
|
||||||
currentSd = None
|
currentSd = None
|
||||||
if currentJob is not None and "filename" in currentJob.keys() and "sd" in currentJob.keys():
|
if currentJob is not None and "filename" in currentJob.keys() and "sd" in currentJob.keys():
|
||||||
currentFilename = currentJob["filename"]
|
currentFilename = currentJob["filename"]
|
||||||
currentSd = currentJob["sd"]
|
currentSd = currentJob["sd"]
|
||||||
|
|
||||||
if "target" in request.values.keys() and request.values["target"] == "sd" and not (currentFilename == filename and currentSd is True):
|
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)
|
printer.deleteSdFile(filename)
|
||||||
elif not (currentFilename == filename and currentSd is False):
|
else:
|
||||||
gcodeManager.removeFile(filename)
|
gcodeManager.removeFile(filename)
|
||||||
return readGcodeFiles()
|
return readGcodeFiles()
|
||||||
|
|
||||||
|
|
|
@ -956,6 +956,15 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel) {
|
||||||
return data["prints"]["last"]["success"] ? "text-success" : "text-error";
|
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) {
|
function TimelapseViewModel(loginStateViewModel) {
|
||||||
|
|
|
@ -181,7 +181,7 @@
|
||||||
<td class="gcode_files_name" data-bind="text: name"></td>
|
<td class="gcode_files_name" data-bind="text: name"></td>
|
||||||
<td class="gcode_files_size" data-bind="text: size"></td>
|
<td class="gcode_files_size" data-bind="text: size"></td>
|
||||||
<td class="gcode_files_action">
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -356,6 +356,14 @@ class MachineCom(object):
|
||||||
eventManager().fire("FileSelected", filename)
|
eventManager().fire("FileSelected", filename)
|
||||||
self._callback.mcFileSelected(filename, self._currentFile.getFilesize(), False)
|
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):
|
def cancelPrint(self):
|
||||||
if not self.isOperational() or self.isStreaming():
|
if not self.isOperational() or self.isStreaming():
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue