From abd8e47f48de60a9ef07a5629e09dad5fb6945f5 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Wed, 29 May 2013 11:34:06 +0200 Subject: Printer: refactoring the whole thing for better pylint result --- bin/hostinfo | 20 +++-- hostinfo/prefix.py | 47 ++++++++++++ hostinfo/printer.py | 210 ++++++++++++++++++++++++++++------------------------ 3 files changed, 174 insertions(+), 103 deletions(-) create mode 100644 hostinfo/prefix.py diff --git a/bin/hostinfo b/bin/hostinfo index 7fb1e9b..d24fdaf 100755 --- a/bin/hostinfo +++ b/bin/hostinfo @@ -19,9 +19,9 @@ def _get_data(path): stream = file(path, 'r') return yaml.load(stream) -def print_info(path, key=None, oneline=False, verbose=False, nospaces=False): +def print_info(path, key=None, flags=list()): data = _get_data(path) - p = printer.Printer(data, oneline, verbose, nospaces) + p = printer.Printer(data, flags) p.info(key) def print_keys(path): @@ -92,8 +92,8 @@ def main(): if 'HOSTINFO_PATH' in os.environ and os.environ['HOSTINFO_PATH'] != '': basepath = os.environ['HOSTINFO_PATH'] - file = oneline = keys = verbose = nospaces = help = \ - hosts = short = False + file = keys = help = hosts = short = False + flags = list() try: optlist, args = getopt.gnu_getopt(sys.argv, 'ofkvnh?p:ls', ['oneline', 'file', 'keys', 'verbose', @@ -104,14 +104,18 @@ def main(): opts[key] = value file = any([o in opts for o in ['--file', '-f']]) - oneline = any([o in opts for o in ['--oneline', '-o']]) keys = any([o in opts for o in ['--keys', '-k']]) - verbose = any([o in opts for o in ['--verbose', '-v']]) - nospaces = any([o in opts for o in ['--nospaces', '-n']]) help = any([o in opts for o in ['--help', '-h', '-?']]) hosts = any([o in opts for o in ['--hosts', '-l']]) short = any([o in opts for o in ['--short', '-s']]) + if any([o in opts for o in ['--verbose', '-v']]): + flags.append('verbose') + if any([o in opts for o in ['--oneline', '-o']]): + flags.append('oneline') + if any([o in opts for o in ['--nospaces', '-n']]): + flags.append('nospaces') + if any([o in opts for o in ['--path', '-p']]): basepath = [opts[o] for o in ['--path', '-p'] if o in opts][0] except getopt.GetoptError, e: @@ -143,7 +147,7 @@ def main(): if len(args) > 1: key = args[1] - print_info(path, key=key, oneline=oneline, verbose=verbose, nospaces=nospaces) + print_info(path, key=key, flags=flags) sys.exit(0) if __name__ == '__main__': diff --git a/hostinfo/prefix.py b/hostinfo/prefix.py new file mode 100644 index 0000000..e9f0bf2 --- /dev/null +++ b/hostinfo/prefix.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +from __future__ import print_function + +class Printer: + flags = list() + + def __init__(self, full_key='', printer=None): + if printer is None: + self.output = print + else: + self.output = printer.pprint + + self.parent = printer + self.empty = 'oneline' in self.__class__.flags + self.full_key = full_key + self.has_output = False + self.label = '' + + def set_label(self, label='', maxlength=0): + self.label = self._get_label(label, maxlength) + + def _get_label(self, label, maxlength): + if label == '': + return label + + label = "%s: " % label + if self.parent is not None and self.parent.full_key == '': + if 'nospaces' in self.__class__.flags: + return label.rjust(maxlength+4) + else: + return (label + " ").rjust(maxlength+6) + else: + return label.ljust(maxlength+2) + + def pprint(self, data): + self.output("%s%s" % (self.label, data)) + self.has_output = True + if not self.empty: + self.label = ' ' * len(self.label) + self.empty = True + + def space(self, force=False): + if 'nospaces' not in self.__class__.flags: + if self.has_output or force: + self.output('') + 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']) -- cgit v1.2.3-1-g7c22