mirror of https://github.com/Desuuuu/klipper.git
virtual_sdcard: add SDCARD_PRINT_FILE gcode
SDCARD_PRINT_FILE allows Klipper to load and start the print for any gcode file within the virtual_sdcard path, including subdirectories. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
af39a209f3
commit
963d7c247b
|
@ -5,6 +5,8 @@
|
||||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
import os, logging
|
import os, logging
|
||||||
|
|
||||||
|
VALID_GCODE_EXTS = ['gcode', 'g', 'gco']
|
||||||
|
|
||||||
class VirtualSD:
|
class VirtualSD:
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
printer = config.get_printer()
|
printer = config.get_printer()
|
||||||
|
@ -28,6 +30,9 @@ class VirtualSD:
|
||||||
self.gcode.register_command(
|
self.gcode.register_command(
|
||||||
"SDCARD_RESET_FILE", self.cmd_SDCARD_RESET_FILE,
|
"SDCARD_RESET_FILE", self.cmd_SDCARD_RESET_FILE,
|
||||||
desc=self.cmd_SDCARD_RESET_FILE_help)
|
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):
|
def handle_shutdown(self):
|
||||||
if self.work_timer is not None:
|
if self.work_timer is not None:
|
||||||
self.must_pause_work = True
|
self.must_pause_work = True
|
||||||
|
@ -46,17 +51,31 @@ class VirtualSD:
|
||||||
if self.work_timer is None:
|
if self.work_timer is None:
|
||||||
return False, ""
|
return False, ""
|
||||||
return True, "sd_pos=%d" % (self.file_position,)
|
return True, "sd_pos=%d" % (self.file_position,)
|
||||||
def get_file_list(self):
|
def get_file_list(self, check_subdirs=False):
|
||||||
dname = self.sdcard_dirname
|
if check_subdirs:
|
||||||
try:
|
flist = []
|
||||||
filenames = os.listdir(self.sdcard_dirname)
|
for root, dirs, files in os.walk(
|
||||||
return [(fname, os.path.getsize(os.path.join(dname, fname)))
|
self.sdcard_dirname, followlinks=True):
|
||||||
for fname in sorted(filenames, key=str.lower)
|
for name in files:
|
||||||
if not fname.startswith('.')
|
ext = name[name.rfind('.')+1:]
|
||||||
and os.path.isfile((os.path.join(dname, fname)))]
|
if ext not in VALID_GCODE_EXTS:
|
||||||
except:
|
continue
|
||||||
logging.exception("virtual_sdcard get_file_list")
|
full_path = os.path.join(root, name)
|
||||||
raise self.gcode.error("Unable to get file list")
|
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):
|
def get_status(self, eventtime):
|
||||||
progress = 0.
|
progress = 0.
|
||||||
if self.work_timer is not None and self.file_size:
|
if self.work_timer is not None and self.file_size:
|
||||||
|
@ -85,6 +104,17 @@ class VirtualSD:
|
||||||
raise gcmd.error(
|
raise gcmd.error(
|
||||||
"SDCARD_RESET_FILE cannot be run from the sdcard")
|
"SDCARD_RESET_FILE cannot be run from the sdcard")
|
||||||
self._reset_file()
|
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):
|
def cmd_M20(self, gcmd):
|
||||||
# List SD card
|
# List SD card
|
||||||
files = self.get_file_list()
|
files = self.get_file_list()
|
||||||
|
@ -99,10 +129,7 @@ class VirtualSD:
|
||||||
# Select SD file
|
# Select SD file
|
||||||
if self.work_timer is not None:
|
if self.work_timer is not None:
|
||||||
raise gcmd.error("SD busy")
|
raise gcmd.error("SD busy")
|
||||||
if self.current_file is not None:
|
self._reset_file()
|
||||||
self.current_file.close()
|
|
||||||
self.current_file = None
|
|
||||||
self.file_position = self.file_size = 0
|
|
||||||
try:
|
try:
|
||||||
orig = gcmd.get_commandline()
|
orig = gcmd.get_commandline()
|
||||||
filename = orig[orig.find("M23") + 4:].split()[0].strip()
|
filename = orig[orig.find("M23") + 4:].split()[0].strip()
|
||||||
|
@ -112,7 +139,9 @@ class VirtualSD:
|
||||||
raise gcmd.error("Unable to extract filename")
|
raise gcmd.error("Unable to extract filename")
|
||||||
if filename.startswith('/'):
|
if filename.startswith('/'):
|
||||||
filename = filename[1:]
|
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 }
|
files_by_lower = { fname.lower(): fname for fname, fsize in files }
|
||||||
try:
|
try:
|
||||||
fname = files_by_lower[filename.lower()]
|
fname = files_by_lower[filename.lower()]
|
||||||
|
|
Loading…
Reference in New Issue