diff --git a/src/octoprint/printer/standard.py b/src/octoprint/printer/standard.py index 1976b750..7a619c45 100644 --- a/src/octoprint/printer/standard.py +++ b/src/octoprint/printer/standard.py @@ -595,12 +595,16 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback): self.refresh_sd_files(blocking=True) existingSdFiles = map(lambda x: x[0], self._comm.getSdFiles()) - remoteName = util.get_dos_filename(filename, - existing_filenames=existingSdFiles, - extension="gco", - whitelisted_extensions=["gco", "g"]) + if valid_file_type(filename, "gcode"): + remoteName = util.get_dos_filename(filename, + existing_filenames=existingSdFiles, + extension="gco", + whitelisted_extensions=["gco", "g"]) + else: + # probably something else added through a plugin, use it's basename as-is + remoteName = os.path.basename(filename) self._timeEstimationData = TimeEstimationHelper() - self._comm.startFileTransfer(absolutePath, filename, "/" + remoteName) + self._comm.startFileTransfer(absolutePath, filename, "/" + remoteName, special=not valid_file_type(filename, "gcode")) return remoteName diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index 44a6605a..425b54d8 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -877,7 +877,7 @@ class MachineCom(object): self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) - def startFileTransfer(self, filename, localFilename, remoteFilename): + def startFileTransfer(self, filename, localFilename, remoteFilename, special=False): if not self.isOperational() or self.isBusy(): self._logger.info("Printer is not operational or busy") return @@ -885,7 +885,10 @@ class MachineCom(object): with self._jobLock: self.resetLineNumbers() - self._currentFile = StreamingGcodeFileInformation(filename, localFilename, remoteFilename) + if special: + self._currentFile = SpecialStreamingGcodeFileInformation(filename, localFilename, remoteFilename) + else: + self._currentFile = StreamingGcodeFileInformation(filename, localFilename, remoteFilename) self._currentFile.start() self.sendCommand("M28 %s" % remoteFilename) @@ -2356,7 +2359,7 @@ class MachineCom(object): # now comes the part where we increase line numbers and send stuff - no turning back now command_requiring_checksum = gcode is not None and gcode in self._checksum_requiring_commands command_allowing_checksum = gcode is not None or self._sendChecksumWithUnknownCommands - checksum_enabled = not self._neverSendChecksum and (self.isPrinting() or + checksum_enabled = not self._neverSendChecksum and ((self.isPrinting() and self._currentFile and self._currentFile.checksum) or self._alwaysSendChecksum or not self._firmware_info_received) @@ -2825,6 +2828,8 @@ class PrintingFileInformation(object): value between 0 and 1. """ + checksum = True + def __init__(self, filename): self._logger = logging.getLogger(__name__) self._filename = filename @@ -2879,6 +2884,8 @@ class PrintingSdFileInformation(PrintingFileInformation): Encapsulates information regarding an ongoing print from SD. """ + checksum = False + def __init__(self, filename, size): PrintingFileInformation.__init__(self, filename) self._size = size @@ -3025,6 +3032,23 @@ class StreamingGcodeFileInformation(PrintingGcodeFileInformation): self._logger.info("Finished in {duration:.3f} s. Approx. transfer rate of {rate:.3f} lines/s or {time_per_line:.3f} ms per line".format(**stats)) +class SpecialStreamingGcodeFileInformation(StreamingGcodeFileInformation): + """ + For streaming files to the printer that aren't GCODE. + + Difference to regular StreamingGcodeFileInformation: no checksum requirement, only rudimentary line processing + (stripping of whitespace from the end and ignoring of empty lines) + """ + + checksum = False + + def _process(self, line, offsets, current_tool): + line = line.rstrip() + if not len(line): + return None + return line + + class SendQueue(PrependableQueue): def __init__(self, maxsize=0):