def _start_session(self, msg, trigger): """ Starts a new touchforms session. Creates the session object in the db and starts the session in touchforms. Returns a tuple of the session and the touchforms response to the first triggering of the form. """ form = trigger.xform context = trigger.context language = context.get('_lang') or (msg.contact.language if msg.contact else None) now = datetime.utcnow() # start session in touchforms config = XFormsConfig(form_path=form.file.path, language=language, session_data=context) try: session_id, responses = tfsms.start_session(config) except Exception: # this is super ghetto, but currently touchforms fails # hard if it can't find the language. So as a fallback just # try without specifying. If this failed for any other # reason it will just fail again. config.language = "" session_id, responses = tfsms.start_session(config) # save session in our data models session = XFormsSession(start_time=now, modified_time=now, session_id=session_id, connection=msg.connection, ended=False, trigger=trigger) session.save() router_factory.set(session_id, self.router) return session, responses
def start_session(domain, contact, app, module, form, case_id=None, yield_responses=False, session_type=XFORMS_SESSION_SMS, case_for_case_submission=False): """ Starts a session in touchforms and saves the record in the database. Returns a tuple containing the session object and the (text-only) list of generated questions/responses based on the form. Special params: yield_responses - If True, the list of xforms responses is returned, otherwise the text prompt for each is returned session_type - XFORMS_SESSION_SMS or XFORMS_SESSION_IVR case_for_case_submission - True if this is a submission that a case is making to alter another related case. For example, if a parent case is filling out an SMS survey which will update its child case, this should be True. """ # NOTE: this call assumes that "contact" will expose three # properties: .raw_username, .get_id, and .get_language_code session_data = get_session_data(domain, contact, case_id, device_id=COMMCONNECT_DEVICE_ID) # since the API user is a superuser, force touchforms to query only # the contact's cases by specifying it as an additional filterp if contact.doc_type == "CommCareCase": session_data["additional_filters"] = { "case_id": contact.get_id, "footprint" : "True", "include_children" : "True" if case_for_case_submission else "False", } else: session_data["additional_filters"] = { "user_id": contact.get_id, "footprint": "True" } language = contact.get_language_code() config = XFormsConfig(form_content=form.render_xform(), language=language, session_data=session_data, auth=AUTH) now = datetime.utcnow() # just use the contact id as the connection id. may need to revisit this connection_id = contact.get_id session_start_info = tfsms.start_session(config) session = XFormsSession(connection_id=connection_id, session_id = session_start_info.session_id, start_time=now, modified_time=now, form_xmlns=form.xmlns, completed=False, domain=domain, app_id=app.get_id, user_id=contact.get_id, session_type=session_type) session.save() responses = session_start_info.first_responses # Prevent future resource conflicts by getting the session again from the db # since the session could have been updated separately in the first_responses call session = XFormsSession.get(session._id) if yield_responses: return (session, responses) else: return (session, _responses_to_text(responses))
def start_session(session, domain, contact, app, module, form, case_id=None, yield_responses=False, case_for_case_submission=False): """ Starts a session in touchforms and saves the record in the database. Returns a tuple containing the session object and the (text-only) list of generated questions/responses based on the form. Special params: yield_responses - If True, the list of xforms responses is returned, otherwise the text prompt for each is returned session_type - XFORMS_SESSION_SMS or XFORMS_SESSION_IVR case_for_case_submission - True if this is a submission that a case is making to alter another related case. For example, if a parent case is filling out an SMS survey which will update its child case, this should be True. """ # NOTE: this call assumes that "contact" will expose three # properties: .raw_username, .get_id, and .get_language_code session_data = CaseSessionDataHelper(domain, contact, case_id, app, form).get_session_data(COMMCONNECT_DEVICE_ID) # since the API user is a superuser, force touchforms to query only # the contact's cases by specifying it as an additional filter if is_commcarecase(contact) and form.requires_case(): session_data["additional_filters"] = { "case_id": case_id, "footprint": "true" if form.uses_parent_case() else "false", } elif isinstance(contact, CouchUser): session_data["additional_filters"] = { "user_id": contact.get_id, "footprint": "true" } if app and form: session_data.update(get_cloudcare_session_data(domain, form, contact)) language = contact.get_language_code() config = XFormsConfig(form_content=form.render_xform(), language=language, session_data=session_data, auth=AUTH) session_start_info = tfsms.start_session(config) session.session_id = session_start_info.session_id session.save() responses = session_start_info.first_responses if len(responses) > 0 and responses[0].status == 'http-error': session.mark_completed(False) session.save() raise TouchformsError('Cannot connect to touchforms.') # Prevent future update conflicts by getting the session again from the db # since the session could have been updated separately in the first_responses call session = SQLXFormsSession.objects.get(pk=session.pk) if yield_responses: return (session, responses) else: return (session, _responses_to_text(responses))
def start_session(domain, contact, app, module, form, case_id=None, yield_responses=False, session_type=XFORMS_SESSION_SMS): """ Starts a session in touchforms and saves the record in the database. Returns a tuple containing the session object and the (text-only) list of generated questions/responses based on the form. """ # NOTE: this call assumes that "contact" will expose three # properties: .raw_username, .get_id, and .get_language_code session_data = get_session_data(domain, contact, case_id, device_id=COMMCONNECT_DEVICE_ID) # since the API user is a superuser, force touchforms to query only # the contact's cases by specifying it as an additional filterp if contact.doc_type == "CommCareCase": session_data["additional_filters"] = {"case_id": contact.get_id} else: session_data["additional_filters"] = {"user_id": contact.get_id} language = contact.get_language_code() config = XFormsConfig(form_content=form.render_xform(), language=language, session_data=session_data, auth=AUTH) now = datetime.utcnow() # just use the contact id as the connection id. may need to revisit this connection_id = contact.get_id session_id, responses = tfsms.start_session(config) session = XFormsSession(connection_id=connection_id, session_id=session_id, start_time=now, modified_time=now, form_xmlns=form.xmlns, completed=False, domain=domain, app_id=app.get_id, user_id=contact.get_id, session_type=session_type) session.save() if yield_responses: return (session, responses) else: return (session, _responses_to_text(responses))
def start_session(domain, contact, app, module, form, case_id=None, yield_responses=False, session_type=XFORMS_SESSION_SMS): """ Starts a session in touchforms and saves the record in the database. Returns a tuple containing the session object and the (text-only) list of generated questions/responses based on the form. """ # NOTE: this call assumes that "contact" will expose three # properties: .raw_username, .get_id, and .get_language_code session_data = get_session_data(domain, contact, case_id, device_id=COMMCONNECT_DEVICE_ID) # since the API user is a superuser, force touchforms to query only # the contact's cases by specifying it as an additional filterp if contact.doc_type == "CommCareCase": session_data["additional_filters"] = { "case_id": contact.get_id } else: session_data["additional_filters"] = { "user_id": contact.get_id } language = contact.get_language_code() config = XFormsConfig(form_content=form.render_xform(), language=language, session_data=session_data, auth=AUTH) now = datetime.utcnow() # just use the contact id as the connection id. may need to revisit this connection_id = contact.get_id session_id, responses = tfsms.start_session(config) session = XFormsSession(connection_id=connection_id, session_id = session_id, start_time=now, modified_time=now, form_xmlns=form.xmlns, completed=False, domain=domain, app_id=app.get_id, user_id=contact.get_id, session_type=session_type) session.save() if yield_responses: return (session, responses) else: return (session, _responses_to_text(responses))
def start_session( domain, contact, app, module, form, case_id=None, yield_responses=False, session_type=XFORMS_SESSION_SMS, case_for_case_submission=False, ): """ Starts a session in touchforms and saves the record in the database. Returns a tuple containing the session object and the (text-only) list of generated questions/responses based on the form. Special params: yield_responses - If True, the list of xforms responses is returned, otherwise the text prompt for each is returned session_type - XFORMS_SESSION_SMS or XFORMS_SESSION_IVR case_for_case_submission - True if this is a submission that a case is making to alter another related case. For example, if a parent case is filling out an SMS survey which will update its child case, this should be True. """ # NOTE: this call assumes that "contact" will expose three # properties: .raw_username, .get_id, and .get_language_code session_data = CaseSessionDataHelper(domain, contact, case_id, app, form).get_session_data(COMMCONNECT_DEVICE_ID) # since the API user is a superuser, force touchforms to query only # the contact's cases by specifying it as an additional filter if is_commcarecase(contact) and form.requires_case(): session_data["additional_filters"] = { "case_id": case_id, "footprint": "true" if form.uses_parent_case() else "false", } elif isinstance(contact, CouchUser): session_data["additional_filters"] = {"user_id": contact.get_id, "footprint": "true"} if app and form: session_data.update(get_cloudcare_session_data(domain, form, contact)) language = contact.get_language_code() config = XFormsConfig(form_content=form.render_xform(), language=language, session_data=session_data, auth=AUTH) now = datetime.utcnow() # just use the contact id as the connection id connection_id = contact.get_id session_start_info = tfsms.start_session(config) session = SQLXFormsSession( couch_id=uuid.uuid4().hex, # for legacy reasons we just generate a couch_id for now connection_id=connection_id, session_id=session_start_info.session_id, start_time=now, modified_time=now, form_xmlns=form.xmlns, completed=False, domain=domain, app_id=app.get_id, user_id=contact.get_id, session_type=session_type, ) session.save() responses = session_start_info.first_responses if len(responses) > 0 and responses[0].status == "http-error": session.end(False) session.save() raise TouchformsError("Cannot connect to touchforms.") # Prevent future update conflicts by getting the session again from the db # since the session could have been updated separately in the first_responses call session = SQLXFormsSession.objects.get(pk=session.pk) if yield_responses: return (session, responses) else: return (session, _responses_to_text(responses))
def start_session(domain, contact, app, module, form, case_id=None, yield_responses=False, session_type=XFORMS_SESSION_SMS, case_for_case_submission=False): """ Starts a session in touchforms and saves the record in the database. Returns a tuple containing the session object and the (text-only) list of generated questions/responses based on the form. Special params: yield_responses - If True, the list of xforms responses is returned, otherwise the text prompt for each is returned session_type - XFORMS_SESSION_SMS or XFORMS_SESSION_IVR case_for_case_submission - True if this is a submission that a case is making to alter another related case. For example, if a parent case is filling out an SMS survey which will update its child case, this should be True. """ # NOTE: this call assumes that "contact" will expose three # properties: .raw_username, .get_id, and .get_language_code session_data = get_session_data(domain, contact, case_id, device_id=COMMCONNECT_DEVICE_ID) # since the API user is a superuser, force touchforms to query only # the contact's cases by specifying it as an additional filterp if contact.doc_type == "CommCareCase": session_data["additional_filters"] = { "case_id": contact.get_id, "footprint": "True", "include_children": "True" if case_for_case_submission else "False", } else: session_data["additional_filters"] = { "user_id": contact.get_id, "footprint": "True" } language = contact.get_language_code() config = XFormsConfig(form_content=form.render_xform(), language=language, session_data=session_data, auth=AUTH) now = datetime.utcnow() # just use the contact id as the connection id. may need to revisit this connection_id = contact.get_id session_start_info = tfsms.start_session(config) session = XFormsSession(connection_id=connection_id, session_id=session_start_info.session_id, start_time=now, modified_time=now, form_xmlns=form.xmlns, completed=False, domain=domain, app_id=app.get_id, user_id=contact.get_id, session_type=session_type) session.save() responses = session_start_info.first_responses # Prevent future resource conflicts by getting the session again from the db # since the session could have been updated separately in the first_responses call session = XFormsSession.get(session._id) if yield_responses: return (session, responses) else: return (session, _responses_to_text(responses))