Refactor all tempmon views to use master3

This commit is contained in:
Lance Edgar 2018-01-08 20:57:22 -06:00
parent ce0195bd51
commit 365a48110c
5 changed files with 140 additions and 119 deletions

View file

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar # Copyright © 2010-2018 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -26,7 +26,7 @@ Views for tempmon
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
from .core import MasterView, ClientFieldRenderer, ProbeFieldRenderer from .core import MasterView
def includeme(config): def includeme(config):

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar # Copyright © 2010-2018 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -28,37 +28,16 @@ from __future__ import unicode_literals, absolute_import
import subprocess import subprocess
import six
from rattail_tempmon.db import model as tempmon from rattail_tempmon.db import model as tempmon
import formalchemy as fa import colander
from webhelpers2.html import HTML, tags from webhelpers2.html import HTML, tags
from tailbone.db import TempmonSession
from tailbone.views.tempmon import MasterView from tailbone.views.tempmon import MasterView
class ProbesFieldRenderer(fa.FieldRenderer):
def render_readonly(self, **kwargs):
probes = self.raw_value
if not probes:
return ''
items = []
for probe in probes:
items.append(HTML.tag('li', c=tags.link_to(probe, self.request.route_url('tempmon.probes.view', uuid=probe.uuid))))
return HTML.tag('ul', c=items)
def unique_config_key(value, field):
client = field.parent.model
query = TempmonSession.query(tempmon.Client)\
.filter(tempmon.Client.config_key == value)
if client.uuid:
query = query.filter(tempmon.Client.uuid != client.uuid)
if query.count():
raise fa.ValidationError("Config key must be unique")
class TempmonClientView(MasterView): class TempmonClientView(MasterView):
""" """
Master view for tempmon clients. Master view for tempmon clients.
@ -78,6 +57,16 @@ class TempmonClientView(MasterView):
'online', 'online',
] ]
form_fields = [
'config_key',
'hostname',
'location',
'delay',
'probes',
'enabled',
'online',
]
def configure_grid(self, g): def configure_grid(self, g):
super(TempmonClientView, self).configure_grid(g) super(TempmonClientView, self).configure_grid(g)
g.filters['hostname'].default_active = True g.filters['hostname'].default_active = True
@ -95,24 +84,38 @@ class TempmonClientView(MasterView):
g.set_link('hostname') g.set_link('hostname')
g.set_link('location') g.set_link('location')
def _preconfigure_fieldset(self, fs): def configure_form(self, f):
fs.config_key.set(validate=unique_config_key) super(TempmonClientView, self).configure_form(f)
fs.probes.set(renderer=ProbesFieldRenderer)
# config_key
f.set_validator('config_key', self.unique_config_key)
# probes
f.set_renderer('probes', self.render_probes)
def configure_fieldset(self, fs):
fs.configure(
include=[
fs.config_key,
fs.hostname,
fs.location,
fs.delay,
fs.probes,
fs.enabled,
fs.online,
])
if self.creating or self.editing: if self.creating or self.editing:
del fs.probes f.remove_fields('probes',
del fs.online 'online')
def unique_config_key(self, node, value):
query = self.Session.query(tempmon.Client)\
.filter(tempmon.Client.config_key == value)
if self.editing:
client = self.get_instance()
query = query.filter(tempmon.Client.uuid != client.uuid)
if query.count():
raise colander.Invalid(node, "Config key must be unique")
def render_probes(self, client, field):
probes = client.probes
if not 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)
def delete_instance(self, client): def delete_instance(self, client):
# bulk-delete all readings first # bulk-delete all readings first

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar # Copyright © 2010-2018 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -28,14 +28,11 @@ from __future__ import unicode_literals, absolute_import
from rattail_tempmon.db import Session as RawTempmonSession from rattail_tempmon.db import Session as RawTempmonSession
from formalchemy.fields import SelectFieldRenderer
from webhelpers2.html import tags
from tailbone import views from tailbone import views
from tailbone.db import TempmonSession from tailbone.db import TempmonSession
class MasterView(views.MasterView2): class MasterView(views.MasterView3):
""" """
Base class for tempmon views. Base class for tempmon views.
""" """
@ -43,21 +40,3 @@ class MasterView(views.MasterView2):
def get_bulk_delete_session(self): def get_bulk_delete_session(self):
return RawTempmonSession() return RawTempmonSession()
class ClientFieldRenderer(SelectFieldRenderer):
def render_readonly(self, **kwargs):
client = self.raw_value
if not client:
return ''
return tags.link_to(client, self.request.route_url('tempmon.clients.view', uuid=client.uuid))
class ProbeFieldRenderer(SelectFieldRenderer):
def render_readonly(self, **kwargs):
probe = self.raw_value
if not probe:
return ''
return tags.link_to(probe, self.request.route_url('tempmon.probes.view', uuid=probe.uuid))

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar # Copyright © 2010-2018 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -26,23 +26,15 @@ Views for tempmon probes
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
import six
from rattail_tempmon.db import model as tempmon from rattail_tempmon.db import model as tempmon
import formalchemy as fa import colander
from webhelpers2.html import tags
from tailbone import forms from tailbone import forms
from tailbone.db import TempmonSession from tailbone.views.tempmon import MasterView
from tailbone.views.tempmon import MasterView, ClientFieldRenderer
def unique_config_key(value, field):
probe = field.parent.model
query = TempmonSession.query(tempmon.Probe)\
.filter(tempmon.Probe.config_key == value)
if probe.uuid:
query = query.filter(tempmon.Probe.uuid != probe.uuid)
if query.count():
raise fa.ValidationError("Config key must be unique")
class TempmonProbeView(MasterView): class TempmonProbeView(MasterView):
@ -65,6 +57,22 @@ class TempmonProbeView(MasterView):
'status', 'status',
] ]
form_fields = [
'client',
'config_key',
'appliance_type',
'description',
'device_path',
'critical_temp_min',
'good_temp_min',
'good_temp_max',
'critical_temp_max',
'therm_status_timeout',
'status_alert_timeout',
'enabled',
'status',
]
def configure_grid(self, g): def configure_grid(self, g):
super(TempmonProbeView, self).configure_grid(g) super(TempmonProbeView, self).configure_grid(g)
@ -83,31 +91,40 @@ class TempmonProbeView(MasterView):
g.set_link('config_key') g.set_link('config_key')
g.set_link('description') g.set_link('description')
def _preconfigure_fieldset(self, fs): def configure_form(self, f):
fs.config_key.set(validate=unique_config_key) super(TempmonProbeView, self).configure_form(f)
fs.client.set(label="TempMon Client", renderer=ClientFieldRenderer)
fs.appliance_type.set(renderer=forms.renderers.EnumFieldRenderer(self.enum.TEMPMON_APPLIANCE_TYPE))
fs.status.set(renderer=forms.renderers.EnumFieldRenderer(self.enum.TEMPMON_PROBE_STATUS))
def configure_fieldset(self, fs): # config_key
fs.configure( f.set_validator('config_key', self.unique_config_key)
include=[
fs.client, # client
fs.config_key, f.set_renderer('client', self.render_client)
fs.appliance_type, f.set_label('client', "Tempmon Client")
fs.description,
fs.device_path, # appliance_type
fs.critical_temp_min, f.set_enum('appliance_type', self.enum.TEMPMON_APPLIANCE_TYPE)
fs.good_temp_min,
fs.good_temp_max, # status
fs.critical_temp_max, f.set_enum('status', self.enum.TEMPMON_PROBE_STATUS)
fs.therm_status_timeout,
fs.status_alert_timeout,
fs.enabled,
fs.status,
])
if self.creating or self.editing: if self.creating or self.editing:
del fs.status f.remove_fields('status')
def unique_config_key(self, node, value):
query = self.Session.query(tempmon.Probe)\
.filter(tempmon.Probe.config_key == value)
if self.editing:
probe = self.get_instance()
query = query.filter(tempmon.Probe.uuid != probe.uuid)
if query.count():
raise colander.Invalid(node, "Config key must be unique")
def render_client(self, probe, field):
client = probe.client
if not client:
return ""
text = six.text_type(client)
url = self.request.route_url('tempmon.clients.view', uuid=client.uuid)
return tags.link_to(text, url)
def delete_instance(self, probe): def delete_instance(self, probe):
# bulk-delete all readings first # bulk-delete all readings first

