Пример #1
0
def format_terminal_row(headers, example_row):
    """Uses headers and a row of example data to generate a format string
    for printing a single row of data.

    Args:
        headers (tuple of strings): The headers for each column of data
        example_row (tuple): A representative tuple of strings or ints

    Returns
        string: A format string with a size for each column
    """
    def format_column(col):
        if isinstance(col, str):
            return '{{:{w}.{w}}}'
        return '{{:<{w}}}'

    widths = [max(len(h), len(str(d))) for h, d in zip(headers, example_row)]

    # Truncate last column to fit terminal width
    original_last_width = widths[-1]
    if sys.stdout.isatty():
        widths[-1] = max(
            len(headers[-1]),
            # console width - width of other columns and gutters - 3 for '...'
            tty.width() - sum(w + 2 for w in widths[0:-1]) - 3)

    # Build format string
    cols = [format_column(c).format(w=w) for c, w in zip(example_row, widths)]
    format_string = '  '.join(cols)
    if original_last_width > widths[-1]:
        format_string += '...'

    return format_string
Пример #2
0
def format_terminal_row(headers, example_row):
    """Uses headers and a row of example data to generate a format string
    for printing a single row of data.

    Args:
        headers (tuple of strings): The headers for each column of data
        example_row (tuple): A representative tuple of strings or ints

    Returns
        string: A format string with a size for each column
    """
    def format_column(col):
        if isinstance(col, str):
            return '{{:{w}.{w}}}'
        return '{{:<{w}}}'

    widths = [max(len(h), len(str(d))) for h, d in zip(headers, example_row)]

    # Truncate last column to fit terminal width
    original_last_width = widths[-1]
    if sys.stdout.isatty():
        widths[-1] = max(
            len(headers[-1]),
            # console width - width of other columns and gutters - 3 for '...'
            tty.width() - sum(w + 2 for w in widths[0:-1]) - 3)

    # Build format string
    cols = [format_column(c).format(w=w) for c, w in zip(example_row, widths)]
    format_string = '  '.join(cols)
    if original_last_width > widths[-1]:
        format_string += '...'

    return format_string
Пример #3
0
def _do_identity_policy_list(args):
    rest_client = RestClient(args.url)
    state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _POLICY_PREFIX)

    head = state['head']
    state_values = state['data']
    printable_policies = []
    for state_value in state_values:
        policies_list = PolicyList()
        decoded = b64decode(state_value['data'])
        policies_list.ParseFromString(decoded)

        for policy in policies_list.policies:
            printable_policies.append(policy)

    printable_policies.sort(key=lambda p: p.name)

    if args.format == 'default':
        tty_width = tty.width()
        for policy in printable_policies:
            # Set value width to the available terminal space, or the min width
            width = tty_width - len(policy.name) - 3
            width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH
            value = "Entries:\n"
            for entry in policy.entries:
                entry_string = (" " * 4) + Policy.Type.Name(entry.type) + " " \
                    + entry.key
                value += (entry_string[:width] + '...' if
                          len(entry_string) > width else entry_string) + "\n"
            print('{}: \n  {}'.format(policy.name, value))
    elif args.format == 'csv':
        try:
            writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
            writer.writerow(['POLICY NAME', 'ENTRIES'])
            for policy in printable_policies:
                output = [policy.name]
                for entry in policy.entries:
                    output.append(
                        Policy.Type.Name(entry.type) + " " + entry.key)
                writer.writerow(output)
        except csv.Error:
            raise CliException('Error writing CSV')
    elif args.format == 'json' or args.format == 'yaml':
        output = {}
        for policy in printable_policies:
            value = "Entries: "
            for entry in policy.entries:
                entry_string = Policy.Type.Name(entry.type) + " " \
                    + entry.key
                value += entry_string + " "
            output[policy.name] = value

        policies_snapshot = {'head': head, 'policies': output}
        if args.format == 'json':
            print(json.dumps(policies_snapshot, indent=2, sort_keys=True))
        else:
            print(yaml.dump(policies_snapshot, default_flow_style=False)[0:-1])
    else:
        raise AssertionError('Unknown format {}'.format(args.format))
