diff options
author | Rob Austein <sra@hactrn.net> | 2012-05-21 18:46:00 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2012-05-21 18:46:00 +0000 |
commit | 8296c4db9f512435fb2daa9a51299df0074f95be (patch) | |
tree | a9fe3f4a24f37fafe684ac57e4298d8db26fd4d3 | |
parent | 70a1de8b0ab03161685a412f340218441233013e (diff) |
Replacement for show.xsl and show.awk.
svn path=/trunk/; revision=4503
-rw-r--r-- | rcynic/rcynic-text.py | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/rcynic/rcynic-text.py b/rcynic/rcynic-text.py new file mode 100644 index 00000000..6af6e7b0 --- /dev/null +++ b/rcynic/rcynic-text.py @@ -0,0 +1,113 @@ +""" +Flat text summary of rcynic.xml. + +$Id$ + +Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +""" + +import sys +import urlparse +import textwrap + +try: + from lxml.etree import ElementTree +except ImportError: + from xml.etree.ElementTree import ElementTree + +class Label(object): + + def __init__(self, elt): + self.tag = elt.tag + self.width = max(len(s) for s in elt.text.split()) + self.lines = textwrap.wrap(elt.text.strip(), width = self.width) + self.counter = 0 + + def line(self, n): + try: + return " " + self.lines[n].center(self.width) + " " + except IndexError: + return " " * (self.width + 2) + + def add(self): + self.counter += 1 + + @property + def total(self): + return " " + str(self.counter).rjust(self.width) + " " + + @property + def visible(self): + return self.counter > 0 + +class Host(object): + + def __init__(self): + self.counters = {} + + def add(self, label): + self.counters[label] = self.counters.get(label, 0) + 1 + label.add() + + def total(self, label): + if label in self.counters: + return " " + str(self.counters[label]).rjust(label.width) + " " + else: + return " " * (label.width + 2) + +class Session(object): + + def __init__(self, labels): + self.hosts = {} + self.labels = labels + self.map = dict((label.tag, label) for label in labels) + + def add(self, elt): + label = self.map[elt.get("status")] + hostname = urlparse.urlparse(elt.text.strip()).hostname + if hostname not in self.hosts: + self.hosts[hostname] = Host() + self.hosts[hostname].add(label) + + def show(self): + visible = [label for label in self.labels if label.visible] + hostnames = sorted(self.hosts) + hostwidth = max(len(hostname) for hostname in hostnames) + separator = ("+-" + "-" * hostwidth + "-+-" + + "-+-".join("-" * (label.width) for label in visible) + "-+") + print separator + for i in xrange(max(len(label.lines) for label in visible)): + print ("|" + " " * (hostwidth + 2) + "|" + + "|".join(label.line(i) for label in visible) + "|") + print separator + for hostname in hostnames: + print ("| " + hostname.ljust(hostwidth + 1) + "|" + + "|".join(self.hosts[hostname].total(label) for label in visible) + "|") + print separator + print ("| " + "Total".ljust(hostwidth) + " |" + + "|".join(label.total for label in visible) + "|") + print separator + + +def main(): + for filename in ([sys.stdin] if len(sys.argv) < 2 else sys.argv[1:]): + etree = ElementTree(file = filename) + session = Session([Label(elt) for elt in etree.find("labels")]) + for elt in etree.findall("validation_status"): + session.add(elt) + session.show() + +if __name__ == "__main__": + main() |