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.config import get_profile_keys
import formalchemy
from pyramid.response import FileResponse
from webhelpers2.html import literal
from webhelpers2.html import HTML, tags
from tailbone import grids
from tailbone.db import Session
from tailbone.views import MasterView2 as MasterView
from tailbone.forms.renderers.bouncer import BounceMessageFieldRenderer
from tailbone.views import MasterView3 as MasterView
class EmailBouncesView(MasterView):
@ -53,6 +50,12 @@ class EmailBouncesView(MasterView):
creatable = False
editable = False
labels = {
'config_key': "Source",
'bounce_recipient_address': "Bounced To",
'intended_recipient_address': "Intended For",
}
grid_columns = [
'config_key',
'bounced',
@ -90,38 +93,59 @@ class EmailBouncesView(MasterView):
g.set_link('bounced')
g.set_link('intended_recipient_address')
def configure_fieldset(self, fs):
bounce = fs.model
handler = self.get_handler(bounce)
fs.append(formalchemy.Field('message',
value=handler.msgpath(bounce),
renderer=BounceMessageFieldRenderer.new(self.request, handler)))
fs.append(formalchemy.Field('links',
value=list(handler.make_links(Session(), bounce.intended_recipient_address)),
renderer=LinksFieldRenderer))
fs.configure(
include=[
fs.config_key.label("Source"),
fs.message,
fs.bounced,
fs.bounce_recipient_address.label("Bounced To"),
fs.intended_recipient_address.label("Intended For"),
fs.links,
fs.processed,
fs.processed_by,
],
readonly=True)
def configure_form(self, f):
super(EmailBouncesView, self).configure_form(f)
bounce = f.model_instance
f.set_renderer('message', self.render_message_file)
f.set_renderer('links', self.render_links)
f.fields = [
'config_key',
'message',
'bounced',
'bounce_recipient_address',
'intended_recipient_address',
'links',
'processed',
'processed_by',
]
if not bounce.processed:
del fs.processed
del fs.processed_by
f.remove_field('processed')
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):
bounce = kwargs['instance']
kwargs['bounce'] = bounce
handler = self.get_handler(bounce)
kwargs['handler'] = handler
with open(handler.msgpath(bounce), 'rb') as f:
kwargs['message'] = f.read()
path = handler.msgpath(bounce)
if os.path.exists(path):
with open(path, 'rb') as f:
kwargs['message'] = f.read()
else:
kwargs['message'] = "(file not found)"
return kwargs
def process(self):
@ -185,19 +209,5 @@ class EmailBouncesView(MasterView):
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):
EmailBouncesView.defaults(config)

View file

@ -26,9 +26,12 @@ Master View
from __future__ import unicode_literals, absolute_import
import os
from sqlalchemy import orm
import deform
from webhelpers2.html import tags
from tailbone import forms2 as forms
from tailbone.views import MasterView2
@ -113,6 +116,34 @@ class MasterView3(MasterView2):
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):
controls = self.request.POST.items()
try:

View file

@ -206,9 +206,8 @@ class UpgradeView(MasterView):
filename = 'stdout.log'
path = self.rattail_config.upgrade_filepath(upgrade.uuid, filename=filename)
if path:
content = "{} ({})".format(filename, self.readable_size(path))
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
def render_package_diff(self, upgrade, fieldname):
@ -291,23 +290,6 @@ class UpgradeView(MasterView):
return six.text_type(req.link)
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):
return self.rattail_config.upgrade_filepath(upgrade.uuid, filename=filename)