def create_message(graderoster, submitter): section = getattr(graderoster, "secondary_section", None) if section is None: section = graderoster.section section_id = section_url_token(section, graderoster.instructor) section_name = section_display_name(section) submitter_name = person_display_name(submitter) success_count = 0 error_count = 0 for item in graderoster.items: if (not item.is_auditor and item.date_withdrawn is None and item.status_code is not None): if item.status_code != "200": error_count += 1 else: success_count += 1 if success_count > 0 and error_count > 0: subject = "Failed grade submission attempt for {}".format(section_name) text_template = "email/partial.txt" html_template = "email/partial.html" elif success_count == 0 and error_count > 0: subject = "Failed grade submission attempt for {}".format(section_name) text_template = "email/failure.txt" html_template = "email/failure.html" elif success_count > 0 and error_count == 0: if success_count == 1: subject = "{} submitted {} grade for {}".format( submitter_name, apnumber(success_count), section_name) else: subject = "{} submitted {} grades for {}".format( submitter_name, apnumber(success_count), section_name) text_template = "email/success.txt" html_template = "email/success.html" else: raise GradesNotSubmitted() gradepage_host = getattr(settings, "GRADEPAGE_HOST", "http://localhost") params = { "submitted_by": submitter_name, "submitted_date": display_datetime(current_datetime()), "submitted_count": success_count + error_count, "success_count": success_count, "failure_count": error_count, "section_name": section_name, "gradepage_url": gradepage_host, "section_url": "{host}/section/{section_id}".format( host=gradepage_host, section_id=section_id), "grading_window_open": section.term.is_grading_period_open(), } if params["grading_window_open"]: deadline = section.term.grade_submission_deadline params["grade_submission_deadline"] = display_datetime(deadline) return (subject, loader.render_to_string(text_template, params), loader.render_to_string(html_template, params))
def __str__(self): n_min = self.quantite_min n_max = self.quantite_max partie = (force_text(self.partie) if n_max == 1 else self.partie.pluriel()) if n_min != n_max: out = ugettext('%s à %s %s') % ( apnumber(n_min), apnumber(n_max), partie) elif n_min > 1: out = f'{apnumber(n_min)} {partie}' else: out = partie if self.facultatif: out = format_html('{} <em>ad libitum</em>', out) return out
def surviving_siblings(self): genders = ('brother', 'sister', 'stepbrother', 'half brother', 'stepsister', 'half sister',) if self.siblings_set.all(): gender_sub_list = [] for gender in genders: child_list = [] gender_set = self.siblings_set.filter(gender=gender) if gender_set: # build gender-based list for child in gender_set: if child.residence: child_list.append(u'%s of %s' % (child.name, child.residence)) else: child_list.append(u'%s' % (child.name)) if len(child_list) == 1: child_str = ', '.join(child_list) else: # insert 'and" in front of last item child_list[-1] = u'and ' + child_list[-1] # merge last two items child_list[-2:] = [ ' '.join(child_list[-2:]) ] child_str = ', '.join(child_list) if len(gender_set) == 1: child_str = u'; a %s, %s' % (gender, child_str) else: child_str = u'; %s %ss, %s' % (apnumber(len(gender_set)), gender, child_str) gender_sub_list.append(child_str) child_display = '; '.join(gender_sub_list) else: child_display = u'' return child_display
def clean(self, value): if not value and self.required: raise forms.ValidationError(self.error_messages['required']) if value and self.max_choices and len(value) > self.max_choices: raise forms.ValidationError('You must select a maximum of %s choice%s.' % (apnumber(self.max_choices), pluralize(self.max_choices))) return value
def clean(self, value): if not value and self.required: raise forms.ValidationError(self.error_messages['required']) if value and self.max_choices and len(value) > self.max_choices: raise forms.ValidationError(u'Você deve selecionar no máximo %s escolha%s.' % (apnumber(self.max_choices), pluralize(self.max_choices))) return value
def command(): """Generate "Next events" section for the Dispatch.""" now = timezone.now() raw_dispatch_date = click.prompt(click.style( "What is the date of the previous Dispatch? (Format: YYYY-MM-DD)", bold=True, fg='yellow')) dispatch_date = (datetime.datetime .strptime(raw_dispatch_date, "%Y-%m-%d") .replace(tzinfo=datetime.timezone.utc)) # Get the events that happened since the last Dispatch. click.echo(click.style("PREVIOUS EVENTS", bold=True)) previous_events = Event.objects.filter( date__gt=dispatch_date.strftime("%Y-%m-%d"), date__lt=now.strftime("%Y-%m-%d")) result_previous = generate_html_content(previous_events) num_events = len(result_previous) if result_previous: click.echo( "%s event%s happened since the last dispatch: " % (apnumber(num_events), "s" if num_events > 1 else "") + ", ".join(result_previous) + ".") else: click.echo("No event took place since the last Dispatch.") # Get the events that were created since the last Dispatch. click.echo(click.style("NEXT EVENTS", bold=True)) next_events = Event.objects.all().filter( created_at__range=(dispatch_date, now)).order_by("date") sorted_event = groupby(next_events, key=lambda event: event.date.month) if next_events: for month, events in sorted_event: month_list = generate_html_content(events) click.echo(calendar.month_name[ month] + ": " + ", ".join(month_list) + "." + "<br />") else: click.echo( "There's no new event to announce. Don't forget to check our " "<a href='https://djangogirls.org/events/'>website</a> to get a " "list of our events planned for the next few months.") # Get the events with open registration. click.echo("OPEN REGISTRATION") open_events = Event.objects.all().filter( form__open_from__lte=now, form__open_until__gte=now) result_open = generate_html_content(open_events) if result_open: click.echo("Registrations are still open for: " + ", ".join(result_open) + ".") else: click.echo("There's no event with open registration.")
def surviving_grands(self): grand_list = ( [self.number_of_grandchildren, u'grandchildren',], [self.number_of_step_grandchildren, u'step grandchildren',], [self.number_of_great_grandchildren, u'great-grandchildren',], [self.number_of_step_great_grandchildren, u'step great-grandchildren',], [self.number_of_great_great_grandchildren, u'great-great grandchildren',], [self.number_of_step_great_great_grandchildren, u'step great-great grandchildren',], ) # Eliminate empty 'grands' and make correct grandchildren grandchild when there's only one. grand_display_list = [] for grand in grand_list: if grand[0]: if grand[0] == u'1': grand[0] = u'a' grand[1] = grand[1][:-3] grand_display_list.append((apnumber(grand[0]), grand[1])) if grand_display_list: if len(grand_display_list) == 1: # SINGLE-ITEM grand_display_list: [(u'eight', u'grandchildren')] grand_display = u'and %s %s' % grand_display_list[0] else: # MULTI grand_display_list: [(14, u'grandchildren'), (14, u'great-grandchildren')] grand_display_list = ['%s %s' % grand_display for grand_display in grand_display_list] grand_display_list[-1] = u'and ' + grand_display_list[-1] grand_display = '; '.join( grand_display_list ) grand_display = u'; ' + grand_display else: grand_display = u'' return grand_display
def humanize_repetition(habit): if hasattr(habit, 'get_resolution_name'): resolution_name = force_text(habit.get_resolution_name()) target_value = habit.target_value else: resolution_name = habit['resolution'] target_value = habit['target_value'] if 1 == target_value: return "<em>once</em> a <em>%s</em>" % resolution_name elif 2 == target_value: return "<em>twice</em> a <em>%s</em>" % resolution_name elif 3 == target_value: return "<em>%s</em> times a <!-- lady, and I love you --> <em>%s</em>" % ( apnumber(target_value), resolution_name ) else: return "<em>%s</em> times a <em>%s</em>" % ( apnumber(target_value), resolution_name )
def experiment_date_time_range_view(request, experiment_date_id=None, experiment_date_time_range_id=None): try: researcher = request.user.researcher except Researcher.DoesNotExist: messages.add_message(request, messages.ERROR, _('Permission denied')) return HttpResponseRedirect(reverse('main-index')) message = None if experiment_date_id is not None: instance = None action = 'Create' experiment_date = get_object_or_404(ExperimentDate, id=experiment_date_id, experiment__researchers=researcher) else: instance = get_object_or_404(ExperimentDateTimeRange, id=experiment_date_time_range_id, experiment_date__experiment__researchers=researcher) action = 'Edit' experiment_date = instance.experiment_date count = Appointment.objects.filter(slot__experiment_date_time_range=instance).count() if count > 0: message = apnumber(count).title() + ' appointment' if count > 1: message += 's' if request.method == 'POST': if instance is not None and 'delete' in request.POST: instance.delete() messages.add_message(request, messages.SUCCESS, _('The experiment date time range for %s was successfully deleted.') % experiment_date) return HttpResponseRedirect(reverse('main-list_experiment_date_time_ranges', args=[experiment_date.id])) form = ExperimentDateTimeRangeForm(experiment_date, request.POST, instance=instance) if form.is_valid(): db_instance = instance is not None and ExperimentDateTimeRange.objects.get(id=instance.id) or None experiment_date_time_range = form.save(commit=False) experiment_date_time_range.experiment_date = experiment_date experiment_date_time_range.save() _ = db_instance is not None and (db_instance.start_time != experiment_date_time_range.start_time or \ db_instance.end_time != experiment_date_time_range.end_time) if _: experiment_date_time_range.slot_set.all().delete() if message is not None: if count > 1: message += ' were' else: message += ' was' messages.add_message(request, messages.SUCCESS, message + _(' successfully deleted.')) if _ or instance is None: experiment_date_time_range.create_slots() messages.add_message(request, messages.SUCCESS, _('The experiment date time range for %s was successfully saved.') % experiment_date) return HttpResponseRedirect(reverse('main-list_experiment_date_time_ranges', args=[experiment_date.id])) else: form = ExperimentDateTimeRangeForm(experiment_date, instance=instance) if message is not None: messages.add_message(request, messages.ERROR, message + _(' will be deleted if the start time field or the end time field is changed.')) return render_to_response('main/experiment_date_time_range.html', {'instance': instance, 'action': action, 'experiment_date': experiment_date, 'form': form}, RequestContext(request))
def surviving_children(self): genders = ('son', 'daughter', 'stepson', 'stepdaughter', 'adopted son', 'adopted daughter', 'child', 'stepchild',) if self.children_set.all(): gender_sub_list = [] for gender in genders: child_list = [] gender_set = self.children_set.filter(gender=gender) if gender_set: # build gender-based list for child in gender_set: if child.residence: child_list.append(u'%s of %s' % (child.name, child.residence)) elif child.name: child_list.append(u'%s' % (child.name)) else: pass if len(child_list) == 0: # No child names in list (!) child_str = '' elif len(child_list) == 1: child_str = ', '.join(child_list) else: # insert 'and" in front of last item child_list[-1] = u'and ' + child_list[-1] # merge last two items child_list[-2:] = [ ' '.join(child_list[-2:]) ] child_str = ', '.join(child_list) if len(gender_set) == 1: child_str = u' a %s, %s' % (gender, child_str) else: # pluralize un-gendered 'child' with 'ren' OR gendered children with 's' if gender.count('child'): child_str = u' %s %sren' % (apnumber(len(gender_set)), gender) else: child_str = u' %s %ss, %s' % (apnumber(len(gender_set)), gender, child_str) gender_sub_list.append(child_str) child_display = '; '.join(gender_sub_list) else: child_display = u'' return child_display
def apnumber(value): retvalue = '-' try: value = int(value) if value > 1 and value < 10: retvalue = ('%s (' + humanize.apnumber(value) + ')') % value elif value == 10: retvalue = '10 (' + _('diez') + ')' except: retvalue = value return retvalue
def experiment_view(request, id=None): try: researcher = request.user.researcher except Researcher.DoesNotExist: messages.add_message(request, messages.ERROR, _('Permission denied')) return HttpResponseRedirect(reverse('main-index')) message = None if id is None: instance = None action = 'Create' else: instance = get_object_or_404(Experiment, id=id, researchers=researcher) action = 'Edit' count = Appointment.objects.filter(slot__experiment_date_time_range__experiment_date__experiment=instance).count() if count > 0: message = apnumber(count).title() + ' appointment' if count > 1: message += 's' if request.method == 'POST': if instance is not None and 'delete' in request.POST: instance.delete() messages.add_message(request, messages.SUCCESS, _('The experiment was successfully deleted.')) return HttpResponseRedirect(reverse('main-list_experiments')) form = ExperimentForm(request.POST, instance=instance) if form.is_valid(): db_instance = instance is not None and Experiment.objects.get(id=instance.id) or None experiment = form.save() experiment.researchers.add(researcher) experiment.save() if db_instance is not None and db_instance.length != experiment.length: Slot.objects.filter(experiment_date_time_range__experiment_date__experiment=experiment).delete() if message is not None: if count > 1: message += ' were' else: message += ' was' messages.add_message(request, messages.SUCCESS, message + _(' successfully deleted.')) for experiment_date_time_range in ExperimentDateTimeRange.objects.filter(experiment_date__experiment=experiment): experiment_date_time_range.create_slots() messages.add_message(request, messages.SUCCESS, _('The experiment was successfully saved.')) return HttpResponseRedirect(reverse('main-list_experiments')) else: form = ExperimentForm(instance=instance) if message is not None: messages.add_message(request, messages.ERROR, message + _(' will be deleted if the length field is changed.')) return render_to_response('main/experiment.html', {'instance': instance, 'action': action, 'form': form}, RequestContext(request))
def get_context_data(self, **kwargs): import django.contrib.humanize.templatetags.humanize as humanize context = super(EMailConfirmationView, self).get_context_data(**kwargs) confirmed_user = self.confirm(**kwargs) if confirmed_user: context['title'] = _("Email confirmed") context['message'] = _('''Your email %s has been successfully confirmed. Your account will be activated shorlty, after which you may login.''') % confirmed_user.email #print type(confirmed_user), confirmed_user.is_active else: context['title'] = _("E-Mail confirmation failed") context['message'] = _(""" Sorry, it didn't work. Either your confirmation link was incorrect, or the confirmation key for your account has expired; confirmation keys are only valid for %s days.""") % humanize.apnumber(settings.EMAIL_CONFIRMATION_DAYS) return context
def _description_builder(self): if self.repeat_type != ScheduleRepeatType.NONE: yield 'every' if self.repeat_every > 1: yield apnumber(self.repeat_every) yield pluralize(self.repeat_every, ScheduleRepeatType.pluralized_instances_dict[self.repeat_type]) if self.repeat_type == ScheduleRepeatType.WEEKLY and \ any(getattr(self, weekday_entry[0]) for weekday_entry in WeekDay.choices): yield 'on' yield self.humanized_weekdays elif self.repeat_type == ScheduleRepeatType.MONTHLY and self.monthly_is_based_on_weekday: week_position = (datetime.date(self.start_date.year, self.start_date.month, 1).weekday() + self.start_date.day) / 7 is_last_weekday = (self.start_date + datetime.timedelta(weeks=1)).month != self.start_date.month if is_last_weekday: yield 'on the last %s' % WeekDay.choices[self.start_date.weekday()][1] else: yield 'on the %s %s' % (ordinal(week_position + 1), WeekDay.choices[self.start_date.weekday()][1]) elif self.repeat_type == ScheduleRepeatType.MONTHLY and not self.monthly_is_based_on_weekday: yield 'on the' yield ordinal(self.start_date.day) yield 'from' yield formats.date_format(self.start_date, 'SHORT_DATE_FORMAT') if self.end_date is not None: yield 'until' yield formats.date_format(self.end_date, 'SHORT_DATE_FORMAT') if self.end_after_occurrences > 0: if self.end_date: yield 'or' yield 'until' yield six.text_type(self.end_after_occurrences) yield pluralize(self.end_after_occurrences, 'occurence,occurences') yield 'took place' else: yield 'on' yield formats.date_format(self.start_date, 'SHORT_DATE_FORMAT')
def managed_blog_count(): """Displays text of how many blogs are being managed.""" blog_count = Blog.objects.all().count() return _n("Managing %(count)s WordPress blog", "Managing %(count)s WordPress blogs", blog_count) % { "count": '<span class="count">%s</span>' % apnumber(blog_count) }
def to_snake_case(string: str) -> str: name = slugify(string.lower()).replace('-', '_') if name[0].isdigit(): return apnumber(name[0]) + name[1:] return name
def notify_about_activity_log(addon, version, note, perm_setting=None, send_to_reviewers=True, send_to_staff=True): """Notify relevant users about an ActivityLog note.""" comments = (note.details or {}).get('comments') if not comments: # Just use the name of the action if no comments provided. Alas we # can't know the locale of recipient, and our templates are English # only so prevent language jumble by forcing into en-US. with translation.override(settings.LANGUAGE_CODE): comments = '%s' % amo.LOG_BY_ID[note.action].short else: htmlparser = HTMLParser() comments = htmlparser.unescape(comments) # Collect add-on authors (excl. the person who sent the email.) and build # the context for them. addon_authors = set(addon.authors.all()) - {note.user} author_context_dict = { 'name': addon.name, 'number': version.version, 'author': note.user.name, 'comments': comments, 'url': absolutify(addon.get_dev_url('versions')), 'SITE_URL': settings.SITE_URL, 'email_reason': 'you are listed as an author of this add-on', 'is_info_request': note.action == amo.LOG.REQUEST_INFORMATION.id, } # Not being localised because we don't know the recipients locale. with translation.override('en-US'): if note.action == amo.LOG.REQUEST_INFORMATION.id: if addon.pending_info_request: days_left = ( # We pad the time left with an extra hour so that the email # does not end up saying "6 days left" because a few # seconds or minutes passed between the datetime was saved # and the email was sent. addon.pending_info_request + timedelta(hours=1) - datetime.now() ).days if days_left > 9: author_context_dict['number_of_days_left'] = ( '%d days' % days_left) elif days_left > 1: author_context_dict['number_of_days_left'] = ( '%s (%d) days' % (apnumber(days_left), days_left)) else: author_context_dict['number_of_days_left'] = 'one (1) day' subject = u'Mozilla Add-ons: Action Required for %s %s' % ( addon.name, version.version) reviewer_subject = u'Mozilla Add-ons: %s %s' % ( addon.name, version.version) else: subject = reviewer_subject = u'Mozilla Add-ons: %s %s' % ( addon.name, version.version) # Build and send the mail for authors. template = template_from_user(note.user, version) from_email = formataddr((note.user.name, NOTIFICATIONS_FROM_EMAIL)) send_activity_mail( subject, template.render(author_context_dict), version, addon_authors, from_email, note.id, perm_setting) if send_to_reviewers or send_to_staff: # If task_user doesn't exist that's no big issue (i.e. in tests) try: task_user = {get_task_user()} except UserProfile.DoesNotExist: task_user = set() if send_to_reviewers: # Collect reviewers on the thread (excl. the email sender and task user # for automated messages), build the context for them and send them # their copy. log_users = { alog.user for alog in ActivityLog.objects.for_version(version) if acl.is_user_any_kind_of_reviewer(alog.user)} reviewers = log_users - addon_authors - task_user - {note.user} reviewer_context_dict = author_context_dict.copy() reviewer_context_dict['url'] = absolutify( reverse('reviewers.review', kwargs={ 'addon_id': version.addon.pk, 'channel': amo.CHANNEL_CHOICES_API[version.channel] }, add_prefix=False)) reviewer_context_dict['email_reason'] = 'you reviewed this add-on' send_activity_mail( reviewer_subject, template.render(reviewer_context_dict), version, reviewers, from_email, note.id, perm_setting) if send_to_staff: # Collect staff that want a copy of the email, build the context for # them and send them their copy. staff = set( UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP)) staff_cc = ( staff - reviewers - addon_authors - task_user - {note.user}) staff_cc_context_dict = reviewer_context_dict.copy() staff_cc_context_dict['email_reason'] = ( 'you are member of the activity email cc group') send_activity_mail( reviewer_subject, template.render(staff_cc_context_dict), version, staff_cc, from_email, note.id, perm_setting)
def apnumber(source): return humanize.apnumber(source)
def getIntroText(stats, org_type): declines = len(stats['most_changing']['declines']) improvements = len(stats['most_changing']['improvements']) possible_savings = len(stats['top_savings']['possible_savings']) worst = len(stats['worst']) best = len(stats['best']) not_great = worst + declines pretty_good = best + improvements msg = "" in_sentence = False if not_great or pretty_good or possible_savings: if not_great: msg = "We've found %s prescribing measure%s where this %s " % ( apnumber(not_great), not_great > 1 and 's' or '', org_type) in_sentence = True if declines and worst: msg += "is <span class='worse'>getting worse, or could be " msg += "doing better</span>" elif declines: msg += "is <span class='worse'>getting worse</span>" else: msg += "could be <span class='worse'>doing better</span>" else: msg = ("Good news: we've not found any problem prescribing " "measures for this %s!" % org_type) in_sentence = False if pretty_good: if msg and in_sentence: msg += ", and %s measure%s where it " % ( apnumber(pretty_good), pretty_good > 1 and 's' or '') else: msg = ("We've found %s prescribing measure%s where " "this %s " % (apnumber(pretty_good), pretty_good > 1 and 's' or '', org_type)) if best and improvements: msg += "is <span class='better'>doing well</span>." elif improvements: msg += "is <span class='better'>improving</span>." else: msg += "is <span class='better'>already doing " msg += "very well</span>." in_sentence = False if in_sentence: msg += ". " if possible_savings: if msg: msg += " We've also found " else: msg = "We've found " msg += ("%s prescribing measure%s where there are some " "potential cost savings." % ( apnumber(possible_savings), possible_savings > 1 and 's' or '')) else: msg = ("We've no new information about this %s this month! " "Its performance is not an outlier on any " "of our common prescribing measures." % org_type) return mark_safe(msg)
def readtime(text): minutes_of_read_time = len(text.split(' ')) / AVERAGE_READING_SPEED_WPM minutes_of_read_time_rounded = math.floor(minutes_of_read_time + 0.5) return apnumber(minutes_of_read_time_rounded)
from django.utils.translation import ugettext as _ from django.utils.safestring import mark_safe from museic import settings import re import tagging _WHITESPACE_REGEX = re.compile(r'\W') assert hasattr(settings, "MUSEIC_CONTENT_ROOT"), "You need to define a "\ "folder to store your content for MUSEIC in" assert hasattr(settings, "MUSEIC_CONTENT_PREFIX"), "You need to define a "\ "prefix to get your content for MUSEIC in" _FILE_STORAGE = FileSystemStorage(location=settings.MUSEIC_CONTENT_ROOT, base_url=settings.MUSEIC_CONTENT_PREFIX) FIVE_STARS = [(n, u"%s stars" % unicode(humanize.apnumber(n))) for n in xrange(5)] class Content(models.Model): """ Represents some kind of user uploaded content. This is a base class. Derived classes must override content(..) """ user = models.ForeignKey(User, db_index=True) title = models.CharField(max_length=255) slug = models.SlugField(editable=False, unique_for_date='pub_date') pub_date = models.DateTimeField(auto_now_add=True,
def __unicode__(self): return "%s Pack - $%s" % ((str(apnumber(self.quantity)).capitalize()), floatformat(self.price, -2))
def notify_about_activity_log(addon, version, note, perm_setting=None, send_to_reviewers=True, send_to_staff=True): """Notify relevant users about an ActivityLog note.""" comments = (note.details or {}).get('comments') if not comments: # Just use the name of the action if no comments provided. Alas we # can't know the locale of recipient, and our templates are English # only so prevent language jumble by forcing into en-US. with translation.override(settings.LANGUAGE_CODE): comments = '%s' % amo.LOG_BY_ID[note.action].short else: comments = unescape(comments) # Collect add-on authors (excl. the person who sent the email.) and build # the context for them. addon_authors = set(addon.authors.all()) - {note.user} author_context_dict = { 'name': addon.name, 'number': version.version, 'author': note.author_name, 'comments': comments, 'url': absolutify(addon.get_dev_url('versions')), 'SITE_URL': settings.SITE_URL, 'email_reason': 'you are listed as an author of this add-on', 'is_info_request': note.action == amo.LOG.REQUEST_INFORMATION.id, } # Not being localised because we don't know the recipients locale. with translation.override('en-US'): if note.action == amo.LOG.REQUEST_INFORMATION.id: if addon.pending_info_request: days_left = ( # We pad the time left with an extra hour so that the email # does not end up saying "6 days left" because a few # seconds or minutes passed between the datetime was saved # and the email was sent. addon.pending_info_request + timedelta(hours=1) - datetime.now() ).days if days_left > 9: author_context_dict['number_of_days_left'] = ( '%d days' % days_left) elif days_left > 1: author_context_dict['number_of_days_left'] = ( '%s (%d) days' % (apnumber(days_left), days_left)) else: author_context_dict['number_of_days_left'] = 'one (1) day' subject = u'Mozilla Add-ons: Action Required for %s %s' % ( addon.name, version.version) reviewer_subject = u'Mozilla Add-ons: %s %s' % ( addon.name, version.version) else: subject = reviewer_subject = u'Mozilla Add-ons: %s %s' % ( addon.name, version.version) # Build and send the mail for authors. template = template_from_user(note.user, version) from_email = formataddr((note.author_name, NOTIFICATIONS_FROM_EMAIL)) send_activity_mail( subject, template.render(author_context_dict), version, addon_authors, from_email, note.id, perm_setting) if send_to_reviewers or send_to_staff: # If task_user doesn't exist that's no big issue (i.e. in tests) try: task_user = {get_task_user()} except UserProfile.DoesNotExist: task_user = set() if send_to_reviewers: # Collect reviewers on the thread (excl. the email sender and task user # for automated messages), build the context for them and send them # their copy. log_users = { alog.user for alog in ActivityLog.objects.for_version(version) if acl.is_user_any_kind_of_reviewer(alog.user)} reviewers = log_users - addon_authors - task_user - {note.user} reviewer_context_dict = author_context_dict.copy() reviewer_context_dict['url'] = absolutify( reverse('reviewers.review', kwargs={ 'addon_id': version.addon.pk, 'channel': amo.CHANNEL_CHOICES_API[version.channel] }, add_prefix=False)) reviewer_context_dict['email_reason'] = 'you reviewed this add-on' send_activity_mail( reviewer_subject, template.render(reviewer_context_dict), version, reviewers, from_email, note.id, perm_setting) if send_to_staff: # Collect staff that want a copy of the email, build the context for # them and send them their copy. staff = set( UserProfile.objects.filter(groups__name=ACTIVITY_MAIL_GROUP)) staff_cc = ( staff - reviewers - addon_authors - task_user - {note.user}) staff_cc_context_dict = reviewer_context_dict.copy() staff_cc_context_dict['email_reason'] = ( 'you are member of the activity email cc group') send_activity_mail( reviewer_subject, template.render(staff_cc_context_dict), version, staff_cc, from_email, note.id, perm_setting)
def command(): """Generate "Next events" section for the Dispatch.""" now = timezone.now() raw_dispatch_date = click.prompt( click.style( "What is the date of the previous Dispatch? (Format: YYYY-MM-DD)", bold=True, fg='yellow')) dispatch_date = (datetime.datetime.strptime( raw_dispatch_date, "%Y-%m-%d").replace(tzinfo=datetime.timezone.utc)) # Get the events that happened since the last Dispatch. click.echo(click.style("PREVIOUS EVENTS", bold=True)) previous_events = Event.objects.filter( date__gt=dispatch_date.strftime("%Y-%m-%d"), date__lt=now.strftime("%Y-%m-%d"), eventpage__isnull=False) result_previous = generate_html_content(previous_events) num_events = len(result_previous) if result_previous: click.echo("%s event%s happened since the last dispatch: " % (apnumber(num_events), "s" if num_events > 1 else "") + ", ".join(result_previous) + ".") else: click.echo("No event took place since the last Dispatch.") # Get the events that were created since the last Dispatch. click.echo(click.style("NEXT EVENTS", bold=True)) next_events = Event.objects.all().filter( created_at__range=(dispatch_date, now), eventpage__isnull=False).order_by("date") sorted_event = groupby(next_events, key=lambda event: event.date.month) if next_events: for month, events in sorted_event: month_list = generate_html_content(events) click.echo(calendar.month_name[month] + ": " + ", ".join(month_list) + "." + "<br />") else: click.echo( "There's no new event to announce. Don't forget to check our " "<a href='https://djangogirls.org/events/'>website</a> to get a " "list of our events planned for the next few months.") # Get the events with open registration. click.echo("OPEN REGISTRATION") open_events = Event.objects.all().filter( eventpage__form__open_from__lte=now, eventpage__form__open_until__gte=now, eventpage__isnull=False) result_open = generate_html_content(open_events) if result_open: click.echo("Registrations are still open for: " + ", ".join(result_open) + ".") else: click.echo("There's no event with open registration.")
def getIntroText(stats, org_type): declines = len(stats['most_changing']['declines']) improvements = len(stats['most_changing']['improvements']) possible_savings = len(stats['top_savings']['possible_savings']) worst = len(stats['worst']) best = len(stats['best']) not_great = worst + declines pretty_good = best + improvements msg = "" in_sentence = False if not_great or pretty_good or possible_savings: if not_great: msg = "We've found %s prescribing measure%s where this %s " % ( apnumber(not_great), not_great > 1 and 's' or '', org_type) in_sentence = True if declines and worst: msg += "is <span class='worse'>getting worse, or could be " msg += "doing better</span>" elif declines: msg += "is <span class='worse'>getting worse</span>" else: msg += "could be <span class='worse'>doing better</span>" else: msg = ("Good news: we've not found any problem prescribing " "measures for this %s!" % org_type) in_sentence = False if pretty_good: if msg and in_sentence: msg += ", and %s measure%s where it " % ( apnumber(pretty_good), pretty_good > 1 and 's' or '') else: msg = ("We've found %s prescribing measure%s where " "this %s " % (apnumber(pretty_good), pretty_good > 1 and 's' or '', org_type)) if best and improvements: msg += "is <span class='better'>doing well</span>." elif improvements: msg += "is <span class='better'>improving</span>." else: msg += "is <span class='better'>already doing " msg += "very well</span>." in_sentence = False if in_sentence: msg += ". " if possible_savings: if msg: msg += " We've also found " else: msg = "We've found " msg += ("%s prescribing measure%s where there are some " "potential cost savings. " % (apnumber(possible_savings), possible_savings > 1 and 's' or '')) msg += ('Note that there can sometimes be good reasons why one CCG is ' 'an outlier, and you should interpret the data thoughtfully: ' 'these are <a href="/faq/#measureinterpret">measures, not ' 'indicators</a>.') else: msg = ("We've no new information about this %s this month! " "Its performance is not an outlier on any " "of our common prescribing measures. " % org_type) return mark_safe(msg)