diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md index d73a3a643860..c0d0c3eafb90 100644 --- a/docs/Config_Reference.md +++ b/docs/Config_Reference.md @@ -4523,6 +4523,21 @@ information on menu attributes available during template rendering. # Position where an item needs to be inserted in list. By default # the item is added at the end. +#[menu some_vsdlist] +#type: vsdlist +#name: +#enable: +# See above for a description of these parameters. +#sort_by_date: False +# Sort files using thier creation date from the filesystem. +# Default: (False) sort files using their names. +#sort_reverse: False +# Reverse order of sorting. +# When sort_by_date is True, files will be sorted from new to old. +# When sort_by_date is False, files will be sorted in alphabetical +# descending order, else they will be sorted in alphabetical +# ascending order. + #[menu some_list] #type: list #name: diff --git a/klippy/extras/display/menu.py b/klippy/extras/display/menu.py index e7723a7e36b0..25689847579c 100644 --- a/klippy/extras/display/menu.py +++ b/klippy/extras/display/menu.py @@ -661,18 +661,29 @@ def draw_container(self, nrows, eventtime): class MenuVSDList(MenuList): def __init__(self, manager, config, **kwargs): + self._sort_reverse = kwargs.get('sort_reverse', False) + self._sort_by_date = kwargs.get('sort_by_date', False) super(MenuVSDList, self).__init__(manager, config, **kwargs) + try: + self._sort_reverse = config.getboolean('sort_reverse', self._sort_reverse) + except config.error: + logging.debug("Failed to get sort_reverse from config file") + pass + try: + self._sort_by_date = config.getboolean('sort_by_date', self._sort_by_date) + except config.error: + logging.debug("Failed to get sort_by_date from config file") + pass def _populate(self): super(MenuVSDList, self)._populate() sdcard = self.manager.printer.lookup_object('virtual_sdcard', None) if sdcard is not None: - files = sdcard.get_file_list() + files = sdcard.get_file_list(sortByDate=self._sort_by_date, sortReverse=self._sort_reverse) for fname, fsize in files: self.insert_item(self.manager.menuitem_from( 'command', name=repr(fname), gcode='M23 /%s' % str(fname))) - menu_items = { 'disabled': MenuDisabled, 'command': MenuCommand, diff --git a/klippy/extras/virtual_sdcard.py b/klippy/extras/virtual_sdcard.py index 6dc49e2f5c39..70c3500e6f3b 100644 --- a/klippy/extras/virtual_sdcard.py +++ b/klippy/extras/virtual_sdcard.py @@ -64,7 +64,7 @@ def stats(self, eventtime): if self.work_timer is None: return False, "" return True, "sd_pos=%d" % (self.file_position,) - def get_file_list(self, check_subdirs=False): + def get_file_list(self, check_subdirs=False, sortByDate=False, sortReverse=False): if check_subdirs: flist = [] for root, dirs, files in os.walk( @@ -77,11 +77,32 @@ def get_file_list(self, check_subdirs=False): r_path = full_path[len(self.sdcard_dirname) + 1:] size = os.path.getsize(full_path) flist.append((r_path, size)) + if sortByDate: + if sortReverse: + return sorted(flist, key=lambda f: os.path.getmtime(f[0], reverse=True)) + return sorted(flist, key=lambda f: os.path.getmtime(f[0])) + if sortReverse: + return sorted(flist, key=lambda f: f[0].lower(), reverse=True) return sorted(flist, key=lambda f: f[0].lower()) else: dname = self.sdcard_dirname try: filenames = os.listdir(self.sdcard_dirname) + if sortByDate: + if sortReverse: + return [(fname, os.path.getsize(os.path.join(dname, fname))) + for fname in sorted(filenames, key=lambda f: os.path.getmtime(os.path.join(dname, f)), reverse=True) + if not fname.startswith('.') + and os.path.isfile((os.path.join(dname, fname)))] + return [(fname, os.path.getsize(os.path.join(dname, fname))) + for fname in sorted(filenames, key=lambda f: os.path.getmtime(os.path.join(dname, f))) + if not fname.startswith('.') + and os.path.isfile((os.path.join(dname, fname)))] + if sortReverse: + return [(fname, os.path.getsize(os.path.join(dname, fname))) + for fname in sorted(filenames, key=str.lower, reverse=True) + if not fname.startswith('.') + and os.path.isfile((os.path.join(dname, fname)))] return [(fname, os.path.getsize(os.path.join(dname, fname))) for fname in sorted(filenames, key=str.lower) if not fname.startswith('.')