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), }
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)
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 _assert = soft_assert(to=['droberts' + '@' + 'dimagi.com']) last_sync_utc = last_sync.date if not _assert(last_sync_utc.tzinfo is None, 'last_sync.date should be an offset-naive dt'): last_sync_utc = UserTime(last_sync_utc).server_time().done() # 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
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)
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_) if get_timezone_data_migration_complete(): phone_dt = server_dt else: phone_dt = ServerTime(server_dt).phone_time(tz).done() self.assertEqual(phone_dt.isoformat(), out)
def _update_tech_issue_for_escalation(case, escalated_ticket_level): today = ServerTime(datetime.utcnow()).user_time(pytz.timezone('Asia/Kolkata')).done().date() return update_case( case.domain, case.case_id, case_properties={ 'ticket_level': escalated_ticket_level, 'change_in_level': '1', 'touch_case_date': today.strftime('%Y-%m-%d'), }, close=False, xmlns=AUTO_UPDATE_XMLNS, device_id=__name__ + "._update_tech_issue_for_escalation", )
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)
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))
def midnights(self, utcnow=None): """Returns a list containing two datetimes in UTC that corresponds to midnight in the domains timezone on either side of the current UTC datetime. i.e. [<previous midnight in TZ>, <next midnight in TZ>] >>> d = DomainLite('', 'Asia/Kolkata', '', True) >>> d.midnights(datetime(2015, 8, 27, 18, 30, 0 )) [datetime.datetime(2015, 8, 26, 18, 30), datetime.datetime(2015, 8, 27, 18, 30)] >>> d.midnights(datetime(2015, 8, 27, 18, 31, 0 )) [datetime.datetime(2015, 8, 27, 18, 30), datetime.datetime(2015, 8, 28, 18, 30)] """ utcnow = utcnow or datetime.utcnow() tz = pytz.timezone(self.default_timezone) current_time_tz = ServerTime(utcnow).user_time(tz).done() midnight_tz1 = current_time_tz.replace(hour=0, minute=0, second=0, microsecond=0) midnight_tz_utc1 = UserTime(midnight_tz1).server_time().done() midnight_tz_utc2 = midnight_tz_utc1 + timedelta(days=(1 if midnight_tz_utc1 < utcnow else -1)) return sorted([midnight_tz_utc1, midnight_tz_utc2])
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
def broadcast_form(self): if self.request.method == "POST": return self.form_class(self.request.POST, **self.form_kwargs) broadcast = self.broadcast start_user_time = ServerTime(broadcast.start_datetime).user_time(self.project_timezone) initial = { "timing": SEND_LATER, "date": start_user_time.ui_string("%Y-%m-%d"), "time": start_user_time.ui_string("%H:%M"), "recipient_type": broadcast.recipient, "case_group_id": broadcast.sample_id, "user_group_id": broadcast.user_group_id, "content_type": broadcast.method, "message": broadcast.events[0].message.get(broadcast.default_lang, None), "subject": broadcast.events[0].subject.get(broadcast.default_lang, None), "form_unique_id": broadcast.events[0].form_unique_id, "location_ids": ",".join(broadcast.location_ids), "include_child_locations": broadcast.include_child_locations, } if toggles.EWS_BROADCAST_BY_ROLE.enabled(self.domain): initial["role"] = broadcast.user_data_filter.get("role", [None])[0] return self.form_class(initial=initial, **self.form_kwargs)
def broadcast_form(self): if self.request.method == 'POST': return self.form_class(self.request.POST, **self.form_kwargs) broadcast = self.broadcast start_user_time = ServerTime(broadcast.start_datetime).user_time(self.project_timezone) initial = { 'timing': SEND_LATER, 'date': start_user_time.ui_string('%Y-%m-%d'), 'time': start_user_time.ui_string('%H:%M'), 'recipient_type': broadcast.recipient, 'case_group_id': broadcast.sample_id, 'user_group_id': broadcast.user_group_id, 'content_type': broadcast.method, 'message': broadcast.events[0].message.get(broadcast.default_lang, None), 'subject': broadcast.events[0].subject.get(broadcast.default_lang, None), 'form_unique_id': broadcast.events[0].form_unique_id, 'location_ids': ','.join(broadcast.location_ids), 'include_child_locations': broadcast.include_child_locations, } if toggles.EWS_BROADCAST_BY_ROLE.enabled(self.domain): initial['role'] = broadcast.user_data_filter.get('role', [None])[0] return self.form_class(initial=initial, **self.form_kwargs)
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
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()
def get_current_date(): return ServerTime(datetime.utcnow()).user_time( pytz.timezone('Asia/Kolkata')).done().date()
def rows(self): group_id = None if self.request.couch_user.is_commcare_user(): group_ids = self.request.couch_user.get_group_ids() if len(group_ids) > 0: group_id = group_ids[0] data = {} for case in get_cases_in_domain(self.domain, type='participant'): if case.closed: continue # If a site coordinator is viewing the report, only show participants from that site (group) if group_id is None or group_id == case.owner_id: timezone = pytz.timezone(case.get_case_property("time_zone")) data[case._id] = { "name": case.name, "time_zone": timezone, "dates": [None] * 14, } dates = self.get_past_two_weeks() date_strings = [json_format_date(date) for date in dates] start_date = dates[0] - timedelta(days=1) end_date = dates[-1] + timedelta(days=2) start_utc_timestamp = json_format_date(start_date) end_utc_timestamp = json_format_date(end_date) expected_callback_events = ExpectedCallbackEventLog.view( "sms/expected_callback_event", startkey=[self.domain, start_utc_timestamp], endkey=[self.domain, end_utc_timestamp], include_docs=True).all() for event in expected_callback_events: if event.couch_recipient in data: timezone = data[event.couch_recipient]["time_zone"] event_date = (ServerTime( event.date).user_time(timezone).ui_string("%Y-%m-%d")) if event_date in date_strings: data[event.couch_recipient]["dates"][date_strings.index( event_date)] = event.status result = [] for case_id, data_dict in data.items(): row = [ self._fmt(data_dict["name"]), None, None, None, ] total_no_response = 0 total_indicated = 0 total_pending = 0 for date_status in data_dict["dates"]: if date_status == CALLBACK_PENDING: total_indicated += 1 total_pending += 1 row.append(self._fmt(_("pending"))) elif date_status == CALLBACK_RECEIVED: total_indicated += 1 row.append(self._fmt(_("OK"))) elif date_status == CALLBACK_MISSED: total_indicated += 1 total_no_response += 1 row.append(self._fmt_highlight(_("No Response"))) else: row.append(self._fmt(_("not indicated"))) if total_no_response > 0: row[1] = self._fmt_highlight(total_no_response) else: row[1] = self._fmt(total_no_response) row[2] = self._fmt(total_indicated) row[3] = self._fmt(total_pending) result.append(row) return result
def server_to_user_time(server_time, timezone): user_time = ServerTime(server_time).user_time(timezone).done() return user_time.strftime("%Y-%m-%d %H:%M")
def adjust_next_fire_to_timezone(reminder_utc): return ServerTime(reminder_utc.next_fire).user_time(timezone).done().replace(tzinfo=None)
def get_timestamp(): return ServerTime(datetime.utcnow()).user_time( pytz.timezone('Asia/Kolkata')).done()
def _create_rows(self, logs, matching_id=None): _device_users_by_xform = memoized(device_users_by_xform) row_set = [] user_query = self._filter_query_by_slug(DeviceLogUsersFilter.slug) device_query = self._filter_query_by_slug(DeviceLogDevicesFilter.slug) paged = slice(self.pagination.start, self.pagination.start + self.pagination.count + 1) self.total_records = logs.count() for log in logs.order_by(self.ordering)[paged]: ui_date = (ServerTime(log.date) .user_time(self.timezone).ui_string()) username = log.username username_fmt = '<a href="%(url)s">%(username)s</a>' % { "url": "%s?%s=%s&%s" % ( self.get_url(domain=self.domain), DeviceLogUsersFilter.slug, DeviceLogUsersFilter.value_to_param(username), user_query, ), "username": ( username if username else '<span class="label label-info">Unknown</span>' ) } device_users = _device_users_by_xform(log.xform_id) device_users_fmt = ', '.join([ '<a href="%(url)s">%(username)s</a>' % { "url": "%s?%s=%s&%s" % (self.get_url(domain=self.domain), DeviceLogUsersFilter.slug, username, user_query), "username": username, } for username in device_users ]) log_tag = log.type or 'unknown' tag_classes = ["label"] if log_tag in self.tag_labels: tag_classes.append(self.tag_labels[log_tag]) log_tag_format = ( '<a href="%(url)s" class="%(classes)s"%(extra_params)s ' 'data-datatable-tooltip="right" ' 'data-datatable-tooltip-text="%(tooltip)s">%(text)s</a>' ) % { "url": "%s?goto=%s" % (self.get_url(domain=self.domain), html.escape(json.dumps(log.id))), "classes": " ".join(tag_classes), "text": log_tag, "extra_params": (' data-datatable-highlight-closest="tr"' if log.id == matching_id else ''), "tooltip": "Show the surrounding 100 logs." } device = log.device_id device_fmt = '<a href="%(url)s">%(device)s</a>' % { "url": "%s?%s=%s&%s" % (self.get_url(domain=self.domain), DeviceLogDevicesFilter.slug, device, device_query), "device": device } version = log.app_version or "unknown" ver_format = ( '%s <a href="#" data-datatable-tooltip="left" ' 'data-datatable-tooltip-text="%s">' '<i class="icon icon-info-sign"></i></a>' ) % (version.split(' ')[0], html.escape(version)) row_set.append([ui_date, log_tag_format, username_fmt, device_users_fmt, device_fmt, log.msg, ver_format]) return row_set
def _create_row(self, log, matching_id, _device_users_by_xform, user_query, device_query): log_date = (ServerTime(log.date).user_time(self.timezone).ui_string()) server_date = (ServerTime(log.server_date).user_time( self.timezone).ui_string()) username = log.username username_fmt = self._username_fmt % { "url": "%s?%s=%s&%s" % ( self.get_url(domain=self.domain), DeviceLogUsersFilter.slug, DeviceLogUsersFilter.value_to_param(username), user_query, ), "username": (username if username else '<span class="label label-info">Unknown</span>') } device_users = _device_users_by_xform(log.xform_id) device_users_fmt = ', '.join([ self._device_users_fmt % { "url": "%s?%s=%s&%s" % (self.get_url(domain=self.domain), DeviceLogUsersFilter.slug, device_username, user_query), "username": device_username, } for device_username in device_users ]) log_tag = log.type or 'unknown' tag_classes = ["label"] if log_tag in self.tag_labels: tag_classes.append(self.tag_labels[log_tag]) if len(tag_classes) == 1: tag_classes.append('label-info') log_tag_format = self._log_tag_fmt % { "url": "%s?goto=%s" % (self.get_url(domain=self.domain), html.escape(json.dumps(log.id))), "classes": " ".join(tag_classes), "text": log_tag, "extra_params": (' data-datatable-highlight-closest="tr"' if log.id == matching_id else ''), "tooltip": "Show the surrounding 100 logs." } device = log.device_id device_fmt = self._device_id_fmt % { "url": "%s?%s=%s&%s" % (self.get_url(domain=self.domain), DeviceLogDevicesFilter.slug, device, device_query), "device": device } app_version = get_version_from_appversion_text( log.app_version) or "unknown" commcare_version = get_commcare_version_from_appversion_text( log.app_version) or "unknown" return [ log_date, server_date, log_tag_format, username_fmt, device_users_fmt, device_fmt, log.msg, app_version, commcare_version ]
def test_utc_phonetime(self): dt = datetime.datetime.utcnow() self.assertEqual( PhoneTime(dt, pytz.UTC).user_time(pytz.FixedOffset(9 * 60 + 30)).done(), ServerTime(dt).user_time(pytz.FixedOffset(9 * 60 + 30)).done())
def get_today_for_recipient(self, schedule): return ServerTime(util.utcnow()).user_time( self.get_timezone(schedule)).done().date()
def test_ui_string(self): now = datetime.datetime.utcnow() user_time = ServerTime(now).user_time(pytz.FixedOffset(-4 * 60)) self.assertEqual(user_time.ui_string(), user_time.done().strftime(USER_DATETIME_FORMAT))
def _fmt_date(somedate): time = ServerTime(somedate).user_time(self.timezone).done() return time.strftime(SERVER_DATETIME_FORMAT)
def is_first_week_of_month(): day = ServerTime(datetime.utcnow()).user_time(pytz.timezone('Asia/Kolkata')).done().day return day >= 1 and day <= 7
def download_file(request, domain, app_id, path): download_target_version = request.GET.get('download_target_version') == 'true' if download_target_version: parts = path.split('.') assert len(parts) == 2 target = Application.get(app_id).commcare_flavor assert target != 'none' path = parts[0] + '-' + target + '.' + parts[1] if path == "app.json": return JsonResponse(request.app.to_json()) content_type_map = { 'ccpr': 'commcare/profile', 'jad': 'text/vnd.sun.j2me.app-descriptor', 'jar': 'application/java-archive', 'xml': 'application/xml', 'txt': 'text/plain', } try: content_type = content_type_map[path.split('.')[-1]] except KeyError: content_type = None response = HttpResponse(content_type=content_type) if request.GET.get('download') == 'true': response['Content-Disposition'] = "attachment; filename={}".format(path) build_profile_id = _get_build_profile_id(request) build_profile_access = domain_has_privilege(domain, privileges.BUILD_PROFILES) if path in ('CommCare.jad', 'CommCare.jar'): set_file_download(response, path) full_path = path elif build_profile_id and build_profile_id in request.app.build_profiles and build_profile_access: full_path = 'files/%s/%s' % (build_profile_id, path) else: full_path = 'files/%s' % path def resolve_path(path): return RegexURLResolver( r'^', 'corehq.apps.app_manager.download_urls').resolve(path) def create_build_files(build_profile_id=None): request.app.create_build_files(build_profile_id=build_profile_id) request.app.save() def create_build_files_if_necessary_handling_conflicts(is_retry=False): try: try: # look for file guaranteed to exist if profile is created request.app.fetch_attachment('files/{id}/profile.xml'.format(id=build_profile_id)) except ResourceNotFound: create_build_files(build_profile_id) except ResourceConflict: if is_retry: raise request.app = Application.get(request.app.get_id) create_build_files_if_necessary_handling_conflicts(True) try: assert request.app.copy_of # create build files for default profile if they were not created during initial build # or for language profiles for which build files have not been created yet try: payload = request.app.fetch_attachment(full_path) except ResourceNotFound: if not build_profile_id: create_build_files() elif build_profile_id in request.app.build_profiles and build_profile_access: create_build_files_if_necessary_handling_conflicts() else: raise payload = request.app.fetch_attachment(full_path) if path in ['profile.xml', 'media_profile.xml']: payload = convert_XML_To_J2ME(payload, path, request.app.use_j2me_endpoint) response.write(payload) if path in ['profile.ccpr', 'media_profile.ccpr'] and request.app.last_released: last_released = request.app.last_released.replace(microsecond=0) # mobile doesn't want microseconds last_released = ServerTime(last_released).user_time(pytz.UTC).done().isoformat() response['X-CommCareHQ-AppReleasedOn'] = last_released response['Content-Length'] = len(response.content) return response except (ResourceNotFound, AssertionError): if request.app.copy_of: if request.META.get('HTTP_USER_AGENT') == 'bitlybot': raise Http404() elif path == 'profile.ccpr': # legacy: should patch build to add odk profile # which wasn't made on build for a long time add_odk_profile_after_build(request.app) request.app.save() return download_file(request, domain, app_id, path) elif path in ('CommCare.jad', 'CommCare.jar'): if not request.app.build_spec.supports_j2me(): raise Http404() request.app.create_jadjar_from_build_files(save=True) try: request.app.save(increment_version=False) except ResourceConflict: # Likely that somebody tried to download the jad and jar # files for the first time simultaneously. pass return download_file(request, domain, app_id, path) else: try: resolve_path(path) except Resolver404: # ok this was just a url that doesn't exist pass else: # this resource should exist but doesn't _assert = soft_assert('@'.join(['jschweers', 'dimagi.com'])) _assert(False, 'Expected build resource %s not found' % path) raise Http404() try: callback, callback_args, callback_kwargs = resolve_path(path) except Resolver404: raise Http404() return callback(request, domain, app_id, *callback_args, **callback_kwargs)
def format_date(datetime): return ServerTime(datetime).user_time( timezone('Africa/Dar_es_Salaam')).done().strftime('%Y-%m-%d %H:%M:%S')
def format_timestamp(self, utc_timestamp): ist_timestamp = ServerTime(utc_timestamp).user_time( self.timezone).done() return ist_timestamp.strftime('%Y-%m-%d %H:%M:%S')
def rows(self): data = Call.by_domain( self.domain, start_date=self.datespan.startdate_utc, end_date=self.datespan.enddate_utc).order_by('date') result = [] # Store the results of lookups for faster loading contact_cache = {} form_map = {} xforms_sessions = {} direction_map = { INCOMING: _("Incoming"), OUTGOING: _("Outgoing"), } # 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) for call in data: doc_info = self.get_recipient_info(call.couch_recipient_doc_type, call.couch_recipient, contact_cache) form_unique_id = call.form_unique_id if form_unique_id in [None, ""]: form_name = "-" elif form_unique_id in form_map: form_name = form_map.get(form_unique_id) else: form_name = get_form_name(form_unique_id) form_map[form_unique_id] = form_name phone_number = call.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(call.date).user_time(self.timezone).done() if call.direction == INCOMING: answered = "-" else: answered = _("Yes") if call.answered else _("No") if call.xforms_session_id: xforms_sessions[call.xforms_session_id] = None row = [ call.xforms_session_id, self._fmt_timestamp(timestamp), self._fmt_contact_link(call.couch_recipient, doc_info), self._fmt(phone_number), self._fmt(direction_map.get(call.direction, "-")), self._fmt(form_name), self._fmt("-"), self._fmt(answered), self._fmt(call.duration), self._fmt(_("Yes") if call.error else _("No")), self._fmt( cgi.escape(call.error_message) if call. error_message else None), ] if self.request.couch_user.is_previewer(): row.append(self._fmt(call.gateway_session_id)) result.append(row) all_session_ids = xforms_sessions.keys() session_submission_map = dict( SQLXFormsSession.objects.filter( session_id__in=all_session_ids).values_list( 'session_id', 'submission_id')) xforms_sessions.update(session_submission_map) # Add into the final result the link to the submission based on the # outcome of the above lookups. final_result = [] for row in result: final_row = row[1:] session_id = row[0] if session_id: submission_id = xforms_sessions[session_id] if submission_id: final_row[5] = self._fmt_submission_link(submission_id) final_result.append(final_row) return final_result
def todays_date(): return ServerTime(datetime.utcnow()).user_time( pytz.timezone('Asia/Kolkata')).done().date()
class OutboundDailyCounter(object): 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() def increment(self): # If the key doesn't exist, redis will set it to 0 and then increment. value = self.client.incr(self.key) # If it's the first time we're calling incr, set the key's expiration if value == 1: self.client.expire(self.key, 24 * 60 * 60) return value def decrement(self): return self.client.decr(self.key) @property def current_usage(self): current_usage = self.client.get(self.key) if isinstance(current_usage, bytes): current_usage = int(current_usage.decode('utf-8')) return current_usage or 0 @property def daily_limit(self): if self.domain_object: return self.domain_object.get_daily_outbound_sms_limit() else: # If the message isn't tied to a domain, still impose a limit. # Outbound messages not tied to a domain can happen when unregistered # contacts opt in or out from a gateway. return 10000 def can_send_outbound_sms(self, queued_sms): """ Returns False if the outbound daily limit has been exceeded. """ value = self.increment() if value > self.daily_limit: # Delay processing by an hour so that in case the # limit gets increased within the same day, we start # processing the backlog right away. self.decrement() delay_processing(queued_sms, 60) # Log the fact that we reached this limit DailyOutboundSMSLimitReached.create_for_domain_and_date( self.domain_object.name if self.domain_object else '', self.date ) return False return True
def _fmt_timestamp(self, timestamp): if not isinstance(timestamp, datetime): return '-' timestamp = ServerTime(timestamp).user_time(self.timezone).done() return timestamp.strftime(SERVER_DATETIME_FORMAT)
def format_broadcast_name(self, broadcast): user_time = ServerTime(broadcast.start_datetime).user_time(self.project_timezone) return user_time.ui_string(SERVER_DATETIME_FORMAT)
class OutboundDailyCounter(object): 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() def increment(self): # If the key doesn't exist, redis will set it to 0 and then increment. value = self.client.incr(self.key) # If it's the first time we're calling incr, set the key's expiration if value == 1: self.client.expire(self.key, 24 * 60 * 60) return value def decrement(self): return self.client.decr(self.key) @property def current_usage(self): return self.client.get(self.key) or 0 @property def daily_limit(self): if self.domain_object: return self.domain_object.get_daily_outbound_sms_limit() else: # If the message isn't tied to a domain, still impose a limit. # Outbound messages not tied to a domain can happen when unregistered # contacts opt in or out from a gateway. return 10000 def can_send_outbound_sms(self, queued_sms): """ Returns False if the outbound daily limit has been exceeded. """ value = self.increment() if value > self.daily_limit: # Delay processing by an hour so that in case the # limit gets increased within the same day, we start # processing the backlog right away. self.decrement() delay_processing(queued_sms, 60) # Log the fact that we reached this limit DailyOutboundSMSLimitReached.create_for_domain_and_date( self.domain_object.name if self.domain_object else '', self.date ) return False return True
change_in_level = '2' else: change_in_level = '1' return update_case( tech_issue_delegate.domain, tech_issue_delegate.case_id, case_properties={'change_in_level': change_in_level}, close=False, xmlns=AUTO_UPDATE_XMLNS, device_id=__name__ + "._update_existing_tech_issue_delegate", ) def _update_tech_issue_for_escalation(case, escalated_ticket_level): today = ServerTime(datetime.utcnow()).user_time( pytz.timezone('Asia/Kolkata')).done().date() return update_case( case.domain, case.case_id, case_properties={ 'ticket_level': escalated_ticket_level, 'change_in_level': '1', 'touch_case_date': today.strftime('%Y-%m-%d'), }, close=False, xmlns=AUTO_UPDATE_XMLNS, device_id=__name__ + "._update_tech_issue_for_escalation", )
def _format_date(self, date): if not date: return '---' return ServerTime(date).user_time(self.timezone).done().strftime(self.date_format)
def get_past_two_weeks(self): now = datetime.utcnow() local_datetime = ServerTime(now).user_time(self.timezone).done() return [(local_datetime + timedelta(days=x)).date() for x in range(-14, 0)]
def get_naive_user_datetime(date, timezone=None): if date and timezone: date = ServerTime(date).user_time(timezone).done().replace(tzinfo=None) return date
def domain_now(self): return ServerTime(datetime.utcnow()).user_time(self.timezone).done()
def _format_time(self, time): if not time: return '' user_time = ServerTime(time).user_time(self.project_timezone) return user_time.ui_string(SERVER_DATETIME_FORMAT)
def rows(self): result = [] contact_cache = {} messaging_event = self.get_messaging_event() for messaging_subevent in MessagingSubEvent.objects.filter( parent=messaging_event): doc_info = self.get_recipient_info( messaging_subevent.get_recipient_doc_type(), messaging_subevent.recipient_id, contact_cache) if messaging_subevent.content_type in ( MessagingEvent.CONTENT_SMS, MessagingEvent.CONTENT_SMS_CALLBACK): messages = SMS.objects.filter( messaging_subevent_id=messaging_subevent.pk) if len(messages) == 0: timestamp = ServerTime(messaging_subevent.date).user_time( self.timezone).done() status = self.get_status_display(messaging_subevent) result.append([ self._fmt_timestamp(timestamp), self._fmt_contact_link(messaging_subevent.recipient_id, doc_info), self._fmt('-'), self._fmt('-'), self._fmt_direction('-'), self._fmt('-'), self._fmt(status), ]) else: for sms in messages: timestamp = ServerTime(sms.date).user_time( self.timezone).done() status = self.get_status_display( messaging_subevent, sms) result.append([ self._fmt_timestamp(timestamp), self._fmt_contact_link( messaging_subevent.recipient_id, doc_info), self._fmt(sms.text), self._fmt(sms.phone_number), self._fmt_direction(sms.direction), self._fmt(sms.backend_api), self._fmt(status), ]) elif messaging_subevent.content_type in ( MessagingEvent.CONTENT_SMS_SURVEY, MessagingEvent.CONTENT_IVR_SURVEY): status = self.get_status_display(messaging_subevent) xforms_session = messaging_subevent.xforms_session timestamp = xforms_session.start_time if xforms_session else messaging_subevent.date timestamp = ServerTime(timestamp).user_time( self.timezone).done() result.append([ self._fmt_timestamp(timestamp), self._fmt_contact_link(messaging_subevent.recipient_id, doc_info), self.get_survey_detail_link(messaging_subevent), self._fmt('-'), self._fmt('-'), self._fmt('-'), self._fmt(status), ]) elif messaging_subevent.content_type == MessagingEvent.CONTENT_EMAIL: timestamp = ServerTime(messaging_subevent.date).user_time( self.timezone).done() status = self.get_status_display(messaging_subevent) result.append([ self._fmt_timestamp(timestamp), self._fmt_contact_link(messaging_subevent.recipient_id, doc_info), self._fmt('-'), self._fmt('-'), self._fmt_direction('-'), self._fmt('-'), self._fmt(status), ]) return result
def today_for_recipient(self): return ServerTime(util.utcnow()).user_time(self.timezone).done().date()
def _last_sync_time(domain, user_id): timezone = get_timezone_for_user(user_id, domain) return ServerTime(_utcnow()).user_time(timezone).done().isoformat()
def get_timestamp(date_): timestamp = ServerTime(date_).user_time(self.timezone).done() table_cell = self._fmt_timestamp(timestamp) return table_cell['html']
def format_timestamp(self, utc_timestamp): ist_timestamp = ServerTime(utc_timestamp).user_time(self.timezone).done() return ist_timestamp.strftime('%Y-%m-%d %H:%M:%S')