Exemplo n.º 1
0
def handle_domain_specific_delays(msg, domain_object, utcnow):
    """
    Checks whether or not we need to hold off on sending an outbound message
    due to any restrictions set on the domain, and delays processing of the
    message if necessary.

    Returns True if a delay was made, False if not.
    """
    domain_now = ServerTime(utcnow).user_time(
        domain_object.get_default_timezone()).done()

    if len(domain_object.restricted_sms_times) > 0:
        if not time_within_windows(domain_now,
                                   domain_object.restricted_sms_times):
            delay_processing(
                msg, settings.SMS_QUEUE_DOMAIN_RESTRICTED_RETRY_INTERVAL)
            return True

    if msg.chat_user_id is None and len(
            domain_object.sms_conversation_times) > 0:
        if time_within_windows(domain_now,
                               domain_object.sms_conversation_times):
            sms_conversation_length = domain_object.sms_conversation_length
            conversation_start_timestamp = utcnow - timedelta(
                minutes=sms_conversation_length)
            if SMS.inbound_entry_exists(msg.couch_recipient_doc_type,
                                        msg.couch_recipient,
                                        conversation_start_timestamp,
                                        to_timestamp=utcnow):
                delay_processing(msg, 1)
                return True

    return False
Exemplo n.º 2
0
    def rows(self):
        data = SMS.by_domain(self.domain,
                             start_date=self.datespan.startdate_utc,
                             end_date=self.datespan.enddate_utc).filter(
                                 workflow__iexact=WORKFLOW_DEFAULT).exclude(
                                     direction=OUTGOING,
                                     processed=False,
                                 ).order_by('date')
        result = []

        direction_map = {
            INCOMING: _("Incoming"),
            OUTGOING: _("Outgoing"),
        }
        reporting_locations_id = self.get_location_filter()

        contact_cache = {}
        for message in data:
            if reporting_locations_id and message.location_id not in reporting_locations_id:
                continue

            doc_info = self.get_recipient_info(message, contact_cache)
            phone_number = message.phone_number
            timestamp = ServerTime(message.date).user_time(
                self.timezone).done()
            result.append([
                self._fmt_timestamp(timestamp),
                self._fmt_contact_link(message, doc_info),
                _fmt(phone_number),
                _fmt(direction_map.get(message.direction, "-")),
                _fmt(message.text)
            ])

        return result
Exemplo n.º 3
0
 def get_server_date_by_form_id(self, form_id):
     try:
         server_date = FormAccessors(self.domain).get_form(form_id).received_on
     except XFormNotFound:
         return None
     else:
         return ServerTime(server_date).ui_string()
Exemplo n.º 4
0
 def rows(self):
     participants = self.get_participants()
     result = []
     for case in participants:
         pid = case.get_case_property("pid")
         study_arm = case.get_case_property("study_arm")
         registration_date = get_date(case, "start_date")
         first_name = case.get_case_property("first_name") or ""
         if registration_date is None:
             continue
         first_survey_date = self.get_first_tuesday(registration_date)
         row = [
             self._fmt(pid),
             self._fmt(first_name),
             self._fmt(study_arm),
         ]
         for i in range(8):
             next_survey_date = first_survey_date + timedelta(days=7 * i)
             response = self.get_first_survey_response(
                 case, next_survey_date)
             if response == RESPONSE_NOT_APPLICABLE:
                 row.append(self._fmt("-"))
             elif response == NO_RESPONSE:
                 row.append(self._fmt(_("No Response")))
             else:
                 response_timestamp = ServerTime(response.date).user_time(
                     self.timezone).done()
                 row.append(self._fmt_timestamp(response_timestamp))
         result.append(row)
     return result
Exemplo n.º 5
0
 def template_context(self):
     return {
         'xforms_session': self.xforms_session,
         'contact': get_doc_info_by_id(self.domain, self.xforms_session.connection_id),
         'start_time': (ServerTime(self.xforms_session.start_time)
                        .user_time(self.timezone).done().strftime(SERVER_DATETIME_FORMAT)),
     }
Exemplo n.º 6
0
 def template_context(self):
     event = self.messaging_event
     date = ServerTime(event.date).user_time(self.timezone).done()
     return {
         'messaging_event_date': date.strftime(SERVER_DATETIME_FORMAT),
         'messaging_event_type': self.get_source_display(event, display_only=True),
     }
