workflows: somehow unify status changes, to have uniform error handling

This commit is contained in:
Frédéric Péters 2012-08-13 12:41:38 +02:00
parent 5af1f48b56
commit 335c26f8c5
3 changed files with 73 additions and 58 deletions

View File

@ -16,19 +16,20 @@
from qommon.form import *
from wcs.workflows import WorkflowStatusItem, register_item_class
from wcs.workflows import WorkflowStatusJumpItem, register_item_class
class JumpWorkflowStatusItem(WorkflowStatusItem):
class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
description = N_('Change Status Automatically')
key = 'jump'
status = None
condition = None
def render_as_line(self):
if self.status:
wf_status = [x for x in self.parent.parent.possible_status if x.id == self.status][0]
wf_status = self.get_status()
if not wf_status:
return _('Change Status Automatically (broken)')
if self.condition:
return _('Change Status Automatically (to %(name)s, if %(condition)s)') % {
'name': wf_status.name,
@ -43,9 +44,7 @@ class JumpWorkflowStatusItem(WorkflowStatusItem):
return ('status', 'condition')
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
if 'status' in parameters:
form.add(SingleSelectWidget, '%sstatus' % prefix, title = _('Status'), value = self.status,
options = [(None, '---')] + [(x.id, x.name) for x in self.parent.parent.possible_status])
WorkflowStatusJumpItem.add_parameters_widgets(self, form, parameters, prefix, formdef)
if 'condition' in parameters:
form.add(StringWidget, '%scondition' % prefix, title=_('Condition (formula)'),
value=self.condition, size=40)
@ -61,7 +60,8 @@ class JumpWorkflowStatusItem(WorkflowStatusItem):
except:
condition = False
if condition:
wf_status = [x for x in self.parent.parent.possible_status if x.id == self.status][0]
formdata.status = 'wf-%s' % wf_status.id
wf_status = self.get_status()
if wf_status:
formdata.status = 'wf-%s' % wf_status.id
register_item_class(JumpWorkflowStatusItem)

View File

@ -16,7 +16,7 @@
from wcs.qommon.humantime import *
from wcs.workflows import Workflow, WorkflowStatusItem, register_item_class, \
from wcs.workflows import Workflow, WorkflowStatusJumpItem, register_item_class, \
render_list_of_roles, get_role_translation
from wcs.formdata import Evolution
@ -24,49 +24,40 @@ from qommon.form import *
from qommon.publisher import get_publisher_class
from qommon.cron import CronJob
class TimeoutWorkflowStatusItem(WorkflowStatusItem):
class TimeoutWorkflowStatusItem(WorkflowStatusJumpItem):
description = N_('Change Status on Timeout')
key = 'timeout'
endpoint = False
status = None
timeout = None
_granularity = 20 * 60 # default: 20 minutes, see bottom of file
def render_as_line(self):
status = [ x for x in self.parent.parent.possible_status \
if str(x.id) == str(self.status)]
if status and self.timeout:
if self.status and self.get_status() and self.timeout:
return _('Change Status on Timeout to "%(status)s" after %(time)s') % \
{'status': status[0].name, 'time': seconds2humanduration(self.timeout)}
{'status': self.get_status().name, 'time': seconds2humanduration(self.timeout)}
else:
return _('Change Status on Timeout (not completed)')
def fill_admin_form(self, form):
form.add(SingleSelectWidget, 'status', title = _('Status'), value = self.status,
options = [(None, '---')] + [(x.id, x.name) for x in self.parent.parent.possible_status])
_hint = htmltext(_("ex.: 7 days 1 minute<br/> Usable units of time: %(variables)s. " \
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
WorkflowStatusJumpItem.add_parameters_widgets(self, form, parameters, prefix, formdef)
if 'timeout' in parameters:
_hint = htmltext(_("ex.: 7 days 1 minute<br/> Usable units of time: %(variables)s. " \
'<br/><span class="warning">Minimal duration is %(granularity)s</span>')) % {
'variables': ','.join(timewords()),
'granularity': seconds2humanduration(self._granularity)}
form.add(StringWidget, 'timeout', title=_('Timeout'),
form.add(StringWidget, 'timeout', title=_('Timeout'),
value=seconds2humanduration(self.timeout), hint=_hint)
def submit_admin_form(self, form):
widget = form.get_widget('timeout')
if widget and widget.parse():
try:
self.timeout = int(widget.parse())
except ValueError:
try:
self.timeout = humanduration2seconds(widget.parse())
except ValueError:
self.timeout = None
for f in ('status',):
widget = form.get_widget(f)
if widget:
setattr(self, f, widget.parse())
def timeout_parse(self, value):
try:
return humanduration2seconds(value)
except ValueError:
return None
def get_parameters(self):
return ('status', 'timeout')
def workflows_with_timeout():
@ -86,6 +77,9 @@ def workflows_with_timeout():
status = 'wf-%s' % status.id
if not wfs_status[id].get(status):
wfs_status[id][status] = []
if not item.get_status():
# this will catch status being a removed status
continue
wfs_status[id][status].append(item)
return wfs_status

View File

@ -478,7 +478,10 @@ class WorkflowStatusItem:
for f in self.get_parameters():
widget = form.get_widget(f)
if widget:
setattr(self, f, widget.parse())
value = widget.parse()
if hasattr(self, '%s_parse' % f):
value = getattr(self, '%s_parse' % f)(value)
setattr(self, f, value)
def compute(self, var):
if not isinstance(var, basestring):
@ -553,6 +556,31 @@ class WorkflowStatusItem:
return odict
class WorkflowStatusJumpItem(WorkflowStatusItem):
status = None
def get_status(self):
if not self.status:
return None
try:
return [x for x in self.parent.parent.possible_status if x.id == self.status][0]
except IndexError:
get_publisher().get_app_logger().error(
'reference to invalid status in workflow %s, status %s, item %s' % (
self.parent.parent.name,
self.parent.name,
self.description))
return None
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
if 'status' in parameters:
form.add(SingleSelectWidget, '%sstatus' % prefix, title = _('Status'), value = self.status,
options = [(None, '---')] + [(x.id, x.name) for x in self.parent.parent.possible_status])
def get_parameters(self):
return ('status',)
def get_role_translation(formdef, role_name):
if role_name == '_receiver':
return formdef.receiver_id
@ -661,13 +689,12 @@ class CommentableWorkflowStatusItem(WorkflowStatusItem):
register_item_class(CommentableWorkflowStatusItem)
class ChoiceWorkflowStatusItem(WorkflowStatusItem):
class ChoiceWorkflowStatusItem(WorkflowStatusJumpItem):
description = N_('Change Status')
key = 'choice'
endpoint = False
label = None
status = None
by = []
def render_as_line(self):
@ -686,18 +713,16 @@ class ChoiceWorkflowStatusItem(WorkflowStatusItem):
def submit_form(self, form, formdata, user, evo):
if form.get_submit() == 'button%s' % self.id:
wf_status = [x for x in self.parent.parent.possible_status \
if str(x.id) == str(self.status)][0]
evo.status = 'wf-%s' % wf_status.id
form.clear_errors()
return True # get out of processing loop
wf_status = self.get_status()
if wf_status:
evo.status = 'wf-%s' % wf_status.id
form.clear_errors()
return True # get out of processing loop
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
if 'label' in parameters:
form.add(StringWidget, '%slabel' % prefix, title = _('Label'), value = self.label)
if 'status' in parameters:
form.add(SingleSelectWidget, '%sstatus' % prefix, title = _('Status'), value = self.status,
options = [(None, '---')] + [(x.id, x.name) for x in self.parent.parent.possible_status])
WorkflowStatusJumpItem.add_parameters_widgets(self, form, parameters, prefix, formdef)
if 'by' in parameters:
form.add(WidgetList, '%sby' % prefix, title = _('By'), element_type = SingleSelectWidget,
value = self.by,
@ -715,28 +740,24 @@ class ChoiceWorkflowStatusItem(WorkflowStatusItem):
register_item_class(ChoiceWorkflowStatusItem)
class JumpOnSubmitWorkflowStatusItem(WorkflowStatusItem):
class JumpOnSubmitWorkflowStatusItem(WorkflowStatusJumpItem):
description = N_('Change Status on Submit')
key = 'jumponsubmit'
status = None
def render_as_line(self):
if self.status:
wf_status = [x for x in self.parent.parent.possible_status if x.id == self.status][0]
return _('Change Status on Submit (to %s)') % wf_status.name
if self.get_status():
return _('Change Status on Submit (to %s)') % self.get_status().name
else:
return _('Change Status on Submit (broken)')
else:
return _('Change Status on Submit (not completed)')
def submit_form(self, form, formdata, user, evo):
if form.is_submitted() and not form.has_errors():
wf_status = [x for x in self.parent.parent.possible_status if x.id == self.status][0]
evo.status = 'wf-%s' % wf_status.id
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
if 'status' in parameters:
form.add(SingleSelectWidget, '%sstatus' % prefix, title = _('Status'), value = self.status,
options = [(None, '---')] + [(x.id, x.name) for x in self.parent.parent.possible_status])
wf_status = self.get_status()
if wf_status:
evo.status = 'wf-%s' % wf_status.id
def get_parameters(self):
return ('status',)