Add basic support for batch execution options
This commit is contained in:
parent
3b265e19c4
commit
db62f82a37
|
@ -10,8 +10,32 @@
|
|||
$('.newgrid-wrapper').gridwrapper();
|
||||
|
||||
$('#execute-batch').click(function() {
|
||||
$(this).button('option', 'label', "Executing, please wait...").button('disable');
|
||||
location.href = '${url('{}.execute'.format(route_prefix), uuid=batch.uuid)}';
|
||||
% if master.has_execution_options:
|
||||
$('#execution-options-dialog').dialog({
|
||||
title: "Execution Options",
|
||||
width: 500,
|
||||
height: 300,
|
||||
modal: true,
|
||||
buttons: [
|
||||
{
|
||||
text: "Execute",
|
||||
click: function(event) {
|
||||
$(event.target).button('option', 'label', "Executing, please wait...").button('disable');
|
||||
$('form[name="batch-execution"]').submit();
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Cancel",
|
||||
click: function() {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
% else:
|
||||
$(this).button('option', 'label', "Executing, please wait...").button('disable');
|
||||
$('form[name="batch-execution"]').submit();
|
||||
% endif
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -52,3 +76,13 @@
|
|||
</div><!-- form-wrapper -->
|
||||
|
||||
${rows_grid|n}
|
||||
|
||||
<div id="execution-options-dialog" style="display: none;">
|
||||
|
||||
${h.form(url('{}.execute'.format(route_prefix), uuid=batch.uuid), name='batch-execution')}
|
||||
% if master.has_execution_options:
|
||||
${rendered_execution_options|n}
|
||||
% endif
|
||||
${h.end_form()}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -45,6 +45,7 @@ import formalchemy
|
|||
from pyramid import httpexceptions
|
||||
from pyramid.renderers import render_to_response
|
||||
from pyramid.response import FileResponse
|
||||
from pyramid_simpleform import Form
|
||||
from webhelpers.html import HTML
|
||||
|
||||
from tailbone import forms, newgrids as grids
|
||||
|
@ -114,7 +115,8 @@ class BatchMasterView(MasterView):
|
|||
self.request.response.text = grid.render_grid()
|
||||
return self.request.response
|
||||
|
||||
return self.render_to_response('view', {
|
||||
context = {
|
||||
'handler': self.handler,
|
||||
'instance': batch,
|
||||
'instance_title': self.get_instance_title(batch),
|
||||
'instance_editable': self.editable_instance(batch),
|
||||
|
@ -124,7 +126,25 @@ class BatchMasterView(MasterView):
|
|||
'execute_title': self.get_execute_title(batch),
|
||||
'execute_enabled': self.executable(batch),
|
||||
'rows_grid': grid.render_complete(allow_save_defaults=False),
|
||||
})
|
||||
}
|
||||
|
||||
if context['execute_enabled']:
|
||||
context['rendered_execution_options'] = self.render_execution_options()
|
||||
|
||||
return self.render_to_response('view', context)
|
||||
|
||||
def render_execution_options(self):
|
||||
batch = self.get_instance()
|
||||
form = self.make_execution_options_form(batch)
|
||||
kwargs = {
|
||||
'batch': batch,
|
||||
'form': forms.FormRenderer(form),
|
||||
}
|
||||
kwargs = self.get_exec_options_kwargs(**kwargs)
|
||||
return self.render('exec_options', kwargs)
|
||||
|
||||
def get_exec_options_kwargs(self, **kwargs):
|
||||
return kwargs
|
||||
|
||||
def get_instance_title(self, batch):
|
||||
return batch.id_str or unicode(batch)
|
||||
|
@ -352,6 +372,26 @@ class BatchMasterView(MasterView):
|
|||
def executable(self, batch):
|
||||
return self.handler.executable(batch)
|
||||
|
||||
@property
|
||||
def has_execution_options(self):
|
||||
return bool(self.execution_options_schema)
|
||||
|
||||
# TODO
|
||||
execution_options_schema = None
|
||||
|
||||
def make_execution_options_form(self, batch):
|
||||
"""
|
||||
Return a proper Form for execution options.
|
||||
"""
|
||||
defaults = {}
|
||||
for field in self.execution_options_schema.fields:
|
||||
key = 'batch.{}.execute_option.{}'.format(batch.batch_key, field)
|
||||
value = self.request.session.get(key)
|
||||
if value:
|
||||
defaults[field] = value
|
||||
return Form(self.request, schema=self.execution_options_schema,
|
||||
defaults=defaults or None)
|
||||
|
||||
def get_execute_title(self, batch):
|
||||
return self.handler.get_execute_title(batch)
|
||||
|
||||
|
@ -648,20 +688,32 @@ class BatchMasterView(MasterView):
|
|||
displays a progress indicator page.
|
||||
"""
|
||||
batch = self.get_instance()
|
||||
if self.request.method == 'POST':
|
||||
|
||||
key = '{}.execute'.format(self.model_class.__tablename__)
|
||||
progress = SessionProgress(self.request, key)
|
||||
thread = Thread(target=self.execute_thread, args=(batch.uuid, self.request.user.uuid, progress))
|
||||
thread.start()
|
||||
kwargs = {}
|
||||
if self.has_execution_options:
|
||||
form = self.make_execution_options_form(batch)
|
||||
assert form.validate() # TODO
|
||||
kwargs.update(form.data)
|
||||
for key, value in form.data.iteritems():
|
||||
# TODO: properly serialize option values?
|
||||
self.request.session['batch.{}.execute_option.{}'.format(batch.batch_key, key)] = unicode(value)
|
||||
|
||||
kwargs = {
|
||||
'key': key,
|
||||
'cancel_url': self.get_action_url('view', batch),
|
||||
'cancel_msg': "Batch execution was canceled.",
|
||||
}
|
||||
return self.render_progress(kwargs)
|
||||
key = '{}.execute'.format(self.model_class.__tablename__)
|
||||
kwargs['progress'] = SessionProgress(self.request, key)
|
||||
thread = Thread(target=self.execute_thread, args=(batch.uuid, self.request.user.uuid), kwargs=kwargs)
|
||||
thread.start()
|
||||
|
||||
def execute_thread(self, batch_uuid, user_uuid, progress=None):
|
||||
return self.render_progress({
|
||||
'key': key,
|
||||
'cancel_url': self.get_action_url('view', batch),
|
||||
'cancel_msg': "Batch execution was canceled.",
|
||||
})
|
||||
|
||||
self.request.session.flash("Sorry, you must POST to execute a batch.", 'error')
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
|
||||
def execute_thread(self, batch_uuid, user_uuid, progress=None, **kwargs):
|
||||
"""
|
||||
Thread target for executing a batch with progress indicator.
|
||||
"""
|
||||
|
@ -670,8 +722,9 @@ class BatchMasterView(MasterView):
|
|||
# transaction binding etc.
|
||||
session = RattailSession()
|
||||
batch = session.query(self.model_class).get(batch_uuid)
|
||||
user = session.query(model.User).get(user_uuid)
|
||||
try:
|
||||
result = self.handler.execute(batch, progress=progress)
|
||||
result = self.handler.execute(batch, user=user, progress=progress, **kwargs)
|
||||
|
||||
# If anything goes wrong, rollback and log the error etc.
|
||||
except Exception as error:
|
||||
|
@ -688,19 +741,27 @@ class BatchMasterView(MasterView):
|
|||
else:
|
||||
if result:
|
||||
batch.executed = datetime.datetime.utcnow()
|
||||
batch.executed_by_uuid = user_uuid
|
||||
batch.executed_by = user
|
||||
session.commit()
|
||||
# TODO: this doesn't always work...?
|
||||
self.request.session.flash("{} has been executed: {}".format(
|
||||
self.get_model_title(), batch.id_str))
|
||||
else:
|
||||
session.rollback()
|
||||
|
||||
session.refresh(batch)
|
||||
success_url = self.get_execute_success_url(batch, result, **kwargs)
|
||||
session.close()
|
||||
|
||||
if progress:
|
||||
progress.session.load()
|
||||
progress.session['complete'] = True
|
||||
progress.session['success_url'] = self.get_action_url('view', batch)
|
||||
progress.session['success_url'] = success_url
|
||||
progress.session.save()
|
||||
|
||||
def get_execute_success_url(self, batch, result, **kwargs):
|
||||
return self.get_action_url('view', batch)
|
||||
|
||||
def csv(self):
|
||||
"""
|
||||
Download batch data as CSV.
|
||||
|
|
Loading…
Reference in a new issue