Exemplo n.º 7
0
    def rows(self):
        contact_cache = {}
        content_cache = {}

        data = self.get_queryset()
        if self.request_params.get('sSortDir_0') == 'asc':
            data = data.order_by('date')
        else:
            data = data.order_by('-date')

        if self.pagination:
            data = data[self.pagination.start:self.pagination.start + self.pagination.count]

        for event in data:
            doc_info = self.get_recipient_info(event.get_recipient_doc_type(),
                event.recipient_id, contact_cache)

            timestamp = ServerTime(event.date).user_time(self.timezone).done()
            status = self.get_status_display(event)
            yield [
                self._fmt_timestamp(timestamp)['html'],
                self.get_content_display(event, content_cache),
                self.get_source_display(event, display_only=True),
                self._fmt_recipient(event, doc_info)['html'],
                status,
                self.get_event_detail_link(event),
            ]
Exemplo n.º 8
0
def case_upload_to_user_json(case_upload, request):
    domain = case_upload.domain
    tz = get_timezone_for_request(request)

    return CaseUploadJSON(
        domain=case_upload.domain,
        created_display=ServerTime(
            case_upload.created).user_time(tz).ui_string(),
        created=json_format_datetime(case_upload.created),
        upload_id=str(case_upload.upload_id),
        task_status=case_upload.get_task_status_json(),
        user_name=get_display_name_for_user_id(domain,
                                               case_upload.couch_user_id,
                                               default=''),
        case_type=case_upload.case_type,
        comment=case_upload.comment,
        upload_file_name=(case_upload.upload_file_meta.filename
                          if case_upload.upload_file_meta else None),
        upload_file_length=(case_upload.upload_file_meta.length
                            if case_upload.upload_file_meta else None),
        upload_file_download_allowed=user_may_view_file_upload(
            domain, request.couch_user, case_upload),
        upload_comment_edit_allowed=user_may_update_comment(
            request.couch_user, case_upload),
    )
Exemplo n.º 9
0
def utc_to_timezone(date, timezone):
    if not timezone:
        timezone = pytz.utc
    if not date:
        return "---"
    if isinstance(date, (str, bytes)):
        raise ValueError("utc_to_timezone no longer accepts strings")
    return ServerTime(date).user_time(timezone).ui_string()
Exemplo n.º 10
0
 def submission_or_completion_time(self):
     time = iso_string_to_datetime(
         safe_index(self.form, self.report.time_field.split('.')))
     if self.report.by_submission_time:
         user_time = ServerTime(time).user_time(self.report.timezone)
     else:
         user_time = PhoneTime(time, self.report.timezone).user_time(
             self.report.timezone)
     return user_time.ui_string(USER_DATETIME_FORMAT_WITH_SEC)
Exemplo n.º 11
0
    def rows(self):
        data = SMS.by_domain(self.domain,
                             start_date=self.datespan.startdate_utc,
                             end_date=self.datespan.enddate_utc).exclude(
                                 direction=OUTGOING,
                                 processed=False).order_by('date')

        if self.show_only_survey_traffic():
            data = data.filter(xforms_session_couch_id__isnull=False)

        result = []
        direction_map = {
            INCOMING: _("Incoming"),
            OUTGOING: _("Outgoing"),
        }
        message_bank_messages = get_message_bank(self.domain,
                                                 for_comparing=True)

        FormProcessorInterface(self.domain).casedb_cache(domain=self.domain,
                                                         strip_history=False,
                                                         deleted_ok=True)
        user_cache = UserCache()

        for message in data:
            # Add metadata from the message bank if it has not been added already
            if (message.direction == OUTGOING) and (
                    not message.fri_message_bank_lookup_completed):
                add_metadata(message, message_bank_messages)

            if message.couch_recipient_doc_type == "CommCareCase":
                recipient = case_cache.get(message.couch_recipient)
            else:
                recipient = user_cache.get(message.couch_recipient)

            if message.chat_user_id:
                sender = user_cache.get(message.chat_user_id)
            else:
                sender = None

            study_arm = None
            if message.couch_recipient_doc_type == "CommCareCase":
                study_arm = case_cache.get(
                    message.couch_recipient).get_case_property("study_arm")

            timestamp = ServerTime(message.date).user_time(
                self.timezone).done()
            result.append([
                self._fmt(self._participant_id(recipient)),
                self._fmt(study_arm or "-"),
                self._fmt(self._originator(message, recipient, sender)),
                self._fmt_timestamp(timestamp),
                self._fmt(message.text),
                self._fmt(message.fri_id or "-"),
                self._fmt(direction_map.get(message.direction, "-")),
            ])
        return result
Exemplo n.º 12
0
def form_inline_display(form_id, timezone=pytz.utc):
    if form_id:
        try:
            form = XFormInstance.get(form_id)
            if form:
                return "%s: %s" % (ServerTime(form.received_on).user_time(timezone).done().date(), form.xmlns)
        except ResourceNotFound:
            pass
        return "%s: %s" % (_("missing form"), form_id)
    return _("empty form id found")
