diff options
author | Rob Austein <sra@hactrn.net> | 2011-10-18 15:39:20 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2011-10-18 15:39:20 +0000 |
commit | 64cc7db89225d9a06a73f22039ea22aaad8b547f (patch) | |
tree | d2a03fbb69d743be328c357e558737492d1760c6 /rcynic/rcynic.py | |
parent | 2f37bb4bdffeac28e7030252745e2a600a4535c2 (diff) |
First pass cleanup. See #64.
svn path=/trunk/; revision=4049
Diffstat (limited to 'rcynic/rcynic.py')
-rw-r--r-- | rcynic/rcynic.py | 253 |
1 files changed, 123 insertions, 130 deletions
diff --git a/rcynic/rcynic.py b/rcynic/rcynic.py index e371edcf..2bd02bcd 100644 --- a/rcynic/rcynic.py +++ b/rcynic/rcynic.py @@ -1,6 +1,8 @@ """ Python translation of rcynic.xsl, which has gotten too slow and complex. +$Id$ + Copyright (C) 2010-2011 Internet Systems Consortium, Inc. ("ISC") Permission to use, copy, modify, and/or distribute this software for any @@ -18,7 +20,7 @@ PERFORMANCE OF THIS SOFTWARE. import sys, urlparse, os -from xml.etree.cElementTree import (ElementTree, Element, SubElement, Comment) +from xml.etree.ElementTree import (ElementTree, Element, SubElement, Comment) refresh = 1800 suppress_zero_columns = True @@ -28,184 +30,175 @@ show_detailed_status = True show_problems = False show_summary = True -#input = ElementTree(file = sys.stdin) -input = ElementTree(file = "rcynic.xml") +class Label(object): + + def __init__(self, elt): + self.code = elt.tag + self.mood = elt.get("kind") + self.text = elt.text.strip() + self.sum = 0 + +class Validation_Status(object): + + def __init__(self, elt, map): + self.uri = elt.text.strip() + self.timestamp = elt.get("timestamp") + self.generation = elt.get("generation") + self.hostname = urlparse.urlparse(self.uri).hostname or None + self.fn2 = os.path.splitext(self.uri)[1] or None if self.generation else None + self.label = map[elt.get("status")] + self.label.sum += 1 + + @property + def code(self): + return self.label.code + + @property + def mood(self): + return self.label.mood + +input = ElementTree(file = sys.stdin) +labels = [Label(elt) for elt in input.find("labels")] +label_map = dict((l.code, l) for l in labels) +validation_status = [Validation_Status(elt, label_map) for elt in input.findall("validation_status")] +del label_map +if suppress_zero_columns: + labels = [l for l in labels if l.sum > 0] html = Element("html") -html.append(Comment(" Generators:\n " + - input.getroot().get("rcynic-version") + - "\n $Id$\n")) +html.append(Comment(" Generators:\n" + + " " + input.getroot().get("rcynic-version") + "\n" + + " $Id$\n")) head = SubElement(html, "head") body = SubElement(html, "body") title = "rcynic summary %s" % input.getroot().get("date") SubElement(head, "title").text = title SubElement(body, "h1").text = title +del title if refresh: SubElement(head, "meta", { "http-equiv" : "Refresh", "content" : str(refresh) }) -css = ''' - td { text-align: center; padding: 4px } +SubElement(head, "style", type = "text/css").text = ''' + th, td { text-align: center; padding: 4px } td.uri { text-align: left } - td.host { text-align: left } + thead tr th, + tfoot tr td { font-weight: bold } ''' +table_css = { "rules" : "all", "border" : "1"} +uri_css = { "class" : "uri" } + if use_colors: - css += '''\ - tr.good,td.good { background-color: #77ff77 } - tr.warn,td.warn { background-color: yellow } - tr.bad,td.bad { background-color: #ff5500 } + SubElement(head, "style", type = "text/css").text = ''' + .good { background-color: #77ff77 } + .warn { background-color: yellow } + .bad { background-color: #ff5500 } ''' -SubElement(head, "style", type = "text/css").text = css - -class Label(object): - - def __init__(self, elt): - self.tag = elt.tag - self.kind = elt.get("kind") - self.text = elt.text.strip() - -class Host_Datum(object): - - def __init__(self, elt): - self.uri = elt.text.strip() - self.status = elt.get("status") - self.timestamp = elt.get("timestamp") - self.generation = elt.get("generation") - self.hostname = urlparse.urlparse(self.uri).hostname - self.label = label_map[self.status] - self.mood = self.label.kind - self.fn2 = os.path.splitext(self.uri)[1] or None - if not self.generation: - self.fn2 = None - - def __cmp__(self, other): - return cmp(self.uri, other.uri) or cmp(self.generation, other.generation) - -class Total(object): - - # This probably should merge into the Label class, right now I'm - # just trying to do straight translation to keep from getting too - # confused by all the different attribute names. - - def __init__(self, label, host_data): - self.label = label - self.name = label.tag - self.mood = label.kind - self.text = label.text - self.sum = sum(int(h.status == self.name) for h in host_data) - self.show = self.sum > 0 or not suppress_zero_columns - -labels = [Label(elt) for elt in input.find("labels")] -label_map = dict((label.tag, label) for label in labels) - if show_summary: - host_data = [Host_Datum(elt) for elt in input.findall("validation_status")] - #host_data.sort() - - unique_hostnames = set(h.hostname for h in host_data) - unique_fn2s = set(h.fn2 for h in host_data) - unique_generations = set(h.generation for h in host_data) - - totals = [Total(label, host_data) for label in labels] - columns = sum(total.sum for total in totals) + unique_hostnames = sorted(set(v.hostname for v in validation_status)) + unique_fn2s = sorted(set(v.fn2 for v in validation_status)) + unique_generations = sorted(set(v.generation for v in validation_status)) if show_summary: SubElement(body, "br") SubElement(body, "h2").text = "Grand Totals" - table = SubElement(body, "table", { "class" : "summary", "rules" : "all", "border" : "1"}) + table = SubElement(body, "table", table_css) thead = SubElement(table, "thead") - tr = SubElement(thead, "tr") - SubElement(tr, "td") - for t in totals: - if t.show: - elt = SubElement(tr, "td") - elt = SubElement(elt, "b") - elt.text = t.text + tfoot = SubElement(table, "tfoot") tbody = SubElement(table, "tbody") - tr = SubElement(tbody, "tr") - elt = SubElement(tr, "td") - elt = SubElement(elt, "b") - elt.text = "Total" - for t in totals: - if t.show: - SubElement(tr, "td", { "class" : t.mood }).text = str(t.sum) + tr = SubElement(thead, "tr") + SubElement(tr, "th") + for l in labels: + SubElement(tr, "th").text = l.text + for fn2 in unique_fn2s: + for generation in unique_generations: + if any(v.fn2 == fn2 and v.generation == generation for v in validation_status): + tr = SubElement(tbody, "tr") + SubElement(tr, "td").text = ((generation or "") + " " + (fn2 or "")).strip() + for l in labels: + value = sum(int(v.fn2 == fn2 and v.generation == generation and v.code == l.code) for v in validation_status) + td = SubElement(tr, "td") + if value > 0: + td.set("class", l.mood) + td.text = str(value) + + tr = SubElement(tfoot, "tr") + SubElement(tr, "td").text = "Total" + for l in labels: + SubElement(tr, "td", { "class" : l.mood }).text = str(l.sum) SubElement(body, "br") SubElement(body, "h2").text = "Summaries by Repository Host" - - for hostname in sorted(unique_hostnames): + for hostname in unique_hostnames: SubElement(body, "br") SubElement(body, "h3").text = hostname - table = SubElement(body, "table", { "class" : "summary", "rules" : "all", "border" : "1"}) + table = SubElement(body, "table", table_css) thead = SubElement(table, "thead") - tr = SubElement(thead, "tr") - SubElement(tr, "td") - for t in totals: - if t.show: - elt = SubElement(tr, "td") - elt = SubElement(elt, "b") - elt.text = t.text + tfoot = SubElement(table, "tfoot") tbody = SubElement(table, "tbody") - for fn2 in sorted(unique_fn2s): - for generation in sorted(unique_generations): - if any(h.hostname == hostname and h.fn2 == fn2 and h.generation == generation for h in host_data): + tr = SubElement(thead, "tr") + SubElement(tr, "th") + for l in labels: + SubElement(tr, "th").text = l.text + for fn2 in unique_fn2s: + for generation in unique_generations: + if any(v.hostname == hostname and v.fn2 == fn2 and v.generation == generation for v in validation_status): tr = SubElement(tbody, "tr") - SubElement(tr, "td").text = (generation or "") + " " + (fn2 or "") - for t in totals: - if t.show: - value = sum(int(h.hostname == hostname and h.fn2 == fn2 and h.generation == generation and h.status == t.name) for h in host_data) - elt = SubElement(tr, "td") - if value > 0: - elt.set("class", t.mood) - elt.text = str(value) - tr = SubElement(tbody, "tr") + SubElement(tr, "td").text = ((generation or "") + " " + (fn2 or "")).strip() + for l in labels: + value = sum(int(v.hostname == hostname and v.fn2 == fn2 and v.generation == generation and v.code == l.code) for v in validation_status) + td = SubElement(tr, "td") + if value > 0: + td.set("class", l.mood) + td.text = str(value) + + tr = SubElement(tfoot, "tr") SubElement(tr, "td").text = "Total" - for t in totals: - if t.show: - value = sum(int(h.hostname == hostname and h.status == t.name) for h in host_data) - elt = SubElement(tr, "td") - if value > 0: - elt.set("class", t.mood) - elt.text = str(value) + for l in labels: + value = sum(int(v.hostname == hostname and v.code == l.code) for v in validation_status) + td = SubElement(tr, "td") + if value > 0: + td.set("class", l.mood) + td.text = str(value) if show_problems: SubElement(body, "br") SubElement(body, "h2").text = "Problems" - table = SubElement(body, "table", { "class" : "problems", "rules" : "all", "border" : "1"}) + table = SubElement(body, "table", table_css) thead = SubElement(table, "thead") - tr = SubElement(thead, "tr") - for c in ("Status", "URI"): - elt = SubElement(tr, "td", { "class" : c.lower() }) - SubElement(elt, "b").text = c tbody = SubElement(table, "tbody") - for h in host_data: - if h.mood != "good": - tr = SubElement(tbody, "tr", { "class" : h.mood }) - SubElement(tr, "td", { "class" : "status" }).text = h.label.text - SubElement(tr, "td", { "class" : "uri" }).text = h.uri + tr = SubElement(thead, "tr") + SubElement(tr, "th").text = "Status" + SubElement(tr, "th").text = "URI" + for v in validation_status: + if v.mood != "good": + tr = SubElement(tbody, "tr", { "class" : v.mood }) + SubElement(tr, "td").text = v.label.text + SubElement(tr, "td", uri_css).text = v.uri if show_detailed_status: SubElement(body, "br") SubElement(body, "h2").text = "Validation Status" - table = SubElement(body, "table", { "class" : "details", "rules" : "all", "border" : "1"}) + table = SubElement(body, "table", table_css) thead = SubElement(table, "thead") - tr = SubElement(thead, "tr") - for c in ("Timestamp", "Generation", "Status", "URI"): - elt = SubElement(tr, "td", { "class" : c.lower() }) - SubElement(elt, "b").text = c tbody = SubElement(table, "tbody") - for h in host_data: - tr = SubElement(tbody, "tr", { "class" : h.mood }) - SubElement(tr, "td", { "class" : "timestamp" }).text = h.timestamp - SubElement(tr, "td", { "class" : "generation" }).text = h.generation - SubElement(tr, "td", { "class" : "status" }).text = h.label.text - SubElement(tr, "td", { "class" : "uri" }).text = h.uri + tr = SubElement(thead, "tr") + SubElement(tr, "th").text = "Timestamp" + SubElement(tr, "th").text = "Generation" + SubElement(tr, "th").text = "Status" + SubElement(tr, "th").text = "URI" + for v in validation_status: + tr = SubElement(tbody, "tr", { "class" : v.mood }) + SubElement(tr, "td").text = v.timestamp + SubElement(tr, "td").text = v.generation + SubElement(tr, "td").text = v.label.text + SubElement(tr, "td", uri_css).text = v.uri ElementTree(element = html).write(sys.stdout) |