303 JS = ( |
303 JS = ( |
304 #"/static/jquery/jquery.js", |
304 #"/static/jquery/jquery.js", |
305 'http://code.jquery.com/jquery-1.8.2.js', |
305 'http://code.jquery.com/jquery-1.8.2.js', |
306 'http://code.jquery.com/ui/1.9.0/jquery-ui.js', |
306 'http://code.jquery.com/ui/1.9.0/jquery-ui.js', |
307 '/static/dhcp/spin.js', |
307 '/static/dhcp/spin.js', |
|
308 '/static/dhcp/table.js', |
308 '/static/dhcp/hosts.js', |
309 '/static/dhcp/hosts.js', |
309 ) |
310 ) |
310 |
311 |
311 COLUMNS = ( |
312 COLUMNS = ( |
312 ( 'ip', 'IP', lambda host: host.ip ), |
313 ( 'ip', 'IP', lambda host: host.ip ), |
320 def process (self) : |
321 def process (self) : |
321 """ |
322 """ |
322 Either return JSON (if ?t=...), or fetch hosts/t for rendering. |
323 Either return JSON (if ?t=...), or fetch hosts/t for rendering. |
323 """ |
324 """ |
324 |
325 |
325 hosts = self.db.query(Host) |
|
326 t = self.request.args.get('t') |
326 t = self.request.args.get('t') |
327 |
327 |
328 # always sorted by last_seen |
|
329 hosts = hosts.order_by(Host.last_seen.desc()) |
|
330 |
|
331 # filter |
|
332 self.filters, hosts = self.filter(hosts) |
|
333 |
|
334 def host_params (host) : |
|
335 yield 'id', host.id |
|
336 |
|
337 for name, title, fvalue in self.COLUMNS : |
|
338 value = fvalue(host) |
|
339 |
|
340 if name == 'seen' : |
|
341 # XXX: hackfix html() rendering |
|
342 value = unicode(html.div(value)) |
|
343 |
|
344 yield name, value |
|
345 |
|
346 # special |
|
347 yield 'state_class', host.state_class() |
|
348 |
|
349 if t : |
328 if t : |
350 # return json |
329 # return json |
351 t = ts2dt(int(t)) |
330 t = ts2dt(int(t)) |
352 |
331 |
|
332 # query |
|
333 hosts = self.query() |
|
334 |
|
335 # always sorted by last_seen |
|
336 hosts = hosts.order_by(Host.last_seen.desc()) |
|
337 |
|
338 # filter |
|
339 self.filters, hosts = self.filter(hosts) |
|
340 |
|
341 if t : |
|
342 # return json |
353 hosts = hosts.filter(Host.last_seen > t) |
343 hosts = hosts.filter(Host.last_seen > t) |
354 hosts = list(hosts) |
344 hosts = list(hosts) |
355 hosts.reverse() |
345 hosts.reverse() |
356 |
346 |
357 if hosts : |
347 if hosts : |
|
348 # update timestamp to most recent |
358 t = hosts[-1].last_seen |
349 t = hosts[-1].last_seen |
359 hosts = [dict(host_params(host)) for host in hosts] |
350 |
360 |
351 # json |
361 else : |
|
362 hosts = [] |
|
363 |
|
364 data = dict( |
352 data = dict( |
365 t = dt2ts(t), |
353 t = dt2ts(t), |
366 hosts = hosts, |
354 hosts = [dict(self.table.json(host)) for host in hosts], |
367 ) |
355 ) |
368 |
356 |
369 return response.json(data) |
357 return response.json(data) |
370 |
358 |
371 else : |
359 else : |
372 # render html |
360 # render html |
373 hosts = hosts.limit(10) |
361 hosts = hosts.limit(self.table.PAGE) |
374 |
362 |
375 # XXX: testing |
363 # XXX: testing |
376 hosts = hosts.offset(1) |
364 hosts = hosts.offset(1) |
377 |
365 |
378 self.hosts = list(hosts) |
366 # extract timestamp |
|
367 for host in hosts : |
|
368 self.t = host.last_seen |
|
369 |
|
370 break |
|
371 |
|
372 else : |
|
373 # no hosts :< |
|
374 self.t = datetime.datetime.now() |
379 |
375 |
380 if self.hosts : |
376 # store |
381 self.t = self.hosts[0].last_seen |
377 self.hosts = hosts |
382 else : |
|
383 self.t = datetime.datetime.now() |
|
384 |
378 |
385 def title (self) : |
379 def title (self) : |
386 if self.filters : |
380 if self.filters : |
387 return "{title}: {filters}".format(title=self.TITLE, filters=self.filters_title()) |
381 return "{title}: {filters}".format(title=self.TITLE, filters=self.filters_title()) |
388 else : |
382 else : |
390 |
384 |
391 def render (self) : |
385 def render (self) : |
392 """ |
386 """ |
393 Render page HTML and initial <table>, along with bootstrap JS (t0, configuration). |
387 Render page HTML and initial <table>, along with bootstrap JS (t0, configuration). |
394 """ |
388 """ |
395 |
389 |
396 def column (name, title, fvalue, host) : |
|
397 cls = name |
|
398 |
|
399 if name == 'state' : |
|
400 cls = host.state_class() |
|
401 |
|
402 return html.td(class_=cls)(fvalue(host)) |
|
403 |
|
404 params = dict( |
|
405 url = self.url(), |
|
406 filters = self.filters, |
|
407 t = dt2ts(self.t), |
|
408 host = self.url(ItemHandler, id='0'), |
|
409 columns = [name for name, title, fvalue in self.COLUMNS] |
|
410 ) |
|
411 params = json.dumps(params) |
|
412 |
|
413 return html.div(id='wrapper')( |
390 return html.div(id='wrapper')( |
414 html.input(type='submit', id='refresh', value="Refresh"), |
391 html.input(type='submit', id='refresh', value="Refresh"), |
415 html.input(type='reset', id='pause', value="Pause"), |
392 html.input(type='reset', id='pause', value="Pause"), |
416 html.table(id='hosts')( |
393 |
417 html.thead( |
394 self.table.render(self.hosts)(id='hosts-realtime'), |
418 html.tr( |
395 |
419 html.th('#'), |
396 html.script(type='text/javascript')( |
420 ( |
397 """ |
421 html.th(class_=name)(title) for name, title, fvalue in self.COLUMNS |
398 $(document).ready(HostsRealtime(Table($('#hosts-realtime'), {table_params}), {params})); |
422 ) |
399 """.format( |
423 ), |
400 table_params = json.dumps(dict( |
424 ), |
401 item_url = self.url(ItemHandler, id='0'), |
425 html.tbody( |
402 columns = [column.attr for column in self.table.columns], |
426 html.tr(id=host.id)( |
403 )), |
427 html.td(html.a(href=self.url(ItemHandler, id=host.id))('#')), |
404 params = json.dumps(dict( |
428 ( |
405 url = self.url(), |
429 column(name, title, fvalue, host) for name, title, fvalue in self.COLUMNS |
406 filters = self.filters, |
430 ), |
407 t = dt2ts(self.t), |
431 ) for host in self.hosts |
408 )), |
432 ) |
409 ) |
433 ), |
|
434 html.script(type='text/javascript')(""" |
|
435 $(document).ready(hosts_realtime({params})); |
|
436 """.format(params=params) |
|
437 ) |
410 ) |
438 ) |
411 ) |
439 |
412 |