From cabe4225080cdaaa7a20b9a434ded1cdd0b8fd0f Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 9 Jan 2022 19:25:18 -0600 Subject: [PATCH] Add progress support when deleting a batch b/c we must delete all rows individually, and some batches can be several thousand rows each --- tailbone/views/batch/core.py | 52 ++++++++++++++++++++++++++++++++++-- tailbone/views/master.py | 12 ++++++--- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/tailbone/views/batch/core.py b/tailbone/views/batch/core.py index 36ad341b..88921f13 100644 --- a/tailbone/views/batch/core.py +++ b/tailbone/views/batch/core.py @@ -82,6 +82,7 @@ class BatchMasterView(MasterView): results_executable = False has_worksheet = False has_worksheet_file = False + delete_requires_progress = True input_file_template_config_section = 'rattail.batch' @@ -742,8 +743,55 @@ class BatchMasterView(MasterView): """ Delete all data (files etc.) for the batch. """ - self.handler.do_delete(batch) - super(BatchMasterView, self).delete_instance(batch) + app = self.get_rattail_app() + session = app.get_session(batch) + self.batch_handler.do_delete(batch) + session.flush() + + def delete_instance_with_progress(self, batch): + """ + Delete all data (files etc.) for the batch. + """ + return self.handler_action(batch, 'delete') + + def delete_thread(self, key, user_uuid, progress, **kwargs): + """ + Thread target for deleting a batch with progress indicator. + """ + app = self.get_rattail_app() + model = self.model + # nb. must make new session, separate from main thread + session = app.make_session() + batch = self.get_instance_for_key(key, session) + batch_str = six.text_type(batch) + + try: + # try to delete batch + self.handler.do_delete(batch, progress=progress, **kwargs) + + except Exception as error: + # error; log that and rollback + log.exception("delete failed for batch: %s", batch) + session.rollback() + session.close() + if progress: + progress.session.load() + progress.session['error'] = True + progress.session['error_msg'] = "Batch deletion failed: {}".format( + simple_error(error)) + progress.session.save() + + else: + # no error; finish up + session.commit() + session.close() + if progress: + progress.session.load() + progress.session['complete'] = True + progress.session['success_url'] = self.get_index_url() + progress.session['success_msg'] = "Batch has been deleted: {}".format( + batch_str) + progress.session.save() def get_fallback_templates(self, template, **kwargs): return [ diff --git a/tailbone/views/master.py b/tailbone/views/master.py index 7fd3cccf..3b7bed2a 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -100,6 +100,7 @@ class MasterView(View): viewable = True editable = True deletable = True + delete_requires_progress = False delete_confirm = 'full' bulk_deletable = False set_deletable = False @@ -1590,10 +1591,13 @@ class MasterView(View): if isinstance(result, httpexceptions.HTTPException): return result - self.delete_instance(instance) - self.request.session.flash("{} has been deleted: {}".format( - self.get_model_title(), instance_title)) - return self.redirect(self.get_after_delete_url(instance)) + if self.delete_requires_progress: + return self.delete_instance_with_progress(instance) + else: + self.delete_instance(instance) + self.request.session.flash("{} has been deleted: {}".format( + self.get_model_title(), instance_title)) + return self.redirect(self.get_after_delete_url(instance)) form.readonly = True return self.render_to_response('delete', {