tailbone/tailbone/views/exports.py
Lance Edgar 4499a872d8 Remove unwanted "export has file" logic for ExportMasterView
this mostly did what "downloadable" already did, plus some other stuff which it
probably shouldn't have been doing anyway
2019-07-05 18:17:53 -05:00

172 lines
5.4 KiB
Python

# -*- coding: utf-8; -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2019 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Master class for generic export history views
"""
from __future__ import unicode_literals, absolute_import
import os
import six
from rattail.db import model
from pyramid.response import FileResponse
from webhelpers2.html import HTML, tags
from tailbone import forms
from tailbone.views import MasterView
class ExportMasterView(MasterView):
"""
Master class for generic export history views
"""
creatable = False
editable = False
downloadable = False
grid_columns = [
'id',
'created',
'created_by',
'record_count',
]
form_fields = [
'id',
'created',
'created_by',
'record_count',
]
def get_export_key(self):
if hasattr(self, 'export_key'):
return self.export_key
def get_file_path(self, export, makedirs=False):
return self.rattail_config.export_filepath(self.export_key,
export.uuid,
export.filename,
makedirs=makedirs)
def download_path(self, export, filename):
# TODO: this assumes 'filename' default!
return self.get_file_path(export)
def configure_grid(self, g):
super(ExportMasterView, self).configure_grid(g)
g.joiners['created_by'] = lambda q: q.join(model.User)
g.sorters['created_by'] = g.make_sorter(model.User.username)
g.filters['created_by'] = g.make_filter('created_by', model.User.username)
g.set_sort_defaults('created', 'desc')
g.set_renderer('id', self.render_id)
g.set_label('id', "ID")
g.set_label('created_by', "Created by")
g.set_link('id')
def render_id(self, export, field):
return export.id_str
def configure_form(self, f):
super(ExportMasterView, self).configure_form(f)
export = f.model_instance
# NOTE: we try to handle the 'creating' scenario even though this class
# doesn't officially support that; just in case a subclass does want to
# id
if self.creating:
f.remove_field('id')
else:
f.set_readonly('id')
f.set_renderer('id', self.render_id)
f.set_label('id', "ID")
# created
if self.creating:
f.remove_field('created')
else:
f.set_readonly('created')
f.set_type('created', 'datetime')
# created_by
if self.creating:
f.remove_field('created_by')
else:
f.set_readonly('created_by')
f.set_renderer('created_by', self.render_created_by)
f.set_label('created_by', "Created by")
# record_count
if self.creating:
f.remove_field('record_count')
else:
f.set_readonly('record_count')
def objectify(self, form, data=None):
obj = super(ExportMasterView, self).objectify(form, data=data)
if self.creating:
obj.created_by = self.request.user
return obj
def render_download(self, export, field):
path = self.get_file_path(export)
text = "{} ({})".format(export.filename, self.readable_size(path))
url = self.request.route_url('{}.download'.format(self.get_route_prefix()), uuid=export.uuid)
return tags.link_to(text, url)
def render_created_by(self, export, field):
user = export.created_by
if not user:
return ""
text = six.text_type(user)
if self.request.has_perm('users.view'):
url = self.request.route_url('users.view', uuid=user.uuid)
return tags.link_to(text, url)
return text
def get_download_url(self, filename):
uuid = self.request.matchdict['uuid']
return self.request.route_url('{}.download'.format(self.get_route_prefix()), uuid=uuid)
def download(self):
"""
View for downloading the export file.
"""
export = self.get_instance()
path = self.get_file_path(export)
response = FileResponse(path, request=self.request)
if six.PY3:
response.headers['Content-Length'] = str(os.path.getsize(path))
response.headers['Content-Disposition'] = 'attachment; filename="{}"'.format(export.filename)
else:
response.headers[b'Content-Length'] = six.binary_type(os.path.getsize(path))
response.headers[b'Content-Disposition'] = b'attachment; filename="{}"'.format(export.filename)
return response