Add running display of stdout.log when executing upgrade

This commit is contained in:
Lance Edgar 2017-08-09 11:44:31 -05:00
parent fbd73a48c4
commit e5b0fe7198
6 changed files with 243 additions and 92 deletions

View file

@ -90,12 +90,15 @@ class View(object):
def progress_loop(self, func, items, factory, *args, **kwargs):
return progress_loop(func, items, factory, *args, **kwargs)
def render_progress(self, progress, kwargs):
# TODO: this signature seems wonky
def render_progress(self, progress, kwargs, template=None):
"""
Render the progress page, with given kwargs as context.
"""
if not template:
template = '/progress.mako'
kwargs['progress'] = progress
return render_to_response('/progress.mako', kwargs, request=self.request)
return render_to_response(template, kwargs, request=self.request)
def file_response(self, path):
"""

View file

@ -71,8 +71,10 @@ class MasterView(View):
bulk_deletable = False
mergeable = False
downloadable = False
executable = False
cloneable = False
executable = False
execute_progress_template = None
execute_progress_initial_msg = None
supports_mobile = False
mobile_creatable = False
@ -841,20 +843,22 @@ class MasterView(View):
model_title = self.get_model_title()
if self.request.method == 'POST':
progress = self.make_execute_progress()
progress = self.make_execute_progress(obj)
kwargs = {'progress': progress}
thread = Thread(target=self.execute_thread, args=(obj.uuid, self.request.user.uuid), kwargs=kwargs)
thread.start()
return self.render_progress(progress, {
'instance': obj,
'initial_msg': self.execute_progress_initial_msg,
'cancel_url': self.get_action_url('view', obj),
'cancel_msg': "{} execution was canceled".format(model_title),
})
}, template=self.execute_progress_template)
self.request.session.flash("Sorry, you must POST to execute a {}.".format(model_title), 'error')
return self.redirect(self.get_action_url('view', obj))
def make_execute_progress(self):
def make_execute_progress(self, obj):
key = '{}.execute'.format(self.get_grid_key())
return SessionProgress(self.request, key)

View file

@ -43,7 +43,7 @@ from deform import widget as dfwidget
from webhelpers2.html import tags
from tailbone.views import MasterView3 as MasterView
from tailbone.progress import SessionProgress
from tailbone.progress import SessionProgress, get_progress_session
class UpgradeView(MasterView):
@ -51,9 +51,12 @@ class UpgradeView(MasterView):
Master view for all user events
"""
model_class = model.Upgrade
executable = True
downloadable = True
cloneable = True
executable = True
execute_progress_template = '/upgrade.mako'
execute_progress_initial_msg = "Upgrading"
labels = {
'executed_by': "Executed by",
'status_code': "Status",
@ -281,6 +284,44 @@ class UpgradeView(MasterView):
upgrade.executed = make_utc()
upgrade.executed_by = user
def execute_progress(self):
upgrade = self.get_instance()
key = '{}.execute'.format(self.get_grid_key())
session = get_progress_session(self.request, key)
if session.get('complete'):
msg = session.get('success_msg')
if msg:
self.request.session.flash(msg)
elif session.get('error'):
self.request.session.flash(session.get('error_msg', "An unspecified error occurred."), 'error')
data = dict(session)
path = self.rattail_config.upgrade_filepath(upgrade.uuid, filename='stdout.log')
offset = session.get('stdout.offset', 0)
size = os.path.getsize(path) - offset
with open(path, 'rb') as f:
f.seek(offset)
chunk = f.read(size)
data['stdout'] = chunk.replace('\n', '<br />')
session['stdout.offset'] = offset + size
session.save()
return data
@classmethod
def defaults(cls, config):
route_prefix = cls.get_route_prefix()
url_prefix = cls.get_url_prefix()
permission_prefix = cls.get_permission_prefix()
model_key = cls.get_model_key()
# execution progress
config.add_route('{}.execute_progress'.format(route_prefix), '{}/{{{}}}/execute/progress'.format(url_prefix, model_key))
config.add_view(cls, attr='execute_progress', route_name='{}.execute_progress'.format(route_prefix),
permission='{}.execute'.format(permission_prefix), renderer='json')
cls._defaults(config)
def includeme(config):
UpgradeView.defaults(config)