From 8bef18c2a82a70b7be968908534d68d6bea16f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Thu, 26 Feb 2015 18:24:10 +0100 Subject: [PATCH] Fix handling of SD card files in folders OctoPrint got confused by prepended / in files on printer's SD cards located within folders. New handling makes comm always use absolute path names for SD card file names (even those in the root), printer converts between this representation and the storage interface compatible version of file and folder names being stated relative to the root (so no leading /) --- src/octoprint/printer/__init__.py | 18 +++++++++++------- src/octoprint/util/comm.py | 12 +++++++++++- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/octoprint/printer/__init__.py b/src/octoprint/printer/__init__.py index 9beb6522..039c6de9 100644 --- a/src/octoprint/printer/__init__.py +++ b/src/octoprint/printer/__init__.py @@ -30,7 +30,7 @@ def getConnectionOptions(): "autoconnect": settings().getBoolean(["serial", "autoconnect"]) } -class Printer(): +class Printer(comm.MachineComPrintCallback): def __init__(self, fileManager, analysisQueue, printerProfileManager): from collections import deque @@ -329,7 +329,7 @@ class Printer(): return self._printAfterSelect = printAfterSelect - self._comm.selectFile(filename, sd) + self._comm.selectFile("/" + filename if sd else filename, sd) self._setProgressData(0, None, None, None) self._setCurrentZ(None) @@ -501,6 +501,10 @@ class Printer(): def _setJobData(self, filename, filesize, sd): if filename is not None: + if sd: + filename = filename[1:] + else: + filename = self._fileManager.path_in_storage(FileDestinations.LOCAL, filename) self._selectedFile = { "filename": filename, "filesize": filesize, @@ -559,7 +563,7 @@ class Printer(): self._stateMonitor.setJobData({ "file": { - "name": os.path.basename(filename) if filename is not None else None, + "name": filename, "origin": FileDestinations.SDCARD if sd else FileDestinations.LOCAL, "size": filesize, "date": date @@ -701,7 +705,7 @@ class Printer(): def getSdFiles(self): if self._comm is None or not self._comm.isSdReady(): return [] - return self._comm.getSdFiles() + return map(lambda x: (x[0][1:], x[1]), self._comm.getSdFiles()) def addSdFile(self, filename, absolutePath, streamingFinishedCallback): if not self._comm or self._comm.isBusy() or not self._comm.isSdReady(): @@ -715,14 +719,14 @@ class Printer(): remoteName = util.getDosFilename(filename, existingSdFiles) self._timeEstimationData = TimeEstimationHelper() - self._comm.startFileTransfer(absolutePath, filename, remoteName) + self._comm.startFileTransfer(absolutePath, filename, "/" + remoteName) return remoteName def deleteSdFile(self, filename): if not self._comm or not self._comm.isSdReady(): return - self._comm.deleteSdFile(filename) + self._comm.deleteSdFile("/" + filename) def initSdCard(self): if not self._comm or self._comm.isSdReady(): @@ -738,7 +742,7 @@ class Printer(): """ Refreshs the list of file stored on the SD card attached to printer (if available and printer communication available). Optional blocking parameter allows making the method block (max 10s) until the file list has been - received (and can be accessed via self._comm.getSdFiles()). Defaults to a asynchronous operation. + received (and can be accessed via self._comm.getSdFiles()). Defaults to an asynchronous operation. """ if not self._comm or not self._comm.isSdReady(): return diff --git a/src/octoprint/util/comm.py b/src/octoprint/util/comm.py index f7886fd6..bd853f5c 100644 --- a/src/octoprint/util/comm.py +++ b/src/octoprint/util/comm.py @@ -167,6 +167,7 @@ class MachineCom(object): self._sdAvailable = False self._sdFileList = False self._sdFiles = [] + self._sdFileToSelect = None # print job self._currentFile = None @@ -438,6 +439,7 @@ class MachineCom(object): if not self.isOperational(): # printer is not connected, can't use SD return + self._sdFileToSelect = filename self.sendCommand("M23 %s" % filename) else: self._currentFile = PrintingGcodeFileInformation(filename, self.getOffsets) @@ -715,6 +717,9 @@ class MachineCom(object): 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: + if not filename.startswith("/"): + # file from the root of the sd -- we'll prepend a / + filename = "/" + filename self._sdFiles.append((filename, size)) continue @@ -783,7 +788,12 @@ class MachineCom(object): 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))) + if self._sdFileToSelect: + name = self._sdFileToSelect + self._sdFileToSelect = None + else: + name = match.group(1) + self._currentFile = PrintingSdFileInformation(name, 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: