Convert bouncer view to master3

also move common file field logic from upgrades into master3
This commit is contained in:
Lance Edgar 2017-08-17 20:13:42 -05:00
parent 2db9d31386
commit e3de40bdfe
3 changed files with 86 additions and 63 deletions

View file

@ -33,14 +33,11 @@ from rattail.db import model
from rattail.bouncer import get_handler from rattail.bouncer import get_handler
from rattail.bouncer.config import get_profile_keys from rattail.bouncer.config import get_profile_keys
import formalchemy
from pyramid.response import FileResponse from pyramid.response import FileResponse
from webhelpers2.html import literal from webhelpers2.html import HTML, tags
from tailbone import grids from tailbone import grids
from tailbone.db import Session from tailbone.views import MasterView3 as MasterView
from tailbone.views import MasterView2 as MasterView
from tailbone.forms.renderers.bouncer import BounceMessageFieldRenderer
class EmailBouncesView(MasterView): class EmailBouncesView(MasterView):
@ -53,6 +50,12 @@ class EmailBouncesView(MasterView):
creatable = False creatable = False
editable = False editable = False
labels = {
'config_key': "Source",
'bounce_recipient_address': "Bounced To",
'intended_recipient_address': "Intended For",
}
grid_columns = [ grid_columns = [
'config_key', 'config_key',
'bounced', 'bounced',
@ -90,38 +93,59 @@ class EmailBouncesView(MasterView):
g.set_link('bounced') g.set_link('bounced')
g.set_link('intended_recipient_address') g.set_link('intended_recipient_address')
def configure_fieldset(self, fs): def configure_form(self, f):
bounce = fs.model super(EmailBouncesView, self).configure_form(f)
handler = self.get_handler(bounce) bounce = f.model_instance
fs.append(formalchemy.Field('message', f.set_renderer('message', self.render_message_file)
value=handler.msgpath(bounce), f.set_renderer('links', self.render_links)
renderer=BounceMessageFieldRenderer.new(self.request, handler))) f.fields = [
fs.append(formalchemy.Field('links', 'config_key',
value=list(handler.make_links(Session(), bounce.intended_recipient_address)), 'message',
renderer=LinksFieldRenderer)) 'bounced',
fs.configure( 'bounce_recipient_address',
include=[ 'intended_recipient_address',
fs.config_key.label("Source"), 'links',
fs.message, 'processed',
fs.bounced, 'processed_by',
fs.bounce_recipient_address.label("Bounced To"), ]
fs.intended_recipient_address.label("Intended For"),
fs.links,
fs.processed,
fs.processed_by,
],
readonly=True)
if not bounce.processed: if not bounce.processed:
del fs.processed f.remove_field('processed')
del fs.processed_by f.remove_field('processed_by')
def render_links(self, bounce, field):
handler = self.get_handler(bounce)
value = list(handler.make_links(self.Session(), bounce.intended_recipient_address))
if not value:
return "n/a"
links = []
for link in value:
label = HTML.literal("{}:  ".format(link.type))
anchor = tags.link_to(link.title, link.url, target='_blank')
links.append(HTML.tag('li', label + anchor))
return HTML.tag('ul', HTML.literal('').join(links))
def render_message_file(self, bounce, field):
handler = self.get_handler(bounce)
path = handler.msgpath(bounce)
if not path:
return ""
url = self.get_action_url('download', bounce)
return self.render_file_field(path, url)
def template_kwargs_view(self, **kwargs): def template_kwargs_view(self, **kwargs):
bounce = kwargs['instance'] bounce = kwargs['instance']
kwargs['bounce'] = bounce kwargs['bounce'] = bounce
handler = self.get_handler(bounce) handler = self.get_handler(bounce)
kwargs['handler'] = handler kwargs['handler'] = handler
with open(handler.msgpath(bounce), 'rb') as f: path = handler.msgpath(bounce)
kwargs['message'] = f.read() if os.path.exists(path):
with open(path, 'rb') as f:
kwargs['message'] = f.read()
else:
kwargs['message'] = "(file not found)"
return kwargs return kwargs
def process(self): def process(self):
@ -185,19 +209,5 @@ class EmailBouncesView(MasterView):
cls._defaults(config) cls._defaults(config)
class LinksFieldRenderer(formalchemy.FieldRenderer):
def render_readonly(self, **kwargs):
value = self.raw_value
if not value:
return 'n/a'
html = literal('<ul>')
for link in value:
html += literal('<li>{0}:&nbsp; <a href="{1}" target="_blank">{2}</a></li>'.format(
link.type, link.url, link.title))
html += literal('</ul>')
return html
def includeme(config): def includeme(config):
EmailBouncesView.defaults(config) EmailBouncesView.defaults(config)

View file

@ -26,9 +26,12 @@ Master View
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
import os
from sqlalchemy import orm from sqlalchemy import orm
import deform import deform
from webhelpers2.html import tags
from tailbone import forms2 as forms from tailbone import forms2 as forms
from tailbone.views import MasterView2 from tailbone.views import MasterView2
@ -113,6 +116,34 @@ class MasterView3(MasterView2):
self.set_labels(form) self.set_labels(form)
def render_file_field(self, path, url=None, filename=None):
"""
Convenience for rendering a file with optional download link
"""
if not filename:
filename = os.path.basename(path)
content = "{} ({})".format(filename, self.readable_size(path))
if url:
return tags.link_to(content, url)
return content
def readable_size(self, path):
# TODO: this was shamelessly copied from FormAlchemy ...
length = self.get_size(path)
if length == 0:
return '0 KB'
if length <= 1024:
return '1 KB'
if length > 1048576:
return '%0.02f MB' % (length / 1048576.0)
return '%0.02f KB' % (length / 1024.0)
def get_size(self, path):
try:
return os.path.getsize(path)
except os.error:
return 0
def validate_form(self, form): def validate_form(self, form):
controls = self.request.POST.items() controls = self.request.POST.items()
try: try:

View file

@ -206,9 +206,8 @@ class UpgradeView(MasterView):
filename = 'stdout.log' filename = 'stdout.log'
path = self.rattail_config.upgrade_filepath(upgrade.uuid, filename=filename) path = self.rattail_config.upgrade_filepath(upgrade.uuid, filename=filename)
if path: if path:
content = "{} ({})".format(filename, self.readable_size(path))
url = '{}?filename={}'.format(self.get_action_url('download', upgrade), filename) url = '{}?filename={}'.format(self.get_action_url('download', upgrade), filename)
return tags.link_to(content, url) return self.render_file_field(path, url, filename=filename)
return filename return filename
def render_package_diff(self, upgrade, fieldname): def render_package_diff(self, upgrade, fieldname):
@ -291,23 +290,6 @@ class UpgradeView(MasterView):
return six.text_type(req.link) return six.text_type(req.link)
return "" return ""
def get_size(self, path):
try:
return os.path.getsize(path)
except os.error:
return 0
def readable_size(self, path):
# TODO: this was shamelessly copied from FormAlchemy ...
length = self.get_size(path)
if length == 0:
return '0 KB'
if length <= 1024:
return '1 KB'
if length > 1048576:
return '%0.02f MB' % (length / 1048576.0)
return '%0.02f KB' % (length / 1024.0)
def download_path(self, upgrade, filename): def download_path(self, upgrade, filename):
return self.rattail_config.upgrade_filepath(upgrade.uuid, filename=filename) return self.rattail_config.upgrade_filepath(upgrade.uuid, filename=filename)