def test_isGcode(self): from octoprint.gcodefiles import isGcodeFileName filename = "/asdj/wefasdf/junk.stl" result = isGcodeFileName(filename) self.assertFalse(result) filename = "/asdj/wefasdf/junk.gcode" result = isGcodeFileName(filename) self.assertTrue(result)
def apiLoad(): logger = logging.getLogger(__name__) if not settings.get("api", "enabled"): abort(401) if not "apikey" in request.values.keys(): abort(401) if request.values["apikey"] != settings.get("api", "key"): abort(403) if not "file" in request.files.keys(): abort(400) # Perform an upload file = request.files["file"] if not gcodefiles.isGcodeFileName(file.filename): abort(400) destination = FileDestinations.LOCAL filename, done = gcodeManager.addFile(file, destination) if filename is None: logger.warn("Upload via API failed") abort(500) # Immediately perform a file select and possibly print too printAfterSelect = False if "print" in request.values.keys() and request.values["print"] in valid_boolean_trues: printAfterSelect = True filepath = gcodeManager.getAbsolutePath(filename) if filepath is not None: printer.selectFile(filepath, False, printAfterSelect) return jsonify(SUCCESS)
def apiLoad(): logger = logging.getLogger(__name__) if not settings().get(["api", "enabled"]): abort(401) if not "apikey" in request.values.keys(): abort(401) if request.values["apikey"] != settings().get(["api", "key"]): abort(403) if not "file" in request.files.keys(): abort(400) # Perform an upload file = request.files["file"] if not gcodefiles.isGcodeFileName(file.filename): abort(400) destination = FileDestinations.LOCAL filename, done = gcodeManager.addFile(file, destination) if filename is None: logger.warn("Upload via API failed") abort(500) # Immediately perform a file select and possibly print too printAfterSelect = False if "print" in request.values.keys( ) and request.values["print"] in valid_boolean_trues: printAfterSelect = True filepath = gcodeManager.getAbsolutePath(filename) if filepath is not None: printer.selectFile(filepath, False, printAfterSelect) return jsonify(SUCCESS)
def _upload(self, path): class WatchdogFileWrapper(object): def __init__(self, path): self._path = path self.filename = os.path.basename(self._path) def save(self, target): util.safeRename(self._path, target) fileWrapper = WatchdogFileWrapper(path) # determine current job currentFilename = None currentOrigin = None currentJob = self._printer.getCurrentJob() if currentJob is not None and "file" in currentJob.keys(): currentJobFile = currentJob["file"] if "name" in currentJobFile.keys( ) and "origin" in currentJobFile.keys(): currentFilename = currentJobFile["name"] currentOrigin = currentJobFile["origin"] # determine future filename of file to be uploaded, abort if it can't be uploaded futureFilename = self._gcodeManager.getFutureFilename(fileWrapper) if futureFilename is None or ( not settings().getBoolean(["cura", "enabled"]) and not gcodefiles.isGcodeFileName(futureFilename)): self._logger.warn("Could not add %s: Invalid file" % fileWrapper.filename) return # prohibit overwriting currently selected file while it's being printed if futureFilename == currentFilename and not currentOrigin == FileDestinations.SDCARD and self._printer.isPrinting( ) or self._printer.isPaused(): self._logger.warn( "Could not add %s: Trying to overwrite file that is currently being printed" % fileWrapper.filename) return self._gcodeManager.addFile(fileWrapper, FileDestinations.LOCAL)
def uploadGcodeFile(target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) if not "file" in request.files.keys(): return make_response("No file included", 400) if target == FileDestinations.SDCARD and not settings().getBoolean(["feature", "sdSupport"]): return make_response("SD card support is disabled", 404) file = request.files["file"] 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 if sd: # validate that all preconditions for SD upload are met before attempting it if not (printer.isOperational() and not (printer.isPrinting() or printer.isPaused())): return make_response("Can not upload to SD card, printer is either not operational or already busy", 409) if not printer.isSdReady(): return make_response("Can not upload to SD card, not yet initialized", 409) # determine current job 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"] # 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, 415) # prohibit overwriting currently selected file while it's being printed if futureFilename == currentFilename and sd == currentSd and printer.isPrinting() or printer.isPaused(): return make_response("Trying to overwrite file that is currently being printed: %s" % currentFilename, 409) 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 selectAndOrPrint. """ if destination == FileDestinations.SDCARD: return filename, printer.addSdFile(filename, absFilename, selectAndOrPrint) else: selectAndOrPrint(absFilename, destination) return filename def selectAndOrPrint(nameToSelect, destination): """ Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is 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, fileProcessingFinished) if filename is None: return make_response("Could not upload the file %s" % file.filename, 500) sdFilename = None if isinstance(filename, tuple): filename, sdFilename = filename eventManager.fire(Events.UPLOAD, {"file": filename, "target": target}) files = {} if done: files.update({ FileDestinations.LOCAL: { "name": filename, "origin": FileDestinations.LOCAL, "refs": { "resource": url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=filename, _external=True), "download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + filename } } }) if sd and sdFilename: files.update({ FileDestinations.SDCARD: { "name": sdFilename, "origin": FileDestinations.SDCARD, "refs": { "resource": url_for(".readGcodeFile", target=FileDestinations.SDCARD, filename=sdFilename, _external=True) } } }) return make_response(jsonify(files=files, done=done), 201)
def _monitor(self): feedbackControls = settings().getFeedbackControls() pauseTriggers = settings().getPauseTriggers() feedbackErrors = [] #Open the serial port. if not self._openSerial(): return self._log("Connected to: %s, starting monitor" % self._serial) if self._baudrate == 0: self._log("Starting baud rate detection") self._changeState(self.STATE_DETECT_BAUDRATE) else: self._changeState(self.STATE_CONNECTING) #Start monitoring the serial port. timeout = getNewTimeout("communication") tempRequestTimeout = getNewTimeout("temperature") sdStatusRequestTimeout = getNewTimeout("sdStatus") startSeen = not settings().getBoolean(["feature", "waitForStartOnConnect"]) heatingUp = False swallowOk = False supportRepetierTargetTemp = settings().getBoolean(["feature", "repetierTargetTemp"]) while True: try: line = self._readline() if line is None: break if line.strip() is not "": timeout = getNewTimeout("communication") ##~~ Error handling line = self._handleErrors(line) ##~~ SD file list # if we are currently receiving an sd file list, each line is just a filename, so just read it and abort processing if self._sdFileList and isGcodeFileName(line.strip().lower()) and not 'End file list' in line: filename = line.strip().lower() if filterNonAscii(filename): self._logger.warn("Got a file from printer's SD that has a non-ascii filename (%s), that shouldn't happen according to the protocol" % filename) else: self._sdFiles.append(filename) continue ##~~ Temperature processing if ' T:' in line or line.startswith('T:') or ' T0:' in line or line.startswith('T0:'): self._processTemperatures(line) self._callback.mcTempUpdate(self._temp, self._bedTemp) #If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate. if not 'ok' in line: heatingUp = True if self._heatupWaitStartTime != 0: t = time.time() self._heatupWaitTimeLost = t - self._heatupWaitStartTime self._heatupWaitStartTime = t elif supportRepetierTargetTemp: matchExtr = self._regex_repetierTempExtr.match(line) matchBed = self._regex_repetierTempBed.match(line) if matchExtr is not None: toolNum = int(matchExtr.group(1)) try: target = float(matchExtr.group(2)) if toolNum in self._temp.keys() and self._temp[toolNum] is not None and isinstance(self._temp[toolNum], tuple): (actual, oldTarget) = self._temp[toolNum] self._temp[toolNum] = (actual, target) else: self._temp[toolNum] = (None, target) self._callback.mcTempUpdate(self._temp, self._bedTemp) except ValueError: pass elif matchBed is not None: try: target = float(matchBed.group(1)) if self._bedTemp is not None and isinstance(self._bedTemp, tuple): (actual, oldTarget) = self._bedTemp self._bedTemp = (actual, target) else: self._bedTemp = (None, target) self._callback.mcTempUpdate(self._temp, self._bedTemp) except ValueError: pass ##~~ SD Card handling elif 'SD init fail' in line or 'volume.init failed' in line or 'openRoot failed' in line: self._sdAvailable = False self._sdFiles = [] self._callback.mcSdStateChange(self._sdAvailable) elif 'Not SD printing' in line: if self.isSdFileSelected() and self.isPrinting(): # something went wrong, printer is reporting that we actually are not printing right now... self._sdFilePos = 0 self._changeState(self.STATE_OPERATIONAL) elif 'SD card ok' in line and not self._sdAvailable: self._sdAvailable = True self.refreshSdFiles() self._callback.mcSdStateChange(self._sdAvailable) elif 'Begin file list' in line: self._sdFiles = [] self._sdFileList = True elif 'End file list' in line: self._sdFileList = False self._callback.mcSdFiles(self._sdFiles) elif 'SD printing byte' in line: # answer to M27, at least on Marlin, Repetier and Sprinter: "SD printing byte %d/%d" match = self._regex_sdPrintingByte.search(line) self._currentFile.setFilepos(int(match.group(1))) self._callback.mcProgress() elif 'File opened' in line: # answer to M23, at least on Marlin, Repetier and Sprinter: "File opened:%s Size:%d" match = self._regex_sdFileOpened.search(line) self._currentFile = PrintingSdFileInformation(match.group(1), int(match.group(2))) elif 'File selected' in line: # final answer to M23, at least on Marlin, Repetier and Sprinter: "File selected" if self._currentFile is not None: self._callback.mcFileSelected(self._currentFile.getFilename(), self._currentFile.getFilesize(), True) eventManager().fire(Events.FILE_SELECTED, { "file": self._currentFile.getFilename(), "origin": self._currentFile.getFileLocation() }) elif 'Writing to file' in line: # anwer to M28, at least on Marlin, Repetier and Sprinter: "Writing to file: %s" self._printSection = "CUSTOM" self._changeState(self.STATE_PRINTING) line = "ok" elif 'Done printing file' in line: # printer is reporting file finished printing self._sdFilePos = 0 self._callback.mcPrintjobDone() self._changeState(self.STATE_OPERATIONAL) eventManager().fire(Events.PRINT_DONE, { "file": self._currentFile.getFilename(), "filename": os.path.basename(self._currentFile.getFilename()), "origin": self._currentFile.getFileLocation(), "time": self.getPrintTime() }) elif 'Done saving file' in line: self.refreshSdFiles() ##~~ Message handling elif line.strip() != '' \ and line.strip() != 'ok' and not line.startswith("wait") \ and not line.startswith('Resend:') \ and line != 'echo:Unknown command:""\n' \ and self.isOperational(): self._callback.mcMessage(line) ##~~ Parsing for feedback commands if feedbackControls: for name, matcher, template in feedbackControls: if name in feedbackErrors: # we previously had an error with that one, so we'll skip it now continue try: match = matcher.search(line) if match is not None: formatFunction = None if isinstance(template, str): formatFunction = str.format elif isinstance(template, unicode): formatFunction = unicode.format if formatFunction is not None: self._callback.mcReceivedRegisteredMessage(name, formatFunction(template, *(match.groups("n/a")))) except: if not name in feedbackErrors: self._logger.info("Something went wrong with feedbackControl \"%s\": " % name, exc_info=True) feedbackErrors.append(name) pass ##~~ Parsing for pause triggers if pauseTriggers and not self.isStreaming(): if "enable" in pauseTriggers.keys() and pauseTriggers["enable"].search(line) is not None: self.setPause(True) elif "disable" in pauseTriggers.keys() and pauseTriggers["disable"].search(line) is not None: self.setPause(False) elif "toggle" in pauseTriggers.keys() and pauseTriggers["toggle"].search(line) is not None: self.setPause(not self.isPaused()) if "ok" in line and heatingUp: heatingUp = False ### Baudrate detection if self._state == self.STATE_DETECT_BAUDRATE: if line == '' or time.time() > timeout: if len(self._baudrateDetectList) < 1: self.close() self._errorValue = "No more baudrates to test, and no suitable baudrate found." self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) elif self._baudrateDetectRetry > 0: self._baudrateDetectRetry -= 1 self._serial.write('\n') self._log("Baudrate test retry: %d" % (self._baudrateDetectRetry)) self._sendCommand("M105") self._testingBaudrate = True else: baudrate = self._baudrateDetectList.pop(0) try: self._serial.baudrate = baudrate self._serial.timeout = settings().getFloat(["serial", "timeout", "detection"]) self._log("Trying baudrate: %d" % (baudrate)) self._baudrateDetectRetry = 5 self._baudrateDetectTestOk = 0 timeout = getNewTimeout("communication") self._serial.write('\n') self._sendCommand("M105") self._testingBaudrate = True except: self._log("Unexpected error while setting baudrate: %d %s" % (baudrate, getExceptionString())) elif 'ok' in line and 'T:' in line: self._baudrateDetectTestOk += 1 if self._baudrateDetectTestOk < 10: self._log("Baudrate test ok: %d" % (self._baudrateDetectTestOk)) self._sendCommand("M105") else: self._sendCommand("M999") self._serial.timeout = settings().getFloat(["serial", "timeout", "connection"]) self._changeState(self.STATE_OPERATIONAL) if self._sdAvailable: self.refreshSdFiles() else: self.initSdCard() eventManager().fire(Events.CONNECTED, {"port": self._port, "baudrate": self._baudrate}) else: self._testingBaudrate = False ### Connection attempt elif self._state == self.STATE_CONNECTING: if (line == "" or "wait" in line) and startSeen: self._sendCommand("M105") elif "start" in line: startSeen = True elif "ok" in line and startSeen: self._changeState(self.STATE_OPERATIONAL) if self._sdAvailable: self.refreshSdFiles() else: self.initSdCard() eventManager().fire(Events.CONNECTED, {"port": self._port, "baudrate": self._baudrate}) elif time.time() > timeout: self.close() ### Operational elif self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PAUSED: #Request the temperature on comm timeout (every 5 seconds) when we are not printing. if line == "" or "wait" in line: if self._resendDelta is not None: self._resendNextCommand() elif not self._commandQueue.empty(): self._sendCommand(self._commandQueue.get()) else: self._sendCommand("M105") tempRequestTimeout = getNewTimeout("temperature") # resend -> start resend procedure from requested line elif line.lower().startswith("resend") or line.lower().startswith("rs"): if settings().get(["feature", "swallowOkAfterResend"]): swallowOk = True self._handleResendRequest(line) ### Printing elif self._state == self.STATE_PRINTING: if line == "" and time.time() > timeout: self._log("Communication timeout during printing, forcing a line") line = 'ok' if self.isSdPrinting(): if time.time() > tempRequestTimeout and not heatingUp: self._sendCommand("M105") tempRequestTimeout = getNewTimeout("temperature") if time.time() > sdStatusRequestTimeout and not heatingUp: self._sendCommand("M27") sdStatusRequestTimeout = getNewTimeout("sdStatus") else: # Even when printing request the temperature every 5 seconds. if time.time() > tempRequestTimeout and not self.isStreaming(): self._commandQueue.put("M105") tempRequestTimeout = getNewTimeout("temperature") if "ok" in line and swallowOk: swallowOk = False elif "ok" in line: if self._resendDelta is not None: self._resendNextCommand() elif not self._commandQueue.empty() and not self.isStreaming(): self._sendCommand(self._commandQueue.get()) else: self._sendNext() elif line.lower().startswith("resend") or line.lower().startswith("rs"): if settings().get(["feature", "swallowOkAfterResend"]): swallowOk = True self._handleResendRequest(line) except: self._logger.exception("Something crashed inside the serial connection loop, please report this in OctoPrint's bug tracker:") errorMsg = "See octoprint.log for details" self._log(errorMsg) self._errorValue = errorMsg self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) self._log("Connection closed, closing down monitor")
def uploadGcodeFile(target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) if not "file" in request.files.keys(): return make_response("No file included", 400) if target == FileDestinations.SDCARD and not settings().getBoolean( ["feature", "sdSupport"]): return make_response("SD card support is disabled", 404) file = request.files["file"] 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 if sd: # validate that all preconditions for SD upload are met before attempting it if not (printer.isOperational() and not (printer.isPrinting() or printer.isPaused())): return make_response( "Can not upload to SD card, printer is either not operational or already busy", 409) if not printer.isSdReady(): return make_response( "Can not upload to SD card, not yet initialized", 409) # determine current job 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"] # 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, 415) # prohibit overwriting currently selected file while it's being printed if futureFilename == currentFilename and sd == currentSd and printer.isPrinting( ) or printer.isPaused(): return make_response( "Trying to overwrite file that is currently being printed: %s" % currentFilename, 409) 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 selectAndOrPrint. """ if destination == FileDestinations.SDCARD: return filename, printer.addSdFile(filename, absFilename, selectAndOrPrint) else: selectAndOrPrint(absFilename, destination) return filename def selectAndOrPrint(nameToSelect, destination): """ Callback for when the file is ready to be selected and optionally printed. For SD file uploads this is 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, fileProcessingFinished) if filename is None: return make_response("Could not upload the file %s" % file.filename, 500) sdFilename = None if isinstance(filename, tuple): filename, sdFilename = filename eventManager.fire(Events.UPLOAD, {"file": filename, "target": target}) files = {} if done: files.update({ FileDestinations.LOCAL: { "name": filename, "origin": FileDestinations.LOCAL, "refs": { "resource": url_for(".readGcodeFile", target=FileDestinations.LOCAL, filename=filename, _external=True), "download": url_for("index", _external=True) + "downloads/files/" + FileDestinations.LOCAL + "/" + filename } } }) if sd and sdFilename: files.update({ FileDestinations.SDCARD: { "name": sdFilename, "origin": FileDestinations.SDCARD, "refs": { "resource": url_for(".readGcodeFile", target=FileDestinations.SDCARD, filename=sdFilename, _external=True) } } }) return make_response(jsonify(files=files, done=done), 201)
def _upload(self, path): class WatchdogFileWrapper(object): def __init__(self, path): self._path = path self.filename = os.path.basename(self._path) def save(self, target): util.safeRename(self._path, target) fileWrapper = WatchdogFileWrapper(path) # determine current job currentFilename = None currentOrigin = None currentJob = self._printer.getCurrentJob() if currentJob is not None and "file" in currentJob.keys(): currentJobFile = currentJob["file"] if "name" in currentJobFile.keys() and "origin" in currentJobFile.keys(): currentFilename = currentJobFile["name"] currentOrigin = currentJobFile["origin"] # determine future filename of file to be uploaded, abort if it can't be uploaded futureFilename = self._gcodeManager.getFutureFilename(fileWrapper) if futureFilename is None or (not settings().getBoolean(["cura", "enabled"]) and not gcodefiles.isGcodeFileName(futureFilename)): self._logger.warn("Could not add %s: Invalid file" % fileWrapper.filename) return # prohibit overwriting currently selected file while it's being printed if futureFilename == currentFilename and not currentOrigin == FileDestinations.SDCARD and self._printer.isPrinting() or self._printer.isPaused(): self._logger.warn("Could not add %s: Trying to overwrite file that is currently being printed" % fileWrapper.filename) return self._gcodeManager.addFile(fileWrapper, FileDestinations.LOCAL)
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 == 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() if currentJob is not None and "filename" in currentJob.keys() and "sd" in currentJob.keys(): 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.get("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(): 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, fileProcessingFinished) if filename is None: return make_response("Could not upload the file %s" % file.filename, 500) eventManager.fire("Upload", filename) return jsonify(files=gcodeManager.getAllFileData(), filename=filename, done=done) else: return make_response("No gcode_file included", 400)
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 == 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() if currentJob is not None and "filename" in currentJob.keys( ) and "sd" in currentJob.keys(): 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(): 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, fileProcessingFinished) if filename is None: return make_response( "Could not upload the file %s" % file.filename, 500) eventManager.fire("Upload", filename) return jsonify(files=gcodeManager.getAllFileData(), filename=filename, done=done) else: return make_response("No gcode_file included", 400)