diff options
Diffstat (limited to 'hostinfo/printer.py')
-rw-r--r-- | hostinfo/printer.py | 210 |
1 files changed, 115 insertions, 95 deletions
diff --git a/hostinfo/printer.py b/hostinfo/printer.py index 3eac182..f6fdda7 100644 --- a/hostinfo/printer.py +++ b/hostinfo/printer.py @@ -1,18 +1,38 @@ # -*- coding: utf-8 -*- -from __future__ import print_function +from __future__ import absolute_import +from hostinfo import prefix -class Prefix: - def __init__(self, prefix, output, oneline): - self.prefix = prefix - self.output = output - self.empty = oneline +def _get_full_key(prev_key, key): + if prev_key == '': + return key + return "%s.%s" % (prev_key, key) + +def _sort_with_list(iterable, sort): + def helper(value): + if sort is None: + return value + + (key, _) = value + if key in sort: + return sort.index(key) + return "%d %s" % (len(sort), key) + + return sorted(iterable, key=helper) + +def _space(filter_key, full_key, printer, force=False): + if filter_key is None and full_key == '': + printer.space(force) + +def _group_by(value, group, display_check, print_value): + groups = {} + for elem in value: + key = group(elem) + if key is not None and display_check(key): + groups.setdefault(key, []).append(print_value(elem)) + + return groups - def pprint(self, data): - self.output("%s%s" % (self.prefix, data)) - if not self.empty: - self.prefix = ' ' * len(self.prefix) - self.empty = True class Printer: labels = { @@ -29,117 +49,116 @@ class Printer: ignore = ['vserver-host', 'groups'] - def __init__(self, data, oneline, verbose, nospaces): + def __init__(self, data, flags): self.data = data - self.oneline = oneline - self.verbose = verbose - self.nospaces = nospaces + self.flags = flags + prefix.Printer.flags = flags - def _sort_with_list(self, list, sort): - def helper(value): - if sort is None: - return value + def cb_print_addresses(self, value, full_key, filter_key): + def _group_ip(address): + if 'vserver' not in address: + return address['interface'] + else: + return None - (key, full_key) = value - if key in sort: - return sort.index(key) - return "%d %s" % (len(sort), key) + def _print_ip(address): + return '%s/%s' % (address['address'], address['netmask']) - return sorted(list, key=helper) + display_check = self._is_group_displayed(full_key, filter_key) + return _group_by(value, _group_ip, display_check, _print_ip) - def print_addresses(self, value, pprint, prefix, filter_key): - self._print_group_by(value, pprint, prefix, filter_key, - lambda ip: 'vserver' not in ip and ip['interface'] or None, - lambda ip: '%s/%s' % (ip['address'], ip['netmask'])) + def cb_print_ports(self, value, full_key, filter_key): + def _group_port(port): + if 'process' in port: + return port['process'] + else: + return 'UNKNOWN' - def print_ports(self, value, pprint, prefix, filter_key): def _print_port(port): if port['proto'] in ['tcp6', 'udp6']: return '(%s) [%s]:%s' % (port['proto'].replace('6', ''), port['ip'], port['port']) return '(%s) %s:%s' % (port['proto'], port['ip'], port['port']) - self._print_group_by(value, pprint, prefix, filter_key, - lambda port: 'process' in port and port['process'] or 'UNKNOWN', - _print_port, - sort=['sshd', 'nrpe', 'munin-node']) + display_check = self._is_group_displayed(full_key, filter_key) + return (_group_by(value, _group_port, display_check, _print_port), + ['sshd', 'nrpe', 'munin-node']) - def print_vserver(self, value, pprint, prefix, filter_key): - if value == 'guest': - pprint('guest running on %s' % self.data['vserver-host']) + def cb_print_vserver(self, value, full_key, filter_key): + if value == 'guest' and 'vserver-host' in self.data and \ + self.data['vserver-host'] is not None: + return 'guest running on %s' % self.data['vserver-host'] else: - pprint(value) + return value + + def _should_display(self, full_key, filter_key=None): + if full_key not in self.ignore: + return True + if filter_key is not None and filter_key.startswith(full_key): + return True + return False - def _print(self, value, pprint, prefix='', filter_key=None, sort=None): + def _is_group_displayed(self, prev_key, filter_key): + return (lambda key: self._should_display(_get_full_key(prev_key, key), + filter_key)) + + def _print(self, value, printer, filter_key=None, sort=None): try: value = value.strip().splitlines() - except: + except AttributeError: pass if isinstance(value, dict): - self._print_dict(value, pprint, prefix, filter_key, sort) + self._print_dict(value, printer, filter_key, sort) elif isinstance(value, list): - for v in value: - pprint(v) + for values in value: + printer.pprint(values) elif value is None: - if self.verbose: - pprint('') + if 'verbose' in self.flags: + printer.pprint('') else: - pprint(value) + printer.pprint(value) + + def _print_key(self, key, value, printer, filter_key): + sort = None + try: + method = getattr(self, 'cb_print_%s' % key.replace('.', '_')) + result = method(value, printer.full_key, filter_key) + + if isinstance(result, tuple): + value, sort = result + else: + value = result + except AttributeError: + pass - def _print_dict(self, value, pprint, prefix, filter_key, sort): - keys = self._sort_with_list( + self._print(value, printer, filter_key, sort) + + def _print_dict(self, value, printer, filter_key, sort): + keys = _sort_with_list( [(key, full_key) for key in value.keys() - for full_key in [self._get_full_key(prefix, key)] - if full_key not in self.ignore or - filter_key is not None and filter_key.startswith(full_key)], + for full_key in [_get_full_key(printer.full_key, key)] + if self._should_display(full_key, filter_key)], sort) - maxlength = max(map(len, map(lambda (key, full_key): self._get_label(key, full_key), keys))) + maxlength = max([len(self._get_label(key, full_key)) \ + for (key, full_key) in keys]) + + _space(filter_key, printer.full_key, printer, True) - if not self.nospaces and filter_key is None and prefix == '': - pprint() for (key, full_key) in keys: - if filter_key is None or filter_key.startswith(full_key): - new_filter_key = filter_key - if full_key == filter_key: - new_filter_key = None - - new_pprint = pprint - if filter_key is None: - label = "%s: " % self._get_label(key, full_key) - if prefix == '': - if self.nospaces: - label = label.rjust(maxlength+4) - else: - label = (label + " ").rjust(maxlength+6) - else: - label = label.ljust(maxlength+2) - - p = Prefix(label, pprint, self.oneline) - new_pprint = p.pprint - - try: - method = getattr(self, 'print_%s' % full_key.replace('.', '_')) - method(value[key], new_pprint, full_key, new_filter_key) - except AttributeError: - self._print(value[key], new_pprint, full_key, new_filter_key) - - if not self.nospaces and filter_key is None and prefix == '': - pprint() - - def _print_group_by(self, value, pprint, prefix, filter_key, group, format, sort=None): - d = {} - for e in value: - key = group(e) - if key is not None: - d.setdefault(key, []).append(format(e)) - - self._print(d, pprint, prefix, filter_key, sort) - - def _get_full_key(self, prefix, key): - if prefix == '': - return key - return "%s.%s" % (prefix, key) + new_filter_key = None + if filter_key is not None: + if filter_key.startswith(full_key + '.'): + new_filter_key = filter_key + elif full_key != filter_key: + continue + + new_printer = prefix.Printer(full_key, printer) + if filter_key is None: + new_printer.set_label(self._get_label(key, full_key), maxlength) + + self._print_key(full_key, value[key], new_printer, new_filter_key) + _space(filter_key, printer.full_key, new_printer) def _get_label(self, key, full_key): if full_key in self.labels: @@ -147,5 +166,6 @@ class Printer: return key def info(self, key): - self._print(self.data, print, filter_key=key, + self._print(self.data, prefix.Printer(), + filter_key=key, sort=['hostname', 'arch', 'os', 'addresses', 'ports']) |