Esempio n. 1
0
 def create_survey_keyword(self,
                           keyword,
                           form_unique_id,
                           delimiter=None,
                           override_open_sessions=True,
                           initiator_filter=None):
     sk = SurveyKeyword(
         domain=self.domain,
         keyword=keyword,
         description=keyword,
         actions=[
             SurveyKeywordAction(
                 recipient=RECIPIENT_SENDER,
                 recipient_id=None,
                 action=METHOD_SMS_SURVEY,
                 message_content=None,
                 form_unique_id=form_unique_id,
                 use_named_args=False,
                 named_args={},
                 named_args_separator=None,
             )
         ],
         delimiter=delimiter,
         override_open_sessions=override_open_sessions,
         initiator_doc_type_filter=initiator_filter or [],
     )
     sk.save()
     self.keywords.append(sk)
     return sk
Esempio n. 2
0
    def migrate(self, log_file):
        count = 0
        ids = self.get_couch_ids()
        total_count = len(ids)
        for doc in iter_docs_with_retry(SurveyKeyword.get_db(), ids):
            try:
                couch_obj = SurveyKeyword.wrap(doc)
                couch_obj._migration_do_sync()
            except Exception as e:
                log_file.write('Could not sync SurveyKeyword %s: %s\n' % (doc['_id'], e))

            count += 1
            if (count % 1000) == 0:
                print 'Processed %s / %s documents' % (count, total_count)
Esempio n. 3
0
 def get_couch_ids(self):
     result = SurveyKeyword.view(
         'reminders/survey_keywords',
         include_docs=False,
         reduce=False,
     ).all()
     return [row['id'] for row in result]
Esempio n. 4
0
 def keyword(self):
     if self.keyword_id is None:
         raise Http404()
     sk = SurveyKeyword.get(self.keyword_id)
     if sk.domain != self.domain:
         raise Http404()
     return sk
Esempio n. 5
0
 def total(self):
     data = (
         SurveyKeyword.get_db()
         .view("reminders/survey_keywords", reduce=True, startkey=[self.domain], endkey=[self.domain, {}])
         .first()
     )
     return data["value"] if data else 0
Esempio n. 6
0
 def keyword(self):
     if self.keyword_id is None:
         raise Http404()
     sk = SurveyKeyword.get(self.keyword_id)
     if sk.domain != self.domain:
         raise Http404()
     return sk
Esempio n. 7
0
    def get_keyword_display(self, keyword_id, content_cache):
        if keyword_id in content_cache:
            args = content_cache[keyword_id]
            return self.table_cell(*args)
        try:
            keyword = SurveyKeyword.get(keyword_id)
            if keyword.deleted():
                display = '%s %s' % (keyword.description,
                                     _('(Deleted Keyword)'))
                display_text = display
            else:
                urlname = (EditStructuredKeywordView.urlname
                           if keyword.is_structured_sms() else
                           EditNormalKeywordView.urlname)
                display = '<a target="_blank" href="%s">%s</a>' % (
                    reverse(urlname, args=[keyword.domain, keyword_id]),
                    keyword.description,
                )
                display_text = keyword.description
            args = (display_text, display)
        except ResourceNotFound:
            args = ('-', '-')

        content_cache[keyword_id] = args
        return self.table_cell(*args)
Esempio n. 8
0
 def total(self):
     data = SurveyKeyword.get_db().view(
         'reminders/survey_keywords',
         reduce=True,
         startkey=[self.domain],
         endkey=[self.domain, {}],
     ).first()
     return data['value'] if data else 0
Esempio n. 9
0
 def total(self):
     data = SurveyKeyword.get_db().view(
         'reminders/survey_keywords',
         reduce=True,
         startkey=[self.domain],
         endkey=[self.domain, {}],
     ).first()
     return data['value'] if data else 0
Esempio n. 10
0
    def testCouchSyncToSQL(self):
        self.assertEqual(self.getCouchCount(), 0)
        self.assertEqual(self.getSQLCount(), 0)

        # Test Create
        couch_obj = SurveyKeyword()
        self.setRandomCouchObjectValues(couch_obj)
        self.assertEqual(self.getCouchCount(), 1)
        self.assertEqual(self.getSQLCount(), 1)

        sql_obj = Keyword.objects.get(couch_id=couch_obj._id)
        self.compareObjects(couch_obj, sql_obj)
        self.assertTrue(SurveyKeyword.get_db().get_rev(couch_obj._id).startswith('1-'))

        # Test Update
        self.setRandomCouchObjectValues(couch_obj)
        self.assertEqual(self.getCouchCount(), 1)
        self.assertEqual(self.getSQLCount(), 1)
        sql_obj = Keyword.objects.get(couch_id=couch_obj._id)
        self.compareObjects(couch_obj, sql_obj)
        self.assertTrue(SurveyKeyword.get_db().get_rev(couch_obj._id).startswith('2-'))

        # Test Delete
        couch_id = couch_obj._id
        couch_obj.delete()
        with self.assertRaises(ResourceNotFound):
            SurveyKeyword.get(couch_id)
        self.assertEqual(self.getCouchCount(), 0)
        self.assertEqual(self.getSQLCount(), 0)
Esempio n. 11
0
 def get_deleted_item_data(self, item_id):
     try:
         s = SurveyKeyword.get(item_id)
     except ResourceNotFound:
         raise Http404()
     if s.domain != self.domain or s.doc_type != "SurveyKeyword":
         raise Http404()
     s.delete()
     return {"itemData": self._fmt_deleted_keyword_data(s), "template": "keyword-deleted-template"}
Esempio n. 12
0
 def get_couch_count(self):
     result = SurveyKeyword.view(
         'reminders/survey_keywords',
         include_docs=False,
         reduce=True,
     ).all()
     if result:
         return result[0]['value']
     return 0
Esempio n. 13
0
 def paginated_list(self):
     for keyword in SurveyKeyword.get_by_domain(
         self.domain,
         limit=self.limit,
         skip=self.skip,
     ):
         yield {
             'itemData': self._fmt_keyword_data(keyword),
             'template': 'keyword-row-template',
         }
Esempio n. 14
0
 def paginated_list(self):
     for keyword in SurveyKeyword.get_by_domain(
             self.domain,
             limit=self.limit,
             skip=self.skip,
     ):
         yield {
             'itemData': self._fmt_keyword_data(keyword),
             'template': 'keyword-row-template',
         }
Esempio n. 15
0
 def getCouchCount(self):
     result = SurveyKeyword.view(
         'reminders/survey_keywords',
         startkey=[self.domain],
         endkey=[self.domain, {}],
         include_docs=False,
         reduce=True,
     ).all()
     if result:
         return result[0]['value']
     return 0
Esempio n. 16
0
 def get_deleted_item_data(self, item_id):
     try:
         s = SurveyKeyword.get(item_id)
     except ResourceNotFound:
         raise Http404()
     if s.domain != self.domain or s.doc_type != "SurveyKeyword":
         raise Http404()
     s.retire()
     return {
         'itemData': self._fmt_keyword_data(s),
         'template': 'keyword-deleted-template',
     }
Esempio n. 17
0
def device_data(request):
    if "data" not in request.POST:
        return HttpResponseBadRequest("Missing 'data' POST parameter.")

    data = request.POST.get("data")
    data = data.strip()
    data_points = data.split(",")
    device_id = None
    for data_point in data_points:
        key_value = data_point.partition("=")
        key = key_value[0].strip().upper()
        value = key_value[2].strip()
        if key == "SN":
            device_id = value
            break

    if device_id is None:
        return HttpResponseBadRequest("Missing 'SN' in data string.")

    # This view lookup is an implicit assert that either one device exists
    # with the given device_id, or no devices exist with this device_id.
    case = CommConnectCase.view("wisepill/device", key=[device_id], include_docs=True).one()

    event = WisePillDeviceEvent(
        domain=case.domain if case is not None else None,
        data=data,
        received_on=datetime.utcnow(),
        case_id=case._id if case is not None else None,
        processed=False,
    )
    event.save()

    if case is not None:
        survey_keywords = SurveyKeyword.get_all(case.domain)
        for survey_keyword in survey_keywords:
            if survey_keyword.keyword.upper() == "DEVICE_EVENT":
                for survey_keyword_action in survey_keyword.actions:
                    if survey_keyword_action.action == METHOD_STRUCTURED_SMS:
                        handle_structured_sms(
                            survey_keyword,
                            survey_keyword_action,
                            case,
                            None,
                            "DEVICE_EVENT,%s" % data,
                            send_response=False,
                        )
                        event.processed = True
                        event.save()
                        break

    return HttpResponse("")
Esempio n. 18
0
 def create_survey_keyword(self, keyword, form_unique_id, delimiter=None,
     override_open_sessions=True, initiator_filter=None):
     sk = SurveyKeyword(
         domain=self.domain,
         keyword=keyword,
         description=keyword,
         actions=[SurveyKeywordAction(
             recipient=RECIPIENT_SENDER,
             recipient_id=None,
             action=METHOD_SMS_SURVEY,
             message_content=None,
             form_unique_id=form_unique_id,
             use_named_args=False,
             named_args={},
             named_args_separator=None,
         )],
         delimiter=delimiter,
         override_open_sessions=override_open_sessions,
         initiator_doc_type_filter=initiator_filter or [],
     )
     sk.save()
     self.keywords.append(sk)
     return sk
Esempio n. 19
0
 def page_context(self):
     domain_has_reminders_or_keywords = (
         CaseReminderHandler.domain_has_reminders(self.domain)
         or SurveyKeyword.domain_has_keywords(self.domain))
     bulk_sms_verification_enabled = (
         domain_has_reminders_or_keywords
         and domain_has_privilege(self.domain, privileges.INBOUND_SMS))
     return {
         'group': self.group,
         'bulk_sms_verification_enabled': bulk_sms_verification_enabled,
         'num_users': len(self.member_ids),
         'user_form': self.user_selection_form,
         'domain_uses_case_sharing': self.domain_uses_case_sharing,
     }
Esempio n. 20
0
 def page_context(self):
     domain_has_reminders_or_keywords = (
         CaseReminderHandler.domain_has_reminders(self.domain) or
         SurveyKeyword.domain_has_keywords(self.domain)
     )
     bulk_sms_verification_enabled = (
         domain_has_reminders_or_keywords and
         domain_has_privilege(self.domain, privileges.INBOUND_SMS)
     )
     return {
         'group': self.group,
         'bulk_sms_verification_enabled': bulk_sms_verification_enabled,
         'num_users': len(self.member_ids),
         'user_form': self.user_selection_form,
         'domain_uses_case_sharing': self.domain_uses_case_sharing,
     }
    def handle(self, *args, **options):
        keywords = SurveyKeyword.view("reminders/survey_keywords",
                                      reduce=False,
                                      include_docs=True).all()
        for keyword in keywords:
            if keyword.oct13_migration_timestamp is None:
                print "Processing keyword %s, %s" % (keyword.domain,
                                                     keyword._id)
                keyword.description = "(none)"
                keyword.initiator_doc_type_filter = []
                if keyword.form_type == FORM_TYPE_ALL_AT_ONCE:
                    keyword.override_open_sessions = True
                    keyword.actions = [
                        SurveyKeywordAction(
                            recipient=RECIPIENT_SENDER,
                            recipient_id=None,
                            action=METHOD_STRUCTURED_SMS,
                            message_content=None,
                            form_unique_id=keyword.form_unique_id,
                            use_named_args=keyword.use_named_args,
                            named_args=keyword.named_args,
                            named_args_separator=keyword.named_args_separator,
                        )
                    ]
                else:
                    keyword.override_open_sessions = False
                    keyword.actions = [
                        SurveyKeywordAction(
                            recipient=RECIPIENT_SENDER,
                            recipient_id=None,
                            action=METHOD_SMS_SURVEY,
                            message_content=None,
                            form_unique_id=keyword.form_unique_id,
                        )
                    ]
                keyword.form_type = None
                keyword.form_unique_id = None
                keyword.use_named_args = None
                keyword.named_args = None
                keyword.named_args_separator = None

                keyword.oct13_migration_timestamp = datetime.utcnow()
                keyword.save()
Esempio n. 22
0
    def get_keyword_display(self, keyword_id, content_cache):
        if keyword_id in content_cache:
            return content_cache[keyword_id]
        try:
            keyword = SurveyKeyword.get(keyword_id)
            if keyword.deleted():
                display = '%s %s' % (keyword.description, _('(Deleted Keyword)'))
            else:
                urlname = (EditStructuredKeywordView.urlname if keyword.is_structured_sms()
                    else EditNormalKeywordView.urlname)
                display = '<a target="_blank" href="%s">%s</a>' % (
                    reverse(urlname, args=[keyword.domain, keyword_id]),
                    keyword.description,
                )
        except ResourceNotFound:
            display = '-'

        content_cache[keyword_id] = display
        return display