Exemplo n.º 13
0
 def rows(self):
     events = self._get_queryset()[self.pagination.start:self.pagination.
                                   end]
     for event in events:
         yield [
             event.user,
             ServerTime(event.event_date).user_time(
                 self.timezone).ui_string(),
             self._event_formatter.display(event),
         ]
Exemplo n.º 14
0
def report_date_to_json(request, domain, date, is_phonetime=True):
    timezone = get_timezone(request, domain)
    if date:
        if is_phonetime:
            user_time = PhoneTime(date, timezone).user_time(timezone)
        else:
            user_time = ServerTime(date).user_time(timezone)
        user_time.ui_string(SERVER_DATETIME_FORMAT)
    else:
        return ''
Exemplo n.º 15
0
 def test_server_to_user(self):
     cases = [
         ('2015-03-20T12:00:00', pytz.FixedOffset(-4 * 60),
          '2015-03-20T08:00:00-04:00'),
         ('2015-03-21T00:30:00', pytz.FixedOffset(-4 * 60),
          '2015-03-20T20:30:00-04:00'),
     ]
     for in_, tz, out in cases:
         server_dt = dateutil.parser.parse(in_)
         user_dt = ServerTime(server_dt).user_time(tz).done()
         self.assertEqual(user_dt.isoformat(), out)
Exemplo n.º 16
0
 def _format_rule(self, rule):
     return {
         'id': rule.pk,
         'name': rule.name,
         'case_type': rule.case_type,
         'active': rule.active,
         'last_run': (ServerTime(rule.last_run)
                      .user_time(self.project_timezone)
                      .done()
                      .strftime(SERVER_DATETIME_FORMAT)) if rule.last_run else '-',
         'edit_url': reverse(EditCaseRuleView.urlname, args=[self.domain, rule.pk]),
     }
Exemplo n.º 17
0
    def rows(self):
        def form_data_link(instance_id):
            return "<a class='ajax_dialog' target='_new' href='%(url)s'>%(text)s</a>" % {
                "url":
                absolute_reverse('render_form_data',
                                 args=[self.domain, instance_id]),
                "text":
                _("View Form")
            }

        submissions = [
            res['_source']
            for res in self.es_results.get('hits', {}).get('hits', [])
        ]

        for form in submissions:
            uid = form["form"]["meta"]["userID"]
            username = form["form"]["meta"].get("username")
            try:
                if username not in ['demo_user', 'admin']:
                    full_name = get_cached_property(CouchUser,
                                                    uid,
                                                    'full_name',
                                                    expiry=7 * 24 * 60 * 60)
                    name = '"%s"' % full_name if full_name else ""
                else:
                    name = ""
            except (ResourceNotFound, IncompatibleDocument):
                name = "<b>[unregistered]</b>"

            time = iso_string_to_datetime(
                safe_index(form, self.time_field.split('.')))
            if self.by_submission_time:
                user_time = ServerTime(time).user_time(self.timezone)
            else:
                user_time = PhoneTime(time,
                                      self.timezone).user_time(self.timezone)

            init_cells = [
                form_data_link(form["_id"]),
                (username or _('No data for username')) +
                (" %s" % name if name else ""),
                user_time.ui_string(USER_DATETIME_FORMAT_WITH_SEC),
                xmlns_to_name(self.domain,
                              form.get("xmlns"),
                              app_id=form.get("app_id")),
            ]

            def cell(field):
                return form["form"].get(field)

            init_cells.extend([cell(field) for field in self.other_fields])
            yield init_cells
Exemplo n.º 18
0
def get_display_data(data, prop_def, processors=None, timezone=pytz.utc):
    # when prop_def came from a couchdbkit document, it will be a LazyDict with
    # a broken pop method.  This conversion also has the effect of a shallow
    # copy, which we want.
    prop_def = dict(prop_def)

    default_processors = {
        'yesno':
        yesno,
        'doc_info':
        lambda value: pretty_doc_info(get_doc_info_by_id(
            data['domain'], value))
    }
    processors = processors or {}
    processors.update(default_processors)

    expr_name = _get_expr_name(prop_def)
    expr = prop_def.pop('expr')
    name = prop_def.pop('name', None) or _format_slug_string_for_display(expr)
    format = prop_def.pop('format', None)
    process = prop_def.pop('process', None)
    timeago = prop_def.get('timeago', False)
    has_history = prop_def.pop('has_history', False)

    val = eval_expr(expr, data)

    if prop_def.pop('parse_date', None):
        val = _parse_date_or_datetime(val)
    # is_utc is deprecated in favor of is_phone_time
    # but preserving here for backwards compatibility
    # is_utc = False is just reinterpreted as is_phone_time = True
    is_phone_time = prop_def.pop('is_phone_time',
                                 not prop_def.pop('is_utc', True))
    if isinstance(val, datetime.datetime):
        if not is_phone_time:
            val = ServerTime(val).user_time(timezone).done()
        else:
            val = PhoneTime(val, timezone).user_time(timezone).done()

    try:
        val = conditional_escape(processors[process](val))
    except KeyError:
        val = mark_safe(_to_html(val, timeago=timeago))
    if format:
        val = mark_safe(format.format(val))

    return {
        "expr": expr_name,
        "name": name,
        "value": val,
        "has_history": has_history,
    }
