--- a/pvl/verkko/hosts.py Sun Feb 10 13:18:21 2013 +0200
+++ b/pvl/verkko/hosts.py Sun Feb 10 13:20:29 2013 +0200
@@ -305,6 +305,7 @@
'http://code.jquery.com/jquery-1.8.2.js',
'http://code.jquery.com/ui/1.9.0/jquery-ui.js',
'/static/dhcp/spin.js',
+ '/static/dhcp/table.js',
'/static/dhcp/hosts.js',
)
@@ -322,8 +323,14 @@
Either return JSON (if ?t=...), or fetch hosts/t for rendering.
"""
- hosts = self.db.query(Host)
t = self.request.args.get('t')
+
+ if t :
+ # return json
+ t = ts2dt(int(t))
+
+ # query
+ hosts = self.query()
# always sorted by last_seen
hosts = hosts.order_by(Host.last_seen.desc())
@@ -331,56 +338,43 @@
# filter
self.filters, hosts = self.filter(hosts)
- def host_params (host) :
- yield 'id', host.id
-
- for name, title, fvalue in self.COLUMNS :
- value = fvalue(host)
-
- if name == 'seen' :
- # XXX: hackfix html() rendering
- value = unicode(html.div(value))
-
- yield name, value
-
- # special
- yield 'state_class', host.state_class()
-
if t :
# return json
- t = ts2dt(int(t))
-
hosts = hosts.filter(Host.last_seen > t)
hosts = list(hosts)
hosts.reverse()
if hosts :
+ # update timestamp to most recent
t = hosts[-1].last_seen
- hosts = [dict(host_params(host)) for host in hosts]
- else :
- hosts = []
-
+ # json
data = dict(
t = dt2ts(t),
- hosts = hosts,
+ hosts = [dict(self.table.json(host)) for host in hosts],
)
return response.json(data)
else :
# render html
- hosts = hosts.limit(10)
+ hosts = hosts.limit(self.table.PAGE)
# XXX: testing
hosts = hosts.offset(1)
- self.hosts = list(hosts)
+ # extract timestamp
+ for host in hosts :
+ self.t = host.last_seen
+
+ break
+
+ else :
+ # no hosts :<
+ self.t = datetime.datetime.now()
- if self.hosts :
- self.t = self.hosts[0].last_seen
- else :
- self.t = datetime.datetime.now()
+ # store
+ self.hosts = hosts
def title (self) :
if self.filters :
@@ -392,48 +386,27 @@
"""
Render page HTML and initial <table>, along with bootstrap JS (t0, configuration).
"""
-
- def column (name, title, fvalue, host) :
- cls = name
-
- if name == 'state' :
- cls = host.state_class()
-
- return html.td(class_=cls)(fvalue(host))
-
- params = dict(
- url = self.url(),
- filters = self.filters,
- t = dt2ts(self.t),
- host = self.url(ItemHandler, id='0'),
- columns = [name for name, title, fvalue in self.COLUMNS]
- )
- params = json.dumps(params)
-
+
return html.div(id='wrapper')(
html.input(type='submit', id='refresh', value="Refresh"),
html.input(type='reset', id='pause', value="Pause"),
- html.table(id='hosts')(
- html.thead(
- html.tr(
- html.th('#'),
- (
- html.th(class_=name)(title) for name, title, fvalue in self.COLUMNS
- )
- ),
- ),
- html.tbody(
- html.tr(id=host.id)(
- html.td(html.a(href=self.url(ItemHandler, id=host.id))('#')),
- (
- column(name, title, fvalue, host) for name, title, fvalue in self.COLUMNS
- ),
- ) for host in self.hosts
+
+ self.table.render(self.hosts)(id='hosts-realtime'),
+
+ html.script(type='text/javascript')(
+ """
+$(document).ready(HostsRealtime(Table($('#hosts-realtime'), {table_params}), {params}));
+ """.format(
+ table_params = json.dumps(dict(
+ item_url = self.url(ItemHandler, id='0'),
+ columns = [column.attr for column in self.table.columns],
+ )),
+ params = json.dumps(dict(
+ url = self.url(),
+ filters = self.filters,
+ t = dt2ts(self.t),
+ )),
)
- ),
- html.script(type='text/javascript')("""
-$(document).ready(hosts_realtime({params}));
-""".format(params=params)
)
)
--- a/static/dhcp/hosts.js Sun Feb 10 13:18:21 2013 +0200
+++ b/static/dhcp/hosts.js Sun Feb 10 13:20:29 2013 +0200
@@ -43,33 +43,20 @@
return this;
};
-function html (tag, params, html) {
- return $("<" + tag + " />", $.extend({html: html}, params));
-};
-
-function hosts_realtime (params) {
+/*
+ * Initialize the realtime host table.
+ *
+ * table - Table to manipulate
+ * url - base URL for ?t=...
+ * filters - { attr: value } for ?t=...
+ * t - ?t=... to poll for
+ *
+ * $(document).ready(HostsRealtime(Table(...), ...));
+ *
+ */
+function HostsRealtime (table, params) {
var t = params.t;
var refreshTimer = Timer(2 * 1000, refresh);
- var animate = false; // true;
-
- function render_host (host) {
- var columns = [
- html("td", {},
- html("a", { href: params.host.replace('0', host.id) }, "#" )
- ),
- ];
-
- $.each(params.columns, function (i, name) {
- column = html("td", { class: name }, host[name]);
-
- if (name == 'state')
- column.addClass(host['state_class']);
-
- columns.push(column);
- });
-
- return html("tr", {id: host.id}, columns);
- }
// XXX: refresh > interval?
function refresh () {
@@ -88,27 +75,12 @@
console.log("refresh: " + t + " -> " + t1 + ": " + hosts.length);
$.each(hosts, function (i, host) {
- var item = $('#' + host.id);
-
- if (item.length) {
- if (animate) item.slideUp();
- } else {
- item = render_host(host)
-
- if (animate) item.hide();
- }
-
- // move to top
- item.prependTo($('#hosts tbody'));
-
- if (animate)
- item.slideDown();
- else
- item.effect("highlight", {}, 'slow');
+ table.update(host);
});
// update
t = t1;
+
}).error(function () {
alert("Error :(");
@@ -123,9 +95,6 @@
return function () {
// init
- if (animate)
- $("#hosts").css('display', 'block');
-
$("#refresh").click(function () {
// in case diabled on error
refreshTimer.enable();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/static/dhcp/table.js Sun Feb 10 13:20:29 2013 +0200
@@ -0,0 +1,70 @@
+/*
+ * Dynamic pvl.verkko.table frontend.
+ */
+function html (tag, params, html) {
+ return $("<" + tag + " />", $.extend({html: html}, params));
+};
+
+/*
+ * item_url - base URL path to /items/0 by id=0
+ * columns - [ column_name ]
+ * animate - attempt to animate table..
+ */
+function Table (table, params) {
+ var tbody = table.children('tbody');
+ var animate = params.animate || false;
+
+ if (animate)
+ table.css('display', 'block');
+
+ /*
+ * Render <tr> for item.
+ */
+ function render_tr (item) {
+ var columns = [
+ html("th", {},
+ html("a", { href: params.item_url.replace('0', item.id) }, "#" )
+ ),
+ ];
+
+ $.each(params.columns, function (i, column) {
+ var col = item[column];
+ var td = html("td", { title: col.title }, col.html);
+
+ $.each(col.css, function (i, css) {
+ td.addClass(css);
+ });
+
+ columns.push(td);
+ });
+
+ return html("tr", { id: item.id }, columns);
+ }
+
+ return {
+ animate: animate,
+
+ /*
+ * Update given item into our <table>
+ */
+ update: function (item) {
+ var tr = $('#' + item.id);
+
+ if (tr.length) {
+ if (animate) tr.slideUp();
+ } else {
+ tr = render_tr(item)
+
+ if (animate) tr.hide();
+ }
+
+ // move to top
+ tr.prependTo(tbody);
+
+ if (animate)
+ tr.slideDown();
+ else
+ tr.effect("highlight", {}, 'slow');
+ }
+ }
+};