diff --git a/tailbone/templates/tempmon/appliances/index.mako b/tailbone/templates/tempmon/appliances/index.mako new file mode 100644 index 00000000..68334aa8 --- /dev/null +++ b/tailbone/templates/tempmon/appliances/index.mako @@ -0,0 +1,30 @@ +## -*- coding: utf-8; -*- +<%inherit file="/master/index.mako" /> + +<%def name="extra_styles()"> + ${parent.extra_styles()} + + + +${parent.body()} diff --git a/tailbone/views/master.py b/tailbone/views/master.py index dcba102a..9308f7f7 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -106,6 +106,7 @@ class MasterView(View): executing = False has_pk_fields = False has_image = False + has_thumbnail = False row_attrs = {} cell_attrs = {} @@ -871,6 +872,22 @@ class MasterView(View): def get_image_bytes(self, obj): raise NotImplementedError + def thumbnail(self): + """ + View which renders the object's thumbnail image as a response. + """ + obj = self.get_instance() + image_bytes = self.get_thumbnail_bytes(obj) + if not image_bytes: + raise self.notfound() + # TODO: how to properly detect image type? + self.request.response.content_type = str('image/jpeg') + self.request.response.body = image_bytes + return self.request.response + + def get_thumbnail_bytes(self, obj): + raise NotImplementedError + def clone(self): """ View for cloning an object's data into a new object. @@ -3002,6 +3019,12 @@ class MasterView(View): config.add_view(cls, attr='image', route_name='{}.image'.format(route_prefix), permission='{}.view'.format(permission_prefix)) + # thumbnail + if cls.has_thumbnail: + config.add_route('{}.thumbnail'.format(route_prefix), '{}/{{{}}}/thumbnail'.format(url_prefix, model_key)) + config.add_view(cls, attr='thumbnail', route_name='{}.thumbnail'.format(route_prefix), + permission='{}.view'.format(permission_prefix)) + # clone if cls.cloneable: config.add_tailbone_permission(permission_prefix, '{}.clone'.format(permission_prefix), diff --git a/tailbone/views/tempmon/appliances.py b/tailbone/views/tempmon/appliances.py index 515b4777..cf0e8493 100644 --- a/tailbone/views/tempmon/appliances.py +++ b/tailbone/views/tempmon/appliances.py @@ -49,10 +49,12 @@ class TempmonApplianceView(MasterView): route_prefix = 'tempmon.appliances' url_prefix = '/tempmon/appliances' has_image = True + has_thumbnail = True grid_columns = [ 'name', 'location', + 'image', ] form_fields = [ @@ -69,6 +71,15 @@ class TempmonApplianceView(MasterView): g.set_link('name') g.set_link('location') + g.set_renderer('image', self.render_grid_thumbnail) + + def render_grid_thumbnail(self, appliance, field): + route_prefix = self.get_route_prefix() + url = self.request.route_url('{}.thumbnail'.format(route_prefix), uuid=appliance.uuid) + image = tags.image(url, "") + helper = HTML.tag('span', class_='image-helper') + return HTML.tag('div', class_='image-frame', c=[helper, image]) + def configure_form(self, f): super(TempmonApplianceView, self).configure_form(f) @@ -106,6 +117,9 @@ class TempmonApplianceView(MasterView): def get_image_bytes(self, appliance): return appliance.image_normal or appliance.image_raw + def get_thumbnail_bytes(self, appliance): + return appliance.image_thumbnail + def render_image(self, appliance, field): route_prefix = self.get_route_prefix() url = self.request.route_url('{}.image'.format(route_prefix), uuid=appliance.uuid)