1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2024-12-26 09:47:58 +00:00

list: --json for archive contents listing

This commit is contained in:
Marian Beermann 2017-02-23 12:51:57 +01:00
parent 25781f53d4
commit 1f8c0929bf
2 changed files with 43 additions and 7 deletions

View file

@ -962,10 +962,12 @@ def _list_archive(self, args, repository, manifest, key, write):
format = "{path}{NL}" format = "{path}{NL}"
else: else:
format = "{mode} {user:6} {group:6} {size:8} {isomtime} {path}{extra}{NL}" format = "{mode} {user:6} {group:6} {size:8} {isomtime} {path}{extra}{NL}"
formatter = ItemFormatter(archive, format)
formatter = ItemFormatter(archive, format, json=args.json)
write(safe_encode(formatter.begin()))
for item in archive.iter_items(lambda item: matcher.match(item.path)): for item in archive.iter_items(lambda item: matcher.match(item.path)):
write(safe_encode(formatter.format_item(item))) write(safe_encode(formatter.format_item(item)))
write(safe_encode(formatter.end()))
return self.exit_code return self.exit_code
def _list_repository(self, args, manifest, write): def _list_repository(self, args, manifest, write):
@ -2504,7 +2506,9 @@ def process_epilog(epilog):
help="""specify format for file listing help="""specify format for file listing
(default: "{mode} {user:6} {group:6} {size:8d} {isomtime} {path}{extra}{NL}")""") (default: "{mode} {user:6} {group:6} {size:8d} {isomtime} {path}{extra}{NL}")""")
subparser.add_argument('--json', action='store_true', subparser.add_argument('--json', action='store_true',
help='format output as JSON') help='format output as JSON. The form of --format is ignored, but keys used in it '
'are added to the JSON output. Some keys are always present. Note: JSON can only '
'represent text. A "bpath" key is therefore not available.')
subparser.add_argument('location', metavar='REPOSITORY_OR_ARCHIVE', nargs='?', default='', subparser.add_argument('location', metavar='REPOSITORY_OR_ARCHIVE', nargs='?', default='',
type=location_validator(), type=location_validator(),
help='repository/archive to list contents of') help='repository/archive to list contents of')

View file

@ -5,6 +5,7 @@
import hashlib import hashlib
import logging import logging
import io import io
import json
import os import os
import os.path import os.path
import platform import platform
@ -1620,8 +1621,9 @@ def keys_help(cls):
assert not keys, str(keys) assert not keys, str(keys)
return "\n".join(help) return "\n".join(help)
def __init__(self, archive, format): def __init__(self, archive, format, *, json=False):
self.archive = archive self.archive = archive
self.json = json
static_keys = { static_keys = {
'archivename': archive.name, 'archivename': archive.name,
'archiveid': archive.fpr, 'archiveid': archive.fpr,
@ -1646,8 +1648,35 @@ def __init__(self, archive, format):
for hash_function in hashlib.algorithms_guaranteed: for hash_function in hashlib.algorithms_guaranteed:
self.add_key(hash_function, partial(self.hash_item, hash_function)) self.add_key(hash_function, partial(self.hash_item, hash_function))
self.used_call_keys = set(self.call_keys) & self.format_keys self.used_call_keys = set(self.call_keys) & self.format_keys
if self.json:
self.item_data = {}
self.format_item = self.format_item_json
self.first = True
else:
self.item_data = static_keys self.item_data = static_keys
def begin(self):
from borg.archiver import BorgJsonEncoder
if not self.json:
return ''
return textwrap.dedent("""
{{
"repository": {repository},
"files": [
""").strip().format(repository=BorgJsonEncoder().encode(self.archive.repository))
def end(self):
if not self.json:
return ''
return "]}"
def format_item_json(self, item):
if self.first:
self.first = False
return json.dumps(self.get_item_data(item))
else:
return ',' + json.dumps(self.get_item_data(item))
def add_key(self, key, callable_with_item): def add_key(self, key, callable_with_item):
self.call_keys[key] = callable_with_item self.call_keys[key] = callable_with_item
self.used_call_keys = set(self.call_keys) & self.format_keys self.used_call_keys = set(self.call_keys) & self.format_keys
@ -1673,12 +1702,15 @@ def get_item_data(self, item):
item_data['uid'] = item.uid item_data['uid'] = item.uid
item_data['gid'] = item.gid item_data['gid'] = item.gid
item_data['path'] = remove_surrogates(item.path) item_data['path'] = remove_surrogates(item.path)
if self.json:
item_data['healthy'] = 'chunks_healthy' not in item
else:
item_data['bpath'] = item.path item_data['bpath'] = item.path
item_data['extra'] = extra
item_data['health'] = 'broken' if 'chunks_healthy' in item else 'healthy'
item_data['source'] = source item_data['source'] = source
item_data['linktarget'] = source item_data['linktarget'] = source
item_data['extra'] = extra
item_data['flags'] = item.get('bsdflags') item_data['flags'] = item.get('bsdflags')
item_data['health'] = 'broken' if 'chunks_healthy' in item else 'healthy'
for key in self.used_call_keys: for key in self.used_call_keys:
item_data[key] = self.call_keys[key](item) item_data[key] = self.call_keys[key](item)
return item_data return item_data