Example #1
0
def allow_delete_user(user_acl, target):
    newer_than = user_acl["can_delete_users_newer_than"]
    less_posts_than = user_acl["can_delete_users_with_less_posts_than"]
    if not newer_than and not less_posts_than:
        raise PermissionDenied(_("You can't delete users."))

    if user_acl["user_id"] == target.id:
        raise PermissionDenied(_("You can't delete your account."))
    if target.is_staff or target.is_superuser:
        raise PermissionDenied(_("You can't delete administrators."))

    if newer_than:
        if target.joined_on < timezone.now() - timedelta(days=newer_than):
            message = ngettext(
                "You can't delete users that are members for more than %(days)s day.",
                "You can't delete users that are members for more than %(days)s days.",
                newer_than,
            )
            raise PermissionDenied(message % {"days": newer_than})
    if less_posts_than:
        if target.posts > less_posts_than:
            message = ngettext(
                "You can't delete users that made more than %(posts)s post.",
                "You can't delete users that made more than %(posts)s posts.",
                less_posts_than,
            )
            raise PermissionDenied(message % {"posts": less_posts_than})
Example #2
0
def validate_post_length(settings, value):
    value_len = len(value)

    if not value_len:
        raise ValidationError(_("You have to enter a message."))

    if value_len < settings.post_length_min:
        # pylint: disable=line-too-long
        message = ngettext(
            "Posted message should be at least %(limit_value)s character long (it has %(show_value)s).",
            "Posted message should be at least %(limit_value)s characters long (it has %(show_value)s).",
            settings.post_length_min,
        )
        raise ValidationError(
            message % {"limit_value": settings.post_length_min, "show_value": value_len}
        )

    if settings.post_length_max and value_len > settings.post_length_max:
        # pylint: disable=line-too-long
        message = ngettext(
            "Posted message cannot be longer than %(limit_value)s character (it has %(show_value)s).",
            "Posted message cannot be longer than %(limit_value)s characters (it has %(show_value)s).",
            settings.post_length_max,
        )
        raise ValidationError(
            message % {"limit_value": settings.post_length_max, "show_value": value_len}
        )
 def form_valid(self, form):
     try:
         location_count = form.update_locations()
         if schedule_locations_update:
             message_parts = [
                 ngettext(
                     '%d prisoner location scheduled for upload.',
                     '%d prisoner locations scheduled for upload.',
                     location_count
                 ) % location_count,
                 _('You will receive an email notification if the upload fails.')
             ]
         else:
             message_parts = [
                 ngettext(
                     '%d prisoner location updated successfully',
                     '%d prisoner locations updated successfully',
                     location_count
                 ) % location_count,
             ]
         messages.info(self.request, ' '.join(message_parts))
         return super().form_valid(form)
     except forms.ValidationError as e:
         form.add_error(None, e)
         return self.form_invalid(form)
Example #4
0
    def get_tables(self):
        tournament = self.tournament

        teams = tournament.team_set.all().annotate(feedback_count=Count('debateteam__adjudicatorfeedback')).prefetch_related('speaker_set')
        team_table = TabbycatTableBuilder(
            view=self, title=_('From Teams'), sort_key='team')
        team_table.add_team_columns(teams)
        team_feedback_data = []
        for team in teams:
            count = team.feedback_count
            team_feedback_data.append({
                'text': ngettext("%(count)d feedback", "%(count)d feedbacks", count) % {'count': count},
                'link': reverse_tournament('adjfeedback-view-from-team',
                                           tournament,
                                           kwargs={'pk': team.id}),
            })
        team_table.add_column({'key': 'feedbacks', 'title': _("Feedbacks")}, team_feedback_data)

        adjs = tournament.adjudicator_set.all().annotate(feedback_count=Count('debateadjudicator__adjudicatorfeedback'))
        adj_table = TabbycatTableBuilder(
            view=self, title=_('From Adjudicators'), sort_key='name')
        adj_table.add_adjudicator_columns(adjs)
        adj_feedback_data = []
        for adj in adjs:
            count = adj.feedback_count
            adj_feedback_data.append({
                'text': ngettext("%(count)d feedback", "%(count)d feedbacks", count) % {'count': count},
                'link': reverse_tournament('adjfeedback-view-from-adjudicator',
                                           tournament,
                                           kwargs={'pk': adj.id}),
            })
        adj_table.add_column({'key': 'feedbacks', 'title': _("Feedbacks")}, adj_feedback_data)

        return [team_table, adj_table]
Example #5
0
    def post(self, request, *args, **kwargs):
        tournament = self.tournament

        nexisting_people = tournament.participants.filter(url_key__isnull=False).count()
        blank_people = tournament.participants.filter(url_key__isnull=True)
        nblank_people = blank_people.count()

        if nblank_people == 0:
            messages.error(self.request, _("All participants already have private URLs. "
                "If you want to delete them, use the Edit Database area."))

        else:
            populate_url_keys(blank_people)

            generated_urls_message = ngettext(
                "A private URL was generated for %(nblank_people)d person.",
                "Private URLs were generated for all %(nblank_people)d people.",
                nblank_people
            ) % {'nblank_people': nblank_people}
            non_generated_urls_message = ngettext(
                "The already-existing private URL for %(nexisting_people)d person was left intact.",
                "The already-existing private URLs for %(nexisting_people)d people were left intact",
                nexisting_people
            ) % {'nexisting_people': nexisting_people}

            if nexisting_people == 0:
                messages.success(self.request, generated_urls_message)
            else:
                messages.success(self.request, format_lazy(generated_urls_message, " ", non_generated_urls_message))

        return super().post(request, *args, **kwargs)
Example #6
0
    def mark_as_confirmed(self, request, queryset):
        original_count = queryset.count()
        for fb in queryset.order_by('version').all():
            fb.confirmed = True
            fb.save()
        final_count = queryset.filter(confirmed=True).count()

        message = ngettext(
            "1 feedback submission was marked as confirmed. Note that this may "
            "have caused other feedback submissions to be marked as unconfirmed.",
            "%(count)d feedback submissions were marked as confirmed. Note that "
            "this may have caused other feedback submissions to be marked as "
            "unconfirmed.",
            final_count
        ) % {'count': final_count}
        self.message_user(request, message)

        difference = original_count - final_count
        if difference > 0:
            message = ngettext(
                "1 feedback submission was not marked as confirmed, probably "
                "because other feedback submissions that conflict with it were "
                "also marked as confirmed.",
                "%(count)d feedback submissions were not marked as confirmed, "
                "probably because other feedback submissions that conflict "
                "with them were also marked as confirmed.",
                difference
            ) % {'count': difference}
            self.message_user(request, message, level=messages.WARNING)
Example #7
0
def pluralize(word, count):
    if word == 'be':
        return ngettext('is', 'are', count) % {'count': count} 
    elif word == 'have':
        return ngettext('has', 'have', count) % {'count': count}
    else:
        return word
Example #8
0
def queue_tabnav(context):
    """Returns tuple of tab navigation for the queue pages.

    Each tuple contains three elements: (tab_code, page_url, tab_text)
    """
    counts = context['queue_counts']
    listed = not context.get('unlisted')

    if listed:
        tabnav = [('nominated', 'queue_nominated',
                   (ngettext('New Add-on ({0})',
                             'New Add-ons ({0})',
                             counts['nominated'])
                    .format(counts['nominated']))),
                  ('pending', 'queue_pending',
                   (ngettext('Update ({0})',
                             'Updates ({0})',
                             counts['pending'])
                    .format(counts['pending']))),
                  ('moderated', 'queue_moderated',
                   (ngettext('Moderated Review ({0})',
                             'Moderated Reviews ({0})',
                             counts['moderated'])
                    .format(counts['moderated'])))]
    else:
        tabnav = [('all', 'unlisted_queue_all', _('All Unlisted Add-ons'))]

    return tabnav
Example #9
0
    def formset_valid(self, formset):
        motions = formset.save(commit=False)
        round = self.round
        for i, motion in enumerate(motions, start=1):
            if not self.tournament.pref('enable_motions'):
                motion.seq = i
            motion.round = round
            motion.save()
            self.log_action(content_object=motion)
        for motion in formset.deleted_objects:
            motion.delete()

        count = len(motions)
        if not self.tournament.pref('enable_motions') and count == 1:
            messages.success(self.request, _("The motion has been saved."))
        elif count > 0:
            messages.success(self.request, ngettext("%(count)d motion has been saved.",
                "%(count)d motions have been saved.", count) % {'count': count})

        count = len(formset.deleted_objects)
        if count > 0:
            messages.success(self.request, ngettext("%(count)d motion has been deleted.",
                "%(count)d motions have been deleted.", count) % {'count': count})

        return redirect_round('draw-display', round)
Example #10
0
def summarize_validation(validation):
    """Readable summary of add-on validation results."""
    # L10n: first parameter is the number of errors
    errors = ngettext('{0} error', '{0} errors',
                      validation.errors).format(validation.errors)
    # L10n: first parameter is the number of warnings
    warnings = ngettext('{0} warning', '{0} warnings',
                        validation.warnings).format(validation.warnings)
    return "%s, %s" % (errors, warnings)
Example #11
0
    def _get_breaking_teams_dict(self):
        if self.round.break_category is None:
            self.error_type = 'no_break_category'
            return {
                'total': 0,
                'in_now': 0,
                'message': _("no teams are debating"),
            }

        if self.round.prev is None or not self.round.prev.is_break_round:
            break_size = self.round.break_category.breakingteam_set_competing.count()
            teams_dict = {'total': break_size}
            if break_size < 2:
                teams_dict['in_now'] = 0
                teams_dict['message'] = ngettext(
                    # Translators: nteams in this string can only be 0 or 1
                    "%(nteams)d breaking team — no debates can happen",
                    "%(nteams)d breaking teams — no debates can happen",  # in English, used when break_size == 0
                    break_size) % {'nteams': break_size}
            else:
                debates, bypassing = partial_break_round_split(break_size)
                teams_dict['in_now'] = 2 * debates
                teams_dict['message'] = ngettext(
                    # Translators: ndebating in this string is always at least 2
                    "%(ndebating)d breaking team is debating this round",  # never used in English, but needed for i18n
                    "%(ndebating)d breaking teams are debating this round",
                    2 * debates) % {'ndebating': 2 * debates}
                if bypassing > 0:
                    teams_dict['message'] += ngettext(
                        # Translators: This gets appended to the previous string (the one with
                        # ndebating in it) if (and only if) nbypassing is greater than 0.
                        # "It" refers to this round.
                        "; %(nbypassing)d team is bypassing it",
                        "; %(nbypassing)d teams are bypassing it",
                        bypassing) % {'nbypassing': bypassing}
            return teams_dict

        else:
            nadvancing = self.round.prev.debate_set.count()
            if self.tournament.pref('teams_in_debate') == 'bp':
                nadvancing *= 2

            # add teams that bypassed the last round
            nadvancing += self.round.prev.debate_set.all().aggregate(
                    lowest_room=Coalesce(Min('room_rank') - 1, 0))['lowest_room']

            return {
                'total'     : nadvancing,
                'in_now'    : nadvancing,
                'message'   : ngettext(
                    # Translators: nadvancing in this string is always at least 2
                    "%(nadvancing)s advancing team is debating this round",  # never used, but needed for i18n
                    "%(nadvancing)s advancing teams are debating this round",
                    nadvancing) % {'nadvancing': nadvancing}
            }
Example #12
0
 def __call__(self, field_data, all_data):
     data = str(field_data)
     try:
         float(data)
     except ValueError:
         raise ValidationError, _("Please enter a valid decimal number.")
     if len(data) > (self.max_digits + 1):
         raise ValidationError, ngettext( "Please enter a valid decimal number with at most %s total digit.",
             "Please enter a valid decimal number with at most %s total digits.", self.max_digits) % self.max_digits
     if '.' in data and len(data.split('.')[1]) > self.decimal_places:
         raise ValidationError, ngettext("Please enter a valid decimal number with at most %s decimal place.",
             "Please enter a valid decimal number with at most %s decimal places.", self.decimal_places) % self.decimal_places
Example #13
0
def queue_tabnav(context):
    """Returns tuple of tab navigation for the queue pages.

    Each tuple contains three elements: (tab_code, page_url, tab_text)
    """
    counts = context['queue_counts']
    unlisted_counts = context['unlisted_queue_counts']
    listed = not context.get('unlisted')

    if listed:
        tabnav = [('fast_track', 'queue_fast_track',
                   (ngettext('Fast Track ({0})',
                             'Fast Track ({0})',
                             counts['fast_track'])
                    .format(counts['fast_track']))),
                  ('nominated', 'queue_nominated',
                   (ngettext('Full Review ({0})',
                             'Full Reviews ({0})',
                             counts['nominated'])
                    .format(counts['nominated']))),
                  ('pending', 'queue_pending',
                   (ngettext('Pending Update ({0})',
                             'Pending Updates ({0})',
                             counts['pending'])
                    .format(counts['pending']))),
                  ('prelim', 'queue_prelim',
                   (ngettext('Preliminary Review ({0})',
                             'Preliminary Reviews ({0})',
                             counts['prelim'])
                    .format(counts['prelim']))),
                  ('moderated', 'queue_moderated',
                   (ngettext('Moderated Review ({0})',
                             'Moderated Reviews ({0})',
                             counts['moderated'])
                    .format(counts['moderated'])))]
    else:
        tabnav = [('nominated', 'unlisted_queue_nominated',
                   (ngettext('Unlisted Full Review ({0})',
                             'Unlisted Full Reviews ({0})',
                             unlisted_counts['nominated'])
                    .format(unlisted_counts['nominated']))),
                  ('pending', 'unlisted_queue_pending',
                   (ngettext('Unlisted Pending Update ({0})',
                             'Unlisted Pending Updates ({0})',
                             unlisted_counts['pending'])
                    .format(unlisted_counts['pending']))),
                  ('prelim', 'unlisted_queue_prelim',
                   (ngettext('Unlisted Preliminary Review ({0})',
                             'Unlisted Preliminary Reviews ({0})',
                             unlisted_counts['prelim'])
                    .format(unlisted_counts['prelim']))),
                  ('all', 'unlisted_queue_all',
                   (ngettext('Unlisted All Add-ons ({0})',
                             'Unlisted All Add-ons ({0})',
                             unlisted_counts['all'])
                    .format(unlisted_counts['all'])))]

    return tabnav
