summaryrefslogtreecommitdiff
path: root/lorrycontroller/htmlstatus.py
diff options
context:
space:
mode:
Diffstat (limited to 'lorrycontroller/htmlstatus.py')
-rw-r--r--lorrycontroller/htmlstatus.py286
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)
-