Пример #4
0
def _do_config_list(args):
    """Lists the current on-chain configuration values.
    """
    rest_client = RestClient(args.url)
    state = rest_client.list_state(subtree=SETTINGS_NAMESPACE)

    prefix = args.filter

    head = state['head']
    state_values = state['data']
    printable_settings = []
    proposals_address = _key_to_address('sawtooth.settings.vote.proposals')
    for state_value in state_values:
        if state_value['address'] == proposals_address:
            # This is completely internal setting and we won't list it here
            continue

        decoded = b64decode(state_value['data'])
        setting = Setting()
        setting.ParseFromString(decoded)

        for entry in setting.entries:
            if entry.key.startswith(prefix):
                printable_settings.append(entry)

    printable_settings.sort(key=lambda s: s.key)

    if args.format == 'default':
        tty_width = tty.width()
        for setting in printable_settings:
            # Set value width to the available terminal space, or the min width
            width = tty_width - len(setting.key) - 3
            width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH
            value = (setting.value[:width] + '...'
                     if len(setting.value) > width
                     else setting.value)
            print('{}: {}'.format(setting.key, value))
    elif args.format == 'csv':
        try:
            writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
            writer.writerow(['KEY', 'VALUE'])
            for setting in printable_settings:
                writer.writerow([setting.key, setting.value])
        except csv.Error:
            raise CliException('Error writing CSV')
    elif args.format == 'json' or args.format == 'yaml':
        settings_snapshot = {
            'head': head,
            'settings': {setting.key: setting.value
                         for setting in printable_settings}
        }
        if args.format == 'json':
            print(json.dumps(settings_snapshot, indent=2, sort_keys=True))
        else:
            print(yaml.dump(settings_snapshot, default_flow_style=False)[0:-1])
    else:
        raise AssertionError('Unknown format {}'.format(args.format))
Пример #5
0
def _do_config_list(args):
    """Lists the current on-chain configuration values.
    """
    rest_client = RestClient(args.url)
    state = rest_client.list_state(subtree=SETTINGS_NAMESPACE)

    prefix = args.filter

    head = state['head']
    state_values = state['data']
    printable_settings = []
    proposals_address = _key_to_address('sawtooth.settings.vote.proposals')
    for state_value in state_values:
        if state_value['address'] == proposals_address:
            # This is completely internal setting and we won't list it here
            continue

        decoded = b64decode(state_value['data'])
        setting = Setting()
        setting.ParseFromString(decoded)

        for entry in setting.entries:
            if entry.key.startswith(prefix):
                printable_settings.append(entry)

    printable_settings.sort(key=lambda s: s.key)

    if args.format == 'default':
        tty_width = tty.width()
        for setting in printable_settings:
            # Set value width to the available terminal space, or the min width
            width = tty_width - len(setting.key) - 3
            width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH
            value = (setting.value[:width] +
                     '...' if len(setting.value) > width else setting.value)
            print('{}: {}'.format(setting.key, value))
    elif args.format == 'csv':
        try:
            writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
            writer.writerow(['KEY', 'VALUE'])
            for setting in printable_settings:
                writer.writerow([setting.key, setting.value])
        except csv.Error:
            raise CliException('Error writing CSV')
    elif args.format == 'json' or args.format == 'yaml':
        settings_snapshot = {
            'head': head,
            'settings':
            {setting.key: setting.value
             for setting in printable_settings}
        }
        if args.format == 'json':
            print(json.dumps(settings_snapshot, indent=2, sort_keys=True))
        else:
            print(yaml.dump(settings_snapshot, default_flow_style=False)[0:-1])
    else:
        raise AssertionError('Unknown format {}'.format(args.format))
Пример #6
0
def _do_identity_role_list(args):
    """Lists the current on-chain configuration values.
    """
    rest_client = RestClient(args.url)
    state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _ROLE_PREFIX)

    head = state['head']
    state_values = state['data']
    printable_roles = []
    for state_value in state_values:
        role_list = RoleList()
        decoded = b64decode(state_value['data'])
        role_list.ParseFromString(decoded)

        for role in role_list.roles:
            printable_roles.append(role)

    printable_roles.sort(key=lambda r: r.name)

    if args.format == 'default':
        tty_width = tty.width()
        for role in printable_roles:
            # Set value width to the available terminal space, or the min width
            width = tty_width - len(role.name) - 3
            width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH
            value = (role.policy_name[:width] + '...'
                     if len(role.policy_name) > width
                     else role.policy_name)
            print('{}: {}'.format(role.name, value))
    elif args.format == 'csv':
        try:
            writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
            writer.writerow(['KEY', 'VALUE'])
            for role in printable_roles:
                writer.writerow([role.name, role.policy_name])
        except csv.Error:
            raise CliException('Error writing CSV')
    elif args.format == 'json' or args.format == 'yaml':
        roles_snapshot = {
            'head': head,
            'roles': {role.name: role.policy_name
                      for role in printable_roles}
        }
        if args.format == 'json':
            print(json.dumps(roles_snapshot, indent=2, sort_keys=True))
        else:
            print(yaml.dump(roles_snapshot, default_flow_style=False)[0:-1])
    else:
        raise AssertionError('Unknown format {}'.format(args.format))
