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 /)
This commit is contained in:
Gina Häußge 2015-02-26 18:24:10 +01:00
parent 4997814abe
commit 8bef18c2a8
2 changed files with 22 additions and 8 deletions

View file

@ -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

View file

@ -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: