Add progress for generating "results as CSV" file to download
This commit is contained in:
parent
7d8c57170f
commit
1b7612ffb0
|
@ -296,6 +296,11 @@
|
|||
<script type="text/javascript">
|
||||
|
||||
## TODO: stop checking for buefy here once we only have the one session.pop()
|
||||
% if use_buefy and request.session.pop('{}.results_csv.generated'.format(route_prefix), False):
|
||||
ThisPage.mounted = function() {
|
||||
location.href = '${url('{}.results_csv_download'.format(route_prefix))}';
|
||||
}
|
||||
% endif
|
||||
% if use_buefy and request.session.pop('{}.results_xlsx.generated'.format(route_prefix), False):
|
||||
ThisPage.mounted = function() {
|
||||
location.href = '${url('{}.results_xlsx_download'.format(route_prefix))}';
|
||||
|
@ -462,6 +467,13 @@
|
|||
% endif
|
||||
|
||||
## TODO: can stop checking for buefy above once this legacy chunk is gone
|
||||
% if request.session.pop('{}.results_csv.generated'.format(route_prefix), False):
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
location.href = '${url('{}.results_csv_download'.format(route_prefix))}';
|
||||
});
|
||||
</script>
|
||||
% endif
|
||||
% if request.session.pop('{}.results_xlsx.generated'.format(route_prefix), False):
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
|
|
@ -2677,27 +2677,94 @@ class MasterView(View):
|
|||
|
||||
def results_csv(self):
|
||||
"""
|
||||
Download current list results as CSV
|
||||
Download current list results as CSV.
|
||||
"""
|
||||
results = self.get_effective_data()
|
||||
fields = self.get_csv_fields()
|
||||
data = six.StringIO()
|
||||
writer = UnicodeDictWriter(data, fields)
|
||||
writer.writeheader()
|
||||
for obj in results:
|
||||
writer.writerow(self.get_csv_row(obj, fields))
|
||||
response = self.request.response
|
||||
if six.PY3:
|
||||
response.text = data.getvalue()
|
||||
response.content_type = 'text/csv'
|
||||
response.content_disposition = 'attachment; filename={}.csv'.format(self.get_grid_key())
|
||||
else:
|
||||
response.body = data.getvalue()
|
||||
response.content_type = b'text/csv'
|
||||
response.content_disposition = b'attachment; filename={}.csv'.format(self.get_grid_key())
|
||||
data.close()
|
||||
response.content_length = len(response.body)
|
||||
return response
|
||||
|
||||
# start thread to actually do work / generate progress data
|
||||
route_prefix = self.get_route_prefix()
|
||||
key = '{}.results_csv'.format(route_prefix)
|
||||
progress = self.make_progress(key)
|
||||
thread = Thread(target=self.results_csv_thread,
|
||||
args=(results, self.request.user.uuid, progress))
|
||||
thread.start()
|
||||
|
||||
# send user to progress page
|
||||
return self.render_progress(progress, {
|
||||
'cancel_url': self.get_index_url(),
|
||||
'cancel_msg': "CSV download was canceled.",
|
||||
})
|
||||
|
||||
def results_csv_session(self):
|
||||
return RattailSession()
|
||||
|
||||
def results_csv_thread(self, results, user_uuid, progress):
|
||||
"""
|
||||
Thread target, responsible for actually generating the CSV file which
|
||||
is to be presented for download.
|
||||
"""
|
||||
route_prefix = self.get_route_prefix()
|
||||
session = self.results_csv_session()
|
||||
try:
|
||||
|
||||
# create folder(s) for output; make sure file doesn't exist
|
||||
path = os.path.join(self.rattail_config.datadir(), 'downloads',
|
||||
'results-csv', route_prefix,
|
||||
user_uuid[:2], user_uuid[2:])
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
path = os.path.join(path, '{}.csv'.format(route_prefix))
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
|
||||
results = results.with_session(session).all()
|
||||
fields = self.get_csv_fields()
|
||||
|
||||
csv_file = open(path, 'wt')
|
||||
writer = UnicodeDictWriter(csv_file, fields)
|
||||
writer.writeheader()
|
||||
|
||||
def write(obj, i):
|
||||
writer.writerow(self.get_csv_row(obj, fields))
|
||||
|
||||
self.progress_loop(write, results, progress,
|
||||
message="Collecting data for CSV")
|
||||
csv_file.close()
|
||||
session.commit()
|
||||
|
||||
except Exception as error:
|
||||
msg = "generating CSV file for download failed!"
|
||||
log.warning(msg, exc_info=True)
|
||||
session.rollback()
|
||||
session.close()
|
||||
if progress:
|
||||
progress.session.load()
|
||||
progress.session['error'] = True
|
||||
progress.session['error_msg'] = "{}: {}".format(
|
||||
msg, simple_error(error))
|
||||
progress.session.save()
|
||||
return
|
||||
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
if progress:
|
||||
progress.session.load()
|
||||
progress.session['complete'] = True
|
||||
progress.session['success_url'] = self.get_index_url()
|
||||
progress.session['extra_session_bits'] = {
|
||||
'{}.results_csv.generated'.format(route_prefix): True,
|
||||
}
|
||||
progress.session.save()
|
||||
|
||||
def results_csv_download(self):
|
||||
route_prefix = self.get_route_prefix()
|
||||
user_uuid = self.request.user.uuid
|
||||
path = os.path.join(self.rattail_config.datadir(), 'downloads',
|
||||
'results-csv', route_prefix,
|
||||
user_uuid[:2], user_uuid[2:],
|
||||
'{}.csv'.format(route_prefix))
|
||||
return self.file_response(path)
|
||||
|
||||
def results_xlsx(self):
|
||||
"""
|
||||
|
@ -3740,6 +3807,9 @@ class MasterView(View):
|
|||
config.add_route('{}.results_csv'.format(route_prefix), '{}/csv'.format(url_prefix))
|
||||
config.add_view(cls, attr='results_csv', route_name='{}.results_csv'.format(route_prefix),
|
||||
permission='{}.results_csv'.format(permission_prefix))
|
||||
config.add_route('{}.results_csv_download'.format(route_prefix), '{}/csv/download'.format(url_prefix))
|
||||
config.add_view(cls, attr='results_csv_download', route_name='{}.results_csv_download'.format(route_prefix),
|
||||
permission='{}.results_csv'.format(permission_prefix))
|
||||
|
||||
if cls.results_downloadable_xlsx:
|
||||
config.add_tailbone_permission(permission_prefix, '{}.results_xlsx'.format(permission_prefix),
|
||||
|
|
Loading…
Reference in a new issue