feat: add basic support for batch execution
no execution options yet, and no progress indicator also basic delete support, invoking handler
This commit is contained in:
parent
e3beb9953d
commit
dd1fd8c0ce
9 changed files with 404 additions and 11 deletions
|
@ -28,6 +28,7 @@ import logging
|
|||
import threading
|
||||
import time
|
||||
|
||||
import markdown
|
||||
from sqlalchemy import orm
|
||||
|
||||
from wuttaweb.views import MasterView
|
||||
|
@ -41,6 +42,13 @@ log = logging.getLogger(__name__)
|
|||
class BatchMasterView(MasterView):
|
||||
"""
|
||||
Base class for all "batch master" views.
|
||||
|
||||
.. attribute:: batch_handler
|
||||
|
||||
Reference to the :term:`batch handler` for use with the view.
|
||||
|
||||
This is set when the view is first created, using return value
|
||||
from :meth:`get_batch_handler()`.
|
||||
"""
|
||||
|
||||
labels = {
|
||||
|
@ -66,6 +74,46 @@ class BatchMasterView(MasterView):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_fallback_templates(self, template):
|
||||
"""
|
||||
We override the default logic here, to prefer "batch"
|
||||
templates over the "master" templates.
|
||||
|
||||
So for instance the "view batch" page will by default use the
|
||||
``/batch/view.mako`` template - which does inherit from
|
||||
``/master/view.mako`` but adds extra features specific to
|
||||
batches.
|
||||
"""
|
||||
templates = super().get_fallback_templates(template)
|
||||
templates.insert(0, f'/batch/{template}.mako')
|
||||
return templates
|
||||
|
||||
def render_to_response(self, template, context):
|
||||
"""
|
||||
We override the default logic here, to inject batch-related
|
||||
context for the
|
||||
:meth:`~wuttaweb.views.master.MasterView.view()` template
|
||||
specifically. These values are used in the template file,
|
||||
``/batch/view.mako``.
|
||||
|
||||
* ``batch`` - reference to the current :term:`batch`
|
||||
* ``batch_handler`` reference to :attr:`batch_handler`
|
||||
* ``why_not_execute`` - text of reason (if any) not to execute batch
|
||||
* ``execution_described`` - HTML (rendered from markdown) describing batch execution
|
||||
"""
|
||||
if template == 'view':
|
||||
batch = context['instance']
|
||||
context['batch'] = batch
|
||||
context['batch_handler'] = self.batch_handler
|
||||
context['why_not_execute'] = self.batch_handler.why_not_execute(batch)
|
||||
|
||||
description = (self.batch_handler.describe_execution(batch)
|
||||
or "Handler does not say! Your guess is as good as mine.")
|
||||
context['execution_described'] = markdown.markdown(
|
||||
description, extensions=['fenced_code', 'codehilite'])
|
||||
|
||||
return super().render_to_response(template, context)
|
||||
|
||||
def configure_grid(self, g):
|
||||
""" """
|
||||
super().configure_grid(g)
|
||||
|
@ -208,6 +256,20 @@ class BatchMasterView(MasterView):
|
|||
thread.start()
|
||||
return self.render_progress(progress)
|
||||
|
||||
def delete_instance(self, batch):
|
||||
"""
|
||||
Delete the given batch instance.
|
||||
|
||||
This calls
|
||||
:meth:`~wuttjamaican:wuttjamaican.batch.BatchHandler.do_delete()`
|
||||
on the :attr:`batch_handler`.
|
||||
"""
|
||||
self.batch_handler.do_delete(batch, self.request.user)
|
||||
|
||||
##############################
|
||||
# populate methods
|
||||
##############################
|
||||
|
||||
def populate_thread(self, batch_uuid, progress=None):
|
||||
"""
|
||||
Thread target for populating new object with progress indicator.
|
||||
|
@ -258,6 +320,31 @@ class BatchMasterView(MasterView):
|
|||
finally:
|
||||
session.close()
|
||||
|
||||
##############################
|
||||
# execute methods
|
||||
##############################
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
View to execute the current :term:`batch`.
|
||||
|
||||
Eventually this should show a progress indicator etc., but for
|
||||
now it simply calls
|
||||
:meth:`~wuttjamaican:wuttjamaican.batch.BatchHandler.do_execute()`
|
||||
on the :attr:`batch_handler` and waits for it to complete,
|
||||
then redirects user back to the "view batch" page.
|
||||
"""
|
||||
self.executing = True
|
||||
batch = self.get_instance()
|
||||
|
||||
try:
|
||||
self.batch_handler.do_execute(batch, self.request.user)
|
||||
except Exception as error:
|
||||
log.warning("failed to execute batch: %s", batch, exc_info=True)
|
||||
self.request.session.flash(f"Execution failed!: {error}", 'error')
|
||||
|
||||
return self.redirect(self.get_action_url('view', batch))
|
||||
|
||||
##############################
|
||||
# row methods
|
||||
##############################
|
||||
|
@ -287,3 +374,31 @@ class BatchMasterView(MasterView):
|
|||
super().configure_row_grid(g)
|
||||
|
||||
g.set_label('sequence', "Seq.", column_only=True)
|
||||
|
||||
##############################
|
||||
# configuration
|
||||
##############################
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
""" """
|
||||
cls._defaults(config)
|
||||
cls._batch_defaults(config)
|
||||
|
||||
@classmethod
|
||||
def _batch_defaults(cls, config):
|
||||
route_prefix = cls.get_route_prefix()
|
||||
permission_prefix = cls.get_permission_prefix()
|
||||
model_title = cls.get_model_title()
|
||||
instance_url_prefix = cls.get_instance_url_prefix()
|
||||
|
||||
# execute
|
||||
config.add_route(f'{route_prefix}.execute',
|
||||
f'{instance_url_prefix}/execute',
|
||||
request_method='POST')
|
||||
config.add_view(cls, attr='execute',
|
||||
route_name=f'{route_prefix}.execute',
|
||||
permission=f'{permission_prefix}.execute')
|
||||
config.add_wutta_permission(permission_prefix,
|
||||
f'{permission_prefix}.execute',
|
||||
f"Execute {model_title}")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue