示例#1
0
def handle_request(content, server):
    start = time.time()
    ensure_required_params(["action"], "All actions", content)

    session_id = "<unknown>"
    if content.get("session-id", None):
        session_id = content["session-id"]

    action = content["action"]
    logger.info("Received action %s for session %s" % (action, session_id))
    nav_mode = content.get("nav", "prompt")
    try:
        # Formplayer routes
        if action == xformplayer.Actions.NEW_FORM:
            form_fields = {"form-name": "uid", "form-content": "raw", "form-url": "url"}
            form_spec = None
            for k, v in form_fields.iteritems():
                try:
                    form_spec = (v, content[k])
                    break
                except KeyError:
                    pass
            if not form_spec:
                return {"error": "form specification required (form-name, form-content, or form-url)"}

            if "instance-content" in content:
                inst_spec = ("raw", content["instance-content"])
            else:
                inst_spec = None

            session_data = content.get("session-data", {})
            return xformplayer.open_form(
                form_spec,
                inst_spec,
                **{
                    "init_lang": content.get("lang"),
                    "extensions": server.extensions,
                    "session_data": session_data,
                    "nav_mode": nav_mode,
                    "api_auth": content.get("hq_auth"),
                    "form_context": content.get("form_context", {}),
                    "staleness_window": content.get("staleness_window", server.default_stale_window),
                }
            )

        elif action == xformplayer.Actions.ANSWER:
            ensure_required_params(["session-id", "answer"], action, content)
            return xformplayer.answer_question(content["session-id"], content["answer"], content.get("ix"))

        # sequential (old-style) repeats only
        elif action == xformplayer.Actions.ADD_REPEAT:
            ensure_required_params(["session-id"], action, content)
            return xformplayer.new_repetition(content["session-id"])

        elif action == xformplayer.Actions.NEXT:
            ensure_required_params(["session-id"], action, content)
            return xformplayer.skip_next(content["session-id"])

        elif action == xformplayer.Actions.BACK:
            ensure_required_params(["session-id"], action, content)
            return xformplayer.go_back(content["session-id"])

        elif action == xformplayer.Actions.CURRENT:
            ensure_required_params(["session-id"], action, content)
            override_state = None
            # override api_auth with the current auth to avoid issues with expired django sessions
            # when editing saved forms
            hq_auth = content.get("hq_auth")
            if hq_auth:
                override_state = {"api_auth": hq_auth}
            return xformplayer.current_question(content["session-id"], override_state=override_state)

        elif action == xformplayer.Actions.HEARTBEAT:
            return {}
        elif action == xformplayer.Actions.EDIT_REPEAT:
            ensure_required_params(["session-id", "ix"], action, content)
            return xformplayer.edit_repeat(content["session-id"], content["ix"])

        elif action == xformplayer.Actions.NEW_REPEAT:
            ensure_required_params(["session-id"], action, content)
            return xformplayer.new_repeat(content["session-id"], content.get("ix"))
        elif action == xformplayer.Actions.DELETE_REPEAT:
            ensure_required_params(["session-id", "ix"], action, content)
            return xformplayer.delete_repeat(content["session-id"], content["ix"], content.get("form_ix"))
        elif action == xformplayer.Actions.SUBMIT_ALL:
            ensure_required_params(["session-id"], action, content)
            return xformplayer.submit_form(
                content["session-id"], content.get("answers", []), content.get("prevalidated", False)
            )
        elif action == xformplayer.Actions.SET_LANG:
            ensure_required_params(["session-id", "lang"], action, content)
            return xformplayer.set_locale(content["session-id"], content["lang"])
        elif action == xformplayer.Actions.PURGE_STALE:
            ensure_required_params(["window"], action, content)
            return xformplayer.purge(content["window"])
        elif action == xformplayer.Actions.GET_INSTANCE:
            ensure_required_params(["session-id"], action, content)
            xfsess = xformplayer.global_state.get_session(content["session-id"])
            return {"output": xfsess.output(), "xmlns": xfsess.get_xmlns()}
        elif action == xformplayer.Actions.EVALUATE_XPATH:
            ensure_required_params(["session-id"], action, content)
            xfsess = xformplayer.global_state.get_session(content["session-id"])
            result = xfsess.evaluate_xpath(content["xpath"])
            return {"output": result["output"], "status": result["status"]}
        # Touchcare routes
        elif action == touchcare.Actions.FILTER_CASES:
            ensure_required_params(["hq_auth", "filter_expr"], action, content)
            result = touchcare.filter_cases(
                content.get("filter_expr"),
                content.get("hq_auth"),
                content.get("session_data", {}),
                content.get("form_context", {}),
            )
            return result

        else:
            raise InvalidRequestException("Unrecognized action: %s" % action)

    except xformplayer.NoSuchSession:
        return {"error": "invalid session id"}
    except xformplayer.SequencingException:
        return {"error": "session is locked by another request"}
    finally:
        delta = (time.time() - start) * 1000
        domain = "<unknown>"
        if content.get("session-id", None) and xformplayer.global_state:
            xfsess = xformplayer.global_state.get_session(session_id)
            domain = xfsess.orig_params["session_data"].get("domain", "<unknown>")
        elif content.get("session-data", None):
            domain = content["session-data"].get("domain", "<unknown>")
        elif content.get("session_data", None):
            domain = content["session_data"].get("domain", "<unknown>")

        logger.info(
            "Finished processing action %s in %s ms for session %s in domain '%s'" % (action, delta, session_id, domain)
        )
示例#2
0
def handle_request (content, **kwargs):
    if 'action' not in content:
        return {'error': 'action required'}

    action = content['action']
    nav_mode = content.get('nav', 'prompt')
    try:
        if action == 'new-form':
            if 'form-name' not in content:
                return {'error': 'form identifier required'}
            preload_data = content.get("preloader-data", {})
            return xformplayer.open_form(content['form-name'], content.get('instance-content'), content.get('lang'), kwargs.get('extensions', []), preload_data, nav_mode)

        elif action == 'edit-form':
            return {'error': 'unsupported'}

        elif action == 'answer':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'answer' not in content:
                return {'error': 'answer required'}

            return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix'))

        #sequential (old-style) repeats only
        elif action == 'add-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repetition(content['session-id'])

        elif action == 'next':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.skip_next(content['session-id'])

        elif action == 'back':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.go_back(content['session-id'])

        elif action == 'edit-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.edit_repeat(content['session-id'], content['ix'])

        elif action == 'new-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repeat(content['session-id'], content.get('ix'))
    
        elif action == 'delete-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix'))

        elif action == 'submit-all':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            
            return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False))

        elif action == 'set-lang':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'lang' not in content:
                return {'error': 'language required'}
            
            return xformplayer.set_locale(content['session-id'], content['lang'])            

        elif action == 'purge-stale':
            if 'window' not in content:
                return {'error': 'staleness window required'}

            return xformplayer.purge(content['window'])

        else:
            return {'error': 'unrecognized action'}
    
    except xformplayer.NoSuchSession:
        return {'error': 'invalid session id'}
    except xformplayer.SequencingException:
        return {'error': 'session is locked by another request'}
示例#3
0
def handle_request(content, server):
    start = time.time()
    ensure_required_params(['action'], 'All actions', content)

    session_id = '<unknown>'
    if content.get('session-id', None):
        session_id = content['session-id']

    action = content['action']
    logger.info('Received action %s for session %s' % (action, session_id))
    datadog_logger.info(
        'event=received action=%s unit=request' % (action),
        extra={'value': 1, 'metric_type': 'counter', 'timestamp': int(time.time()), 'metric': 'actions'}
    )
    nav_mode = content.get('nav', 'prompt')
    try:
        # Formplayer routes
        if action == xformplayer.Actions.NEW_FORM:
            form_fields = {'form-name': 'uid', 'form-content': 'raw', 'form-url': 'url'}
            form_spec = None
            for k, v in form_fields.iteritems():
                try:
                    form_spec = (v, content[k])
                    break
                except KeyError:
                    pass
            if not form_spec:
                return {'error': 'form specification required (form-name, form-content, or form-url)'}

            if 'instance-content' in content:
                inst_spec = ('raw', content['instance-content'])
            else:
                inst_spec = None

            session_data = content.get("session-data", {})

            return xformplayer.open_form(form_spec, inst_spec, **{
                'init_lang': content.get('lang'),
                'extensions': server.extensions,
                'session_data': session_data,
                'nav_mode': nav_mode,
                'api_auth': content.get('hq_auth'),
                'form_context': content.get('form_context', {}),
                'staleness_window': content.get('staleness_window', server.default_stale_window),
                'uses_sql_backend': content.get('uses_sql_backend'),
            })

        elif action == xformplayer.Actions.ANSWER:
            ensure_required_params(['session-id', 'answer'], action, content)
            return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix'))

        #sequential (old-style) repeats only
        elif action == xformplayer.Actions.ADD_REPEAT:
            ensure_required_params(['session-id'], action, content)
            return xformplayer.new_repetition(content['session-id'])

        elif action == xformplayer.Actions.NEXT:
            ensure_required_params(['session-id'], action, content)
            return xformplayer.skip_next(content['session-id'])

        elif action == xformplayer.Actions.BACK:
            ensure_required_params(['session-id'], action, content)
            return xformplayer.go_back(content['session-id'])

        elif action == xformplayer.Actions.CURRENT:
            ensure_required_params(['session-id'], action, content)
            override_state = _get_override_state(content)
            return xformplayer.current_question(content['session-id'], override_state=override_state)

        elif action == xformplayer.Actions.HEARTBEAT:
            return {}
        elif action == xformplayer.Actions.EDIT_REPEAT:
            ensure_required_params(['session-id', 'ix'], action, content)
            return xformplayer.edit_repeat(content['session-id'], content['ix'])

        elif action == xformplayer.Actions.NEW_REPEAT:
            ensure_required_params(['session-id'], action, content)
            return xformplayer.new_repeat(content['session-id'], content.get('ix'))
        elif action == xformplayer.Actions.DELETE_REPEAT:
            ensure_required_params(['session-id', 'ix'], action, content)
            return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix'))
        elif action == xformplayer.Actions.SUBMIT_ALL:
            ensure_required_params(['session-id'], action, content)
            return xformplayer.submit_form(content['session-id'],
                                           content.get('answers', []),
                                           content.get('prevalidated', False))
        elif action == xformplayer.Actions.SET_LANG:
            ensure_required_params(['session-id', 'lang'], action, content)
            return xformplayer.set_locale(content['session-id'], content['lang'])
        elif action == xformplayer.Actions.PURGE_STALE:
            ensure_required_params(['window'], action, content)
            return xformplayer.purge(content['window'])
        elif action == xformplayer.Actions.GET_INSTANCE:
            ensure_required_params(['session-id'], action, content)
            xfsess = xformplayer.global_state.get_session(content['session-id'])
            return {"output": xfsess.output(), "xmlns": xfsess.get_xmlns()}
        elif action == xformplayer.Actions.EVALUATE_XPATH:
            ensure_required_params(['session-id'], action, content)
            xfsess = xformplayer.global_state.get_session(content['session-id'])
            result = xfsess.evaluate_xpath(content['xpath'])
            return {"output": result['output'], "status": result['status']}
        elif action == xformplayer.Actions.SYNC_USER_DB:
            ensure_required_params(['username', 'domain', 'hq_auth'], action, content)
            username = content['username']
            domain = content['domain']
            # if a mobile user, we only want the username up to the @{domain}.{host} portion
            if username.endswith('commcarehq.org'):
                username = content['username'][:content['username'].index('@')]
            result = touchcare.force_ota_restore(username, domain, auth=content['hq_auth'])
            return result
        # Touchcare routes
        elif action == touchcare.Actions.FILTER_CASES:
            ensure_required_params(['hq_auth', 'filter_expr'], action, content)
            result = touchcare.filter_cases(
                content.get('filter_expr'),
                content.get('hq_auth'),
                content.get('session_data', {}),
                content.get('form_context', {}),
                uses_sqlite=content.get('uses_sql_backend', False)
            )
            return result

        else:
            raise InvalidRequestException("Unrecognized action: %s" % action)
    
    except xformplayer.NoSuchSession:
        return {'error': 'invalid session id'}
    except xformplayer.SequencingException:
        return {'error': 'session is locked by another request'}
    finally:
        delta = (time.time() - start) * 1000
        _log_action(action, content, delta, session_id)
示例#4
0
def handle_request (content, **kwargs):
    if 'action' not in content:
        return {'error': 'action required'}

    action = content['action']
    nav_mode = content.get('nav', 'prompt')
    try:
        if action == 'new-form':
            if 'form-name' not in content:
                return {'error': 'form identifier required'}
            preload_data = content["preloader-data"] if "preloader-data" in content else {}
            return xformplayer.open_form(content['form-name'], content.get('instance-content'), kwargs.get('extensions', []), preload_data, nav_mode)

        elif action == 'edit-form':
            return {'error': 'unsupported'}

        elif action == 'answer':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'answer' not in content:
                return {'error': 'answer required'}

            return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix'))

        #sequential (old-style) repeats only
        elif action == 'add-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repetition(content['session-id'])

        elif action == 'next':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.skip_next(content['session-id'])

        elif action == 'back':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.go_back(content['session-id'])

        elif action == 'edit-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.edit_repeat(content['session-id'], content['ix'])

        elif action == 'new-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repeat(content['session-id'], content.get('ix'))
    
        elif action == 'delete-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix'))

        elif action == 'submit-all':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            
            return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False))

        elif action == 'purge-stale':
            if 'window' not in content:
                return {'error': 'staleness window required'}

            return xformplayer.purge(content['window'])

        else:
            return {'error': 'unrecognized action'}
    
    except xformplayer.NoSuchSession:
        return {'error': 'invalid session id'}
    except xformplayer.SequencingException:
        return {'error': 'session is locked by another request'}
示例#5
0
def handle_request (content, server):
    if 'action' not in content:
        return {'error': 'action required'}

    action = content['action']
    nav_mode = content.get('nav', 'prompt')
    try:
        if action == 'new-form':
            form_fields = {'form-name': 'uid', 'form-content': 'raw', 'form-url': 'url'}
            form_spec = None
            for k, v in form_fields.iteritems():
                try:
                    form_spec = (v, content[k])
                    break
                except KeyError:
                    pass
            if not form_spec:
                return {'error': 'form specification required (form-name, form-content, or form-url)'}

            inst_fields = {'instance-content': 'raw'}
            inst_spec = None
            for k, v in inst_fields.iteritems():
                try:
                    inst_spec = (v, content[k])
                    break
                except KeyError:
                    pass

            session_data = content.get("session-data", {})
            return xformplayer.open_form(form_spec, inst_spec, **{
                    'init_lang': content.get('lang'),
                    'extensions': server.extensions,
                    'session_data': session_data,
                    'nav_mode': nav_mode,
                    'api_auth': content.get('hq_auth'),
                    'staleness_window': content.get('staleness_window', server.default_stale_window),
                })

        elif action == 'edit-form':
            return {'error': 'unsupported'}

        elif action == 'answer':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'answer' not in content:
                return {'error': 'answer required'}

            return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix'))

        #sequential (old-style) repeats only
        elif action == 'add-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repetition(content['session-id'])

        elif action == 'next':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.skip_next(content['session-id'])

        elif action == 'back':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.go_back(content['session-id'])

        elif action == 'current':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.current_question(content['session-id'])

        elif action == 'heartbeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.heartbeat(content['session-id'])

        elif action == 'edit-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.edit_repeat(content['session-id'], content['ix'])

        elif action == 'new-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repeat(content['session-id'], content.get('ix'))
    
        elif action == 'delete-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix'))

        elif action == 'submit-all':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            
            return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False))

        elif action == 'set-lang':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'lang' not in content:
                return {'error': 'language required'}
            
            return xformplayer.set_locale(content['session-id'], content['lang'])            

        elif action == 'purge-stale':
            if 'window' not in content:
                return {'error': 'staleness window required'}

            return xformplayer.purge(content['window'])

        elif action in touchcare.SUPPORTED_ACTIONS:
            return touchcare.handle_request(content, server)
            
        elif action == 'get-instance':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            xfsess = xformplayer.global_state.get_session(content['session-id'])
            return {"output": xfsess.output()}

        else:
            return {'error': 'unrecognized action'}
    
    except xformplayer.NoSuchSession:
        return {'error': 'invalid session id'}
    except xformplayer.SequencingException:
        return {'error': 'session is locked by another request'}
