summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <lars.wirzenius@codethink.co.uk>2014-02-24 16:29:19 +0000
committerLars Wirzenius <lars.wirzenius@codethink.co.uk>2014-02-24 16:29:19 +0000
commitb214d56da3e404107ee5e9512cee1e38e358ceb8 (patch)
treea041fba80b90793d7bdf4cbbec7c6b4cae8a7733
parenta2ce097c089156023da2e7c03f5c5aa6953ec580 (diff)
downloadlorry-controller-b214d56da3e404107ee5e9512cee1e38e358ceb8.tar.gz
Show run-queue contents in HTML status
-rwxr-xr-xlorry-controller-webapp126
1 files changed, 105 insertions, 21 deletions
diff --git a/lorry-controller-webapp b/lorry-controller-webapp
index ba1cdf5..0ff9d65 100755
--- a/lorry-controller-webapp
+++ b/lorry-controller-webapp
@@ -31,24 +31,76 @@ import cliapp
from flup.server.fcgi import WSGIServer
-STATUS_HTML_TEMPLATE = '''
+STATUS_HTML_TEMPLATE = '''\
<!DOCTYPE HTML>
<html>
- <head>
- <title>Lorry Controller status</title>
- </head>
- <body>
- <blockquote>{quote}</blockquote>
-
- <h1>Status of Lorry Controller</h1>
-
- <p>Running queue: {running-queue}.</p>
- <p>Free disk space: {disk-free-gib} GiB.</p>
-
- <hr>
-
- <p>Updated: {timestamp}</p>
- </body>
+ <head>
+ <title>Lorry Controller status</title>
+
+ <style>
+table {
+ border: 1px solid black;
+}
+
+th, td {
+ padding-right: 2em;
+}
+
+th {
+ font-weight: bold;
+ text-align: left;
+}
+
+td {
+ font-family: monospace;
+ border-top: 1px solid black;
+ text-align: left;
+}
+ </style>
+
+ </head>
+ <body>
+ % import json
+
+ <h1>Status of Lorry Controller</h1>
+
+ <p>Running jobs from run-queue: {{"yes" if running_queue else "no"}}.</p>
+
+ <p>Free disk space: {{disk_free_gib}} GiB.</p>
+
+ <h2>Run-queue</h2>
+
+ <table>
+ <tr>
+<th>Pos</th>
+<th>Path</th>
+<th>URL</th>
+<th>Interval</th>
+<th>Due</th>
+<th>Job</th>
+ </tr>
+ % for i, spec in enumerate(run_queue):
+ % obj = json.loads(spec['text'])
+ % name = obj.keys()[0]
+ % fields = obj[name]
+ <tr>
+<td>{{i+1}}</td>
+<td>{{spec['path']}}</td>
+<td>{{fields['url']}}</td>
+<td>{{spec['interval']}}</td>
+<td>{{spec['due_nice']}}</td>
+<td>{{spec['running_job']}}</td>
+ </tr>
+ % end
+ </table>
+
+ <hr />
+
+ <p>Scotty says: {{quote}}</p>
+
+ <p>Updated: {{timestamp}}</p>
+
+ </body>
</html>
'''
@@ -274,14 +326,15 @@ class StatusRenderer(object):
import random
status = {
'quote': '%s' % random.choice(quotes),
- 'running-queue': statedb.get_running_queue(),
+ 'running_queue': statedb.get_running_queue(),
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
+ 'run_queue': self.get_run_queue(statedb),
}
status.update(self.get_free_disk_space(work_directory))
return status
def render_status_as_html(self, status):
- return STATUS_HTML_TEMPLATE.format(**status)
+ return bottle.template(STATUS_HTML_TEMPLATE, **status)
def write_status_as_html(self, status, filename):
html = self.render_status_as_html(status)
@@ -292,11 +345,42 @@ class StatusRenderer(object):
result = os.statvfs(dirname)
free_bytes = result.f_bavail * result.f_bsize
return {
- 'disk-free': free_bytes,
- 'disk-free-mib': free_bytes / 1024**2,
- 'disk-free-gib': free_bytes / 1024**2,
+ 'disk_free': free_bytes,
+ 'disk_free_mib': free_bytes / 1024**2,
+ 'disk_free_gib': free_bytes / 1024**3,
}
+ def get_run_queue(self, statedb):
+ lorries = statedb.get_all_lorries_info()
+ now = time.time()
+ for lorry in lorries:
+ exact = time.strftime(
+ '%Y-%m-%d %H:%M:%S UTC',
+ time.gmtime(lorry['due']))
+ nice = self.format_secs_nicely(lorry['due'] - now)
+ lorry['due_nice'] = '%s (%s)' % (exact, nice)
+ return lorries
+
+ def format_secs_nicely(self, secs):
+ if secs <= 0:
+ return 'now'
+
+ result = []
+
+ hours = secs / 3600
+ if hours > 0:
+ result.append('%d hours' % hours)
+ secs %= 3600
+
+ mins = secs / 60
+ if mins > 0 or hours > 0:
+ result.append('%d mins' % mins)
+ secs %= 60
+
+ result.append('%d secs' % secs)
+
+ return ' '.join(result)
+
class Status(LorryControllerRoute):