Example #1
0
	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)
Example #2
0
    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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
    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)
Example #6
0
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)
Example #7
0
	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")
Example #8
0
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)
Example #9
0
	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)
Example #10
0
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)
Example #11
0
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)