示例#6
0
def handle_request (content, **kwargs):
    if 'action' not in content:
        return {'error': 'action required'}

    action = content['action']
    nav_mode = content.get('nav', 'prompt')
    try:
        if action == 'new-form':
            form_fields = {'form-name': 'uid', 'form-content': 'raw', 'form-url': 'url'}
            form_spec = None
            for k, v in form_fields.iteritems():
                try:
                    form_spec = (v, content[k])
                    break
                except KeyError:
                    pass
            if not form_spec:
                return {'error': 'form specification required (form-name, form-content, or form-url)'}

            inst_fields = {'instance-content': 'raw'}
            inst_spec = None
            for k, v in inst_fields.iteritems():
                try:
                    inst_spec = (v, content[k])
                    break
                except KeyError:
                    pass

            session_data = content.get("session-data", {})
            return xformplayer.open_form(form_spec, inst_spec,
                                         content.get('lang'), kwargs.get('extensions', []), session_data, nav_mode, content.get('hq_auth'))

        elif action == 'edit-form':
            return {'error': 'unsupported'}

        elif action == 'answer':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'answer' not in content:
                return {'error': 'answer required'}

            return xformplayer.answer_question(content['session-id'], content['answer'], content.get('ix'))

        #sequential (old-style) repeats only
        elif action == 'add-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repetition(content['session-id'])

        elif action == 'next':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.skip_next(content['session-id'])

        elif action == 'back':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.go_back(content['session-id'])

        elif action == 'current':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.current_question(content['session-id'])

        elif action == 'edit-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.edit_repeat(content['session-id'], content['ix'])

        elif action == 'new-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}

            return xformplayer.new_repeat(content['session-id'], content.get('ix'))
    
        elif action == 'delete-repeat':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'ix' not in content:
                return {'error': 'repeat index required'}

            return xformplayer.delete_repeat(content['session-id'], content['ix'], content.get('form_ix'))

        elif action == 'submit-all':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            
            return xformplayer.submit_form(content['session-id'], content.get('answers', []), content.get('prevalidated', False))

        elif action == 'set-lang':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            if 'lang' not in content:
                return {'error': 'language required'}
            
            return xformplayer.set_locale(content['session-id'], content['lang'])            

        elif action == 'purge-stale':
            if 'window' not in content:
                return {'error': 'staleness window required'}

            return xformplayer.purge(content['window'])

        elif action in touchcare.SUPPORTED_ACTIONS:
            return touchcare.handle_request(content, **kwargs)
            
        elif action == 'get-instance':
            if 'session-id' not in content:
                return {'error': 'session id required'}
            xfsess = xformplayer.global_state.get_session(content['session-id'])
            return {"output": xfsess.output()}

        else:
            return {'error': 'unrecognized action'}
    
    except xformplayer.NoSuchSession:
        return {'error': 'invalid session id'}
    except xformplayer.SequencingException:
        return {'error': 'session is locked by another request'}