Пример #7
0
def _do_identity_role_list(args):
    """Lists the current on-chain configuration values.
    """
    rest_client = RestClient(args.url)
    state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _ROLE_PREFIX)

    head = state['head']
    state_values = state['data']
    printable_roles = []
    for state_value in state_values:
        role_list = RoleList()
        decoded = b64decode(state_value['data'])
        role_list.ParseFromString(decoded)

        for role in role_list.roles:
            printable_roles.append(role)

    printable_roles.sort(key=lambda r: r.name)

    if args.format == 'default':
        tty_width = tty.width()
        for role in printable_roles:
            # Set value width to the available terminal space, or the min width
            width = tty_width - len(role.name) - 3
            width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH
            value = (role.policy_name[:width] + '...'
                     if len(role.policy_name) > width
                     else role.policy_name)
            print('{}: {}'.format(role.name, value))
    elif args.format == 'csv':
        try:
            writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
            writer.writerow(['KEY', 'VALUE'])
            for role in printable_roles:
                writer.writerow([role.name, role.policy_name])
        except csv.Error:
            raise CliException('Error writing CSV')
    elif args.format == 'json' or args.format == 'yaml':
        roles_snapshot = {
            'head': head,
            'roles': {role.name: role.policy_name
                      for role in printable_roles}
        }
        if args.format == 'json':
            print(json.dumps(roles_snapshot, indent=2, sort_keys=True))
        else:
            print(yaml.dump(roles_snapshot, default_flow_style=False)[0:-1])
    else:
        raise AssertionError('Unknown format {}'.format(args.format))
Пример #8
0
def do_batch(args):
    """Runs the batch list or batch show command, printing output to the console

        Args:
            args: The parsed arguments sent to the command at runtime
    """

    rest_client = RestClient(args.url)

    def print_json(data):
        print(
            json.dumps(data, indent=2, separators=(',', ': '), sort_keys=True))

    def print_yaml(data):
        print(yaml.dump(data, default_flow_style=False)[0:-1])

    if args.subcommand == 'list':
        batches = rest_client.list_batches()
        keys = ('batch_id', 'txns', 'signer')
        headers = (k.upper() for k in keys)

        def get_data(batch):
            return (batch['header_signature'],
                    len(batch.get('transactions',
                                  [])), batch['header']['signer_pubkey'])

        if args.format == 'default':
            # Set column widths based on window and data size
            window_width = tty.width()

            try:
                id_width = len(batches[0]['header_signature'])
                sign_width = len(batches[0]['header']['signer_pubkey'])
            except IndexError:
                # if no data was returned, use short default widths
                id_width = 30
                sign_width = 15

            if sys.stdout.isatty():
                adjusted = int(window_width) - id_width - 11
                adjusted = 6 if adjusted < 6 else adjusted
            else:
                adjusted = sign_width

            fmt_string = '{{:{i}.{i}}}  {{:<4}}  {{:{a}.{a}}}'\
                .format(i=id_width, a=adjusted)

            # Print data in rows and columns
            print(fmt_string.format(*headers))
            for batch in batches:
                print(
                    fmt_string.format(*get_data(batch)) +
                    ('...' if adjusted < sign_width and sign_width else ''))

        elif args.format == 'csv':
            try:
                writer = csv.writer(sys.stdout)
                writer.writerow(headers)
                for batch in batches:
                    writer.writerow(get_data(batch))
            except csv.Error as e:
                raise CliException('Error writing CSV: {}'.format(e))

        elif args.format == 'json' or args.format == 'yaml':
            data = [{k: d for k, d in zip(keys, get_data(b))} for b in batches]

            if args.format == 'yaml':
                print_yaml(data)
            elif args.format == 'json':
                print_json(data)
            else:
                raise AssertionError('Missing handler: {}'.format(args.format))

        else:
            raise AssertionError('Missing handler: {}'.format(args.format))

    if args.subcommand == 'show':
        batch = rest_client.get_batch(args.batch_id)

        if args.key:
            if args.key in batch:
                print(batch[args.key])
            elif args.key in batch['header']:
                print(batch['header'][args.key])
            else:
                raise CliException(
                    'key "{}" not found in batch or header'.format(args.key))
        else:
            if args.format == 'yaml':
                print_yaml(batch)
            elif args.format == 'json':
                print_json(batch)
            else:
                raise AssertionError('Missing handler: {}'.format(args.format))
Пример #9
0
def _do_identity_policy_list(args):
    rest_client = RestClient(args.url)
    state = rest_client.list_state(subtree=IDENTITY_NAMESPACE + _POLICY_PREFIX)

    head = state['head']
    state_values = state['data']
    printable_policies = []
    for state_value in state_values:
        policies_list = PolicyList()
        decoded = b64decode(state_value['data'])
        policies_list.ParseFromString(decoded)

        for policy in policies_list.policies:
            printable_policies.append(policy)

    printable_policies.sort(key=lambda p: p.name)

    if args.format == 'default':
        tty_width = tty.width()
        for policy in printable_policies:
            # Set value width to the available terminal space, or the min width
            width = tty_width - len(policy.name) - 3
            width = width if width > _MIN_PRINT_WIDTH else _MIN_PRINT_WIDTH
            value = "Entries:\n"
            for entry in policy.entries:
                entry_string = (" " * 4) + Policy.EntryType.Name(entry.type) \
                    + " " + entry.key
                value += (entry_string[:width] + '...'
                          if len(entry_string) > width
                          else entry_string) + "\n"
            print('{}: \n  {}'.format(policy.name, value))
    elif args.format == 'csv':
        try:
            writer = csv.writer(sys.stdout, quoting=csv.QUOTE_ALL)
            writer.writerow(['POLICY NAME', 'ENTRIES'])
            for policy in printable_policies:
                output = [policy.name]
                for entry in policy.entries:
                    output.append(
                        Policy.EntryType.Name(entry.type) + " " + entry.key)
                writer.writerow(output)
        except csv.Error:
            raise CliException('Error writing CSV')
    elif args.format == 'json' or args.format == 'yaml':
        output = {}
        for policy in printable_policies:
            value = "Entries: "
            for entry in policy.entries:
                entry_string = Policy.EntryType.Name(entry.type) + " " \
                    + entry.key
                value += entry_string + " "
            output[policy.name] = value

        policies_snapshot = {
            'head': head,
            'policies': output
        }
        if args.format == 'json':
            print(json.dumps(policies_snapshot, indent=2, sort_keys=True))
        else:
            print(yaml.dump(policies_snapshot, default_flow_style=False)[0:-1])
    else:
        raise AssertionError('Unknown format {}'.format(args.format))
Пример #10
0
def do_state(args):
    """Runs the batch list or batch show command, printing output to the console

        Args:
            args: The parsed arguments sent to the command at runtime
    """
    rest_client = RestClient(args.url)

    def print_json(data):
        print(
            json.dumps(data, indent=2, separators=(',', ': '), sort_keys=True))

    def print_yaml(data):
        print(yaml.dump(data, default_flow_style=False)[0:-1])

    if args.subcommand == 'list':
        response = rest_client.list_state(args.subtree, args.head)
        leaves = response['data']
        head = response['head']
        keys = ('address', 'size', 'data')
        headers = (k.upper() for k in keys)

        def get_leaf_data(leaf, decode=True):
            decoded = b64decode(leaf['data'])
            return (leaf['address'], len(decoded),
                    str(decoded) if decode else leaf['data'])

        if args.format == 'default':
            # Set column widths based on window and data size
            window_width = tty.width()

            try:
                addr_width = len(leaves[0]['address'])
                data_width = len(str(b64decode(leaves[0]['data'])))
            except IndexError:
                # if no data was returned, use short default widths
                addr_width = 30
                data_width = 15

            if sys.stdout.isatty():
                adjusted = int(window_width) - addr_width - 11
                adjusted = 6 if adjusted < 6 else adjusted
            else:
                adjusted = data_width

            fmt_string = '{{:{a}.{a}}}  {{:<4}}  {{:{j}.{j}}}'\
                .format(a=addr_width, j=adjusted)

            # Print data in rows and columns
            print(fmt_string.format(*headers))
            for leaf in leaves:
                print(
                    fmt_string.format(*get_leaf_data(leaf)) +
                    ('...' if adjusted < data_width and data_width else ''))
            print('HEAD BLOCK: "{}"'.format(head))

        elif args.format == 'csv':
            try:
                writer = csv.writer(sys.stdout)
                writer.writerow(headers)
                for leaf in leaves:
                    writer.writerow(get_leaf_data(leaf))
            except csv.Error as e:
                raise CliException('Error writing CSV: {}'.format(e))
            print('(data for head block: "{}")'.format(head))

        elif args.format == 'json' or args.format == 'yaml':
            state_data = {
                'head':
                head,
                'data': [{k: d
                          for k, d in zip(keys, get_leaf_data(l, False))}
                         for l in leaves]
            }

            if args.format == 'yaml':
                print_yaml(state_data)
            elif args.format == 'json':
                print_json(state_data)
            else:
                raise AssertionError('Missing handler: {}'.format(args.format))

        else:
            raise AssertionError('Missing handler: {}'.format(args.format))

    if args.subcommand == 'show':
        leaf = rest_client.get_leaf(args.address, args.head)
        if leaf is not None:
            print('DATA: "{}"'.format(b64decode(leaf['data'])))
            print('HEAD: "{}"'.format(leaf['head']))
        else:
            raise CliException('No data available at {}'.format(args.address))