From b5f98580552ecbea13a322785293306aa8281ce5 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Thu, 13 Oct 2016 05:21:52 +0200 Subject: [PATCH] move first/last/sort_by-multiple functionality into Manifest.list also: rename list_filtered to list_considering --- src/borg/archive.py | 2 +- src/borg/archiver.py | 12 ++++++------ src/borg/fuse.py | 2 +- src/borg/helpers.py | 29 +++++++++++++---------------- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/borg/archive.py b/src/borg/archive.py index 621ad50b4..bfc583612 100644 --- a/src/borg/archive.py +++ b/src/borg/archive.py @@ -1295,7 +1295,7 @@ class ArchiveChecker: if archive is None: # we need last N or all archives - archive_infos = self.manifest.archives.list(sort_by='ts', reverse=True) + archive_infos = self.manifest.archives.list(sort_by=['ts'], reverse=True) if prefix is not None: archive_infos = [info for info in archive_infos if info.name.startswith(prefix)] num_archives = len(archive_infos) diff --git a/src/borg/archiver.py b/src/borg/archiver.py index 6fe3c8234..40024261e 100644 --- a/src/borg/archiver.py +++ b/src/borg/archiver.py @@ -783,7 +783,7 @@ class Archiver: if args.location.archive: archive_names = (args.location.archive,) else: - archive_names = tuple(x.name for x in manifest.archives.list_filtered(args)) + archive_names = tuple(x.name for x in manifest.archives.list_considering(args)) if not archive_names: return self.exit_code @@ -825,7 +825,7 @@ class Archiver: else: msg.append("You requested to completely DELETE the repository *including* all archives it " "contains:") - for archive_info in manifest.archives.list(sort_by='ts'): + for archive_info in manifest.archives.list(sort_by=['ts']): msg.append(format_archive(archive_info)) msg.append("Type 'YES' if you understand this and want to continue: ") msg = '\n'.join(msg) @@ -904,7 +904,7 @@ class Archiver: format = "{archive:<36} {time} [{id}]{NL}" formatter = ArchiveFormatter(format) - for archive_info in manifest.archives.list_filtered(args): + for archive_info in manifest.archives.list_considering(args): write(safe_encode(formatter.format_item(archive_info))) return self.exit_code @@ -924,7 +924,7 @@ class Archiver: if args.location.archive: archive_names = (args.location.archive,) else: - archive_names = tuple(x.name for x in manifest.archives.list_filtered(args)) + archive_names = tuple(x.name for x in manifest.archives.list_considering(args)) if not archive_names: return self.exit_code @@ -976,7 +976,7 @@ class Archiver: '"keep-secondly", "keep-minutely", "keep-hourly", "keep-daily", ' '"keep-weekly", "keep-monthly" or "keep-yearly" settings must be specified.') return self.exit_code - archives_checkpoints = manifest.archives.list(sort_by='ts', reverse=True) # just a ArchiveInfo list + archives_checkpoints = manifest.archives.list(sort_by=['ts'], reverse=True) # just a ArchiveInfo list if args.prefix: archives_checkpoints = [arch for arch in archives_checkpoints if arch.name.startswith(args.prefix)] is_checkpoint = re.compile(r'\.checkpoint(\.\d+)?$').search @@ -1094,7 +1094,7 @@ class Archiver: if args.target is not None: self.print_error('--target: Need to specify single archive') return self.exit_code - for archive in manifest.archives.list(sort_by='ts'): + for archive in manifest.archives.list(sort_by=['ts']): name = archive.name if recreater.is_temporary_archive(name): continue diff --git a/src/borg/fuse.py b/src/borg/fuse.py index 9cdc86aee..8de141fef 100644 --- a/src/borg/fuse.py +++ b/src/borg/fuse.py @@ -84,7 +84,7 @@ class FuseOperations(llfuse.Operations): consider_part_files=self.args.consider_part_files) self.process_archive(archive) else: - archive_names = (x.name for x in self.manifest.archives.list_filtered(self.args)) + archive_names = (x.name for x in self.manifest.archives.list_considering(self.args)) for name in archive_names: archive = Archive(self.repository_uncached, self.key, self.manifest, name, consider_part_files=self.args.consider_part_files) diff --git a/src/borg/helpers.py b/src/borg/helpers.py index 89f09bceb..42d96b166 100644 --- a/src/borg/helpers.py +++ b/src/borg/helpers.py @@ -142,32 +142,29 @@ class Archives(abc.MutableMapping): name = safe_encode(name) del self._archives[name] - def list(self, sort_by=None, reverse=False, prefix=''): + def list(self, sort_by=(), reverse=False, prefix='', first=None, last=None): """ Inexpensive Archive.list_archives replacement if we just need .name, .id, .ts - Returns list of borg.helpers.ArchiveInfo instances + Returns list of borg.helpers.ArchiveInfo instances. + sort_by can be a list of sort keys, they are applied in reverse order. """ + if isinstance(sort_by, (str, bytes)): + raise TypeError('sort_by must be a sequence of str') archives = [x for x in self.values() if x.name.startswith(prefix)] - if sort_by is not None: - archives = sorted(archives, key=attrgetter(sort_by)) - if reverse: + for sortkey in reversed(sort_by): + archives.sort(key=attrgetter(sortkey)) + if reverse or last: archives.reverse() - return archives + n = first or last or len(archives) + return archives[:n] - def list_filtered(self, args): + def list_considering(self, args): """ - get a filtered list of archives, considering --first/last/prefix/sort + get a list of archives, considering --first/last/prefix/sort cmdline args """ if args.location.archive: raise Error('The options --first, --last and --prefix can only be used on repository targets.') - archives = self.list(prefix=args.prefix) - for sortkey in reversed(args.sort_by.split(',')): - archives.sort(key=attrgetter(sortkey)) - if args.last: - archives.reverse() - n = args.first or args.last or len(archives) - return archives[:n] - + return self.list(sort_by=args.sort_by.split(','), prefix=args.prefix, first=args.first, last=args.last) def set_raw_dict(self, d): """set the dict we get from the msgpack unpacker"""