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)
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)
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')
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)
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)
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.")
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)
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')
def test_contact_not_found(self): with self.assertRaises(ContactNotFoundException): get_contact(self.domain, "this-id-should-not-be-found")
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))