A couple of manual merges...
This commit is contained in:
parent
df269eb4f7
commit
64084bb628
5 changed files with 80 additions and 60 deletions
|
|
@ -14,6 +14,7 @@ import octoprint.util.gcodeInterpreter as gcodeInterpreter
|
|||
|
||||
from octoprint.settings import settings
|
||||
from octoprint.events import eventManager
|
||||
from octoprint.filemanager.destinations import FileDestinations
|
||||
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
|
|
@ -165,9 +166,15 @@ class GcodeManager:
|
|||
|
||||
#~~ file handling
|
||||
|
||||
def addFile(self, file, destination):
|
||||
from octoprint.filemanager.destinations import FileDestinations
|
||||
def addFile(self, file, destination, uploadCallback=None):
|
||||
"""
|
||||
Adds the given file for the given destination to the systems. Takes care of slicing if enabled and
|
||||
necessary.
|
||||
|
||||
If the file's processing won't be finished directly with the return from this method but happen
|
||||
asynchronously in the background (e.g. due to slicing), returns a tuple containing the just added file's
|
||||
filename and False. Otherwise returns a tuple (filename, True).
|
||||
"""
|
||||
if not file or not destination:
|
||||
return None, True
|
||||
|
||||
|
|
@ -183,11 +190,10 @@ class GcodeManager:
|
|||
file.save(absolutePath)
|
||||
|
||||
if gcode:
|
||||
return self.processGcode(absolutePath), True
|
||||
return self.processGcode(absolutePath, destination, uploadCallback), True
|
||||
else:
|
||||
local = (destination == FileDestinations.LOCAL)
|
||||
if curaEnabled and isSTLFileName(filename) and local:
|
||||
self.processStl(absolutePath)
|
||||
if curaEnabled and isSTLFileName(filename):
|
||||
self.processStl(absolutePath, destination, uploadCallback)
|
||||
return filename, False
|
||||
|
||||
|
||||
|
|
@ -202,7 +208,7 @@ class GcodeManager:
|
|||
return self._getBasicFilename(absolutePath)
|
||||
|
||||
|
||||
def processStl(self, absolutePath):
|
||||
def processStl(self, absolutePath, destination, uploadCallback=None):
|
||||
from octoprint.slicers.cura import CuraFactory
|
||||
|
||||
cura = CuraFactory.create_slicer()
|
||||
|
|
@ -210,6 +216,7 @@ class GcodeManager:
|
|||
config = self._settings.get(["cura", "config"])
|
||||
|
||||
slicingStart = time.time()
|
||||
|
||||
def stlProcessed(stlPath, gcodePath, error=None):
|
||||
if error:
|
||||
eventManager().fire("SlicingFailed", {"stl": self._getBasicFilename(stlPath), "gcode": self._getBasicFilename(gcodePath), "reason": error})
|
||||
|
|
@ -218,13 +225,13 @@ class GcodeManager:
|
|||
else:
|
||||
slicingStop = time.time()
|
||||
eventManager().fire("SlicingDone", {"stl": self._getBasicFilename(stlPath), "gcode": self._getBasicFilename(gcodePath), "time": "%.2f" % (slicingStop - slicingStart)})
|
||||
self.processGcode(gcodePath)
|
||||
self.processGcode(gcodePath, destination, uploadCallback)
|
||||
|
||||
eventManager().fire("SlicingStarted", {"stl": self._getBasicFilename(absolutePath), "gcode": self._getBasicFilename(gcodePath)})
|
||||
cura.process_file(config, gcodePath, absolutePath, stlProcessed, [absolutePath, gcodePath])
|
||||
|
||||
|
||||
def processGcode(self, absolutePath):
|
||||
def processGcode(self, absolutePath, destination, uploadCallback=None):
|
||||
if absolutePath is None:
|
||||
return None
|
||||
|
||||
|
|
@ -238,7 +245,9 @@ class GcodeManager:
|
|||
|
||||
self._metadataAnalyzer.addFileToQueue(os.path.basename(absolutePath))
|
||||
|
||||
return filename
|
||||
if uploadCallback is not None:
|
||||
uploadCallback(filename, absolutePath, destination)
|
||||
return filename
|
||||
|
||||
def getFutureFilename(self, file):
|
||||
if not file:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import octoprint.util as util
|
|||
from octoprint.settings import settings
|
||||
from octoprint.events import eventManager
|
||||
|
||||
from octoprint.filemanager.destinations import FileDestinations
|
||||
|
||||
def getConnectionOptions():
|
||||
"""
|
||||
Retrieves the available ports, baudrates, prefered port and baudrate for connecting to the printer.
|
||||
|
|
@ -71,6 +73,8 @@ class Printer():
|
|||
self._sdPrinting = False
|
||||
self._sdStreaming = False
|
||||
self._sdFilelistAvailable = threading.Event()
|
||||
self._sdRemoteName = None
|
||||
self._streamingFinishedCallback = None
|
||||
|
||||
self._selectedFile = None
|
||||
|
||||
|
|
@ -458,6 +462,10 @@ class Printer():
|
|||
def mcFileTransferDone(self):
|
||||
self._sdStreaming = False
|
||||
|
||||
if self._streamingFinishedCallback is not None:
|
||||
self._streamingFinishedCallback(self._sdRemoteName, FileDestinations.SDCARD)
|
||||
|
||||
self._sdRemoteName = None
|
||||
self._setCurrentZ(None)
|
||||
self._setJobData(None, None, None)
|
||||
self._setProgressData(None, None, None, None)
|
||||
|
|
@ -473,35 +481,18 @@ class Printer():
|
|||
return []
|
||||
return self._comm.getSdFiles()
|
||||
|
||||
def addSdFile(self, filename, absolutePath):
|
||||
from octoprint.gcodefiles import isGcodeFileName
|
||||
from octoprint.gcodefiles import isSTLFileName
|
||||
|
||||
def addSdFile(self, filename, absolutePath, streamingFinishedCallback):
|
||||
if not self._comm or self._comm.isBusy() or not self._comm.isSdReady():
|
||||
logging.error("No connection to printer or printer is busy")
|
||||
return
|
||||
|
||||
if isGcodeFileName(filename):
|
||||
self.streamSdFile(filename, absolutePath)
|
||||
|
||||
if isSTLFileName(filename):
|
||||
gcodePath = util.genGcodeFileName(absolutePath)
|
||||
gcodeFileName = util.genGcodeFileName(filename)
|
||||
callBackArgs = [gcodeFileName, gcodePath]
|
||||
callBack = self.streamSdFile
|
||||
|
||||
self._gcodeManager.processStl(
|
||||
absolutePath, callBack, callBackArgs)
|
||||
|
||||
def streamSdFile(self, filename, path):
|
||||
if not self._comm or self._comm.isBusy() or not self._comm.isSdReady():
|
||||
return
|
||||
self._streamingFinishedCallback = streamingFinishedCallback
|
||||
|
||||
self.refreshSdFiles(blocking=True)
|
||||
existingSdFiles = self._comm.getSdFiles()
|
||||
|
||||
sdFilename = util.getDosFilename(filename, existingSdFiles)
|
||||
self._comm.startFileTransfer(path, sdFilename)
|
||||
self._sdRemoteName = util.getDosFilename(filename, existingSdFiles)
|
||||
self._comm.startFileTransfer(absolutePath, self._sdRemoteName)
|
||||
|
||||
def deleteSdFile(self, filename):
|
||||
if not self._comm or not self._comm.isSdReady():
|
||||
|
|
|
|||
|
|
@ -33,18 +33,19 @@ def readGcodeFiles():
|
|||
return jsonify(files=files, free=util.getFormattedSize(util.getFreeBytes(settings().getBaseFolder("uploads"))))
|
||||
|
||||
|
||||
@ajax.route("/gcodefiles/<path:filename>", methods=["GET"])
|
||||
def readGcodeFile(filename):
|
||||
return redirectToTornado(request, url_for("index") + "downloads/gcode/" + filename)
|
||||
|
||||
|
||||
@ajax.route("/gcodefiles/upload", methods=["POST"])
|
||||
@ajax.route("/gcodefiles/<string:target>", methods=["POST"])
|
||||
@restricted_access
|
||||
def uploadGcodeFile():
|
||||
def uploadGcodeFile(target):
|
||||
if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]:
|
||||
return make_response("Invalid target: %s" % target, 400)
|
||||
|
||||
if "gcode_file" in request.files.keys():
|
||||
file = request.files["gcode_file"]
|
||||
sd = "target" in request.values.keys() and request.values["target"] == "sd";
|
||||
sd = target == FileDestinations.SDCARD
|
||||
selectAfterUpload = "select" in request.values.keys() and request.values["select"] in valid_boolean_trues
|
||||
printAfterSelect = "print" in request.values.keys() and request.values["print"] in valid_boolean_trues
|
||||
|
||||
# determine current job
|
||||
currentFilename = None
|
||||
currentSd = None
|
||||
currentJob = printer.getCurrentJob()
|
||||
|
|
@ -52,34 +53,52 @@ def uploadGcodeFile():
|
|||
currentFilename = currentJob["filename"]
|
||||
currentSd = currentJob["sd"]
|
||||
|
||||
# determine future filename of file to be uploaded, abort if it can't be uploaded
|
||||
futureFilename = gcodeManager.getFutureFilename(file)
|
||||
if futureFilename is None or (not settings().getBoolean(["cura", "enabled"]) and not gcodefiles.isGcodeFileName(futureFilename)):
|
||||
return make_response("Can not upload file %s, wrong format?" % file.filename, 400)
|
||||
|
||||
# prohibit overwriting currently selected file while it's being printed
|
||||
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 = None
|
||||
|
||||
def fileProcessingFinished(filename, absFilename, destination):
|
||||
"""
|
||||
Callback for when the file processing (upload, optional slicing, addition to analysis queue) has
|
||||
finished.
|
||||
|
||||
Depending on the file's destination triggers either streaming to SD card or directly calls selectOrPrint.
|
||||
"""
|
||||
sd = destination == FileDestinations.SDCARD
|
||||
if sd:
|
||||
printer.addSdFile(filename, absFilename, selectAndOrPrint)
|
||||
else:
|
||||
selectAndOrPrint(absFilename, destination)
|
||||
|
||||
def selectAndOrPrint(nameToSelect, destination):
|
||||
"""
|
||||
Callback for when the file is ready to be selected and optionally printed. For SD file uploads this only
|
||||
the case after they have finished streaming to the printer, which is why this callback is also used
|
||||
for the corresponding call to addSdFile.
|
||||
|
||||
Selects the just uploaded file if either selectAfterUpload or printAfterSelect are True, or if the
|
||||
exact file is already selected, such reloading it.
|
||||
"""
|
||||
sd = destination == FileDestinations.SDCARD
|
||||
if selectAfterUpload or printAfterSelect or (currentFilename == filename and currentSd == sd):
|
||||
printer.selectFile(nameToSelect, sd, printAfterSelect)
|
||||
|
||||
destination = FileDestinations.SDCARD if sd else FileDestinations.LOCAL
|
||||
|
||||
filename, done = gcodeManager.addFile(file, destination)
|
||||
|
||||
filename, done = gcodeManager.addFile(file, destination, fileProcessingFinished)
|
||||
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)
|
||||
|
||||
eventManager.fire("Upload", filename)
|
||||
return jsonify(files=gcodeManager.getAllFileData(), filename=filename, done=done)
|
||||
return jsonify(files=gcodeManager.getAllFileData(), filename=filename, done=done)
|
||||
else:
|
||||
return make_response("No gcode_file included", 400)
|
||||
|
||||
|
||||
@ajax.route("/gcodefiles/load", methods=["POST"])
|
||||
|
|
|
|||
|
|
@ -107,9 +107,9 @@ $(function() {
|
|||
|
||||
function enable_local_dropzone() {
|
||||
$("#gcode_upload").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/local",
|
||||
dataType: "json",
|
||||
dropZone: localTarget,
|
||||
formData: {target: "local"},
|
||||
done: gcode_upload_done,
|
||||
fail: gcode_upload_fail,
|
||||
progressall: gcode_upload_progress
|
||||
|
|
@ -118,9 +118,9 @@ $(function() {
|
|||
|
||||
function disable_local_dropzone() {
|
||||
$("#gcode_upload").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/local",
|
||||
dataType: "json",
|
||||
dropZone: null,
|
||||
formData: {target: "local"},
|
||||
done: gcode_upload_done,
|
||||
fail: gcode_upload_fail,
|
||||
progressall: gcode_upload_progress
|
||||
|
|
@ -129,9 +129,9 @@ $(function() {
|
|||
|
||||
function enable_sd_dropzone() {
|
||||
$("#gcode_upload_sd").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/sdcard",
|
||||
dataType: "json",
|
||||
dropZone: $("#drop_sd"),
|
||||
formData: {target: "sd"},
|
||||
done: gcode_upload_done,
|
||||
fail: gcode_upload_fail,
|
||||
progressall: gcode_upload_progress
|
||||
|
|
@ -140,6 +140,7 @@ $(function() {
|
|||
|
||||
function disable_sd_dropzone() {
|
||||
$("#gcode_upload_sd").fileupload({
|
||||
url: AJAX_BASEURL + "gcodefiles/sdcard",
|
||||
dataType: "json",
|
||||
dropZone: null,
|
||||
formData: {target: "sd"},
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ function GcodeFilesViewModel(printerStateViewModel, loginStateViewModel) {
|
|||
return !(file["prints"] && file["prints"]["success"] && file["prints"]["success"] > 0);
|
||||
},
|
||||
"sd": function(file) {
|
||||
return file["origin"] && file["origin"] == "sd";
|
||||
return file["origin"] && file["origin"] == "sdcard";
|
||||
},
|
||||
"local": function(file) {
|
||||
return !(file["origin"] && file["origin"] == "sd");
|
||||
return !(file["origin"] && file["origin"] == "sdcard");
|
||||
}
|
||||
},
|
||||
"name",
|
||||
|
|
|
|||
Loading…
Reference in a new issue