add trigger-jumps command

This commit is contained in:
Thomas NOËL 2013-06-13 16:39:28 +02:00
parent 6cbc19ab78
commit f754a0e39e
2 changed files with 136 additions and 7 deletions

121
wcs/ctl/trigger_jumps.py Normal file
View File

@ -0,0 +1,121 @@
# w.c.s. - web application for online forms
# Copyright (C) 2005-2013 Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import os
import sys
import json
from qommon.ctl import Command, make_option
from wcs.formdef import FormDef
from wcs.wf.jump import JumpWorkflowStatusItem, jump_and_perform
class CmdTriggerJumps(Command):
'''Triggers all "jump trigger" for a formdef, given host publisher context
source.json file format:
[
{
"data": { "info_for_wf_data": 42, ... },
"select": { "form_number": 1, ... }
},
...
]
'''
name = 'trigger-jumps'
def __init__(self):
Command.__init__(self, [
make_option('--formdef-id', metavar='FORMDEF_ID', action='store',
dest='formdef_id', help='(mandatory)'),
make_option('--trigger', metavar='TRIGGER', action='store',
dest='trigger', help='(mandatory) trigger name'),
make_option('--vhost', metavar='VHOST', action='store',
dest='vhost'),
])
def execute(self, base_options, sub_options, args):
if not sub_options.vhost:
print >> sys.stderr, 'you must specificy --vhost'
sys.exit(1)
if not sub_options.trigger:
print >> sys.stderr, 'you must specificy --trigger'
sys.exit(1)
if not sub_options.formdef_id:
print >> sys.stderr, 'you must specificy --formdef-id'
sys.exit(1)
import publisher
self.config.remove_option('main', 'error_log')
publisher.WcsPublisher.configure(self.config, sub_options.extra)
publisher = publisher.WcsPublisher.create_publisher()
publisher.app_dir = os.path.join(publisher.app_dir, sub_options.vhost)
publisher.set_config()
formdef = FormDef.get(id=sub_options.formdef_id)
trigger = sub_options.trigger
rows = list(get_rows(args))
for formdata, jump_to in get_formdata_accepting_trigger(formdef, trigger):
for row in rows:
if match_row(formdata, row):
print 'formdata %s jumps to status %s' % \
(formdata, jump_to)
jump_and_perform(formdata, jump_to, row.get('data'))
break # next formdata
CmdTriggerJumps.register()
def get_rows(args):
if not args:
for row in json.load(sys.stdin):
yield row
for arg in args:
for row in json.load(file(arg)):
yield row
def get_status_ids_accepting_trigger(formdef, trigger):
workflow = formdef.get_workflow()
for status in workflow.possible_status:
for item in status.items:
if isinstance(item, JumpWorkflowStatusItem) and \
item.trigger == trigger:
yield 'wf-%s' % status.id, item.status
break
def get_formdata_accepting_trigger(formdef, trigger):
status_ids = get_status_ids_accepting_trigger(formdef, trigger)
formdata_ids = []
data_class = formdef.data_class()
for status_id, jump_to in status_ids:
formdata_ids = data_class.get_ids_with_indexed_value(
'status', status_id)
for formdata_id in formdata_ids:
yield data_class.get(id=formdata_id), jump_to
def match_row(formdata, row):
select = row['select']
substitution_variables = formdata.get_substitution_variables()
for key, value in select.iteritems():
if str(substitution_variables.get(key)) != str(value):
return False
return True

View File

@ -31,6 +31,15 @@ from wcs.formdata import Evolution
from wcs.api import get_user_from_api_query_string
def jump_and_perform(formdata, status, workflow_data=None):
if workflow_data:
formdata.update_workflow_data(workflow_data)
formdata.store()
formdata.jump_status(status)
url = formdata.perform_workflow()
return url
class JumpDirectory(Directory):
_q_exports = ['trigger']
@ -67,11 +76,11 @@ class TriggerDirectory(Directory):
if not item.check_auth(self.formdata, user):
raise errors.AccessForbiddenError()
get_request().trigger_name = component
workflow_data = None
if hasattr(get_request(), 'json'):
self.formdata.update_workflow_data(get_request().json)
self.formdata.store()
self.formdata.jump_status(self.wfstatusitem.status)
url = self.formdata.perform_workflow()
workflow_data = get_request().json
url = jump_and_perform(self.formdata, self.wfstatusitem.status,
workflow_data=workflow_data)
if get_request().is_json():
return json.dumps({'err': 0, 'url': url})
elif url:
@ -115,7 +124,7 @@ class JumpWorkflowStatusItem(WorkflowStatusJumpItem):
return _('Change Status Automatically (to %s) (%s)') % (
wf_status.name, ', '.join(reasons))
else:
return _('Change Status Automatically (to %s)')
return _('Change Status Automatically (to %s)') % wf_status.name
def get_parameters(self):
return ('status', 'condition', 'trigger', 'by', 'timeout')
@ -231,8 +240,7 @@ def _apply_timeouts(publisher):
if formdata.status in wfs_status[str(formdef.workflow_id)]:
for x in wfs_status[str(formdef.workflow_id)][formdata.status]:
if x.must_jump(formdata):
formdata.jump_status(x.status)
formdata.perform_workflow()
jump_and_perform(formdata, x.status)
break
if get_publisher_class():