Refactor all tempmon views to use master3
This commit is contained in:
parent
ce0195bd51
commit
365a48110c
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue