def timesince(d, now=None, reversed=False, time_strings=None): """ Take two datetime objects and return the time between d and now as a nicely formatted string, e.g. "10 minutes". If d occurs after now, return "0 minutes". Units used are years, months, weeks, days, hours, and minutes. Seconds and microseconds are ignored. Up to two adjacent units will be displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not. `time_strings` is an optional dict of strings to replace the default TIME_STRINGS dict. Adapted from https://web.archive.org/web/20060617175230/http://blog.natbat.co.uk/archive/2003/Jun/14/time_since """ if time_strings is None: time_strings = TIME_STRINGS # Convert datetime.date to datetime.datetime for comparison. if not isinstance(d, datetime.datetime): d = datetime.datetime(d.year, d.month, d.day) if now and not isinstance(now, datetime.datetime): now = datetime.datetime(now.year, now.month, now.day) now = now or datetime.datetime.now(utc if is_aware(d) else None) if reversed: d, now = now, d delta = now - d # Deal with leapyears by subtracing the number of leapdays leapdays = calendar.leapdays(d.year, now.year) if leapdays != 0: if calendar.isleap(d.year): leapdays -= 1 elif calendar.isleap(now.year): leapdays += 1 delta -= datetime.timedelta(leapdays) # ignore microseconds since = delta.days * 24 * 60 * 60 + delta.seconds if since <= 0: # d is in the future compared to now, stop processing. return avoid_wrapping(gettext('0 minutes')) for i, (seconds, name) in enumerate(TIMESINCE_CHUNKS): count = since // seconds if count != 0: break result = avoid_wrapping(time_strings[name] % count) if i + 1 < len(TIMESINCE_CHUNKS): # Now get the second item seconds2, name2 = TIMESINCE_CHUNKS[i + 1] count2 = (since - (seconds * count)) // seconds2 if count2 != 0: result += gettext(', ') + avoid_wrapping( time_strings[name2] % count2) return result
def inline_formset_data(self): verbose_name = self.opts.verbose_name return json.dumps({ 'name': '#%s' % self.formset.prefix, 'options': { 'prefix': self.formset.prefix, 'addText': gettext('Add another %(verbose_name)s') % { 'verbose_name': capfirst(verbose_name), }, 'deleteText': gettext('Remove'), } })
def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_max_show_all, list_editable, model_admin, sortable_by): self.model = model self.opts = model._meta self.lookup_opts = self.opts self.root_queryset = model_admin.get_queryset(request) self.list_display = list_display self.list_display_links = list_display_links self.list_filter = list_filter self.date_hierarchy = date_hierarchy self.search_fields = search_fields self.list_select_related = list_select_related self.list_per_page = list_per_page self.list_max_show_all = list_max_show_all self.model_admin = model_admin self.preserved_filters = model_admin.get_preserved_filters(request) self.sortable_by = sortable_by # Get search parameters from the query string. try: self.page_num = int(request.GET.get(PAGE_VAR, 0)) except ValueError: self.page_num = 0 self.show_all = ALL_VAR in request.GET self.is_popup = IS_POPUP_VAR in request.GET to_field = request.GET.get(TO_FIELD_VAR) if to_field and not model_admin.to_field_allowed(request, to_field): raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) self.to_field = to_field self.params = dict(request.GET.items()) if PAGE_VAR in self.params: del self.params[PAGE_VAR] if ERROR_FLAG in self.params: del self.params[ERROR_FLAG] if self.is_popup: self.list_editable = () else: self.list_editable = list_editable self.query = request.GET.get(SEARCH_VAR, '') self.queryset = self.get_queryset(request) self.get_results(request) if self.is_popup: title = gettext('Select %s') elif self.model_admin.has_change_permission(request): title = gettext('Select %s to change') else: title = gettext('Select %s to view') self.title = title % self.opts.verbose_name self.pk_attname = self.lookup_opts.pk.attname
def yesno(value, arg=None): """ Given a string mapping values for true, false, and (optionally) None, return one of those strings according to the value: ========== ====================== ================================== Value Argument Outputs ========== ====================== ================================== ``True`` ``"yeah,no,maybe"`` ``yeah`` ``False`` ``"yeah,no,maybe"`` ``no`` ``None`` ``"yeah,no,maybe"`` ``maybe`` ``None`` ``"yeah,no"`` ``"no"`` (converts None to False if no mapping for None is given. ========== ====================== ================================== """ if arg is None: arg = gettext('yes,no,maybe') bits = arg.split(',') if len(bits) < 2: return value # Invalid arg. try: yes, no, maybe = bits except ValueError: # Unpack list of wrong size (no "maybe" value provided). yes, no, maybe = bits[0], bits[1], bits[1] if value is None: return maybe if value: return yes return no
def filesizeformat(bytes_): """ Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102 bytes, etc.). """ try: bytes_ = float(bytes_) except (TypeError, ValueError, UnicodeDecodeError): value = ngettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0} return avoid_wrapping(value) def filesize_number_format(value): return formats.number_format(round(value, 1), 1) KB = 1 << 10 MB = 1 << 20 GB = 1 << 30 TB = 1 << 40 PB = 1 << 50 negative = bytes_ < 0 if negative: bytes_ = -bytes_ # Allow formatting of negative numbers. if bytes_ < KB: value = ngettext("%(size)d byte", "%(size)d bytes", bytes_) % { 'size': bytes_ } elif bytes_ < MB: value = gettext("%s KB") % filesize_number_format(bytes_ / KB) elif bytes_ < GB: value = gettext("%s MB") % filesize_number_format(bytes_ / MB) elif bytes_ < TB: value = gettext("%s GB") % filesize_number_format(bytes_ / GB) elif bytes_ < PB: value = gettext("%s TB") % filesize_number_format(bytes_ / TB) else: value = gettext("%s PB") % filesize_number_format(bytes_ / PB) if negative: value = "-%s" % value return avoid_wrapping(value)
def render(self, context, nested=False): if self.message_context: message_context = self.message_context.resolve(context) else: message_context = None tmp_context = {} for var, val in self.extra_context.items(): tmp_context[var] = val.resolve(context) # Update() works like a push(), so corresponding context.pop() is at # the end of function context.update(tmp_context) singular, vars = self.render_token_list(self.singular) if self.plural and self.countervar and self.counter: count = self.counter.resolve(context) context[self.countervar] = count plural, plural_vars = self.render_token_list(self.plural) if message_context: result = translation.npgettext(message_context, singular, plural, count) else: result = translation.ngettext(singular, plural, count) vars.extend(plural_vars) else: if message_context: result = translation.pgettext(message_context, singular) else: result = translation.gettext(singular) default_value = context.template.engine.string_if_invalid def render_value(key): if key in context: val = context[key] else: val = default_value % key if '%s' in default_value else default_value return render_value_in_context(val, context) data = {v: render_value(v) for v in vars} context.pop() try: result = result % data except (KeyError, ValueError): if nested: # Either string is malformed, or it's a bug raise TemplateSyntaxError( "'blocktrans' is unable to format string returned by gettext: %r using %r" % (result, data)) with translation.override(None): result = self.render(context, nested=True) if self.asvar: context[self.asvar] = result return '' else: return result
def language_name_translated(lang_code): english_name = translation.get_language_info(lang_code)['name'] return translation.gettext(english_name)
def render(self, context): context[self.variable] = [(k, translation.gettext(v)) for k, v in settings.LANGUAGES] return ''
def user_change_password(self, request, id, form_url=''): if not self.has_change_permission(request): raise PermissionDenied user = self.get_object(request, unquote(id)) if user is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': self.model._meta.verbose_name, 'key': escape(id), }) if request.method == 'POST': form = self.change_password_form(user, request.POST) if form.is_valid(): form.save() change_message = self.construct_change_message( request, form, None) self.log_change(request, user, change_message) msg = gettext('Password changed successfully.') messages.success(request, msg) update_session_auth_hash(request, form.user) return HttpResponseRedirect( reverse( '%s:%s_%s_change' % ( self.admin_site.name, user._meta.app_label, user._meta.model_name, ), args=(user.pk, ), )) else: form = self.change_password_form(user) fieldsets = [(None, {'fields': list(form.base_fields)})] adminForm = admin.helpers.AdminForm(form, fieldsets, {}) context = { 'title': _('Change password: %s') % escape(user.get_username()), 'adminForm': adminForm, 'form_url': form_url, 'form': form, 'is_popup': (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), 'add': True, 'change': False, 'has_delete_permission': False, 'has_change_permission': True, 'has_absolute_url': False, 'opts': self.model._meta, 'original': user, 'save_as': False, 'show_save': True, **self.admin_site.each_context(request), } request.current_app = self.admin_site.name return TemplateResponse( request, self.change_user_password_template or 'admin/auth/user/change_password.html', context, )