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:
parent
25781f53d4
commit
1f8c0929bf
2 changed files with 43 additions and 7 deletions
|
@ -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')
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue