Example #1
0
 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
Example #2
0
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))
Example #3
0
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))
Example #4
0
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))
Example #5
0
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))
Example #6
0
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))
Example #7
0
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))