Esempio n. 23
0
def global_keyword_start(v, text, msg, text_words, open_sessions):
    from corehq.apps.reminders.models import SurveyKeyword

    outbound_metadata = MessageMetadata(workflow=WORKFLOW_KEYWORD, )

    if len(text_words) > 1:
        keyword = text_words[1]
        sk = SurveyKeyword.get_keyword(v.domain, keyword)
        if sk:
            if not contact_can_use_keyword(v, sk):
                return False
            process_survey_keyword_actions(v, sk, text[6:].strip(), msg)
        else:
            message = get_message(MSG_KEYWORD_NOT_FOUND, v, (keyword, ))
            send_sms_to_verified_number(v, message, metadata=outbound_metadata)
    else:
        message = get_message(MSG_START_KEYWORD_USAGE, v, (text_words[0], ))
        send_sms_to_verified_number(v, message, metadata=outbound_metadata)
    return True
Esempio n. 24
0
    def get_keyword_display(self, keyword_id, content_cache):
        if keyword_id in content_cache:
            return content_cache[keyword_id]
        try:
            keyword = SurveyKeyword.get(keyword_id)
            if keyword.deleted():
                display = '%s %s' % (keyword.description, _('(Deleted Keyword)'))
            else:
                urlname = (EditStructuredKeywordView.urlname if keyword.is_structured_sms()
                    else EditNormalKeywordView.urlname)
                display = '<a target="_blank" href="%s">%s</a>' % (
                    reverse(urlname, args=[keyword.domain, keyword_id]),
                    keyword.description,
                )
        except ResourceNotFound:
            display = '-'

        content_cache[keyword_id] = display
        return display
Esempio n. 25
0
def handle_domain_keywords(v, text, msg, text_words, sessions):
    any_session_open = len(sessions) > 0
    for survey_keyword in SurveyKeyword.get_all(v.domain):
        args = split_args(text, survey_keyword)
        keyword = args[0].upper()
        if keyword == survey_keyword.keyword.upper():
            if any_session_open and not survey_keyword.override_open_sessions:
                # We don't want to override any open sessions, so just pass and
                # let the form session handler handle the message
                return False
            elif not contact_can_use_keyword(v, survey_keyword):
                # The contact type is not allowed to invoke this keyword
                return False
            else:
                inbound_metadata = MessageMetadata(workflow=WORKFLOW_KEYWORD, )
                add_msg_tags(msg, inbound_metadata)
                process_survey_keyword_actions(v, survey_keyword, text, msg)
                return True
    # No keywords matched, so pass the message onto the next handler
    return False
Esempio n. 26
0
    def get_keyword_display(self, keyword_id, content_cache):
        if keyword_id in content_cache:
            return content_cache[keyword_id]
        try:
            keyword = SurveyKeyword.get(keyword_id)
            if keyword.doc_type.endswith('-Deleted'):
                # We'll get rid of this once we move to postgres
                raise ResourceNotFound()
        except ResourceNotFound:
            display = _('(Deleted Keyword)')
        else:
            urlname = (EditStructuredKeywordView.urlname if keyword.is_structured_sms()
                else EditNormalKeywordView.urlname)
            display = '<a target="_blank" href="%s">%s</a>' % (
                reverse(urlname, args=[keyword.domain, keyword_id]),
                keyword.description,
            )

        content_cache[keyword_id] = display
        return display
Esempio n. 27
0
def handle_domain_keywords(v, text, msg, text_words, sessions):
    any_session_open = len(sessions) > 0
    for survey_keyword in SurveyKeyword.get_all(v.domain):
        args = split_args(text, survey_keyword)
        keyword = args[0].upper()
        if keyword == survey_keyword.keyword.upper():
            if any_session_open and not survey_keyword.override_open_sessions:
                # We don't want to override any open sessions, so just pass and
                # let the form session handler handle the message
                return False
            elif not contact_can_use_keyword(v, survey_keyword):
                # The contact type is not allowed to invoke this keyword
                return False
            else:
                inbound_metadata = MessageMetadata(
                    workflow=WORKFLOW_KEYWORD,
                )
                add_msg_tags(msg, inbound_metadata)
                process_survey_keyword_actions(v, survey_keyword, text, msg)
                return True
    # No keywords matched, so pass the message onto the next handler
    return False
Esempio n. 28
0
def global_keyword_start(v, text, msg, text_words, open_sessions):
    from corehq.apps.reminders.models import SurveyKeyword

    outbound_metadata = MessageMetadata(
        workflow=WORKFLOW_KEYWORD,
    )

    if len(text_words) > 1:
        keyword = text_words[1]
        sk = SurveyKeyword.get_keyword(v.domain, keyword)
        if sk:
            if not contact_can_use_keyword(v, sk):
                return False
            process_survey_keyword_actions(v, sk, text[6:].strip(), msg)
        else:
            message = get_message(MSG_KEYWORD_NOT_FOUND, v, (keyword,))
            send_sms_to_verified_number(v, message, metadata=outbound_metadata)
    else:
        message = get_message(MSG_START_KEYWORD_USAGE, v, 
            (text_words[0],))
        send_sms_to_verified_number(v, message, metadata=outbound_metadata)
    return True
Esempio n. 29
0
    def get_keyword_display(self, keyword_id, content_cache):
        if keyword_id in content_cache:
            args = content_cache[keyword_id]
            return self.table_cell(*args)
        try:
            keyword = SurveyKeyword.get(keyword_id)
            if keyword.deleted():
                display = '%s %s' % (keyword.description, _('(Deleted Keyword)'))
                display_text = display
            else:
                urlname = (EditStructuredKeywordView.urlname if keyword.is_structured_sms()
                    else EditNormalKeywordView.urlname)
                display = '<a target="_blank" href="%s">%s</a>' % (
                    reverse(urlname, args=[keyword.domain, keyword_id]),
                    keyword.description,
                )
                display_text = keyword.description
            args = (display_text, display)
        except ResourceNotFound:
            args = ('-', '-')

        content_cache[keyword_id] = args
        return self.table_cell(*args)
Esempio n. 30
0
def add_keyword(request, domain, keyword_id=None):
    if keyword_id is None:
        s = SurveyKeyword(domain = domain)
    else:
        s = SurveyKeyword.get(keyword_id)
    
    context = {
        "domain" : domain,
        "form_list" : get_form_list(domain),
        "errors" : [],
        "keyword" : s
    }
    
    if request.method == "GET":
        return render_to_response(request, "reminders/partial/add_keyword.html", context)
    else:
        keyword = request.POST.get("keyword", None)
        form_unique_id = request.POST.get("survey", None)
        
        if keyword is not None:
            keyword = keyword.strip()
        
        s.keyword = keyword
        s.form_unique_id = form_unique_id
        
        errors = []
        if keyword is None or keyword == "":
            errors.append("Please enter a keyword.")
        if form_unique_id is None:
            errors.append("Please create a form first, and then add a keyword for it.")
        duplicate_entry = SurveyKeyword.get_keyword(domain, keyword)
        if duplicate_entry is not None and keyword_id != duplicate_entry._id:
            errors.append("Keyword already exists.")
        
        if len(errors) > 0:
            context["errors"] = errors
            return render_to_response(request, "reminders/partial/add_keyword.html", context)
        else:
            s.save()
            return HttpResponseRedirect(reverse("manage_surveys", args=[domain]))
    def handle(self, dry_run=False, **options):
        def _add_field(doc):
            updated = False
            log_prefix = "{} Domain {}, form unique_id {}".format(
                "[DRY RUN]" if dry_run else "", doc['domain'],
                doc['form_unique_id'])

            if doc.get('form_unique_id', None) and not doc.get('app_id', None):
                doc['app_id'] = get_app_id_from_form_unique_id(
                    doc['domain'], doc['form_unique_id'])
                if doc['app_id']:
                    updated = True
                    logger.info("{}: Updated {} to use app id {}".format(
                        log_prefix, doc['_id'], doc['app_id']))
                else:
                    logger.info("{}: Could not find app".format(log_prefix))

            for action in doc.get('actions', []):
                if action.get('form_unique_id',
                              None) and not action.get('app_id', None):
                    action['app_id'] = get_app_id_from_form_unique_id(
                        doc['domain'], action['form_unique_id'])
                    if action['app_id']:
                        updated = True
                        logger.info(
                            "{}: Updated action in {} to use app id {}".format(
                                log_prefix, doc['_id'], action['app_id']))
                    else:
                        logger.info(
                            "{}: Could not find app".format(log_prefix))

            if updated and not dry_run:
                return DocUpdate(doc)

        doc_ids = get_doc_ids_by_class(
            SurveyKeyword) + get_deleted_doc_ids_by_class(SurveyKeyword)
        iter_update(SurveyKeyword.get_db(), _add_field, doc_ids)
Esempio n. 32
0
    def handle(self, *args, **options):
        keywords = SurveyKeyword.view("reminders/survey_keywords", reduce=False, include_docs=True).all()
        for keyword in keywords:
            if keyword.oct13_migration_timestamp is None:
                print "Processing keyword %s, %s" % (keyword.domain, keyword._id)
                keyword.description = "(none)"
                keyword.initiator_doc_type_filter = []
                if keyword.form_type == FORM_TYPE_ALL_AT_ONCE:
                    keyword.override_open_sessions = True
                    keyword.actions = [SurveyKeywordAction(
                        recipient = RECIPIENT_SENDER,
                        recipient_id = None,
                        action = METHOD_STRUCTURED_SMS,
                        message_content = None,
                        form_unique_id = keyword.form_unique_id,
                        use_named_args = keyword.use_named_args,
                        named_args = keyword.named_args,
                        named_args_separator = keyword.named_args_separator,
                    )]
                else:
                    keyword.override_open_sessions = False
                    keyword.actions = [SurveyKeywordAction(
                        recipient = RECIPIENT_SENDER,
                        recipient_id = None,
                        action = METHOD_SMS_SURVEY,
                        message_content = None,
                        form_unique_id = keyword.form_unique_id,
                    )]
                keyword.form_type = None
                keyword.form_unique_id = None
                keyword.use_named_args = None
                keyword.named_args = None
                keyword.named_args_separator = None

                keyword.oct13_migration_timestamp = datetime.utcnow()
                keyword.save()
Esempio n. 33
0
    def deleteAllObjects(self):
        for obj in SurveyKeyword.get_all(self.domain):
            obj.delete()

        Keyword.objects.filter(domain=self.domain).delete()
Esempio n. 34
0
def delete_keyword(request, domain, keyword_id):
    s = SurveyKeyword.get(keyword_id)
    s.retire()
    return HttpResponseRedirect(reverse("manage_surveys", args=[domain]))
Esempio n. 35
0
 def keyword(self):
     return SurveyKeyword(domain=self.domain)
Esempio n. 36
0
def form_session_handler(v, text):
    # Circular Import
    from corehq.apps.reminders.models import SurveyKeyword, FORM_TYPE_ONE_BY_ONE

    # Handle incoming sms
    session = XFormsSession.view(
        "smsforms/open_sms_sessions_by_connection", key=[v.domain, v.owner_id], include_docs=True
    ).one()

    text_words = text.upper().split()

    # Respond to "#START <keyword>" command
    if len(text_words) > 0 and text_words[0] == "#START":
        if len(text_words) > 1:
            sk = SurveyKeyword.get_keyword(v.domain, text_words[1])
            if sk is not None and sk.form_type == FORM_TYPE_ONE_BY_ONE:
                if session is not None:
                    session.end(False)
                    session.save()
                start_session_from_keyword(sk, v)
            else:
                send_sms_to_verified_number(v, "Survey '" + text_words[1] + "' not found.")
        else:
            send_sms_to_verified_number(v, "Usage: #START <keyword>")

    # Respond to "#STOP" keyword
    elif len(text_words) > 0 and text_words[0] == "#STOP":
        if session is not None:
            session.end(False)
            session.save()

    # Respond to "#CURRENT" keyword
    elif len(text_words) > 0 and text_words[0] == "#CURRENT":
        if session is not None:
            resp = current_question(session.session_id)
            send_sms_to_verified_number(v, resp.event.text_prompt)

    # Respond to unknown command
    elif len(text_words) > 0 and text_words[0][0] == "#":
        send_sms_to_verified_number(v, "Unknown command '" + text_words[0] + "'")

    # If there's an open session, treat the inbound text as the answer to the next question
    elif session is not None:
        resp = current_question(session.session_id)
        event = resp.event
        valid, text, error_msg = validate_answer(event, text)

        if valid:
            responses = _get_responses(v.domain, v.owner_id, text)
            if len(responses) > 0:
                response_text = format_message_list(responses)
                send_sms_to_verified_number(v, response_text)
        else:
            send_sms_to_verified_number(v, error_msg + event.text_prompt)

    # Try to match the text against a keyword to start a survey
    elif len(text_words) > 0:
        sk = SurveyKeyword.get_keyword(v.domain, text_words[0])
        if sk is not None and sk.form_type == FORM_TYPE_ONE_BY_ONE:
            start_session_from_keyword(sk, v)

    # TODO should clarify what scenarios this handler actually handles. i.e.,
    # should the error responses instead be handler by some generic error/fallback
    # handler
    return True
Esempio n. 37
0
def delete_keyword(request, domain, keyword_id):
    s = SurveyKeyword.get(keyword_id)
    if s.domain != domain or s.doc_type != "SurveyKeyword":
        raise Http404
    s.retire()
    return HttpResponseRedirect(reverse("manage_keywords", args=[domain]))
Esempio n. 38
0
def add_keyword(request, domain, keyword_id=None):
    sk = None
    if keyword_id is not None:
        sk = SurveyKeyword.get(keyword_id)
        if sk.domain != domain:
            raise Http404
    
    if request.method == "POST":
        form = KeywordForm(request.POST)
        form._cchq_domain = domain
        form._sk_id = sk._id if sk is not None else None
        if form.is_valid():
            if sk is None:
                sk = SurveyKeyword(domain=domain)
            sk.keyword = form.cleaned_data.get("keyword")
            sk.form_type = form.cleaned_data.get("form_type")
            sk.form_unique_id = form.cleaned_data.get("form_unique_id")
            sk.delimiter = form.cleaned_data.get("delimiter")
            sk.use_named_args = form.cleaned_data.get("use_named_args", False)
            sk.named_args = form.cleaned_data.get("named_args")
            sk.named_args_separator = form.cleaned_data.get("named_args_separator")
            sk.save()
            return HttpResponseRedirect(reverse("manage_keywords", args=[domain]))
    else:
        initial = {}
        if sk is not None:
            initial = {
                "keyword" : sk.keyword,
                "form_unique_id" : sk.form_unique_id,
                "form_type" : sk.form_type,
                "use_custom_delimiter" : sk.delimiter is not None,
                "delimiter" : sk.delimiter,
                "use_named_args" : sk.use_named_args,
                "use_named_args_separator" : sk.named_args_separator is not None,
                "named_args" : [{"name" : k, "xpath" : v} for k, v in sk.named_args.items()],
                "named_args_separator" : sk.named_args_separator,
            }
        form = KeywordForm(initial=initial)
    
    context = {
        "domain" : domain,
        "form_list" : get_form_list(domain),
        "form" : form,
        "keyword" : sk,
    }
    
    return render(request, "reminders/partial/add_keyword.html", context)
Esempio n. 39
0
def delete_keyword(request, domain, keyword_id):
    s = SurveyKeyword.get(keyword_id)
    s.retire()
    return HttpResponseRedirect(reverse("manage_keywords", args=[domain]))
Esempio n. 40
0
def add_keyword(request, domain, keyword_id=None):
    sk = None
    if keyword_id is not None:
        sk = SurveyKeyword.get(keyword_id)
        if sk.domain != domain:
            raise Http404

    if request.method == "POST":
        form = KeywordForm(request.POST)
        form._cchq_domain = domain
        form._sk_id = sk._id if sk is not None else None
        if form.is_valid():
            if sk is None:
                sk = SurveyKeyword(domain=domain)
            sk.keyword = form.cleaned_data.get("keyword")
            sk.form_type = form.cleaned_data.get("form_type")
            sk.form_unique_id = form.cleaned_data.get("form_unique_id")
            sk.delimiter = form.cleaned_data.get("delimiter")
            sk.use_named_args = form.cleaned_data.get("use_named_args", False)
            sk.named_args = form.cleaned_data.get("named_args")
            sk.named_args_separator = form.cleaned_data.get(
                "named_args_separator")
            sk.save()
            return HttpResponseRedirect(
                reverse("manage_keywords", args=[domain]))
    else:
        initial = {}
        if sk is not None:
            initial = {
                "keyword":
                sk.keyword,
                "form_unique_id":
                sk.form_unique_id,
                "form_type":
                sk.form_type,
                "use_custom_delimiter":
                sk.delimiter is not None,
                "delimiter":
                sk.delimiter,
                "use_named_args":
                sk.use_named_args,
                "use_named_args_separator":
                sk.named_args_separator is not None,
                "named_args": [{
                    "name": k,
                    "xpath": v
                } for k, v in sk.named_args.items()],
                "named_args_separator":
                sk.named_args_separator,
            }
        form = KeywordForm(initial=initial)

    context = {
        "domain": domain,
        "form_list": get_form_list(domain),
        "form": form,
        "keyword": sk,
    }

    return render(request, "reminders/partial/add_keyword.html", context)
Esempio n. 41
0
def form_session_handler(v, text):
    # Circular Import
    from corehq.apps.reminders.models import SurveyKeyword, FORM_TYPE_ONE_BY_ONE

    # Handle incoming sms
    session = XFormsSession.view("smsforms/open_sms_sessions_by_connection",
                                 key=[v.domain, v.owner_id],
                                 include_docs=True).one()

    text_words = text.upper().split()

    # Respond to "#START <keyword>" command
    if len(text_words) > 0 and text_words[0] == "#START":
        if len(text_words) > 1:
            sk = SurveyKeyword.get_keyword(v.domain, text_words[1])
            if sk is not None and sk.form_type == FORM_TYPE_ONE_BY_ONE:
                if session is not None:
                    session.end(False)
                    session.save()
                start_session_from_keyword(sk, v)
            else:
                send_sms_to_verified_number(
                    v, "Survey '" + text_words[1] + "' not found.")
        else:
            send_sms_to_verified_number(v, "Usage: #START <keyword>")

    # Respond to "#STOP" keyword
    elif len(text_words) > 0 and text_words[0] == "#STOP":
        if session is not None:
            session.end(False)
            session.save()

    # Respond to "#CURRENT" keyword
    elif len(text_words) > 0 and text_words[0] == "#CURRENT":
        if session is not None:
            resp = current_question(session.session_id)
            send_sms_to_verified_number(v, resp.event.text_prompt)

    # Respond to unknown command
    elif len(text_words) > 0 and text_words[0][0] == "#":
        send_sms_to_verified_number(v,
                                    "Unknown command '" + text_words[0] + "'")

    # If there's an open session, treat the inbound text as the answer to the next question
    elif session is not None:
        resp = current_question(session.session_id)
        event = resp.event
        valid, text, error_msg = validate_answer(event, text)

        if valid:
            responses = _get_responses(v.domain, v.owner_id, text)
            if len(responses) > 0:
                response_text = format_message_list(responses)
                send_sms_to_verified_number(v, response_text)
        else:
            send_sms_to_verified_number(v, error_msg + event.text_prompt)

    # Try to match the text against a keyword to start a survey
    elif len(text_words) > 0:
        sk = SurveyKeyword.get_keyword(v.domain, text_words[0])
        if sk is not None and sk.form_type == FORM_TYPE_ONE_BY_ONE:
            start_session_from_keyword(sk, v)

    # TODO should clarify what scenarios this handler actually handles. i.e.,
    # should the error responses instead be handler by some generic error/fallback
    # handler
    return True
Esempio n. 42
0
 def paginated_list(self):
     for keyword in SurveyKeyword.get_by_domain(self.domain, limit=self.limit, skip=self.skip):
         yield {"itemData": self._fmt_keyword_data(keyword), "template": "keyword-row-template"}
Esempio n. 43
0
def structured_sms_handler(verified_number, text):

    # Circular Import
    from corehq.apps.reminders.models import SurveyKeyword, FORM_TYPE_ALL_AT_ONCE

    text = text.strip()
    if text == "":
        return False
    for survey_keyword in SurveyKeyword.get_all(verified_number.domain):
        if survey_keyword.form_type == FORM_TYPE_ALL_AT_ONCE:
            if survey_keyword.delimiter is not None:
                args = text.split(survey_keyword.delimiter)
            else:
                args = text.split()

            keyword = args[0].strip().upper()
            if keyword != survey_keyword.keyword.upper():
                continue

            try:
                error_occurred = False
                error_msg = ""
                form_complete = False

                # Close any open sessions
                close_open_sessions(verified_number.domain, verified_number.owner_id)

                # Start the session
                form = Form.get_form(survey_keyword.form_unique_id)
                app = form.get_app()
                module = form.get_module()

                if verified_number.owner_doc_type == "CommCareCase":
                    case_id = verified_number.owner_id
                else:
                    # TODO: Need a way to choose the case when it's a user that's playing the form
                    case_id = None

                session, responses = start_session(
                    verified_number.domain,
                    verified_number.owner,
                    app,
                    module,
                    form,
                    case_id=case_id,
                    yield_responses=True,
                )
                assert len(responses) > 0, "There should be at least one response."

                current_question = responses[-1]
                form_complete = is_form_complete(current_question)

                if not form_complete:
                    if survey_keyword.use_named_args:
                        # Arguments in the sms are named
                        xpath_answer = {}  # Dictionary of {xpath : answer}
                        for answer in args[1:]:
                            answer = answer.strip()
                            answer_upper = answer.upper()
                            if survey_keyword.named_args_separator is not None:
                                # A separator is used for naming arguments; for example, the "=" in "register name=joe age=25"
                                answer_parts = answer.partition(survey_keyword.named_args_separator)
                                if answer_parts[1] != survey_keyword.named_args_separator:
                                    error_occurred = True
                                    error_msg = "ERROR: Expected name and value to be joined by" + (
                                        " '%s'" % survey_keyword.named_args_separator
                                    )
                                    break
                                else:
                                    arg_name = answer_parts[0].upper().strip()
                                    xpath = survey_keyword.named_args.get(arg_name, None)
                                    if xpath is not None:
                                        if xpath in xpath_answer:
                                            error_occurred = True
                                            error_msg = "ERROR: More than one answer found for" + (" '%s'" % arg_name)
                                            break

                                        xpath_answer[xpath] = answer_parts[2].strip()
                                    else:
                                        # Ignore unexpected named arguments
                                        pass
                            else:
                                # No separator is used for naming arguments; for example, "update a100 b34 c5"
                                matches = 0
                                for k, v in survey_keyword.named_args.items():
                                    if answer_upper.startswith(k):
                                        matches += 1
                                        if matches > 1:
                                            error_occurred = True
                                            error_msg = "ERROR: More than one question matches" + (" '%s'" % answer)
                                            break

                                        if v in xpath_answer:
                                            error_occurred = True
                                            error_msg = "ERROR: More than one answer found for" + (" '%s'" % k)
                                            break

                                        xpath_answer[v] = answer[len(k) :].strip()

                                if matches == 0:
                                    # Ignore unexpected named arguments
                                    pass

                            if error_occurred:
                                break

                        # Go through each question in the form, answering only the questions that the sms has answers for
                        while not form_complete and not error_occurred:
                            if current_question.is_error:
                                error_occurred = True
                                error_msg = current_question.text_prompt or "ERROR: Internal server error"
                                break

                            xpath = current_question.event._dict["binding"]
                            if xpath in xpath_answer:
                                valid, answer, _error_msg = validate_answer(current_question.event, xpath_answer[xpath])
                                if not valid:
                                    error_occurred = True
                                    error_msg = "ERROR: " + _error_msg
                                    break
                                responses = _get_responses(
                                    verified_number.domain, verified_number.owner_id, answer, yield_responses=True
                                )
                            else:
                                responses = _get_responses(
                                    verified_number.domain, verified_number.owner_id, "", yield_responses=True
                                )

                            current_question = responses[-1]
                            if is_form_complete(current_question):
                                form_complete = True
                    else:
                        # Arguments in the sms are not named; pass each argument to each question in order
                        for answer in args[1:]:
                            if form_complete:
                                # Form is complete, ignore remaining answers
                                break

                            if current_question.is_error:
                                error_occurred = True
                                error_msg = current_question.text_prompt or "ERROR: Internal server error"
                                break

                            valid, answer, _error_msg = validate_answer(current_question.event, answer.strip())
                            if not valid:
                                error_occurred = True
                                error_msg = "ERROR: " + _error_msg
                                break

                            responses = _get_responses(
                                verified_number.domain, verified_number.owner_id, answer, yield_responses=True
                            )
                            current_question = responses[-1]
                            form_complete = is_form_complete(current_question)

                        # If the form isn't finished yet but we're out of arguments, try to leave each remaining question blank and continue
                        while not form_complete and not error_occurred:
                            responses = _get_responses(
                                verified_number.domain, verified_number.owner_id, "", yield_responses=True
                            )
                            current_question = responses[-1]

                            if current_question.is_error:
                                error_occurred = True
                                error_msg = current_question.text_prompt or "ERROR: Internal server error"

                            if is_form_complete(current_question):
                                form_complete = True
            except Exception:
                logging.exception(
                    "Could not process structured sms for verified number %s, domain %s, keyword %s"
                    % (verified_number._id, verified_number.domain, keyword)
                )
                error_occurred = True
                error_msg = "ERROR: Internal server error"

            if error_occurred:
                send_sms_to_verified_number(verified_number, error_msg)

            if error_occurred or not form_complete:
                session = XFormsSession.get(session._id)
                session.end(False)
                session.save()

            return True

    return False
Esempio n. 44
0
def form_session_handler(v, text):
    # Circular Import
    from corehq.apps.reminders.models import SurveyKeyword
    
    # Handle incoming sms
    session = XFormsSession.view("smsforms/open_sms_sessions_by_connection",
                                 key=[v.domain, v.owner_id],
                                 include_docs=True).one()
    
    text_words = text.upper().split()
    
    # Respond to "#START <keyword>" command
    if len(text_words) > 0 and text_words[0] == "#START":
        if len(text_words) > 1:
            sk = SurveyKeyword.get_keyword(v.domain, text_words[1])
            if sk is not None:
                if session is not None:
                    session.end(False)
                    session.save()
                start_session_from_keyword(sk, v)
            else:
                send_sms_to_verified_number(v, "Survey '" + text_words[1] + "' not found.")
        else:
            send_sms_to_verified_number(v, "Usage: #START <keyword>")
        
    # Respond to "#STOP" keyword
    elif len(text_words) > 0 and text_words[0] == "#STOP":
        if session is not None:
            session.end(False)
            session.save()
        
    # Respond to "#CURRENT" keyword
    elif len(text_words) > 0 and text_words[0] == "#CURRENT":
        if session is not None:
            resp = current_question(session.session_id)
            send_sms_to_verified_number(v, resp.event.text_prompt)
        
    # Respond to unknown command
    elif len(text_words) > 0 and text_words[0][0] == "#":
        send_sms_to_verified_number(v, "Unknown command '" + text_words[0] + "'")
        
    # If there's an open session, treat the inbound text as the answer to the next question
    elif session is not None:
        resp = current_question(session.session_id)
        event = resp.event
        valid = False
        text = text.strip()
        upper_text = text.upper()
        
        # Validate select
        if event.datatype == "select":
            # Try to match on phrase (i.e., "Yes" or "No")
            choices = format_choices(event._dict["choices"])
            if upper_text in choices:
                text = str(choices[upper_text])
                valid = True
            else:
                try:
                    answer = int(text)
                    if answer >= 1 and answer <= len(event._dict["choices"]):
                        valid = True
                except ValueError:
                    pass
        
        # Validate multiselect
        elif event.datatype == "multiselect":
            choices = format_choices(event._dict["choices"])
            max_index = len(event._dict["choices"])
            proposed_answers = text.split()
            final_answers = {}
            
            try:
                if event._dict.get("required", True):
                    assert len(proposed_answers) > 0
                for answer in proposed_answers:
                    upper_answer = answer.upper()
                    if upper_answer in choices:
                        final_answers[str(choices[upper_answer])] = ""
                    else:
                        int_answer = int(answer)
                        assert int_answer >= 1 and int_answer <= max_index
                        final_answers[str(int_answer)] = ""
                text = " ".join(final_answers.keys())
                valid = True
            except Exception:
                pass
        
        # Validate int
        elif event.datatype == "int":
            try:
                int(text)
                valid = True
            except ValueError:
                pass
        
        # Validate float
        elif event.datatype == "float":
            try:
                float(text)
                valid = True
            except ValueError:
                pass
        
        # Validate longint
        elif event.datatype == "longint":
            try:
                long(text)
                valid = True
            except ValueError:
                pass
        
        # Validate date (Format: YYYYMMDD)
        elif event.datatype == "date":
            try:
                assert len(text) == 8
                int(text)
                text = text[0:4] + "-" + text[4:6] + "-" + text[6:]
                parse(text)
                valid = True
            except Exception:
                pass
        
        # Validate time (Format: HHMM, 24-hour)
        elif event.datatype == "time":
            try:
                assert len(text) == 4
                hour = int(text[0:2])
                minute = int(text[2:])
                assert hour >= 0 and hour <= 23
                assert minute >= 0 and minute <= 59
                text = "%s:%s" % (hour, minute)
                valid = True
            except Exception:
                pass
        
        # Other question types pass
        else:
            valid = True
        
        if valid:
            responses = _get_responses(v.domain, v.owner_id, text)
            if len(responses) > 0:
                response_text = format_message_list(responses)
                send_sms_to_verified_number(v, response_text)
        else:
            error_msg = "Invalid Response. " + event.text_prompt
            send_sms_to_verified_number(v, error_msg)
        
    # Try to match the text against a keyword to start a survey
    elif len(text_words) > 0:
        sk = SurveyKeyword.get_keyword(v.domain, text_words[0])
        if sk is not None:
            start_session_from_keyword(sk, v)

    # TODO should clarify what scenarios this handler actually handles. i.e.,
    # should the error responses instead be handler by some generic error/fallback
    # handler
    return True
Esempio n. 45
0
def structured_sms_handler(verified_number, text):

    # Circular Import
    from corehq.apps.reminders.models import SurveyKeyword, FORM_TYPE_ALL_AT_ONCE

    text = text.strip()
    if text == "":
        return False
    for survey_keyword in SurveyKeyword.get_all(verified_number.domain):
        if survey_keyword.form_type == FORM_TYPE_ALL_AT_ONCE:
            if survey_keyword.delimiter is not None:
                args = text.split(survey_keyword.delimiter)
            else:
                args = text.split()

            keyword = args[0].strip().upper()
            if keyword != survey_keyword.keyword.upper():
                continue

            try:
                error_occurred = False
                error_msg = ""
                form_complete = False

                # Close any open sessions
                close_open_sessions(verified_number.domain,
                                    verified_number.owner_id)

                # Start the session
                form = Form.get_form(survey_keyword.form_unique_id)
                app = form.get_app()
                module = form.get_module()

                if verified_number.owner_doc_type == "CommCareCase":
                    case_id = verified_number.owner_id
                else:
                    #TODO: Need a way to choose the case when it's a user that's playing the form
                    case_id = None

                session, responses = start_session(verified_number.domain,
                                                   verified_number.owner,
                                                   app,
                                                   module,
                                                   form,
                                                   case_id=case_id,
                                                   yield_responses=True)
                assert len(
                    responses) > 0, "There should be at least one response."

                current_question = responses[-1]
                form_complete = is_form_complete(current_question)

                if not form_complete:
                    if survey_keyword.use_named_args:
                        # Arguments in the sms are named
                        xpath_answer = {}  # Dictionary of {xpath : answer}
                        for answer in args[1:]:
                            answer = answer.strip()
                            answer_upper = answer.upper()
                            if survey_keyword.named_args_separator is not None:
                                # A separator is used for naming arguments; for example, the "=" in "register name=joe age=25"
                                answer_parts = answer.partition(
                                    survey_keyword.named_args_separator)
                                if answer_parts[
                                        1] != survey_keyword.named_args_separator:
                                    error_occurred = True
                                    error_msg = "ERROR: Expected name and value to be joined by" + (
                                        " '%s'" %
                                        survey_keyword.named_args_separator)
                                    break
                                else:
                                    arg_name = answer_parts[0].upper().strip()
                                    xpath = survey_keyword.named_args.get(
                                        arg_name, None)
                                    if xpath is not None:
                                        if xpath in xpath_answer:
                                            error_occurred = True
                                            error_msg = "ERROR: More than one answer found for" + (
                                                " '%s'" % arg_name)
                                            break

                                        xpath_answer[xpath] = answer_parts[
                                            2].strip()
                                    else:
                                        # Ignore unexpected named arguments
                                        pass
                            else:
                                # No separator is used for naming arguments; for example, "update a100 b34 c5"
                                matches = 0
                                for k, v in survey_keyword.named_args.items():
                                    if answer_upper.startswith(k):
                                        matches += 1
                                        if matches > 1:
                                            error_occurred = True
                                            error_msg = "ERROR: More than one question matches" + (
                                                " '%s'" % answer)
                                            break

                                        if v in xpath_answer:
                                            error_occurred = True
                                            error_msg = "ERROR: More than one answer found for" + (
                                                " '%s'" % k)
                                            break

                                        xpath_answer[v] = answer[
                                            len(k):].strip()

                                if matches == 0:
                                    # Ignore unexpected named arguments
                                    pass

                            if error_occurred:
                                break

                        # Go through each question in the form, answering only the questions that the sms has answers for
                        while not form_complete and not error_occurred:
                            if current_question.is_error:
                                error_occurred = True
                                error_msg = current_question.text_prompt or "ERROR: Internal server error"
                                break

                            xpath = current_question.event._dict["binding"]
                            if xpath in xpath_answer:
                                valid, answer, _error_msg = validate_answer(
                                    current_question.event,
                                    xpath_answer[xpath])
                                if not valid:
                                    error_occurred = True
                                    error_msg = "ERROR: " + _error_msg
                                    break
                                responses = _get_responses(
                                    verified_number.domain,
                                    verified_number.owner_id,
                                    answer,
                                    yield_responses=True)
                            else:
                                responses = _get_responses(
                                    verified_number.domain,
                                    verified_number.owner_id,
                                    "",
                                    yield_responses=True)

                            current_question = responses[-1]
                            if is_form_complete(current_question):
                                form_complete = True
                    else:
                        # Arguments in the sms are not named; pass each argument to each question in order
                        for answer in args[1:]:
                            if form_complete:
                                # Form is complete, ignore remaining answers
                                break

                            if current_question.is_error:
                                error_occurred = True
                                error_msg = current_question.text_prompt or "ERROR: Internal server error"
                                break

                            valid, answer, _error_msg = validate_answer(
                                current_question.event, answer.strip())
                            if not valid:
                                error_occurred = True
                                error_msg = "ERROR: " + _error_msg
                                break

                            responses = _get_responses(
                                verified_number.domain,
                                verified_number.owner_id,
                                answer,
                                yield_responses=True)
                            current_question = responses[-1]
                            form_complete = is_form_complete(current_question)

                        # If the form isn't finished yet but we're out of arguments, try to leave each remaining question blank and continue
                        while not form_complete and not error_occurred:
                            responses = _get_responses(
                                verified_number.domain,
                                verified_number.owner_id,
                                "",
                                yield_responses=True)
                            current_question = responses[-1]

                            if current_question.is_error:
                                error_occurred = True
                                error_msg = current_question.text_prompt or "ERROR: Internal server error"

                            if is_form_complete(current_question):
                                form_complete = True
            except Exception:
                logging.exception(
                    "Could not process structured sms for verified number %s, domain %s, keyword %s"
                    % (verified_number._id, verified_number.domain, keyword))
                error_occurred = True
                error_msg = "ERROR: Internal server error"

            if error_occurred:
                send_sms_to_verified_number(verified_number, error_msg)

            if error_occurred or not form_complete:
                session = XFormsSession.get(session._id)
                session.end(False)
                session.save()

            return True

    return False
Esempio n. 46
0
def manage_keywords(request, domain):
    context = {"domain": domain, "keywords": SurveyKeyword.get_all(domain)}
    return render(request, "reminders/partial/manage_keywords.html", context)
Esempio n. 47
0
def sms_keyword_handler(v, text, msg=None):
    from corehq.apps.reminders.models import SurveyKeyword

    text = text.strip()
    if text == "":
        return False

    sessions = XFormsSession.get_all_open_sms_sessions(v.domain, v.owner_id)
    any_session_open = len(sessions) > 0
    text_words = text.upper().split()

    if text.startswith("#"):
        if len(text_words) > 0 and text_words[0] == "#START":
            # Respond to "#START <keyword>" command
            if len(text_words) > 1:
                sk = SurveyKeyword.get_keyword(v.domain, text_words[1])
                if sk is not None:
                    if len(sk.initiator_doc_type_filter) > 0 and v.owner_doc_type not in sk.initiator_doc_type_filter:
                        # The contact type is not allowed to invoke this keyword
                        return False
                    process_survey_keyword_actions(v, sk, text[6:].strip(), msg=msg)
                else:
                    send_sms_to_verified_number(
                        v, "Keyword not found: '%s'." % text_words[1], workflow=WORKFLOW_KEYWORD
                    )
            else:
                send_sms_to_verified_number(v, "Usage: #START <keyword>", workflow=WORKFLOW_KEYWORD)
        elif len(text_words) > 0 and text_words[0] == "#STOP":
            # Respond to "#STOP" keyword
            XFormsSession.close_all_open_sms_sessions(v.domain, v.owner_id)
        elif len(text_words) > 0 and text_words[0] == "#CURRENT":
            # Respond to "#CURRENT" keyword
            if len(sessions) == 1:
                resp = current_question(sessions[0].session_id)
                send_sms_to_verified_number(
                    v,
                    resp.event.text_prompt,
                    workflow=sessions[0].workflow,
                    reminder_id=sessions[0].reminder_id,
                    xforms_session_couch_id=sessions[0]._id,
                )
        else:
            # Response to unknown command
            send_sms_to_verified_number(v, "Unknown command: '%s'" % text_words[0])
        if msg is not None:
            msg.workflow = WORKFLOW_KEYWORD
            msg.save()
        return True
    else:
        for survey_keyword in SurveyKeyword.get_all(v.domain):
            if survey_keyword.delimiter is not None:
                args = text.split(survey_keyword.delimiter)
            else:
                args = text.split()

            keyword = args[0].strip().upper()
            if keyword == survey_keyword.keyword.upper():
                if any_session_open and not survey_keyword.override_open_sessions:
                    # We don't want to override any open sessions, so just pass and let the form session handler handle the message
                    return False
                elif (
                    len(survey_keyword.initiator_doc_type_filter) > 0
                    and v.owner_doc_type not in survey_keyword.initiator_doc_type_filter
                ):
                    # The contact type is not allowed to invoke this keyword
                    return False
                else:
                    process_survey_keyword_actions(v, survey_keyword, text, msg=msg)
                    if msg is not None:
                        msg.workflow = WORKFLOW_KEYWORD
                        msg.save()
                    return True
        # No keywords matched, so pass the message onto the next handler
        return False
Esempio n. 48
0
def manage_surveys(request, domain):
    context = {
        "domain" : domain,
        "keywords" : SurveyKeyword.get_all(domain)
    }
    return render_to_response(request, "reminders/partial/manage_surveys.html", context)