def du(summarize, human_readable, s3_paths): """ display disk usage statistics """ size_formatter = magic.human_bytes if human_readable else lambda s: s for s3_path in s3_paths: totals = {} # In recursive tallying of totals this key is the stop condition. stop_path = '/' + s3_util.bucket_and_key(s3_path)[1].rstrip('/') def tally(path_segment, size): if not summarize or path_segment == stop_path: # If the summarize option is present, we only care about the grand total. if path_segment not in totals: totals[path_segment] = 0 totals[path_segment] += size if path_segment != stop_path: parent_dir = path_segment.rsplit('/', 1)[0] if parent_dir == '': # Edge case when totalling the entire bucket. parent_dir = '/' tally(parent_dir, size) for obj in s3_util.keys(s3_path): # usage for all given paths, and recursively for directories (excludes individual files) dbg('adding {}', obj) dir_key = '/' + obj['key'].rsplit('/', 1)[0] tally(dir_key, obj['len']) for path, total in sorted(totals.items()): out('{}\t{}', size_formatter(total), path)
def ls(color, long_format, s3_paths): """ list directory contents. zs3 ls [bucket][/key_or_prefix]... """ if color: # Click actually does some of this for us, but keep it in here to be explicit and to mirror `ls --color` if color.lower() == 'always': color = True elif color.lower() == 'auto': color = sys.stdout.isatty() if not len(s3_paths): s3_paths = [''] for s3_path in s3_paths: # ls normally prints names aligned to a grid objs = list(s3_util.ls(s3_path)) if not objs: _, key = s3_util.bucket_and_key(s3_path) if key: raise ClickException("ls {}: No such file or directory".format(s3_path)) else: # TODO same sort of exception if the bucket doesn't exist continue objs = sorted(objs, key=itemgetter('path')) if long_format: def out_gen(): for obj in objs: filename = os.path.basename(obj['path']) if color and obj['is_dir']: out_key = Style.BRIGHT + Fore.BLUE + filename + Style.RESET_ALL else: out_key = filename if obj['is_dir']: yield ['?' * 10, '??', '?????', '?????', '0', '??? ?? ??:??', out_key] else: yield ['?' * 10, '??', '?????', '?????', '{}'.format(obj['size']), '??? ?? ??:??', out_key] out(tabulate(out_gen(), tablefmt='plain')) else: # not long_format def out_gen(): for obj in objs: filename = os.path.basename(obj['path']) if color and obj['is_dir']: yield Style.BRIGHT + Fore.BLUE + filename + Style.RESET_ALL else: yield filename out_grid(list(out_gen()))