예제 #1
0
def handle_due_survey_action(domain, contact_id, session_id):
    with critical_section_for_smsforms_sessions(contact_id):
        session = SQLXFormsSession.by_session_id(session_id)
        if (not session or not session.session_is_open
                or session.current_action_due > utcnow()):
            return

        if session.current_action_is_a_reminder:
            # Resend the current question in the open survey to the contact
            p = PhoneNumber.get_phone_number_for_owner(session.connection_id,
                                                       session.phone_number)
            if p:
                metadata = MessageMetadata(
                    workflow=session.workflow,
                    xforms_session_couch_id=session._id,
                )
                resp = current_question(session.session_id, domain)
                send_sms_to_verified_number(
                    p,
                    resp.event.text_prompt,
                    metadata,
                    logged_subevent=session.related_subevent)

            session.move_to_next_action()
            session.save()
        else:
            # Close the session
            session.close()
            session.save()
예제 #2
0
 def test_get_by_session_id(self):
     session_id = uuid.uuid4().hex
     sql_session = SQLXFormsSession.objects.create(
         session_id=session_id,
         start_time=datetime.utcnow(),
         modified_time=datetime.utcnow(),
     )
     self.assertEqual(sql_session.pk, SQLXFormsSession.by_session_id(session_id).pk)
예제 #3
0
 def test_get_by_session_id(self):
     session_id = uuid.uuid4().hex
     sql_session = SQLXFormsSession.objects.create(
         session_id=session_id,
         start_time=datetime.utcnow(),
         modified_time=datetime.utcnow(),
     )
     self.assertEqual(sql_session.pk, SQLXFormsSession.by_session_id(session_id).pk)
예제 #4
0
def form_session_handler(v, text, msg):
    """
    The form session handler will use the inbound text to answer the next question
    in the open SQLXformsSession for the associated contact. If no session is open,
    the handler passes. If multiple sessions are open, they are all closed and an
    error message is displayed to the user.
    """
    with critical_section_for_smsforms_sessions(v.owner_id):
        if toggles.ONE_PHONE_NUMBER_MULTIPLE_CONTACTS.enabled(v.domain):
            channel = get_channel_for_contact(v.owner_id, v.phone_number)
            running_session_info = XFormsSessionSynchronization.get_running_session_info_for_channel(
                channel)
            if running_session_info.session_id:
                session = SQLXFormsSession.by_session_id(
                    running_session_info.session_id)
                if not session.session_is_open:
                    # This should never happen. But if it does we should set the channel free
                    # and act like there was no available session
                    notify_error(
                        "The supposedly running session was not open and was released. "
                        'No known way for this to happen, so worth investigating.'
                    )
                    XFormsSessionSynchronization.clear_stale_channel_claim(
                        channel)
                    session = None
            else:
                session = None
        else:
            multiple, session = get_single_open_session_or_close_multiple(
                v.domain, v.owner_id)
            if multiple:
                send_sms_to_verified_number(
                    v, get_message(MSG_MULTIPLE_SESSIONS, v))
                return True

        if session:
            session.phone_number = v.phone_number
            session.modified_time = datetime.utcnow()
            session.save()

            # Metadata to be applied to the inbound message
            inbound_metadata = MessageMetadata(
                workflow=session.workflow,
                reminder_id=session.reminder_id,
                xforms_session_couch_id=session._id,
            )
            add_msg_tags(msg, inbound_metadata)

            try:
                answer_next_question(v, text, msg, session)
            except Exception:
                # Catch any touchforms errors
                log_sms_exception(msg)
                send_sms_to_verified_number(
                    v, get_message(MSG_TOUCHFORMS_DOWN, v))
            return True
        else:
            return False
예제 #5
0
파일: api.py 프로젝트: dankohn/commcare-hq
    def user_id(self):
        from corehq.apps.smsforms.models import SQLXFormsSession

        if self._user_id is Ellipsis:
            session = SQLXFormsSession.by_session_id(self.session_id)
            if session:
                self._user_id = session.user_id
            else:
                self._user_id = None

        return self._user_id
예제 #6
0
def handle_sms_form_complete(sender, session_id, form, **kwargs):
    from corehq.apps.smsforms.models import SQLXFormsSession
    session = SQLXFormsSession.by_session_id(session_id)
    if session:
        resp = submit_form_locally(form, session.domain, app_id=session.app_id)
        xform_id = resp['X-CommCareHQ-FormID']
        session.end(completed=True)
        session.submission_id = xform_id
        session.save()
        
        xform = XFormInstance.get(xform_id)
        xform.survey_incentive = session.survey_incentive
        xform.save()
예제 #7
0
def handle_sms_form_complete(sender, session_id, form, **kwargs):
    from corehq.apps.smsforms.models import SQLXFormsSession
    session = SQLXFormsSession.by_session_id(session_id)
    if session:
        resp = submit_form_locally(form, session.domain, app_id=session.app_id)
        xform_id = resp['X-CommCareHQ-FormID']
        session.end(completed=True)
        session.submission_id = xform_id
        session.save()

        xform = XFormInstance.get(xform_id)
        xform.survey_incentive = session.survey_incentive
        xform.save()
예제 #8
0
def handle_due_survey_action(domain, contact_id, session_id):
    with critical_section_for_smsforms_sessions(contact_id):
        session = SQLXFormsSession.by_session_id(session_id)
        if (not session or not session.session_is_open
                or session.current_action_due > utcnow()):
            return

        if toggles.ONE_PHONE_NUMBER_MULTIPLE_CONTACTS.enabled(domain):
            if not XFormsSessionSynchronization.claim_channel_for_session(
                    session):
                from .management.commands import handle_survey_actions
                # Unless we release this lock, handle_survey_actions will be unable to requeue this task
                # for the default duration of 1h, which we don't want
                handle_survey_actions.Command.get_enqueue_lock(
                    session_id, session.current_action_due).release()
                return

        if session_is_stale(session):
            # If a session is having some unrecoverable errors that aren't benefitting from
            # being retried, those errors should show up in sentry log and the fix should
            # be dealt with. In terms of the current session itself, we just close it out
            # to allow new sessions to start.
            session.mark_completed(False)
            session.save()
            return

        if session.current_action_is_a_reminder:
            # Resend the current question in the open survey to the contact
            p = PhoneNumber.get_phone_number_for_owner(session.connection_id,
                                                       session.phone_number)
            if p:
                metadata = MessageMetadata(
                    workflow=session.workflow,
                    xforms_session_couch_id=session._id,
                )
                resp = FormplayerInterface(session.session_id,
                                           domain).current_question()
                send_sms_to_verified_number(
                    p,
                    resp.event.text_prompt,
                    metadata,
                    logged_subevent=session.related_subevent)

            session.move_to_next_action()
            session.save()
        else:
            # Close the session
            session.close()
            session.save()
예제 #9
0
파일: tasks.py 프로젝트: soitun/commcare-hq
def close_session(self, contact_id, session_id):
    with critical_section_for_smsforms_sessions(contact_id):
        session = SQLXFormsSession.by_session_id(session_id)
        try:
            session.close(force=False)
        except TouchformsError as e:
            try:
                self.retry(exc=e)
            except TouchformsError as e:
                raise e
            finally:
                # Eventually the session needs to get closed
                session.mark_completed(False)
                session.save()
                return
        session.save()
예제 #10
0
def handle_due_survey_action(domain, contact_id, session_id):
    with critical_section_for_smsforms_sessions(contact_id):
        session = SQLXFormsSession.by_session_id(session_id)
        if (
            not session
            or not session.session_is_open
            or session.current_action_due > utcnow()
        ):
            return

        if session_is_stale(session):
            # If a session is having some unrecoverable errors that aren't benefitting from
            # being retried, those errors should show up in sentry log and the fix should
            # be dealt with. In terms of the current session itself, we just close it out
            # to allow new sessions to start.
            session.mark_completed(False)
            session.save()
            return

        if session.current_action_is_a_reminder:
            # Resend the current question in the open survey to the contact
            p = PhoneNumber.get_phone_number_for_owner(session.connection_id, session.phone_number)
            if p:
                metadata = MessageMetadata(
                    workflow=session.workflow,
                    xforms_session_couch_id=session._id,
                )
                resp = current_question(session.session_id, domain)
                send_sms_to_verified_number(
                    p,
                    resp.event.text_prompt,
                    metadata,
                    logged_subevent=session.related_subevent
                )

            session.move_to_next_action()
            session.save()
        else:
            # Close the session
            session.close()
            session.save()
예제 #11
0
파일: tasks.py 프로젝트: dimagi/commcare-hq
def handle_due_survey_action(domain, contact_id, session_id):
    with critical_section_for_smsforms_sessions(contact_id):
        session = SQLXFormsSession.by_session_id(session_id)
        if (
            not session
            or not session.session_is_open
            or session.current_action_due > utcnow()
        ):
            return

        if session_is_stale(session):
            # If a session is having some unrecoverable errors that aren't benefitting from
            # being retried, those errors should show up in sentry log and the fix should
            # be dealt with. In terms of the current session itself, we just close it out
            # to allow new sessions to start.
            session.mark_completed(False)
            session.save()
            return

        if session.current_action_is_a_reminder:
            # Resend the current question in the open survey to the contact
            p = PhoneNumber.get_phone_number_for_owner(session.connection_id, session.phone_number)
            if p:
                metadata = MessageMetadata(
                    workflow=session.workflow,
                    xforms_session_couch_id=session._id,
                )
                resp = current_question(session.session_id, domain)
                send_sms_to_verified_number(
                    p,
                    resp.event.text_prompt,
                    metadata,
                    logged_subevent=session.related_subevent
                )

            session.move_to_next_action()
            session.save()
        else:
            # Close the session
            session.close()
            session.save()
예제 #12
0
    def test_session_is_stale(self, utcnow_mock_1, utcnow_mock_2):
        utcnow_mock_2.return_value = datetime(2018, 1, 1, 0, 0)
        session = SQLXFormsSession.create_session_object(
            'test',
            Mock(get_id='contact_id'),
            '+9990001',
            Mock(get_id='app_id'),
            Mock(xmlns='xmlns'),
            expire_after=24 * 60,
            reminder_intervals=[30, 60],
            submit_partially_completed_forms=True,
        )
        session.save()
        self.addCleanup(session.delete)

        utcnow_mock_1.return_value = datetime(2018, 1, 14, 0, 0)
        self.assertFalse(session_is_stale(session))

        utcnow_mock_1.return_value = datetime(2018, 1, 16, 0, 0)
        self.assertTrue(session_is_stale(session))

        handle_due_survey_action('test', 'contact_id', session.session_id)
        session = SQLXFormsSession.by_session_id(session.session_id)
        self.assertFalse(session.session_is_open)
예제 #13
0
    def test_session_is_stale(self, utcnow_mock_1, utcnow_mock_2):
        utcnow_mock_2.return_value = datetime(2018, 1, 1, 0, 0)
        session = SQLXFormsSession.create_session_object(
            'test',
            Mock(get_id='contact_id'),
            '+9990001',
            Mock(get_id='app_id'),
            Mock(xmlns='xmlns'),
            expire_after=24 * 60,
            reminder_intervals=[30, 60],
            submit_partially_completed_forms=True,
        )
        session.save()
        self.addCleanup(session.delete)

        utcnow_mock_1.return_value = datetime(2018, 1, 14, 0, 0)
        self.assertFalse(session_is_stale(session))

        utcnow_mock_1.return_value = datetime(2018, 1, 16, 0, 0)
        self.assertTrue(session_is_stale(session))

        handle_due_survey_action('test', 'contact_id', session.session_id)
        session = SQLXFormsSession.by_session_id(session.session_id)
        self.assertFalse(session.session_is_open)
예제 #14
0
 def test_get_by_session_id(self):
     sql_session = _make_session()
     self.assertEqual(
         sql_session.pk,
         SQLXFormsSession.by_session_id(sql_session.session_id).pk)
예제 #15
0
 def test_get_by_session_id(self):
     sql_session = _make_session()
     self.assertEqual(sql_session.pk, SQLXFormsSession.by_session_id(sql_session.session_id).pk)
예제 #16
0
def handle_sms_form_complete(sender, session_id, form, **kwargs):
    from corehq.apps.smsforms.models import SQLXFormsSession
    session = SQLXFormsSession.by_session_id(session_id)
    if session:
        process_sms_form_complete(session, form, completed=True)
예제 #17
0
def handle_sms_form_complete(sender, session_id, form, **kwargs):
    from corehq.apps.smsforms.models import SQLXFormsSession
    session = SQLXFormsSession.by_session_id(session_id)
    if session:
        process_sms_form_complete(session, form)
예제 #18
0
 def test_get_by_session_id_not_found(self):
     self.assertEqual(None,
                      SQLXFormsSession.by_session_id(uuid.uuid4().hex))
예제 #19
0
 def test_get_by_session_id_not_found(self):
     self.assertEqual(None, SQLXFormsSession.by_session_id(uuid.uuid4().hex))