Exemplo n.º 19
0
 def options(self):
     timezone = get_timezone_for_user(self.request.couch_user, self.domain)
     records = UserUploadRecord.objects.filter(domain=self.domain).order_by('-date_created')
     return [
         (
             str(record.id),
             _("Upload by {username} at {time}").format(
                 username=cached_user_id_to_user_display(record.user_id),
                 time=ServerTime(record.date_created).user_time(timezone).ui_string(USER_DATETIME_FORMAT)
             )
         )
         for record in records
     ]
Exemplo n.º 20
0
 def rendered_report_title(self):
     new_title = self.name
     if self.errors_only:
         new_title = format_html(
             "Errors &amp; Warnings Log <small>for {}</small>", ", ".join(
                 self.device_log_users)
         ) if self.device_log_users else "Errors & Warnings Log"
     elif self.goto_key:
         log = self.goto_log
         new_title = format_html(
             "Last {} Logs <small>before {}</small>", self.limit,
             ServerTime(log.date).user_time(self.timezone).ui_string())
     return new_title
Exemplo n.º 21
0
 def rendered_report_title(self):
     new_title = self.name
     if self.errors_only:
         new_title = ("Errors &amp; Warnings Log <small>for %s</small>" %
                      (", ".join(self.device_log_users))
                      if self.device_log_users else
                      "Errors &amp; Warnings Log")
     elif self.goto_key:
         log = self.goto_log
         new_title = "Last %s Logs <small>before %s</small>" % (
             self.limit, ServerTime(log.date).user_time(
                 self.timezone).ui_string())
     return mark_safe(new_title)
Exemplo n.º 22
0
 def _format_rule(self, rule):
     return {
         'id': rule.pk,
         'name': rule.name,
         'case_type': rule.case_type,
         'active': rule.active,
         'last_run': (ServerTime(rule.last_run)
                      .user_time(self.project_timezone)
                      .done()
                      .strftime(SERVER_DATETIME_FORMAT)) if rule.last_run else '-',
         'edit_url': reverse(EditCaseRuleView.urlname, args=[self.domain, rule.pk]),
         'action_error': "",     # must be provided because knockout template looks for it
     }
Exemplo n.º 23
0
    def rows(self):
        startdate = json_format_datetime(self.datespan.startdate_utc)
        enddate = json_format_datetime(self.datespan.enddate_utc)
        data = SMSLog.by_domain_date(self.domain, startdate, enddate)
        result = []

        reporting_locations_id = self.get_location_filter(
        ) if self.uses_locations else []
        # Retrieve message log options
        message_log_options = getattr(settings, "MESSAGE_LOG_OPTIONS", {})
        abbreviated_phone_number_domains = message_log_options.get(
            "abbreviated_phone_number_domains", [])
        abbreviate_phone_number = (self.domain
                                   in abbreviated_phone_number_domains)

        contact_cache = {}
        message_type_filter = self.get_message_type_filter()

        for message in data:
            if message.direction == OUTGOING and not message.processed:
                continue

            message_types = self._get_message_types(message)
            if not message_type_filter(message_types):
                continue

            if reporting_locations_id and message.location_id not in reporting_locations_id:
                continue

            doc_info = self.get_recipient_info(
                message.couch_recipient_doc_type, message.couch_recipient,
                contact_cache)

            phone_number = message.phone_number
            if abbreviate_phone_number and phone_number is not None:
                phone_number = phone_number[0:7] if phone_number[
                    0:1] == "+" else phone_number[0:6]

            timestamp = ServerTime(message.date).user_time(
                self.timezone).done()
            result.append([
                self._fmt_timestamp(timestamp),
                self._fmt_contact_link(message.couch_recipient, doc_info),
                self._fmt(phone_number),
                self._fmt_direction(message.direction),
                self._fmt(message.text),
                self._fmt(", ".join(message_types)),
            ])

        return result
Exemplo n.º 24
0
    def default_datespan(self):
        # DateSpan.since() will make enddate default to yesterday when it's None
        enddate = None
        if self.default_datespan_end_date_to_today:
            enddate = ServerTime(datetime.utcnow()).user_time(
                self.timezone).done().date()

        datespan = DateSpan.since(self.datespan_default_days,
                                  enddate=enddate,
                                  inclusive=self.inclusive,
                                  timezone=self.timezone)
        datespan.max_days = self.datespan_max_days
        datespan.is_default = True
        return datespan
Exemplo n.º 25
0
def should_sync(domain, last_sync, utcnow=None):
    # definitely sync if we haven't synced before
    if not last_sync or not last_sync.date:
        return True

    # utcnow only used in tests to mock other times
    utcnow = utcnow or datetime.utcnow()

    try:
        timezone = domain.get_default_timezone()
    except pytz.UnknownTimeZoneError:
        timezone = utc

    last_sync_utc = last_sync.date

    # check if user has already synced today (in local timezone).
    # Indicators only change daily.
    last_sync_local = ServerTime(last_sync_utc).user_time(timezone).done()
    current_date_local = ServerTime(utcnow).user_time(timezone).done()

    if current_date_local.date() != last_sync_local.date():
        return True

    return False
Exemplo n.º 26
0
 def test_server_to_phone(self):
     cases = [
         ('2015-03-20T12:00:00', pytz.FixedOffset(-4 * 60),
          '2015-03-20T08:00:00'),
         ('2015-03-21T00:30:00', pytz.FixedOffset(-4 * 60),
          '2015-03-20T20:30:00'),
     ]
     for in_, tz, out in cases:
         server_dt = dateutil.parser.parse(in_)
         phone_dt = ServerTime(server_dt).phone_time(tz).done()
         if phone_timezones_have_been_processed():
             # no change
             self.assertEqual(phone_dt.isoformat(), in_)
         else:
             self.assertEqual(phone_dt.isoformat(), out)
Exemplo n.º 27
0
 def rows(self):
     result = []
     xforms_session = self.xforms_session
     for sms in SMS.objects.filter(xforms_session_couch_id=xforms_session.couch_id):
         timestamp = ServerTime(sms.date).user_time(self.timezone).done()
         status = self.get_sms_status_display(sms)
         result.append([
             self._fmt_timestamp(timestamp),
             self._fmt(sms.text),
             self._fmt(sms.phone_number),
             self._fmt_direction(sms.direction),
             self._fmt(sms.backend_api),
             self._fmt(status),
         ])
     return result
Exemplo n.º 28
0
 def check_obs_props(obs, props):
     for k, v in props.items():
         if k.endswith("_date"):
             # datetime check
             obs_datetime = getattr(obs, k)
             val_datetime = dateutil.parser.parse(v)
             if k in ('completed_date', 'created_date'):
                 obs_datetime = ServerTime(obs_datetime).user_time(PACT_TIMEZONE).done()
             obs_date = obs_datetime.date()
             val_date = val_datetime.date()
             self.assertEquals(obs_date, val_date)
         else:
             self.assertEquals(getattr(obs, k), v,
                               msg="Error, observation %s\n\t%s didn't match: %s != %s" % (
                               json.dumps(obs.to_json(), indent=4), k, getattr(obs, k),
                               v))
Exemplo n.º 29
0
 def rows(self):
     data = (SMS.by_domain(self.config['domain']).filter(
         location_id=self.config['location_id']).exclude(
             processed=False, direction=OUTGOING).order_by('-date'))
     messages = []
     for message in data:
         recipient = message.recipient
         timestamp = ServerTime(message.date).user_time(
             self.config['timezone']).done()
         messages.append([
             _fmt_timestamp(timestamp),
             recipient.full_name,
             message.phone_number,
             _fmt(message.direction),
             _fmt(message.text),
         ])
     return messages
Exemplo n.º 30
0
    def __init__(self, domain_object=None):
        self.domain_object = domain_object

        if domain_object:
            self.date = ServerTime(datetime.utcnow()).user_time(
                domain_object.get_default_timezone()).done().date()
        else:
            self.date = datetime.utcnow().date()

        self.key = 'outbound-daily-count-for-%s-%s' % (
            domain_object.name if domain_object else '',
            self.date.strftime('%Y-%m-%d'))

        # We need access to the raw redis client because calling incr on
        # a django_redis RedisCache object raises an error if the key
        # doesn't exist.
        self.client = get_redis_client().client.get_client()