View file

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2017 Lance Edgar # Copyright © 2010-2018 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -26,13 +26,14 @@ Views for tempmon readings
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
import six
from sqlalchemy import orm from sqlalchemy import orm
from rattail_tempmon.db import model as tempmon from rattail_tempmon.db import model as tempmon
import formalchemy as fa from webhelpers2.html import tags
from tailbone.views.tempmon import MasterView, ClientFieldRenderer, ProbeFieldRenderer from tailbone.views.tempmon import MasterView
class TempmonReadingView(MasterView): class TempmonReadingView(MasterView):
@ -56,6 +57,13 @@ class TempmonReadingView(MasterView):
'degrees_f', 'degrees_f',
] ]
form_fields = [
'client',
'probe',
'taken',
'degrees_f',
]
def query(self, session): def query(self, session):
return session.query(tempmon.Reading)\ return session.query(tempmon.Reading)\
.join(tempmon.Client)\ .join(tempmon.Client)\
@ -89,18 +97,32 @@ class TempmonReadingView(MasterView):
def render_client_host(self, reading, column): def render_client_host(self, reading, column):
return reading.client.hostname return reading.client.hostname
def _preconfigure_fieldset(self, fs): def configure_form(self, f):
fs.client.set(label="TempMon Client", renderer=ClientFieldRenderer) super(TempmonReadingView, self).configure_form(f)
fs.probe.set(label="TempMon Probe", renderer=ProbeFieldRenderer)
def configure_fieldset(self, fs): # client
fs.configure( f.set_renderer('client', self.render_client)
include=[ f.set_label('client', "Tempmon Client")
fs.client,
fs.probe, # probe
fs.taken, f.set_renderer('probe', self.render_probe)
fs.degrees_f, f.set_label('probe', "Tempmon Probe")
])
def render_client(self, reading, field):
client = reading.client
if not client:
return ""
text = six.text_type(client)
url = self.request.route_url('tempmon.clients.view', uuid=client.uuid)
return tags.link_to(text, url)
def render_probe(self, reading, field):
probe = reading.probe
if not probe:
return ""
text = six.text_type(probe)
url = self.request.route_url('tempmon.probes.view', uuid=probe.uuid)
return tags.link_to(text, url)
def includeme(config): def includeme(config):