Exemple #1
0
    def test_get_contact_for_user(self):
        contact = get_contact(self.domain, self.user.get_id)
        self.assertEqual(contact.get_id, self.user.get_id)
        self.assertTrue(isinstance(contact, CommCareUser))

        with self.assertRaises(ContactNotFoundException):
            get_contact(self.domain + "x", self.user.get_id)
    def test_get_contact_for_user(self):
        contact = get_contact(self.domain, self.user.get_id)
        self.assertEqual(contact.get_id, self.user.get_id)
        self.assertTrue(isinstance(contact, CommCareUser))

        with self.assertRaises(ContactNotFoundException):
            get_contact(self.domain + 'x', self.user.get_id)
Exemple #3
0
    def test_get_contact_for_case(self):
        with create_test_case(self.domain, "contact", "test-case") as case:
            contact = get_contact(self.domain, case.case_id)
            self.assertEqual(contact.case_id, case.case_id)
            self.assertTrue(is_commcarecase(contact))

            with self.assertRaises(ContactNotFoundException):
                get_contact(self.domain + "x", case.case_id)
Exemple #4
0
    def test_get_contact(self):
        contact = get_contact(self.case.get_id)
        self.assertEqual(contact.get_id, self.case.get_id)
        self.assertTrue(isinstance(contact, CommConnectCase))

        contact = get_contact(self.user.get_id)
        self.assertEqual(contact.get_id, self.user.get_id)
        self.assertTrue(isinstance(contact, CommCareUser))

        with self.assertRaises(ContactNotFoundException):
            get_contact('this-id-should-not-be-found')
Exemple #5
0
    def test_get_contact(self):
        contact = get_contact(self.case.get_id)
        self.assertEqual(contact.get_id, self.case.get_id)
        self.assertTrue(isinstance(contact, CommConnectCase))

        contact = get_contact(self.user.get_id)
        self.assertEqual(contact.get_id, self.user.get_id)
        self.assertTrue(isinstance(contact, CommCareUser))

        try:
            get_contact('this-id-should-not-be-found')
        except Exception:
            pass
        else:
            self.assertTrue(False)
Exemple #6
0
def chat(request, domain, contact_id):
    domain_obj = Domain.get_by_name(domain, strict=True)
    timezone = report_utils.get_timezone(None, domain)

    # floored_utc_timestamp is the datetime in UTC representing
    # midnight today in local time. This is used to calculate
    # all message history choices' timestamps, so that choosing
    # "Yesterday", for example, gives you data from yesterday at
    # midnight local time.
    local_date = datetime.now(timezone).date()
    floored_utc_timestamp = tz_utils.adjust_datetime_to_timezone(
        datetime.combine(local_date, time(0,0)),
        timezone.zone,
        pytz.utc.zone
    ).replace(tzinfo=None)

    def _fmt(d):
        return json_format_datetime(floored_utc_timestamp - timedelta(days=d))
    history_choices = [(_(x), _fmt(y)) for (x, y) in SMS_CHAT_HISTORY_CHOICES]
    history_choices.append(
        (_("All Time"), json_format_datetime(datetime(1970, 1, 1)))
    )

    context = {
        "domain" : domain,
        "contact_id" : contact_id,
        "contact" : get_contact(contact_id),
        "message_count_threshold" : domain_obj.chat_message_count_threshold or DEFAULT_MESSAGE_COUNT_THRESHOLD,
        "custom_case_username" : domain_obj.custom_case_username,
        "history_choices" : history_choices,
    }
    template = settings.CUSTOM_CHAT_TEMPLATES.get(domain_obj.custom_chat_template) or "sms/chat.html"
    return render(request, template, context)
Exemple #7
0
def api_send_sms(request, domain):
    """
    An API to send SMS.
    Expected post parameters:
        phone_number - the phone number to send to
        contact_id - the _id of a contact to send to (overrides phone_number)
        text - the text of the message
        backend_id - the name of the MobileBackend to use while sending
    """
    if request.method == "POST":
        phone_number = request.POST.get("phone_number", None)
        contact_id = request.POST.get("contact_id", None)
        text = request.POST.get("text", None)
        backend_id = request.POST.get("backend_id", None)
        chat = request.POST.get("chat", None)

        if (phone_number is None and contact_id is None) or (text is None):
            return HttpResponseBadRequest("Not enough arguments.")

        vn = None
        if contact_id is not None:
            try:
                contact = get_contact(contact_id)
                assert contact is not None
                assert contact.domain == domain
            except Exception:
                return HttpResponseBadRequest("Contact not found.")
            try:
                vn = contact.get_verified_number()
                assert vn is not None
                phone_number = vn.phone_number
            except Exception:
                return HttpResponseBadRequest("Contact has no phone number.")

        try:
            chat_workflow = string_to_boolean(chat)
        except Exception:
            chat_workflow = False

        if chat_workflow:
            chat_user_id = request.couch_user._id
        else:
            chat_user_id = None

        metadata = MessageMetadata(
            chat_user_id=chat_user_id
        )
        if backend_id is not None:
            success = send_sms_with_backend_name(domain, phone_number, text, backend_id, metadata)
        elif vn is not None:
            success = send_sms_to_verified_number(vn, text, metadata)
        else:
            success = send_sms(domain, None, phone_number, text, metadata)

        if success:
            return HttpResponse("OK")
        else:
            return HttpResponse("ERROR")
    else:
        return HttpResponseBadRequest("POST Expected.")
Exemple #8
0
    def test_get_contact(self):
        with create_test_case(self.domain, 'contact', 'test-case') as case:
            user = CommCareUser.create(self.domain, 'test-user', '123')
            self.addCleanup(user.delete)

            contact = get_contact(self.domain, case.case_id)
            self.assertEqual(contact.case_id, case.case_id)
            self.assertTrue(is_commcarecase(contact))

            contact = get_contact(self.domain, user.get_id)
            self.assertEqual(contact.get_id, user.get_id)
            self.assertTrue(isinstance(contact, CommCareUser))

            with self.assertRaises(ContactNotFoundException):
                get_contact(self.domain, 'this-id-should-not-be-found')

            with self.assertRaises(ContactNotFoundException):
                get_contact(self.domain + 'x', case.case_id)

            with self.assertRaises(ContactNotFoundException):
                get_contact(self.domain + 'x', user.get_id)
Exemple #9
0
def api_history(request, domain):
    result = []
    contact_id = request.GET.get("contact_id", None)
    start_date = request.GET.get("start_date", None)
    timezone = report_utils.get_timezone(None, domain)
    domain_obj = Domain.get_by_name(domain, strict=True)

    try:
        assert contact_id is not None
        doc = get_contact(contact_id)
        assert doc is not None
        assert doc.domain == domain
    except Exception:
        return HttpResponse("[]")

    query_start_date_str = None
    if start_date is not None:
        try:
            query_start_date = parse(start_date)
            query_start_date += timedelta(seconds=1)
            query_start_date_str = json_format_datetime(query_start_date)
        except Exception:
            pass

    if query_start_date_str is not None:
        data = SMSLog.view("sms/by_recipient",
                           startkey=[doc.doc_type, contact_id, "SMSLog", INCOMING, query_start_date_str],
                           endkey=[doc.doc_type, contact_id, "SMSLog", INCOMING, {}],
                           include_docs=True,
                           reduce=False).all()
        data += SMSLog.view("sms/by_recipient",
                            startkey=[doc.doc_type, contact_id, "SMSLog", OUTGOING, query_start_date_str],
                            endkey=[doc.doc_type, contact_id, "SMSLog", OUTGOING, {}],
                            include_docs=True,
                            reduce=False).all()
    else:
        data = SMSLog.view("sms/by_recipient",
                           startkey=[doc.doc_type, contact_id, "SMSLog"],
                           endkey=[doc.doc_type, contact_id, "SMSLog", {}],
                           include_docs=True,
                           reduce=False).all()
    data.sort(key=lambda x : x.date)
    username_map = {}
    last_sms = None
    for sms in data:
        # Don't show outgoing SMS that haven't been processed yet
        if sms.direction == OUTGOING and not sms.processed:
            continue
        # Filter SMS that are tied to surveys if necessary
        if ((domain_obj.filter_surveys_from_chat and 
             sms.xforms_session_couch_id)
            and not
            (domain_obj.show_invalid_survey_responses_in_chat and
             sms.direction == INCOMING and
             sms.invalid_survey_response)):
            continue
        if sms.direction == INCOMING:
            if doc.doc_type == "CommCareCase" and domain_obj.custom_case_username:
                sender = doc.get_case_property(domain_obj.custom_case_username)
            elif doc.doc_type == "CommCareCase":
                sender = doc.name
            else:
                sender = doc.first_name or doc.raw_username
        elif sms.chat_user_id is not None:
            if sms.chat_user_id in username_map:
                sender = username_map[sms.chat_user_id]
            else:
                try:
                    user = CouchUser.get_by_user_id(sms.chat_user_id)
                    sender = user.first_name or user.raw_username
                except Exception:
                    sender = _("Unknown")
                username_map[sms.chat_user_id] = sender
        else:
            sender = _("System")
        last_sms = sms
        result.append({
            "sender" : sender,
            "text" : sms.text,
            "timestamp" : tz_utils.adjust_datetime_to_timezone(sms.date, pytz.utc.zone, timezone.zone).strftime("%I:%M%p %m/%d/%y").lower(),
            "utc_timestamp" : json_format_datetime(sms.date),
        })
    if last_sms:
        try:
            entry, lock = LastReadMessage.get_locked_obj(
                sms.domain,
                request.couch_user._id,
                sms.couch_recipient,
                create=True
            )
            if (not entry.message_timestamp or
                entry.message_timestamp < last_sms.date):
                entry.message_id = last_sms._id
                entry.message_timestamp = last_sms.date
                entry.save()
            lock.release()
        except:
            logging.exception("Could not create/save LastReadMessage for message %s" % last_sms._id)
            # Don't let this block returning of the data
            pass
    return HttpResponse(json.dumps(result))
 def test_contact_not_found(self):
     with self.assertRaises(ContactNotFoundException):
         get_contact(self.domain, 'this-id-should-not-be-found')
Exemple #11
0
 def test_contact_not_found(self):
     with self.assertRaises(ContactNotFoundException):
         get_contact(self.domain, "this-id-should-not-be-found")
Exemple #12
0
def api_history(request, domain):
    result = []
    contact_id = request.GET.get("contact_id", None)
    start_date = request.GET.get("start_date", None)
    timezone = report_utils.get_timezone(None, domain)
    domain_obj = Domain.get_by_name(domain, strict=True)

    try:
        assert contact_id is not None
        doc = get_contact(contact_id)
        assert doc is not None
        assert doc.domain == domain
    except Exception:
        return HttpResponse("[]")

    query_start_date_str = None
    if start_date is not None:
        try:
            query_start_date = parse(start_date)
            query_start_date += timedelta(seconds=1)
            query_start_date_str = json_format_datetime(query_start_date)
        except Exception:
            pass

    if query_start_date_str is not None:
        data = SMSLog.view(
            "sms/by_recipient",
            startkey=[doc.doc_type, contact_id, "SMSLog", INCOMING, query_start_date_str],
            endkey=[doc.doc_type, contact_id, "SMSLog", INCOMING, {}],
            include_docs=True,
            reduce=False,
        ).all()
        data += SMSLog.view(
            "sms/by_recipient",
            startkey=[doc.doc_type, contact_id, "SMSLog", OUTGOING, query_start_date_str],
            endkey=[doc.doc_type, contact_id, "SMSLog", OUTGOING, {}],
            include_docs=True,
            reduce=False,
        ).all()
    else:
        data = SMSLog.view(
            "sms/by_recipient",
            startkey=[doc.doc_type, contact_id, "SMSLog"],
            endkey=[doc.doc_type, contact_id, "SMSLog", {}],
            include_docs=True,
            reduce=False,
        ).all()
    data.sort(key=lambda x: x.date)
    username_map = {}
    for sms in data:
        if sms.direction == INCOMING:
            if doc.doc_type == "CommCareCase" and domain_obj.custom_case_username:
                sender = doc.get_case_property(domain_obj.custom_case_username)
            elif doc.doc_type == "CommCareCase":
                sender = doc.name
            else:
                sender = doc.first_name or doc.raw_username
        elif sms.chat_user_id is not None:
            if sms.chat_user_id in username_map:
                sender = username_map[sms.chat_user_id]
            else:
                try:
                    user = CouchUser.get_by_user_id(sms.chat_user_id)
                    sender = user.first_name or user.raw_username
                except Exception:
                    sender = _("Unknown")
                username_map[sms.chat_user_id] = sender
        else:
            sender = _("System")
        result.append(
            {
                "sender": sender,
                "text": sms.text,
                "timestamp": tz_utils.adjust_datetime_to_timezone(sms.date, pytz.utc.zone, timezone.zone)
                .strftime("%I:%M%p %m/%d/%y")
                .lower(),
                "utc_timestamp": json_format_datetime(sms.date),
            }
        )
    return HttpResponse(json.dumps(result))