Add download feature for file batches.

This commit is contained in:
Lance Edgar 2015-02-12 23:19:01 -06:00
parent 23addae818
commit eedbcb81f8

View file

@ -35,7 +35,9 @@ import logging
import formalchemy import formalchemy
from pyramid.renderers import render_to_response from pyramid.renderers import render_to_response
from pyramid.response import FileResponse
from pyramid.httpexceptions import HTTPFound, HTTPNotFound from pyramid.httpexceptions import HTTPFound, HTTPNotFound
from webhelpers.html.tags import link_to
from rattail.db import model from rattail.db import model
from rattail.db import Session as RatSession from rattail.db import Session as RatSession
@ -517,6 +519,28 @@ class BatchCrud(BaseCrud):
return HTTPFound(location=self.view_url(batch.uuid)) return HTTPFound(location=self.view_url(batch.uuid))
class DownloadLinkRenderer(formalchemy.FieldRenderer):
"""
Field renderer for batch filenames, shows a link to download the file.
"""
def __init__(self, route_prefix):
self.route_prefix = route_prefix
def __call__(self, field):
super(DownloadLinkRenderer, self).__init__(field)
return self
def render_readonly(self, **kwargs):
filename = self.value
if not filename:
return ''
batch = self.field.parent.model
return link_to(filename, self.request.route_url(
'{0}.download'.format(self.route_prefix),
uuid=batch.uuid))
class FileBatchCrud(BatchCrud): class FileBatchCrud(BatchCrud):
""" """
Base CRUD view for batches which involve a file upload as the first step. Base CRUD view for batches which involve a file upload as the first step.
@ -545,6 +569,7 @@ class FileBatchCrud(BatchCrud):
fs.executed_by.set(label="Executed by", renderer=UserFieldRenderer) fs.executed_by.set(label="Executed by", renderer=UserFieldRenderer)
fs.append(formalchemy.Field('data_file')) fs.append(formalchemy.Field('data_file'))
fs.data_file.set(renderer=formalchemy.fields.FileFieldRenderer) fs.data_file.set(renderer=formalchemy.fields.FileFieldRenderer)
fs.filename.set(renderer=DownloadLinkRenderer(self.route_prefix))
self.configure_fieldset(fs) self.configure_fieldset(fs)
if self.creating: if self.creating:
del fs.created del fs.created
@ -649,6 +674,20 @@ class FileBatchCrud(BatchCrud):
batch.delete_data(self.request.rattail_config) batch.delete_data(self.request.rattail_config)
del batch.data_rows[:] del batch.data_rows[:]
def download(self):
"""
View for downloading the data file associated with a batch.
"""
batch = self.current_batch()
if not batch:
return HTTPNotFound()
config = self.request.rattail_config
path = batch.filepath(config)
response = FileResponse(path, request=self.request)
response.headers[b'Content-Length'] = str(batch.filesize(config))
response.headers[b'Content-Disposition'] = b'attachment; filename={0}'.format(batch.filename)
return response
class BatchRowGrid(BaseGrid): class BatchRowGrid(BaseGrid):
""" """
@ -877,6 +916,12 @@ def defaults(config, batch_grid, batch_crud, row_grid, row_crud, url_prefix,
config.add_view(batch_crud, attr='execute', route_name='{0}.execute'.format(route_prefix), config.add_view(batch_crud, attr='execute', route_name='{0}.execute'.format(route_prefix),
permission='{0}.execute'.format(permission_prefix)) permission='{0}.execute'.format(permission_prefix))
# Download batch data file
if hasattr(batch_crud, 'download'):
config.add_route('{0}.download'.format(route_prefix), '{0}{{uuid}}/download'.format(url_prefix))
config.add_view(batch_crud, attr='download', route_name='{0}.download'.format(route_prefix),
permission='{0}.download'.format(permission_prefix))
# Delete batch # Delete batch
config.add_route('{0}.delete'.format(route_prefix), '{0}{{uuid}}/delete'.format(url_prefix)) config.add_route('{0}.delete'.format(route_prefix), '{0}{{uuid}}/delete'.format(url_prefix))
config.add_view(batch_crud, attr='delete', route_name='{0}.delete'.format(route_prefix), config.add_view(batch_crud, attr='delete', route_name='{0}.delete'.format(route_prefix),
@ -891,7 +936,7 @@ def defaults(config, batch_grid, batch_crud, row_grid, row_crud, url_prefix,
# Bulk delete batch rows # Bulk delete batch rows
config.add_route('{0}.rows.bulk_delete'.format(route_prefix), '{0}{{uuid}}/rows/delete'.format(url_prefix)) config.add_route('{0}.rows.bulk_delete'.format(route_prefix), '{0}{{uuid}}/rows/delete'.format(url_prefix))
config.add_view(row_grid, attr='bulk_delete', route_name='{0}.rows.bulk_delete'.format(route_prefix), config.add_view(row_grid, attr='bulk_delete', route_name='{0}.rows.bulk_delete'.format(route_prefix),
permission='{0}.delete'.format(permission_prefix)) permission='{0}.edit'.format(permission_prefix))
# Delete batch row # Delete batch row
config.add_route('{0}.rows.delete'.format(route_prefix), '{0}delete-row/{{uuid}}'.format(url_prefix)) config.add_route('{0}.rows.delete'.format(route_prefix), '{0}delete-row/{{uuid}}'.format(url_prefix))