예제 #1
0
    def test_creates_one_email_per_person_with_different_languages(self):
        n = 5

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='en'))

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='de'))

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='fr'))

        from_date, to_date = group_emails.calculate_group_summary_dates(
            self.group)
        context = group_emails.prepare_group_summary_data(
            self.group, from_date, to_date)
        emails = group_emails.prepare_group_summary_emails(self.group, context)
        self.assertEqual(len(emails), 15)

        to = []
        for email in emails:
            to.extend(email.to)

        expected_members = self.group.members.filter(
            groupmembership__in=GroupMembership.objects.active(
            ).with_notification_type(GroupNotificationType.WEEKLY_SUMMARY)
        ).exclude(
            groupmembership__user__in=get_user_model().objects.unverified())

        self.assertEqual(sorted(to),
                         sorted([member.email for member in expected_members]))

        self.assertNotIn(self.user_without_notifications.email, to)
예제 #2
0
 def test_summary_email_dates_printed_correctly(self):
     mail.outbox = []
     with timezone.override(timezone.utc), freeze_time(
             datetime.datetime(2018, 8, 19)):  # Sunday
         group = GroupFactory()
         self.make_activity_in_group(group)
         from_date, to_date = calculate_group_summary_dates(group)
         context = prepare_group_summary_data(group, from_date, to_date)
         emails = prepare_group_summary_emails(group, context)
         self.assertGreater(len(emails), 0)
         email = emails[0]
         expected_format = 'Sunday, August 12, 2018 to Saturday, August 18, 2018'
         self.assertIn(expected_format, email.body)
    def test_creates_emails_unknown_locale(self):
        n = 5

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='dummy'))

        from_date, to_date = group_emails.calculate_group_summary_dates(self.group)
        context = group_emails.prepare_group_summary_data(self.group, from_date, to_date)
        emails = group_emails.prepare_group_summary_emails(self.group, context)
        self.assertEqual(len(emails), 5)

        expected_members = self.group.members.filter(
            groupmembership__in=GroupMembership.objects.active().
            with_notification_type(GroupNotificationType.WEEKLY_SUMMARY)
        ).exclude(groupmembership__user__in=get_user_model().objects.unverified())

        self.assertEqual(
            sorted([email.to[0] for email in emails]), sorted([member.email for member in expected_members])
        )
        self.assertNotIn(self.user_without_notifications.email, emails[0].to)
예제 #4
0
def send_summary_emails():
    """
    We want to send them on Sunday at 8am in the local time of the group
    So we run this each hour to check if any group needs their summary email sending.
    We limit it to just the weekend (Saturday, Sunday) as this will cover any possible timezone offset (-11/+12)
    In cron Sunday is day 0 and Saturday is day 6
    """
    with timer() as t:
        email_count = 0
        recipient_count = 0

        def is_8am_localtime(group):
            with timezone.override(group.timezone):
                localtime = timezone.localtime()
                # Sunday is day 6 here, confusing!
                return localtime.hour == 8 and localtime.weekday() == 6

        groups = Group.objects.annotate(member_count=Count('members')).filter(
            member_count__gt=0)

        for group in groups:
            if not is_8am_localtime(group):
                continue

            from_date, to_date = calculate_group_summary_dates(group)

            if not group.sent_summary_up_to or group.sent_summary_up_to < to_date:

                email_recipient_count = 0

                context = prepare_group_summary_data(group, from_date, to_date)
                if context['has_activity']:
                    for email in prepare_group_summary_emails(group, context):
                        try:
                            email.send()
                            email_count += 1
                            email_recipient_count += len(email.to)
                        except AnymailAPIError:
                            sentry_client.captureException()

                # we save this even if some of the email sending fails, no retries right now basically...
                # we also save if no emails were sent due to missing activity, to not try again over and over.
                group.sent_summary_up_to = to_date
                group.save()

                group_summary_email(
                    group,
                    email_recipient_count=email_recipient_count,
                    feedback_count=context['feedbacks'].count(),
                    message_count=context['messages'].count(),
                    new_user_count=context['new_users'].count(),
                    activities_done_count=context['activities_done_count'],
                    activities_missed_count=context['activities_missed_count'],
                    has_activity=context['has_activity'],
                )

                recipient_count += email_recipient_count

    stats_utils.periodic_task('group__send_summary_emails',
                              seconds=t.elapsed_seconds,
                              extra_fields={
                                  'recipient_count': recipient_count,
                                  'email_count': email_count,
                              })