aboutsummaryrefslogtreecommitdiffstats
path: root/klippy
diff options
context:
space:
mode:
Diffstat (limited to 'klippy')
-rw-r--r--klippy/extras/virtual_sdcard.py61
1 files changed, 45 insertions, 16 deletions
diff --git a/klippy/extras/virtual_sdcard.py b/klippy/extras/virtual_sdcard.py
index b08cdd18..45467906 100644
--- a/klippy/extras/virtual_sdcard.py
+++ b/klippy/extras/virtual_sdcard.py
@@ -5,6 +5,8 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
import os, logging
+VALID_GCODE_EXTS = ['gcode', 'g', 'gco']
+
class VirtualSD:
def __init__(self, config):
printer = config.get_printer()
@@ -28,6 +30,9 @@ class VirtualSD:
self.gcode.register_command(
"SDCARD_RESET_FILE", self.cmd_SDCARD_RESET_FILE,
desc=self.cmd_SDCARD_RESET_FILE_help)
+ self.gcode.register_command(
+ "SDCARD_PRINT_FILE", self.cmd_SDCARD_PRINT_FILE,
+ desc=self.cmd_SDCARD_PRINT_FILE_help)
def handle_shutdown(self):
if self.work_timer is not None:
self.must_pause_work = True
@@ -46,17 +51,31 @@ class VirtualSD:
if self.work_timer is None:
return False, ""
return True, "sd_pos=%d" % (self.file_position,)
- def get_file_list(self):
- dname = self.sdcard_dirname
- try:
- filenames = os.listdir(self.sdcard_dirname)
- return [(fname, os.path.getsize(os.path.join(dname, fname)))
- for fname in sorted(filenames, key=str.lower)
- if not fname.startswith('.')
- and os.path.isfile((os.path.join(dname, fname)))]
- except:
- logging.exception("virtual_sdcard get_file_list")
- raise self.gcode.error("Unable to get file list")
+ def get_file_list(self, check_subdirs=False):
+ if check_subdirs:
+ flist = []
+ for root, dirs, files in os.walk(
+ self.sdcard_dirname, followlinks=True):
+ for name in files:
+ ext = name[name.rfind('.')+1:]
+ if ext not in VALID_GCODE_EXTS:
+ continue
+ full_path = os.path.join(root, name)
+ r_path = full_path[len(self.sdcard_dirname) + 1:]
+ size = os.path.getsize(full_path)
+ flist.append((r_path, size))
+ return sorted(flist, key=lambda f: f[0].lower())
+ else:
+ dname = self.sdcard_dirname
+ try:
+ filenames = os.listdir(self.sdcard_dirname)
+ return [(fname, os.path.getsize(os.path.join(dname, fname)))
+ for fname in sorted(filenames, key=str.lower)
+ if not fname.startswith('.')
+ and os.path.isfile((os.path.join(dname, fname)))]
+ except:
+ logging.exception("virtual_sdcard get_file_list")
+ raise self.gcode.error("Unable to get file list")
def get_status(self, eventtime):
progress = 0.
if self.work_timer is not None and self.file_size:
@@ -85,6 +104,17 @@ class VirtualSD:
raise gcmd.error(
"SDCARD_RESET_FILE cannot be run from the sdcard")
self._reset_file()
+ cmd_SDCARD_PRINT_FILE_help = "Loads a SD file and starts the print. May "\
+ "include files in subdirectories."
+ def cmd_SDCARD_PRINT_FILE(self, gcmd):
+ if self.work_timer is not None:
+ raise gcmd.error("SD busy")
+ self._reset_file()
+ filename = gcmd.get("FILENAME")
+ if filename[0] == '/':
+ filename = filename[1:]
+ self._load_file(gcmd, filename, check_subdirs=True)
+ self.cmd_M24(gcmd)
def cmd_M20(self, gcmd):
# List SD card
files = self.get_file_list()
@@ -99,10 +129,7 @@ class VirtualSD:
# Select SD file
if self.work_timer is not None:
raise gcmd.error("SD busy")
- if self.current_file is not None:
- self.current_file.close()
- self.current_file = None
- self.file_position = self.file_size = 0
+ self._reset_file()
try:
orig = gcmd.get_commandline()
filename = orig[orig.find("M23") + 4:].split()[0].strip()
@@ -112,7 +139,9 @@ class VirtualSD:
raise gcmd.error("Unable to extract filename")
if filename.startswith('/'):
filename = filename[1:]
- files = self.get_file_list()
+ self._load_file(gcmd, filename)
+ def _load_file(self, gcmd, filename, check_subdirs=False):
+ files = self.get_file_list(check_subdirs)
files_by_lower = { fname.lower(): fname for fname, fsize in files }
try:
fname = files_by_lower[filename.lower()]