-
+% if instance.enabled and master.restartable_client(instance) and request.has_perm('{}.restart'.format(route_prefix)):
+
+
Client Tools
+
+
+
% endif
+
+
+ ${form.render()|n}
+
+
+% if master.has_rows:
+ ${rows_grid|n}
+% endif
diff --git a/tailbone/views/tempmon/clients.py b/tailbone/views/tempmon/clients.py
index 3fd41723..1b9fd37d 100644
--- a/tailbone/views/tempmon/clients.py
+++ b/tailbone/views/tempmon/clients.py
@@ -35,6 +35,7 @@ from rattail_tempmon.db import model as tempmon
import colander
from webhelpers2.html import HTML, tags
+from tailbone import grids
from tailbone.views.tempmon import MasterView
@@ -48,6 +49,9 @@ class TempmonClientView(MasterView):
route_prefix = 'tempmon.clients'
url_prefix = '/tempmon/clients'
+ has_rows = True
+ model_row_class = tempmon.Reading
+
grid_columns = [
'config_key',
'hostname',
@@ -71,6 +75,12 @@ class TempmonClientView(MasterView):
'archived',
]
+ row_grid_columns = [
+ 'probe',
+ 'taken',
+ 'degrees_f',
+ ]
+
def configure_grid(self, g):
super(TempmonClientView, self).configure_grid(g)
@@ -106,15 +116,21 @@ class TempmonClientView(MasterView):
f.set_enum('disk_type', self.enum.TEMPMON_DISK_TYPE)
f.widgets['disk_type'].values.insert(0, ('', "(unknown)"))
+ # delay
+ f.set_helptext('delay', tempmon.Client.delay.__doc__)
+
# probes
- f.set_renderer('probes', self.render_probes)
+ if self.viewing:
+ f.set_renderer('probes', self.render_probes)
+ else:
+ f.remove_field('probes')
# notes
f.set_type('notes', 'text')
+ # online
if self.creating or self.editing:
- f.remove_fields('probes',
- 'online')
+ f.remove_field('online')
def unique_config_key(self, node, value):
query = self.Session.query(tempmon.Client)\
@@ -126,15 +142,43 @@ class TempmonClientView(MasterView):
raise colander.Invalid(node, "Config key must be unique")
def render_probes(self, client, field):
- probes = client.probes
- if not probes:
+ if not client.probes:
return ""
- items = []
- for probe in probes:
- text = six.text_type(probe)
- url = self.request.route_url('tempmon.probes.view', uuid=probe.uuid)
- items.append(HTML.tag('li', c=[tags.link_to(text, url)]))
- return HTML.tag('ul', c=items)
+
+ route_prefix = self.get_route_prefix()
+ view_url = lambda p, i: self.request.route_url('tempmon.probes.view', uuid=p.uuid)
+ actions = [
+ grids.GridAction('view', icon='zoomin', url=view_url),
+ ]
+ if self.request.has_perm('tempmon.probes.edit'):
+ url = lambda p, i: self.request.route_url('tempmon.probes.edit', uuid=p.uuid)
+ actions.append(grids.GridAction('edit', icon='pencil', url=url))
+
+ g = grids.Grid(
+ key='{}.probes'.format(route_prefix),
+ data=client.probes,
+ columns=[
+ 'description',
+ 'critical_temp_min',
+ 'good_temp_min',
+ 'good_temp_max',
+ 'critical_temp_max',
+ 'status',
+ 'enabled',
+ ],
+ labels={
+ 'critical_temp_min': "Crit. Min",
+ 'good_temp_min': "Good Min",
+ 'good_temp_max': "Good Max",
+ 'critical_temp_max': "Crit. Max",
+ },
+ url=lambda p: self.request.route_url('tempmon.probes.view', uuid=p.uuid),
+ linked_columns=['description'],
+ main_actions=actions,
+ )
+ g.set_enum('status', self.enum.TEMPMON_PROBE_STATUS)
+ g.set_type('enabled', 'boolean')
+ return HTML.literal(g.render_grid())
def delete_instance(self, client):
# bulk-delete all readings first
@@ -149,6 +193,24 @@ class TempmonClientView(MasterView):
self.Session.delete(client)
self.Session.flush()
+ def get_row_data(self, client):
+ query = self.Session.query(tempmon.Reading)\
+ .join(tempmon.Probe)\
+ .filter(tempmon.Reading.client == client)
+ return query
+
+ def get_parent(self, reading):
+ return reading.client
+
+ def configure_row_grid(self, g):
+ super(TempmonClientView, self).configure_row_grid(g)
+
+ # probe
+ g.set_filter('probe', tempmon.Probe.description)
+ g.set_sorter('probe', tempmon.Probe.description)
+
+ g.set_sort_defaults('taken', 'desc')
+
def restartable_client(self, client):
return True
diff --git a/tailbone/views/tempmon/probes.py b/tailbone/views/tempmon/probes.py
index dda7192f..2320fa34 100644
--- a/tailbone/views/tempmon/probes.py
+++ b/tailbone/views/tempmon/probes.py
@@ -34,6 +34,7 @@ import colander
from deform import widget as dfwidget
from webhelpers2.html import tags
+from tailbone import grids
from tailbone.views.tempmon import MasterView
@@ -47,6 +48,9 @@ class TempmonProbeView(MasterView):
route_prefix = 'tempmon.probes'
url_prefix = '/tempmon/probes'
+ has_rows = True
+ model_row_class = tempmon.Reading
+
grid_columns = [
'client',
'config_key',
@@ -74,6 +78,11 @@ class TempmonProbeView(MasterView):
'status',
]
+ row_grid_columns = [
+ 'taken',
+ 'degrees_f',
+ ]
+
def configure_grid(self, g):
super(TempmonProbeView, self).configure_grid(g)
@@ -103,8 +112,10 @@ class TempmonProbeView(MasterView):
f.set_label('client', "Tempmon Client")
if self.creating or self.editing:
f.replace('client', 'client_uuid')
- clients = self.Session.query(tempmon.Client)\
- .order_by(tempmon.Client.config_key)
+ clients = self.Session.query(tempmon.Client)
+ if self.creating:
+ clients = clients.filter(tempmon.Client.archived == False)
+ clients = clients.order_by(tempmon.Client.config_key)
client_values = [(client.uuid, "{} ({})".format(client.config_key, client.hostname))
for client in clients]
f.set_widget('client_uuid', dfwidget.SelectWidget(values=client_values))
@@ -151,6 +162,23 @@ class TempmonProbeView(MasterView):
self.Session.delete(probe)
self.Session.flush()
+ def get_row_data(self, probe):
+ query = self.Session.query(tempmon.Reading)\
+ .filter(tempmon.Reading.probe == probe)
+ return query
+
+ def get_parent(self, reading):
+ return reading.client
+
+ def configure_row_grid(self, g):
+ super(TempmonProbeView, self).configure_row_grid(g)
+
+ # # probe
+ # g.set_filter('probe', tempmon.Probe.description)
+ # g.set_sorter('probe', tempmon.Probe.description)
+
+ g.set_sort_defaults('taken', 'desc')
+
def includeme(config):
TempmonProbeView.defaults(config)