move first/last/sort_by-multiple functionality into Manifest.list

also: rename list_filtered to list_considering
This commit is contained in:
Thomas Waldmann 2016-10-13 05:21:52 +02:00
parent 694c3978a1
commit b5f9858055
4 changed files with 21 additions and 24 deletions

View File

@ -1295,7 +1295,7 @@ class ArchiveChecker:
if archive is None: if archive is None:
# we need last N or all archives # 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: if prefix is not None:
archive_infos = [info for info in archive_infos if info.name.startswith(prefix)] archive_infos = [info for info in archive_infos if info.name.startswith(prefix)]
num_archives = len(archive_infos) num_archives = len(archive_infos)

View File

@ -783,7 +783,7 @@ class Archiver:
if args.location.archive: if args.location.archive:
archive_names = (args.location.archive,) archive_names = (args.location.archive,)
else: 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: if not archive_names:
return self.exit_code return self.exit_code
@ -825,7 +825,7 @@ class Archiver:
else: else:
msg.append("You requested to completely DELETE the repository *including* all archives it " msg.append("You requested to completely DELETE the repository *including* all archives it "
"contains:") "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(format_archive(archive_info))
msg.append("Type 'YES' if you understand this and want to continue: ") msg.append("Type 'YES' if you understand this and want to continue: ")
msg = '\n'.join(msg) msg = '\n'.join(msg)
@ -904,7 +904,7 @@ class Archiver:
format = "{archive:<36} {time} [{id}]{NL}" format = "{archive:<36} {time} [{id}]{NL}"
formatter = ArchiveFormatter(format) 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))) write(safe_encode(formatter.format_item(archive_info)))
return self.exit_code return self.exit_code
@ -924,7 +924,7 @@ class Archiver:
if args.location.archive: if args.location.archive:
archive_names = (args.location.archive,) archive_names = (args.location.archive,)
else: 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: if not archive_names:
return self.exit_code return self.exit_code
@ -976,7 +976,7 @@ class Archiver:
'"keep-secondly", "keep-minutely", "keep-hourly", "keep-daily", ' '"keep-secondly", "keep-minutely", "keep-hourly", "keep-daily", '
'"keep-weekly", "keep-monthly" or "keep-yearly" settings must be specified.') '"keep-weekly", "keep-monthly" or "keep-yearly" settings must be specified.')
return self.exit_code 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: if args.prefix:
archives_checkpoints = [arch for arch in archives_checkpoints if arch.name.startswith(args.prefix)] archives_checkpoints = [arch for arch in archives_checkpoints if arch.name.startswith(args.prefix)]
is_checkpoint = re.compile(r'\.checkpoint(\.\d+)?$').search is_checkpoint = re.compile(r'\.checkpoint(\.\d+)?$').search
@ -1094,7 +1094,7 @@ class Archiver:
if args.target is not None: if args.target is not None:
self.print_error('--target: Need to specify single archive') self.print_error('--target: Need to specify single archive')
return self.exit_code 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 name = archive.name
if recreater.is_temporary_archive(name): if recreater.is_temporary_archive(name):
continue continue

View File

@ -84,7 +84,7 @@ class FuseOperations(llfuse.Operations):
consider_part_files=self.args.consider_part_files) consider_part_files=self.args.consider_part_files)
self.process_archive(archive) self.process_archive(archive)
else: 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: for name in archive_names:
archive = Archive(self.repository_uncached, self.key, self.manifest, name, archive = Archive(self.repository_uncached, self.key, self.manifest, name,
consider_part_files=self.args.consider_part_files) consider_part_files=self.args.consider_part_files)

View File

@ -142,32 +142,29 @@ class Archives(abc.MutableMapping):
name = safe_encode(name) name = safe_encode(name)
del self._archives[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 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)] archives = [x for x in self.values() if x.name.startswith(prefix)]
if sort_by is not None: for sortkey in reversed(sort_by):
archives = sorted(archives, key=attrgetter(sort_by)) archives.sort(key=attrgetter(sortkey))
if reverse: if reverse or last:
archives.reverse() 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: if args.location.archive:
raise Error('The options --first, --last and --prefix can only be used on repository targets.') raise Error('The options --first, --last and --prefix can only be used on repository targets.')
archives = self.list(prefix=args.prefix) return self.list(sort_by=args.sort_by.split(','), prefix=args.prefix, first=args.first, last=args.last)
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]
def set_raw_dict(self, d): def set_raw_dict(self, d):
"""set the dict we get from the msgpack unpacker""" """set the dict we get from the msgpack unpacker"""