diff options
Diffstat (limited to 'lorrycontroller/htmlstatus.py')
-rw-r--r-- | lorrycontroller/htmlstatus.py | 286 |
1 files changed, 0 insertions, 286 deletions
diff --git a/lorrycontroller/htmlstatus.py b/lorrycontroller/htmlstatus.py deleted file mode 100644 index 30b52f0..0000000 --- a/lorrycontroller/htmlstatus.py +++ /dev/null @@ -1,286 +0,0 @@ -# Copyright (C) 2013 Codethink Limited -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -import os -import time -from cgi import escape - -state_names = [ - "Initialisation", - "Load Troves", - "Remove old repos", - "Create new repos", - "Process Lorries", - "Finished" - ] - -def format_time(time_t): - return time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime(time_t)) - -class HTMLStatusManager(object): - '''Manage the HTML status page for lorry-controller.''' - - - def __init__(self, app): - self.app = app - self.state = 0 - self.series = None - self.filename = self.app.settings['html-file'] - self.mgr = None - self.all_processing = set() - self.processing = None - self.processing_time = time.time() - self.failing = None - self.all_lorries_ever = set() - self.bump_time = time.time() - - def set_failing(self, failmsg): - self.failing = failmsg - self.write_out_status() - - def set_mgr(self, mgr): - self.mgr = mgr - - def set_processing(self, proc): - if self.processing is not None: - self.all_processing.add(self.processing) - self.processing = proc - self.processing_time = time.time() - self.write_out_status() - - def bump_state(self): - self.state = self.state + 1 - self.bump_time = time.time() - self.processing = None - self.write_out_status() - - def write_out_status(self): - if self.filename is None: return - try: - with open(self.filename + ".new", "w") as ofh: - ofh.write("<!DOCTYPE html>\n") - ofh.write(self.gen_html()) - ofh.write("\n") - target = self.filename - if self.series is not None: - target += ".%d" % self.series - self.series += 1 - os.rename(self.filename + ".new", target) - except: - os.unlink(self.filename + ".new") - raise - - def gen_html(self): - head = self.gen_head() - body = self.gen_body() - return self.tag("html", content=head+"\n"+body, gap=True) - - def gen_head(self): - title = self.tag("title", content="Lorry Controller") - css = self.tag("link", href="trove.css", rel="stylesheet", - type="text/css") - script = self.tag( - "script", type="text/javascript", src="/table.js", content="") - return self.tag("head", content=title+css+script) - - def gen_body(self): - # 1. Rough header, branded as trove - curtime = format_time(time.time()) - link = "/" - if self.series is not None: - link = self.filename + ".%d" % (self.series + 1) - header = ''' -<table id='header'><tr><td class='logo' rowspan='2'> -<a href='%s'><img src='trove.png' alt='trove logo'/></a></td> -<td class='main'>Status of Lorry Controller</td></tr> -<tr><td class='sub'>Updated at %s</td></tr></table> -''' % (link, curtime) - # 2. List of steps and where we are currently - steps = self.gen_steps() - - # 4. Main content - content = self.gen_content() - - # 5. footer - footer = self.gen_footer() - - # magic args - return self.tag("body", content=self.tag( - "div", content=(header+steps+content+footer), - Class="lorrycontroller")) - - def gen_content(self): - if self.failing is not None: - return self.tag("div", Class="failure", content=self.failing) - # 1. Troves known - troves = self.gen_troves() - # 2. Lorries known - lorries = self.gen_lorries() - - return self.tag("div", Class="content", content= - self.tag("div", id="troves", content=troves) + - self.tag("div", id="lorries", content=lorries)) - - def gen_troves(self): - troves = [] - now = time.time() - for trove in self.app.conf.troves: - troveinfo = {} - if self.mgr is not None: - troveinfo = self.mgr.trove_state.get(trove['uuid'], {}) - uuid = self.tag("td", content=escape(trove['uuid'])) - state = "Up to date" - if self.processing == trove['uuid']: - state = "Processing since " + \ - format_time(self.processing_time) - elif troveinfo.get('next-vls', now - 1) < now: - if self.state < len(state_names) - 1: - state = "Due to be checked this run." - else: - state = "Due to be checked on the next run" - state = self.tag("td", content=escape(state)) - nextdue = self.tag("td", content=escape(format_time( - troveinfo.get('next-vls', now - 1)))) - lorrycount = len([l for l in self.app.conf.lorries.itervalues() - if l['controller-uuid'] == trove['uuid']]) - lorrycount = self.tag("td", content=str(lorrycount)) - - troves.append(self.tag("tr", content= - uuid+state+nextdue+lorrycount)) - if len(troves) == 0: - content = "No troves detected" - else: - header = self.tag("tr", content= - self.tag("th", content="Trove UUID") + - self.tag("th", content="Status") + - self.tag("th", content="Next due") + - self.tag("th", content="Lorries created")) - content = self.tag("table", content= - header + "".join(troves)) - - return content - - def gen_lorries(self): - lorries = [] - now = time.time() - all_lorry_names = set(self.app.conf.lorries.keys()) - if self.mgr is not None: - all_lorry_names.update(set(self.mgr.lorry_state.keys())) - self.all_lorries_ever.update(all_lorry_names) - all_lorry_names = list(self.all_lorries_ever) - all_lorry_names.sort() - for lorry_name in all_lorry_names: - lorry = self.app.conf.lorries.get(lorry_name, None) - dead_lorry = False - dead_and_gone = False - if lorry is None: - lorrystate = self.mgr.lorry_state.get(lorry_name, None) - if lorrystate is None: - dead_and_gone = True - lorry = {} - else: - lorry = lorrystate['lorry'] - dead_lorry = True - lorryinfo = {} - if self.mgr is not None: - lorryinfo = self.mgr.lorry_state.get(lorry_name, {}) - uuid = self.tag("td", content= - escape(lorry.get('controller-uuid', 'Dead'))) - state = "Waiting " - if self.processing == lorry_name: - state = "Processing since " + \ - format_time(self.processing_time) - elif lorryinfo.get('next-due', now - 1) < self.bump_time: - if self.state < len(state_names) - 1: - state = "Due to be checked this run." - else: - state = "Due to be checked on the next run" - if self.mgr is not None: - if self.mgr.lorry_state.get(lorry_name, None) is None: - state = "Needs creating" - elif lorry_name in self.all_processing: - state = "Processed" - if dead_lorry: - state = "Dead - To be removed" - if dead_and_gone: - state = "Dead" - if self.processing == lorry_name: - state = "Removing since " + \ - format_time(self.processing_time) - state = self.tag("td", content=escape(state)) - lastresult = self.tag("td", content=self.tag( - "pre", content=escape(lorryinfo.get('result', '-')))) - nextdue = self.tag("td", content=escape(format_time( - lorryinfo.get('next-due', now - 1)))) - lorryname = self.tag("td", content=escape(lorry_name)) - lorries.append(self.tag("tr", content= - lorryname+uuid+state+lastresult+nextdue)) - if len(lorries) == 0: - content = "No lorries detected yet" - else: - header = self.tag("tr", content= - self.tag("th", - Class="table-sortable:alphanumeric", - content="Lorry Name") + - self.tag("th", - Class="table-sortable:alphanumeric", - content="Comes From") + - self.tag("th", - Class="table-sortable:alphanumeric", - content="Status") + - self.tag("th", - Class="table-sortable:alphanumeric", - content="Last result") + - self.tag("th", - Class="table-sortable:alphanumeric", - content="Next due")) - header = self.tag("thead", content=header) - content = self.tag("table", Class="table-autosort:4", content= - header + "\n" + "\n".join(lorries)) - - return content - - - def gen_footer(self): - curtime = format_time(time.time()) - return self.tag("div", Class="footer", content= - "Generated by Lorry Controller at " + curtime) - - def gen_steps(self): - steps = [] - for idx in xrange(len(state_names)): - if idx < self.state: - Class = "donestep" - elif idx == self.state: - Class = "activestep" - else: - Class = "pendingstep" - steps.append(self.tag("span", Class=Class, - content=state_names[idx])) - return self.tag("table", Class="steps", content= - self.tag("tr", content= - self.tag("td", content= - "".join(steps)))) - - def tag(self, tagname, content=None, gap=False, **kwargs): - tagval = " ".join([tagname] + - ["%s=%r" % (k.lower(), v) for k, v in kwargs.iteritems()]) - gap = "\n" if gap else "" - if content is None: - return "<%s />" % tagval - else: - return "<%s>%s%s%s</%s>" % (tagval, gap, content, gap, tagname) - |