arvados.commands.ls
1# Copyright (C) The Arvados Authors. All rights reserved. 2# 3# SPDX-License-Identifier: Apache-2.0 4 5import argparse 6import collections 7import logging 8import re 9import sys 10 11import arvados 12import arvados.commands._util as arv_cmd 13 14from arvados._version import __version__ 15 16FileInfo = collections.namedtuple('FileInfo', ['stream_name', 'name', 'size']) 17 18def parse_args(args): 19 parser = argparse.ArgumentParser( 20 description='List contents of a manifest', 21 parents=[arv_cmd.retry_opt]) 22 23 parser.add_argument('locator', type=str, 24 help="""Collection UUID or locator, optionally with a subdir path.""") 25 parser.add_argument('-s', action='store_true', 26 help="""List file sizes, in KiB.""") 27 parser.add_argument('--version', action='version', 28 version="%s %s" % (sys.argv[0], __version__), 29 help='Print version and exit.') 30 31 return parser.parse_args(args) 32 33def size_formatter(coll_file): 34 return "{:>10}".format((coll_file.size + 1023) // 1024) 35 36def name_formatter(coll_file): 37 return "{}/{}".format(coll_file.stream_name, coll_file.name) 38 39def main(args, stdout, stderr, api_client=None, logger=None): 40 args = parse_args(args) 41 42 if api_client is None: 43 api_client = arvados.api('v1', num_retries=args.retries) 44 45 if logger is None: 46 logger = logging.getLogger('arvados.arv-ls') 47 48 try: 49 r = re.search(r'^(.*?)(/.*)?$', args.locator) 50 collection = r.group(1) 51 get_prefix = r.group(2) 52 53 cr = arvados.CollectionReader(collection, api_client=api_client, 54 num_retries=args.retries) 55 if get_prefix: 56 if get_prefix[-1] == '/': 57 get_prefix = get_prefix[:-1] 58 stream_name = '.' + get_prefix 59 reader = cr.find(stream_name) 60 if not (isinstance(reader, arvados.CollectionReader) or 61 isinstance(reader, arvados.collection.Subcollection)): 62 logger.error("'{}' is not a subdirectory".format(get_prefix)) 63 return 1 64 else: 65 stream_name = '.' 66 reader = cr 67 except (arvados.errors.ApiError, 68 arvados.errors.ArgumentError, 69 arvados.errors.NotFoundError) as error: 70 logger.error("error fetching collection: {}".format(error)) 71 return 1 72 73 formatters = [] 74 if args.s: 75 formatters.append(size_formatter) 76 formatters.append(name_formatter) 77 78 for f in files_in_collection(reader, stream_name): 79 print(*(info_func(f) for info_func in formatters), file=stdout) 80 81 return 0 82 83def files_in_collection(c, stream_name='.'): 84 # Sort first by file type, then alphabetically by file path. 85 for i in sorted(c.keys(), 86 key=lambda k: ( 87 isinstance(c[k], arvados.collection.Subcollection), 88 k.upper())): 89 if isinstance(c[i], arvados.arvfile.ArvadosFile): 90 yield FileInfo(stream_name=stream_name, 91 name=i, 92 size=c[i].size()) 93 elif isinstance(c[i], arvados.collection.Subcollection): 94 for f in files_in_collection(c[i], "{}/{}".format(stream_name, i)): 95 yield f
class
FileInfo(builtins.tuple):
FileInfo(stream_name, name, size)
Inherited Members
- builtins.tuple
- index
- count
def
parse_args(args):
19def parse_args(args): 20 parser = argparse.ArgumentParser( 21 description='List contents of a manifest', 22 parents=[arv_cmd.retry_opt]) 23 24 parser.add_argument('locator', type=str, 25 help="""Collection UUID or locator, optionally with a subdir path.""") 26 parser.add_argument('-s', action='store_true', 27 help="""List file sizes, in KiB.""") 28 parser.add_argument('--version', action='version', 29 version="%s %s" % (sys.argv[0], __version__), 30 help='Print version and exit.') 31 32 return parser.parse_args(args)
def
size_formatter(coll_file):
def
name_formatter(coll_file):
def
main(args, stdout, stderr, api_client=None, logger=None):
40def main(args, stdout, stderr, api_client=None, logger=None): 41 args = parse_args(args) 42 43 if api_client is None: 44 api_client = arvados.api('v1', num_retries=args.retries) 45 46 if logger is None: 47 logger = logging.getLogger('arvados.arv-ls') 48 49 try: 50 r = re.search(r'^(.*?)(/.*)?$', args.locator) 51 collection = r.group(1) 52 get_prefix = r.group(2) 53 54 cr = arvados.CollectionReader(collection, api_client=api_client, 55 num_retries=args.retries) 56 if get_prefix: 57 if get_prefix[-1] == '/': 58 get_prefix = get_prefix[:-1] 59 stream_name = '.' + get_prefix 60 reader = cr.find(stream_name) 61 if not (isinstance(reader, arvados.CollectionReader) or 62 isinstance(reader, arvados.collection.Subcollection)): 63 logger.error("'{}' is not a subdirectory".format(get_prefix)) 64 return 1 65 else: 66 stream_name = '.' 67 reader = cr 68 except (arvados.errors.ApiError, 69 arvados.errors.ArgumentError, 70 arvados.errors.NotFoundError) as error: 71 logger.error("error fetching collection: {}".format(error)) 72 return 1 73 74 formatters = [] 75 if args.s: 76 formatters.append(size_formatter) 77 formatters.append(name_formatter) 78 79 for f in files_in_collection(reader, stream_name): 80 print(*(info_func(f) for info_func in formatters), file=stdout) 81 82 return 0
def
files_in_collection(c, stream_name='.'):
84def files_in_collection(c, stream_name='.'): 85 # Sort first by file type, then alphabetically by file path. 86 for i in sorted(c.keys(), 87 key=lambda k: ( 88 isinstance(c[k], arvados.collection.Subcollection), 89 k.upper())): 90 if isinstance(c[i], arvados.arvfile.ArvadosFile): 91 yield FileInfo(stream_name=stream_name, 92 name=i, 93 size=c[i].size()) 94 elif isinstance(c[i], arvados.collection.Subcollection): 95 for f in files_in_collection(c[i], "{}/{}".format(stream_name, i)): 96 yield f