Example #14
0
def clean_tags(request, tags, max_tags=None):
    """
    Blocked tags are not allowed.
    Restricted tags can only be edited by Reviewers and Curators.
    """
    target = [slugify(t, spaces=True, lower=True) for t in tags.split(",")]
    target = set(filter(None, target))

    min_len = mkt.MIN_TAG_LENGTH
    max_len = Tag._meta.get_field("tag_text").max_length
    max_tags = max_tags or mkt.MAX_TAGS
    total = len(target)

    blocked = Tag.objects.values_list("tag_text", flat=True).filter(tag_text__in=target, blocked=True)
    if blocked:
        # L10n: {0} is a single tag or a comma-separated list of tags.
        msg = ngettext(u"Invalid tag: {0}", "Invalid tags: {0}", len(blocked)).format(", ".join(blocked))
        raise forms.ValidationError(msg)

    restricted = Tag.objects.values_list("tag_text", flat=True).filter(tag_text__in=target, restricted=True)
    if restricted and not can_edit_restricted_tags(request):
        # L10n: {0} is a single tag or a comma-separated list of tags.
        msg = ngettext(
            u'"{0}" is a reserved tag and cannot be used.',
            u'"{0}" are reserved tags and cannot be used.',
            len(restricted),
        ).format('", "'.join(restricted))
        raise forms.ValidationError(msg)
    else:
        # Admin's restricted tags don't count towards the limit.
        total = len(target - set(restricted))

    if total > max_tags:
        num = total - max_tags
        msg = ngettext(u"You have {0} too many tags.", u"You have {0} too many tags.", num).format(num)
        raise forms.ValidationError(msg)

    if any(t for t in target if len(t) > max_len):
        raise forms.ValidationError(
            _(u"All tags must be %s characters " u"or less after invalid characters are removed." % max_len)
        )

    if any(t for t in target if len(t) < min_len):
        msg = ngettext(
            u"All tags must be at least {0} character.", u"All tags must be at least {0} characters.", min_len
        ).format(min_len)
        raise forms.ValidationError(msg)

    return target
Example #15
0
def date(time=False, asdays=False, short=False):
    '''Returns a pretty formatted date.
    Inputs:
        time is a datetime object or an int timestamp
        asdays is True if you only want to measure days, not seconds
        short is True if you want "1d ago", "2d ago", etc. False if you want
    '''

    now = datetime.now()
    if type(time) is int:   time = datetime.fromtimestamp(time)
    elif not time:          time = now

    if time > now:  past, diff = False, time - now
    else:           past, diff = True,  now - time
    seconds = diff.seconds
    days    = diff.days

    if short:
        if days == 0 and not asdays:
            if   seconds < 10:          return _('now')
            elif seconds < 60:          return _df(seconds, 1, _('s'), past)
            elif seconds < 3600:        return _df(seconds, 60, _('m'), past)
            else:                       return _df(seconds, 3600, _('h'), past)
        else:
            if   days   == 0:           return _('today')
            elif days   == 1:           return past and _('yest') or _('tom')
            elif days    < 7:           return _df(days, 1, _('d'), past)
            elif days    < 31:          return _df(days, 7, _('w'), past)
            elif days    < 365:         return _df(days, 30, _('mo'), past)
            else:                       return _df(days, 365, _('y'), past)
    else:
        if days == 0 and not asdays:
            if   seconds < 10:          return _('now')
            elif seconds < 60:          return _df(seconds, 1, _(' seconds'), past)
            elif seconds < 120:         return past and _('a minute ago') or _('in a minute')
            elif seconds < 3600:        return _df(seconds, 60, _(' minutes'), past)
            elif seconds < 7200:        return past and _('an hour ago') or _('in an hour')
            else:                       return _df(seconds, 3600, ngettext(' hours', ' hours', 0), past)
        else:
            if   days   == 0:           return _('today')
            elif days   == 1:           return past and _('yesterday') or _('tomorrow')
            elif days   == 2:           return past and _('day before') or _('day after')
            elif days    < 7:           return _df(days, 1, _(' days'), past)
            elif days    < 14:          return past and _('last week') or _('next week')
            elif days    < 31:          return _df(days, 7, _(' weeks'), past)
            elif days    < 61:          return past and _('last month') or _('next month')
            elif days    < 365:         return _df(days, 30, _(' months'), past)
            elif days    < 730:         return past and _('last year') or _('next year')
            else:                       return _df(days, 365, ngettext(' years', ' years', 0), past)
Example #16
0
def hasNoProfanities(field_data, all_data):
    """
    Checks that the given string has no profanities in it. This does a simple
    check for whether each profanity exists within the string, so 'f**k' will
    catch 'm**********r' as well. Raises a ValidationError such as:
        Watch your mouth! The words "f--k" and "s--t" are not allowed here.
    """
    field_data = field_data.lower() # normalize
    words_seen = [w for w in settings.PROFANITIES_LIST if w in field_data]
    if words_seen:
        from django.utils.text import get_text_list
        plural = len(words_seen) > 1
        raise ValidationError, ngettext("Watch your mouth! The word %s is not allowed here.",
            "Watch your mouth! The words %s are not allowed here.", plural) % \
            get_text_list(['"%s%s%s"' % (i[0], '-'*(len(i)-2), i[-1]) for i in words_seen], 'and')
Example #17
0
 def add_message(self, nsaved, ndeleted):
     if nsaved > 0:
         messages.success(self.request, ngettext(
             "Saved %(count)d adjudicator-institution conflict.",
             "Saved %(count)d adjudicator-institution conflicts.",
             nsaved,
         ) % {'count': nsaved})
     if ndeleted > 0:
         messages.success(self.request, ngettext(
             "Deleted %(count)d adjudicator-institution conflict.",
             "Deleted %(count)d adjudicator-institution conflicts.",
             ndeleted,
         ) % {'count': ndeleted})
     if nsaved == 0 and ndeleted == 0:
         messages.success(self.request, _("No changes were made to adjudicator-institution conflicts."))
Example #18
0
def clean_tags(request, tags):
    target = [slugify(t, spaces=True, lower=True) for t in tags.split(',')]
    target = set(filter(None, target))

    min_len = amo.MIN_TAG_LENGTH
    max_len = Tag._meta.get_field('tag_text').max_length
    max_tags = amo.MAX_TAGS
    total = len(target)

    blacklisted = (Tag.objects.values_list('tag_text', flat=True)
                      .filter(tag_text__in=target, blacklisted=True))
    if blacklisted:
        # L10n: {0} is a single tag or a comma-separated list of tags.
        msg = ngettext('Invalid tag: {0}', 'Invalid tags: {0}',
                       len(blacklisted)).format(', '.join(blacklisted))
        raise forms.ValidationError(msg)

    restricted = (Tag.objects.values_list('tag_text', flat=True)
                     .filter(tag_text__in=target, restricted=True))
    if not acl.action_allowed(request, 'Addons', 'Edit'):
        if restricted:
            # L10n: {0} is a single tag or a comma-separated list of tags.
            msg = ngettext('"{0}" is a reserved tag and cannot be used.',
                           '"{0}" are reserved tags and cannot be used.',
                           len(restricted)).format('", "'.join(restricted))
            raise forms.ValidationError(msg)
    else:
        # Admin's restricted tags don't count towards the limit.
        total = len(target - set(restricted))

    if total > max_tags:
        num = total - max_tags
        msg = ngettext('You have {0} too many tags.',
                       'You have {0} too many tags.', num).format(num)
        raise forms.ValidationError(msg)

    if any(t for t in target if len(t) > max_len):
        raise forms.ValidationError(
            _('All tags must be %s characters or less after invalid characters'
              ' are removed.' % max_len))

    if any(t for t in target if len(t) < min_len):
        msg = ngettext("All tags must be at least {0} character.",
                       "All tags must be at least {0} characters.",
                       min_len).format(min_len)
        raise forms.ValidationError(msg)

    return target
Example #19
0
    def execute(self):
        error_msg = ''
        ext_result = True
        final_result = True
        failed_exts = []

        if self._using_default_storage():
            for extensions_list, content in self.file_checks:
                for ext in extensions_list:
                    try:
                        ext_result = self.download_and_compare(
                            'exec_check' + ext)
                        if final_result and not ext_result:
                            final_result = False
                    except Exception as e:
                        return (False,
                                _('Uncaught exception during test: %s') % e)

                    if not ext_result:
                        failed_exts.append(ext)

        if not final_result:
            error_msg = _(
                ngettext(
                    'The web server incorrectly executed these file types: %s',
                    'The web server incorrectly executed this file type: %s',
                    len(failed_exts))
                % ', '.join(failed_exts))

        return final_result, error_msg
Example #20
0
def validate_username_length(settings, value):
    if len(value) < settings.username_length_min:
        message = ngettext(
            "Username must be at least %(limit_value)s character long.",
            "Username must be at least %(limit_value)s characters long.",
            settings.username_length_min,
        )
        raise ValidationError(message % {"limit_value": settings.username_length_min})

    if len(value) > settings.username_length_max:
        message = ngettext(
            "Username cannot be longer than %(limit_value)s characters.",
            "Username cannot be longer than %(limit_value)s characters.",
            settings.username_length_max,
        )
        raise ValidationError(message % {"limit_value": settings.username_length_max})
Example #21
0
 def render_waiting_time_min(self, row):
     if row.waiting_time_min == 0:
         r = _lazy('moments ago')
     elif row.waiting_time_hours == 0:
         # L10n: first argument is number of minutes
         r = ngettext(u'{0} minute', u'{0} minutes',
                      row.waiting_time_min).format(row.waiting_time_min)
     elif row.waiting_time_days == 0:
         # L10n: first argument is number of hours
         r = ngettext(u'{0} hour', u'{0} hours',
                      row.waiting_time_hours).format(row.waiting_time_hours)
     else:
         # L10n: first argument is number of days
         r = ngettext(u'{0} day', u'{0} days',
                      row.waiting_time_days).format(row.waiting_time_days)
     return jinja2.escape(r)
Example #22
0
 def save(self, new_data):
     today = datetime.date.today()
     c = self.get_comment(new_data)
     for old in Comment.objects.filter(content_type__id__exact=new_data["content_type_id"],
         object_id__exact=new_data["object_id"], user__id__exact=self.get_user_id()):
         # Check that this comment isn't duplicate. (Sometimes people post
         # comments twice by mistake.) If it is, fail silently by pretending
         # the comment was posted successfully.
         if old.submit_date.date() == today and old.comment == c.comment \
             and old.rating1 == c.rating1 and old.rating2 == c.rating2 \
             and old.rating3 == c.rating3 and old.rating4 == c.rating4 \
             and old.rating5 == c.rating5 and old.rating6 == c.rating6 \
             and old.rating7 == c.rating7 and old.rating8 == c.rating8:
             return old
         # If the user is leaving a rating, invalidate all old ratings.
         if c.rating1 is not None:
             old.valid_rating = False
             old.save()
     c.save()
     # If the commentor has posted fewer than COMMENTS_FIRST_FEW comments,
     # send the comment to the managers.
     if self.user_cache.comment_set.count() <= settings.COMMENTS_FIRST_FEW:
         message = ngettext('This comment was posted by a user who has posted fewer than %(count)s comment:\n\n%(text)s',
             'This comment was posted by a user who has posted fewer than %(count)s comments:\n\n%(text)s', settings.COMMENTS_FIRST_FEW) % \
             {'count': settings.COMMENTS_FIRST_FEW, 'text': c.get_as_text()}
         mail_managers("Comment posted by rookie user", message)
     if settings.COMMENTS_SKETCHY_USERS_GROUP and settings.COMMENTS_SKETCHY_USERS_GROUP in [g.id for g in self.user_cache.get_group_list()]:
         message = _('This comment was posted by a sketchy user:\n\n%(text)s') % {'text': c.get_as_text()}
         mail_managers("Comment posted by sketchy user (%s)" % self.user_cache.username, c.get_as_text())
     return c
Example #23
0
def rescore_success(request, problem, task_id):
    count = AsyncResult(task_id).result
    if not isinstance(count, int):
        raise Http404()
    messages.success(request, ngettext('%d submission were successfully rescored.',
                                       '%d submissions were successfully rescored.', count) % (count,))
    return HttpResponseRedirect(reverse('problem_manage_submissions', args=[problem]))
Example #24
0
def allow_delete_poll(user_acl, target):
    if user_acl["is_anonymous"]:
        raise PermissionDenied(_("You have to sign in to delete polls."))

    category_acl = user_acl["categories"].get(
        target.category_id, {"can_close_threads": False}
    )

    if not user_acl.get("can_delete_polls"):
        raise PermissionDenied(_("You can't delete polls."))

    if user_acl.get("can_delete_polls") < 2:
        if user_acl["user_id"] != target.poster_id:
            raise PermissionDenied(
                _("You can't delete other users polls in this category.")
            )
        if not has_time_to_edit_poll(user_acl, target):
            message = ngettext(
                "You can't delete polls that are older than %(minutes)s minute.",
                "You can't delete polls that are older than %(minutes)s minutes.",
                user_acl["poll_edit_time"],
            )
            raise PermissionDenied(message % {"minutes": user_acl["poll_edit_time"]})
        if target.is_over:
            raise PermissionDenied(_("This poll is over. You can't delete it."))

    if not category_acl.get("can_close_threads"):
        if target.category.is_closed:
            raise PermissionDenied(
                _("This category is closed. You can't delete polls in it.")
            )
        if target.thread.is_closed:
            raise PermissionDenied(
                _("This thread is closed. You can't delete polls in it.")
            )
Example #25
0
    def add_draw_conflicts_columns(self, debates, venue_conflicts, adjudicator_conflicts):

        conflicts_by_debate = []
        for debate in debates:
            # conflicts is a list of (level, message) tuples
            conflicts = [("secondary", flag) for flag in debate.get_flags_display()]
            conflicts += [("secondary", "%(team)s: %(flag)s" % {'team': self._team_short_name(debate.get_team(side)), 'flag': flag})
                    for side in self.tournament.sides for flag in debate.get_dt(side).get_flags_display()]

            if self.tournament.pref('avoid_team_history'):
                history = debate.history
                if history > 0:
                    conflicts.append(("warning", ngettext("Teams have met once",
                            "Teams have met %(count)d times", history) % {'count': history}))

            if self.tournament.pref('avoid_same_institution'):
                institutions = [t.institution_id for t in debate.teams if t.institution_id is not None]
                if len(set(institutions)) != len(institutions):
                    conflicts.append(("warning", _("Teams are from the same institution")))

            conflicts.extend(adjudicator_conflicts[debate])
            conflicts.extend(venue_conflicts[debate])
            conflicts_by_debate.append(conflicts)

        conflicts_header = {'title': _("Conflicts/Flags"), 'key': 'conflags'}
        conflicts_data = [{
            'text': "".join(["<div class=\"text-{0}\">{1}</div>".format(*conflict) for conflict in debate_conflicts]),
            'class': 'small'
        } for debate_conflicts in conflicts_by_debate]
        self.add_column(conflicts_header, conflicts_data)
Example #26
0
def rejudge_success(request, problem, task_id):
    count = AsyncResult(task_id).result
    if not isinstance(count, int):
        raise Http404()
    messages.success(request, ngettext('Successfully scheduled %d submission for rejudging.',
                                       'Successfully scheduled %d submissions for rejudging.', count) % (count,))
    return HttpResponseRedirect(reverse('problem_manage_submissions', args=[problem]))
Example #27
0
    def validate_choices(self, data):
        if len(data) > self.context["allowed_choices"]:
            message = ngettext(
                "This poll disallows voting for more than %(choices)s choice.",
                "This poll disallows voting for more than %(choices)s choices.",
                self.context["allowed_choices"],
            )
            raise serializers.ValidationError(
                message % {"choices": self.context["allowed_choices"]}
            )

        valid_choices = [c["hash"] for c in self.context["choices"]]
        clean_choices = []

        for choice in data:
            if choice in valid_choices and choice not in clean_choices:
                clean_choices.append(choice)

        if len(clean_choices) != len(data):
            raise serializers.ValidationError(
                _("One or more of poll choices were invalid.")
            )

        if not clean_choices:
            raise serializers.ValidationError(_("You have to make a choice."))

        return clean_choices
Example #28
0
def time_from_sec(seconds, separator=', '):
    """
    Takes an amount of seconds and turns it into a human-readable amount of time.
    """

    suffixes = [(lambda count: ngettext(' day', ' days', count) % {'count': count}),
                (lambda count: _(' h') % {'count': count}),
                (lambda count: _(' min') % {'count': count}),
                (lambda count: _(' s') % {'count': count})]

    # the formatted time string to be returned
    time = []

    # the pieces of time to iterate over (days, hours, minutes, etc)
    # - the first piece in each tuple is the suffix (d, h, w)
    # - the second piece is the length in seconds (a day is 60s * 60m * 24h)
    parts = [(suffixes[0], 60 * 60 * 24),
             (suffixes[1], 60 * 60),
             (suffixes[2], 60),
             (suffixes[3], 1)]

    # for each time piece, grab the value and remaining seconds, and add it to
    # the time string
    for suffix, length in parts:
        value = seconds / length
        if value > 0:
            seconds = seconds % length
            time.append('%s%s' % (str(value), force_unicode(suffix(int(value)))))  # (suffix, (suffix, suffix + 's')[value > 1])[add_s]))
        if seconds < 1:
            break

    return separator.join(time)
Example #29
0
 def isValidIDList(self, field_data, all_data):
     "Validates that the value is a valid list of foreign keys"
     mod = self.rel.to
     try:
         pks = map(int, field_data.split(','))
     except ValueError:
         # the CommaSeparatedIntegerField validator will catch this error
         return
     objects = mod._default_manager.in_bulk(pks)
     if len(objects) != len(pks):
         badkeys = [k for k in pks if k not in objects]
         raise validators.ValidationError, ngettext("Please enter valid %(self)s IDs. The value %(value)r is invalid.",
                 "Please enter valid %(self)s IDs. The values %(value)r are invalid.", len(badkeys)) % {
             'self': self.verbose_name,
             'value': len(badkeys) == 1 and badkeys[0] or tuple(badkeys),
         }
Example #30
0
def themes_commit(request):
    ThemeReviewFormset = formset_factory(forms.ThemeReviewForm)
    formset = ThemeReviewFormset(request.POST)

    scores = []
    for form in formset:
        try:
            lock = ThemeLock.objects.filter(
                theme_id=form.data[form.prefix + '-theme'],
                reviewer=request.user)
        except MultiValueDictKeyError:
            # Address off-by-one error caused by management form.
            continue
        if lock and form.is_valid():
            scores.append(form.save())

    # Success message.
    points = sum(scores)
    success = ngettext(
        # L10n: {0} is the number of reviews. {1} is the points just earned.
        # L10n: {2} is the total number of points the reviewer has overall.
        '{0} theme review successfully processed (+{1} points, {2} total).',
        '{0} theme reviews successfully processed (+{1} points, {2} total).',
        len(scores)).format(len(scores), points,
                            ReviewerScore.get_total(request.user))
    amo.messages.success(request, success)

    if 'theme_redirect_url' in request.session:
        return redirect(request.session['theme_redirect_url'])
    else:
        return redirect(reverse('editors.themes.queue_themes'))
Example #31
0
	def quitar_carrusel(self, request, queryset):
		updated = queryset.update(carrusel=False)
		self.message_user(request, ngettext('%d publicación se quitó del carrusel.', '%d publicaciones se quitaron del carrusel.', updated) % updated, messages.SUCCESS)
Example #32
0
def message_remove(request, undo=False):
    """
    A ``POST`` to remove messages.

    :param undo:
        A Boolean that if ``True`` unremoves messages.

    POST can have the following keys:

        ``message_pks``
            List of message id's that should be deleted.

        ``next``
            String containing the URI which to redirect to after the keys are
            removed. Redirect defaults to the inbox view.

    The ``next`` value can also be supplied in the URI with ``?next=<value>``.

    """
    message_pks = request.POST.getlist("message_pks")
    redirect_to = request.GET.get(REDIRECT_FIELD_NAME,
                                  request.POST.get(REDIRECT_FIELD_NAME, False))

    if message_pks:
        # Check that all values are integers.
        valid_message_pk_list = set()
        for pk in message_pks:
            try:
                valid_pk = int(pk)
            except (TypeError, ValueError):
                pass
            else:
                valid_message_pk_list.add(valid_pk)

        # Delete all the messages, if they belong to the user.
        now = get_datetime_now()
        changed_message_list = set()
        for pk in valid_message_pk_list:
            message = get_object_or_404(Message, pk=pk)

            # Check if the user is the owner
            if message.sender == request.user:
                if undo:
                    message.sender_deleted_at = None
                else:
                    message.sender_deleted_at = now
                message.save()
                changed_message_list.add(message.pk)

            # Check if the user is a recipient of the message
            if request.user in message.recipients.all():
                mr = message.messagerecipient_set.get(user=request.user,
                                                      message=message)
                if undo:
                    mr.deleted_at = None
                else:
                    mr.deleted_at = now
                mr.save()
                changed_message_list.add(message.pk)

        # Send messages
        if (len(changed_message_list) >
                0) and userena_settings.USERENA_USE_MESSAGES:
            if undo:
                message = ngettext(
                    "Message is succesfully restored.",
                    "Messages are succesfully restored.",
                    len(changed_message_list),
                )
            else:
                message = ngettext(
                    "Message is successfully removed.",
                    "Messages are successfully removed.",
                    len(changed_message_list),
                )

            messages.success(request, message, fail_silently=True)

    if redirect_to:
        return redirect(redirect_to)
    else:
        return redirect(reverse("userena_umessages_list"))
Example #33
0
def process_import(request):
    supported_extensions = get_supported_extensions()
    from_encoding = "utf-8"

    form_kwargs = {}
    form = ConfirmImportForm(DEFAULT_FORMATS, request.POST or None,
                             request.FILES or None, **form_kwargs)

    is_confirm_form_valid = form.is_valid()

    import_formats = get_import_formats()
    input_format = import_formats[int(form.cleaned_data["input_format"])]()

    FileStorage = get_file_storage()
    file_storage = FileStorage(name=form.cleaned_data["import_file_name"])

    if not is_confirm_form_valid:
        data = file_storage.read(input_format.get_read_mode())
        if not input_format.is_binary() and from_encoding:
            data = force_str(data, from_encoding)
        dataset = input_format.create_dataset(data)

        initial = {
            "import_file_name": file_storage.name,
            "original_file_name": form.cleaned_data["import_file_name"],
        }

        return render(
            request,
            "wagtailredirects/confirm_import.html",
            {
                "form":
                ConfirmImportForm(
                    dataset.headers,
                    request.POST or None,
                    request.FILES or None,
                    initial=initial,
                ),
                "dataset":
                dataset,
            },
        )

    data = file_storage.read(input_format.get_read_mode())
    if not input_format.is_binary() and from_encoding:
        data = force_str(data, from_encoding)
    dataset = input_format.create_dataset(data)

    import_summary = create_redirects_from_dataset(
        dataset,
        {
            "from_index": int(form.cleaned_data["from_index"]),
            "to_index": int(form.cleaned_data["to_index"]),
            "permanent": form.cleaned_data["permanent"],
            "site": form.cleaned_data["site"],
        },
    )

    file_storage.remove()

    if import_summary["errors_count"] > 0:
        return render(
            request,
            "wagtailredirects/import_summary.html",
            {
                "form": ImportForm(supported_extensions),
                "import_summary": import_summary,
            },
        )

    total = import_summary["total"]
    messages.success(
        request,
        ngettext("Imported %(total)d redirect", "Imported %(total)d redirects",
                 total) % {'total': total})

    return redirect('wagtailredirects:index')
Example #34
0
def delete(request, app_label, model_name, pk=None):
    model = get_snippet_model_from_url_params(app_label, model_name)

    permission = get_permission_name('delete', model)
    if not request.user.has_perm(permission):
        raise PermissionDenied

    if pk:
        instances = [get_object_or_404(model, pk=unquote(pk))]
    else:
        ids = request.GET.getlist('id')
        instances = model.objects.filter(pk__in=ids)

    for fn in hooks.get_hooks('before_delete_snippet'):
        result = fn(request, instances)
        if hasattr(result, 'status_code'):
            return result

    count = len(instances)

    if request.method == 'POST':
        for instance in instances:
            instance.delete()

        if count == 1:
            message_content = _("%(snippet_type)s '%(instance)s' deleted.") % {
                'snippet_type': capfirst(model._meta.verbose_name),
                'instance': instance
            }
        else:
            # This message is only used in plural form, but we'll define it with ngettext so that
            # languages with multiple plural forms can be handled correctly (or, at least, as
            # correctly as possible within the limitations of verbose_name_plural...)
            message_content = ngettext(
                "%(count)d %(snippet_type)s deleted.",
                "%(count)d %(snippet_type)s deleted.", count) % {
                    'snippet_type': capfirst(model._meta.verbose_name_plural),
                    'count': count
                }

        messages.success(request, message_content)

        for fn in hooks.get_hooks('after_delete_snippet'):
            result = fn(request, instances)
            if hasattr(result, 'status_code'):
                return result

        return redirect('wagtailsnippets:list', app_label, model_name)

    return TemplateResponse(
        request, 'wagtailsnippets/snippets/confirm_delete.html', {
            'model_opts':
            model._meta,
            'count':
            count,
            'instances':
            instances,
            'submit_url':
            (reverse('wagtailsnippets:delete-multiple',
                     args=(app_label, model_name)) + '?' +
             urlencode([('id', instance.pk) for instance in instances])),
        })
Example #35
0
    def clean_speakers(self, cleaned_data):
        """Checks that the speaker selections are valid."""

        # Pull team info again, in case it's changed since the form was loaded.
        if self.choosing_sides:
            teams = cleaned_data.get('choose_sides', [None] * len(self.sides))
        else:
            teams = [self.debate.get_team(side) for side in self.sides]
        if None in teams:
            logger.warning("Team identities not found")

        for side, team in zip(self.sides, teams):

            speaker_positions = dict()
            for pos in range(1, self.last_substantive_position + 1):
                speaker = cleaned_data.get(self._fieldname_speaker(side, pos))
                if speaker is None:
                    logger.warning("Field '%s' not found", self._fieldname_speaker(side, pos))
                    continue

                # The speaker must be on the relevant team.
                if team is not None and speaker not in team.speakers:
                    self.add_error(self._fieldname_speaker(side, pos), forms.ValidationError(
                        _("The speaker %(speaker)s doesn't appear to be on team %(team)s."),
                        params={'speaker': speaker.name, 'team': team.short_name},
                        code='speaker_wrongteam'),
                    )

                # Don't count this speaker if the speech is marked as a ghost
                if not cleaned_data.get(self._fieldname_ghost(side, pos)):
                    speaker_positions.setdefault(speaker, []).append(pos)

            # The substantive speakers must be unique.
            for speaker, positions in speaker_positions.items():
                if len(positions) > 1:
                    # Translators: count is always at least 2
                    message = ngettext(
                        "%(speaker)s appears to have given %(count)d substantive speech.",  # never used, needed for i18n
                        "%(speaker)s appears to have given %(count)d substantive speeches.",
                        len(positions),
                    )
                    params = {'speaker': speaker.name, 'count': len(positions)}
                    for pos in positions:
                        self.add_error(self._fieldname_speaker(side, pos), forms.ValidationError(
                            message, params=params, code='speaker_repeat'))

            # Check reply speaker only if not marked as a ghost
            if self.using_replies and not cleaned_data.get(self._fieldname_ghost(side, self.reply_position)):
                reply_speaker = cleaned_data.get(self._fieldname_speaker(side, self.reply_position))
                last_speaker = cleaned_data.get(self._fieldname_speaker(side, self.last_substantive_position))

                # The last speaker can't give the reply.
                if reply_speaker == last_speaker and reply_speaker is not None:
                    self.add_error(self._fieldname_speaker(side, self.reply_position), forms.ValidationError(
                        _("The last substantive speaker and reply speaker can't be the same."),
                        code='reply_speaker_consecutive',
                    ))

                # The reply speaker must have given a substantive speech.
                if self.tournament.pref('require_substantive_for_reply') and len(speaker_positions.get(reply_speaker, [])) == 0:
                    self.add_error(self._fieldname_speaker(side, self.reply_position), forms.ValidationError(
                        _("The reply speaker for this team did not give a substantive speech."),
                        code='reply_speaker_not_repeat',
                    ))
Example #36
0
    def form_valid(self, form):
        if not self.urlpath.parent:
            messages.error(
                self.request,
                _('This article cannot be moved because it is a root article.')
            )
            return redirect('wiki:get', article_id=self.article.id)

        dest_path = get_object_or_404(models.URLPath,
                                      pk=form.cleaned_data['destination'])
        tmp_path = dest_path

        while tmp_path.parent:
            if tmp_path == self.urlpath:
                messages.error(
                    self.request,
                    _('This article cannot be moved to a child of itself.'))
                return redirect('wiki:move', article_id=self.article.id)
            tmp_path = tmp_path.parent

        # Clear cache to update article lists (Old links)
        for ancestor in self.article.ancestor_objects():
            ancestor.article.clear_cache()

        # Save the old path for later
        old_path = self.urlpath.path

        self.urlpath.parent = dest_path
        self.urlpath.slug = form.cleaned_data['slug']
        self.urlpath.save()

        # Reload url path form database
        self.urlpath = models.URLPath.objects.get(pk=self.urlpath.pk)

        # Use a copy of ourself (to avoid cache) and update article links again
        for ancestor in models.Article.objects.get(
                pk=self.article.pk).ancestor_objects():
            ancestor.article.clear_cache()

        # Create a redirect page for every moved article
        # /old-slug
        # /old-slug/child
        # /old-slug/child/grand-child
        if form.cleaned_data['redirect']:

            # NB! Includes self!
            descendants = list(
                self.urlpath.get_descendants(
                    include_self=True).order_by("level"))

            root_len = len(descendants[0].path)

            for descendant in descendants:
                # Without this descendant.get_ancestors() and as a result
                # descendant.path is wrong after the first create_article() due
                # to path caching
                descendant.refresh_from_db()
                dst_path = descendant.path
                src_path = urljoin(old_path, dst_path[root_len:])
                src_len = len(src_path)
                pos = src_path.rfind("/", 0, src_len - 1)
                slug = src_path[pos + 1:src_len - 1]
                parent_urlpath = models.URLPath.get_by_path(
                    src_path[0:max(pos, 0)])

                link = "[wiki:/{path}](wiki:/{path})".format(path=dst_path)
                urlpath_new = models.URLPath._create_urlpath_from_request(
                    self.request,
                    self.article,
                    parent_urlpath,
                    slug,
                    _("Moved: {title}").format(title=descendant.article),
                    _("Article moved to {link}").format(link=link),
                    _("Created redirect (auto)"),
                )
                urlpath_new.moved_to = descendant
                urlpath_new.save()

            messages.success(
                self.request,
                ngettext("Article successfully moved! Created {n} redirect.",
                         "Article successfully moved! Created {n} redirects.",
                         len(descendants)).format(n=len(descendants)))

        else:
            messages.success(self.request, _('Article successfully moved!'))
        return redirect("wiki:get", path=self.urlpath.path)
Example #37
0
	def quitar_publicados(self, request, queryset):
		pendiente = DetalleTabla.objects.filter(tabla__tabla='estados_pub', elemento='pendiente')
		updated = queryset.update(estado=pendiente)
		self.message_user(request, 'Se cambió el estado a ' + ngettext('%d publicación', '%d publicaciones', updated) % updated, messages.SUCCESS)
Example #38
0
	def desactivar(self, request, queryset):
		queryset.update(activo=False)
		self.message_user(request, ngettext('%d imagen se removió del carrusel', '%d imágenes se removieron del carrusel', updated) % updated, messages.SUCCESS)
 def get_help_text(self):
     return ngettext(
         "Your password must contain at least %(min_length)d character.",
         "Your password must contain at least %(min_length)d characters.",
         self.min_length
     ) % {'min_length': self.min_length}
Example #40
0
        except (TypeError, ValueError):
            return intcomma(value, False)
        else:
            return number_format(value, force_grouping=True)
    orig = str(value)
    new = re.sub(r"^(-?\d+)(\d{3})", r'\g<1>,\g<2>', orig)
    if orig == new:
        return new
    else:
        return intcomma(new, use_l10n)


# A tuple of standard large number to their converters
intword_converters = (
    (6, lambda number: (
        ngettext('%(value).1f million', '%(value).1f million', number),
        ngettext('%(value)s million', '%(value)s million', number),
    )),
    (9, lambda number: (
        ngettext('%(value).1f billion', '%(value).1f billion', number),
        ngettext('%(value)s billion', '%(value)s billion', number),
    )),
    (12, lambda number: (
        ngettext('%(value).1f trillion', '%(value).1f trillion', number),
        ngettext('%(value)s trillion', '%(value)s trillion', number),
    )),
    (15, lambda number: (
        ngettext('%(value).1f quadrillion', '%(value).1f quadrillion', number),
        ngettext('%(value)s quadrillion', '%(value)s quadrillion', number),
    )),
    (18, lambda number: (
Example #41
0
def indicate_alerts(context, obj):
    result = []

    translation = None
    component = None
    project = None

    global_base = context.get("global_base")

    if isinstance(obj, (Translation, GhostTranslation)):
        translation = obj
        component = obj.component
        project = component.project
    elif isinstance(obj, Component):
        component = obj
        project = component.project
    elif isinstance(obj, Project):
        project = obj
    elif isinstance(obj, ProjectLanguage):
        project = obj.project
        # For source language
        result.extend(translation_alerts(obj))
    elif isinstance(obj, GhostProjectLanguageStats):
        component = obj.component
        project = component.project

    if project is not None and context["user"].has_perm("project.edit", project):
        result.append(
            ("state/admin.svg", gettext("You administrate this project."), None)
        )

    if translation is not None:
        result.extend(translation_alerts(translation))

    if component is not None:
        result.extend(component_alerts(component))
    elif project is not None:
        result.extend(project_alerts(project))

    if getattr(obj, "is_ghost", False):
        result.append(
            ("state/ghost.svg", gettext("This translation does not yet exist."), None)
        )
    elif global_base:
        if isinstance(global_base, str):
            global_base = getattr(obj, global_base)
        stats = get_stats(obj)

        count = global_base.source_strings - stats.all
        if count:
            result.append(
                (
                    "state/ghost.svg",
                    ngettext(
                        "%(count)s string is not being translated here.",
                        "%(count)s strings are not being translated here.",
                        count,
                    )
                    % {"count": count},
                    None,
                )
            )

    if getattr(obj, "is_shared", False):
        result.append(
            (
                "state/share.svg",
                gettext("Shared from the %s project.") % obj.is_shared,
                None,
            )
        )

    return {"icons": result, "component": component, "project": project}
Example #42
0
	def promover_carrusel(self, request, queryset):
		updated = queryset.update(carrusel=True)
		self.message_user(request, ngettext('%d publicación se promovió al carrusel.', '%d publicaciones fueron promovidas al carrusel.', updated) % updated, messages.SUCCESS)
Example #43
0
def search_replace(request, project, component=None, lang=None):
    obj, unit_set, context = parse_url(request, project, component, lang)

    form = ReplaceForm(request.POST)

    if not form.is_valid():
        messages.error(request, _("Failed to process form!"))
        show_form_errors(request, form)
        return redirect(obj)

    search_text = form.cleaned_data["search"]
    replacement = form.cleaned_data["replacement"]

    matching = unit_set.filter(target__contains=search_text)

    updated = 0
    if matching.exists():
        confirm = ReplaceConfirmForm(matching, request.POST)
        limited = False

        if matching.count() > 300:
            matching = matching.order_by("id")[:250]
            limited = True

        if not confirm.is_valid():
            for unit in matching:
                unit.replacement = unit.target.replace(search_text,
                                                       replacement)
            context.update({
                "matching": matching,
                "search_query": search_text,
                "replacement": replacement,
                "form": form,
                "limited": limited,
                "confirm": ReplaceConfirmForm(matching),
            })
            return render(request, "replace.html", context)

        matching = confirm.cleaned_data["units"]

        with transaction.atomic():
            for unit in matching.select_for_update():
                if not request.user.has_perm("unit.edit", unit):
                    continue
                unit.translate(
                    request.user,
                    unit.target.replace(search_text, replacement),
                    unit.state,
                    change_action=Change.ACTION_REPLACE,
                )
                updated += 1

    import_message(
        request,
        updated,
        _("Search and replace completed, no strings were updated."),
        ngettext(
            "Search and replace completed, %d string was updated.",
            "Search and replace completed, %d strings were updated.",
            updated,
        ),
    )

    return redirect(obj)
Example #44
0
 def make_published(self, request, queryset):
     updated = queryset.update(status='p')
     self.message_user(
         request,
         ngettext('{}个故事已被成功标记为published.', '{}个故事已被成功标记为published.',
                  updated).format(updated), messages.SUCCESS)
Example #45
0
def naturaltime_future(value, now):
    """Handling of future dates for naturaltime."""
    # this function is huge
    # pylint: disable=too-many-branches,too-many-return-statements

    delta = value - now

    if delta.days >= 365:
        count = delta.days // 365
        if count == 1:
            return gettext("a year from now")
        return ngettext("%(count)s year from now", "%(count)s years from now",
                        count) % {
                            "count": count
                        }
    if delta.days >= 30:
        count = delta.days // 30
        if count == 1:
            return gettext("a month from now")
        return ngettext("%(count)s month from now",
                        "%(count)s months from now", count) % {
                            "count": count
                        }
    if delta.days >= 14:
        count = delta.days // 7
        return ngettext("%(count)s week from now", "%(count)s weeks from now",
                        count) % {
                            "count": count
                        }
    if delta.days > 0:
        if delta.days == 1:
            return gettext("tomorrow")
        if delta.days == 7:
            return gettext("a week from now")
        return ngettext("%(count)s day from now", "%(count)s days from now",
                        delta.days) % {
                            "count": delta.days
                        }
    if delta.seconds == 0:
        return gettext("now")
    if delta.seconds < 60:
        if delta.seconds == 1:
            return gettext("a second from now")
        return ngettext("%(count)s second from now",
                        "%(count)s seconds from now", delta.seconds) % {
                            "count": delta.seconds
                        }
    if delta.seconds // 60 < 60:
        count = delta.seconds // 60
        if count == 1:
            return gettext("a minute from now")
        return ngettext("%(count)s minute from now",
                        "%(count)s minutes from now", count) % {
                            "count": count
                        }
    count = delta.seconds // 60 // 60
    if count == 1:
        return gettext("an hour from now")
    return ngettext("%(count)s hour from now", "%(count)s hours from now",
                    count) % {
                        "count": count
                    }