Exemple #1
0
    def schedules_for_bin(self):
        schedules = self.get_schedules_with_target_date_by_bin_and_orgs()
        template_context = get_base_template_context(self.site)

        for (user, user_schedules) in groupby(schedules,
                                              lambda s: s.enrollment.user):
            user_schedules = list(user_schedules)
            course_id_strs = [
                str(schedule.enrollment.course_id)
                for schedule in user_schedules
            ]

            # This is used by the bulk email optout policy
            template_context['course_ids'] = course_id_strs

            first_schedule = user_schedules[0]
            try:
                template_context.update(
                    self.get_template_context(user, user_schedules))
            except InvalidContextError:
                continue

            yield (user,
                   first_schedule.enrollment.course.closest_released_language,
                   template_context)
Exemple #2
0
    def schedules_for_bin(self):
        week_num = abs(self.day_offset) / 7
        schedules = self.get_schedules_with_target_date_by_bin_and_orgs(
            order_by='enrollment__course', )

        template_context = get_base_template_context(self.site)
        for schedule in schedules:
            enrollment = schedule.enrollment
            try:
                week_highlights = get_week_highlights(enrollment.course_id,
                                                      week_num)
            except CourseUpdateDoesNotExist:
                continue

            user = enrollment.user
            course_id_str = str(enrollment.course_id)

            template_context.update({
                'course_name':
                schedule.enrollment.course.display_name,
                'course_url':
                absolute_url(self.site,
                             reverse('course_root', args=[course_id_str])),
                'week_num':
                week_num,
                'week_highlights':
                week_highlights,

                # This is used by the bulk email optout policy
                'course_ids': [course_id_str],
            })
            template_context.update(
                _get_upsell_information_for_schedule(user, schedule))

            yield (user, schedule.enrollment.course.language, template_context)
Exemple #3
0
def _build_message_context(context):
    message_context = get_base_template_context(
        Site.objects.get(id=context['site_id']))
    message_context.update(_deserialize_context_dates(context))
    message_context['post_link'] = _get_thread_url(context)
    message_context['ga_tracking_pixel_url'] = _generate_ga_pixel_url(context)
    return message_context
Exemple #4
0
    def schedules_for_bin(self):
        week_num = abs(self.day_offset) / 7
        schedules = self.get_schedules_with_target_date_by_bin_and_orgs(
            order_by='enrollment__course',
        )

        template_context = get_base_template_context(self.site)
        for schedule in schedules:
            enrollment = schedule.enrollment
            try:
                week_highlights = get_week_highlights(enrollment.course_id, week_num)
            except CourseUpdateDoesNotExist:
                continue

            user = enrollment.user
            course_id_str = str(enrollment.course_id)

            template_context.update({
                'course_name': schedule.enrollment.course.display_name,
                'course_url': absolute_url(
                    self.site, reverse('course_root', args=[course_id_str])
                ),
                'week_num': week_num,
                'week_highlights': week_highlights,

                # This is used by the bulk email optout policy
                'course_ids': [course_id_str],
            })
            template_context.update(_get_upsell_information_for_schedule(user, schedule))

            yield (user, schedule.enrollment.course.language, template_context)
Exemple #5
0
def _recurring_nudge_schedules_for_bin(site, target_day, bin_num, org_list, exclude_orgs=False):
    beginning_of_day = target_day.replace(hour=0, minute=0, second=0)
    schedules = get_schedules_with_target_date_by_bin_and_orgs(
        schedule_date_field='start',
        target_date=beginning_of_day,
        bin_num=bin_num,
        num_bins=RECURRING_NUDGE_NUM_BINS,
        org_list=org_list,
        exclude_orgs=exclude_orgs,
    )

    LOG.debug('Recurring Nudge: Query = %r', schedules.query.sql_with_params())

    for (user, user_schedules) in groupby(schedules, lambda s: s.enrollment.user):
        user_schedules = list(user_schedules)
        course_id_strs = [str(schedule.enrollment.course_id) for schedule in user_schedules]

        first_schedule = user_schedules[0]
        template_context = get_base_template_context(site)
        template_context.update({
            'student_name': user.profile.name,

            'course_name': first_schedule.enrollment.course.display_name,
            'course_url': absolute_url(site, reverse('course_root', args=[str(first_schedule.enrollment.course_id)])),

            # This is used by the bulk email optout policy
            'course_ids': course_id_strs,
        })

        # Information for including upsell messaging in template.
        _add_upsell_button_information_to_template_context(user, first_schedule, template_context)

        yield (user, first_schedule.enrollment.course.language, template_context)
Exemple #6
0
def _recurring_nudge_schedules_for_bin(site, current_datetime, target_datetime, bin_num, org_list, exclude_orgs=False):
    schedules = get_schedules_with_target_date_by_bin_and_orgs(
        schedule_date_field='start',
        current_datetime=current_datetime,
        target_datetime=target_datetime,
        bin_num=bin_num,
        num_bins=RECURRING_NUDGE_NUM_BINS,
        org_list=org_list,
        exclude_orgs=exclude_orgs,
    )

    LOG.debug('Recurring Nudge: Query = %r', schedules.query.sql_with_params())

    for (user, user_schedules) in groupby(schedules, lambda s: s.enrollment.user):
        user_schedules = list(user_schedules)
        course_id_strs = [str(schedule.enrollment.course_id) for schedule in user_schedules]

        first_schedule = user_schedules[0]
        template_context = get_base_template_context(site)
        template_context.update({
            'student_name': user.profile.name,

            'course_name': first_schedule.enrollment.course.display_name,
            'course_url': absolute_url(site, reverse('course_root', args=[str(first_schedule.enrollment.course_id)])),

            # This is used by the bulk email optout policy
            'course_ids': course_id_strs,
        })

        # Information for including upsell messaging in template.
        _add_upsell_button_information_to_template_context(user, first_schedule, template_context)

        yield (user, first_schedule.enrollment.course.language, template_context)
Exemple #7
0
def _upgrade_reminder_schedules_for_bin(site,
                                        current_datetime,
                                        target_datetime,
                                        bin_num,
                                        org_list,
                                        exclude_orgs=False):
    schedules = get_schedules_with_target_date_by_bin_and_orgs(
        schedule_date_field='upgrade_deadline',
        current_datetime=current_datetime,
        target_datetime=target_datetime,
        bin_num=bin_num,
        num_bins=RECURRING_NUDGE_NUM_BINS,
        org_list=org_list,
        exclude_orgs=exclude_orgs,
    )

    for schedule in schedules:
        enrollment = schedule.enrollment
        user = enrollment.user

        course_id_str = str(enrollment.course_id)

        # TODO: group by schedule and user like recurring nudge
        course_id_strs = [course_id_str]
        first_schedule = schedule

        template_context = get_base_template_context(site)
        template_context.update({
            'student_name':
            user.profile.name,
            'user_personal_address':
            user.profile.name if user.profile.name else user.username,
            'course_name':
            first_schedule.enrollment.course.display_name,
            'course_url':
            absolute_url(
                site,
                reverse('course_root',
                        args=[str(first_schedule.enrollment.course_id)])),

            # This is used by the bulk email optout policy
            'course_ids':
            course_id_strs,
            'cert_image':
            absolute_url(site,
                         static('course_experience/images/verified-cert.png')),
        })

        _add_upsell_button_information_to_template_context(
            user, first_schedule, template_context)

        yield (user, first_schedule.enrollment.course.language,
               template_context)
Exemple #8
0
def _course_update_schedules_for_bin(site,
                                     current_datetime,
                                     target_datetime,
                                     day_offset,
                                     bin_num,
                                     org_list,
                                     exclude_orgs=False):
    week_num = abs(day_offset) / 7
    schedules = get_schedules_with_target_date_by_bin_and_orgs(
        schedule_date_field='start',
        current_datetime=current_datetime,
        target_datetime=target_datetime,
        bin_num=bin_num,
        num_bins=COURSE_UPDATE_NUM_BINS,
        org_list=org_list,
        exclude_orgs=exclude_orgs,
        order_by='enrollment__course',
    )

    for schedule in schedules:
        enrollment = schedule.enrollment
        try:
            week_summary = get_course_week_summary(enrollment.course_id,
                                                   week_num)
        except CourseUpdateDoesNotExist:
            continue

        user = enrollment.user
        course_id_str = str(enrollment.course_id)

        template_context = get_base_template_context(site)
        template_context.update({
            'student_name':
            user.profile.name,
            'user_personal_address':
            user.profile.name if user.profile.name else user.username,
            'course_name':
            schedule.enrollment.course.display_name,
            'course_url':
            absolute_url(
                site,
                reverse('course_root',
                        args=[str(schedule.enrollment.course_id)])),
            'week_num':
            week_num,
            'week_summary':
            week_summary,

            # This is used by the bulk email optout policy
            'course_ids': [course_id_str],
        })

        yield (user, schedule.enrollment.course.language, template_context)
Exemple #9
0
    def test_send_discussion_email_notification(self, user_subscribed):
        if user_subscribed:
            non_matching_id = 'not-a-match'
            # with per_page left with a default value of 1, this ensures
            # that we test a multiple page result when calling
            # comment_client.User.subscribed_threads()
            subscribed_thread_ids = [non_matching_id, self.discussion_id]
        else:
            subscribed_thread_ids = []

        self.mock_request.side_effect = make_mock_responder(
            subscribed_thread_ids=subscribed_thread_ids,
            comment_data=self.comment,
            thread_data=self.thread,
        )
        user = mock.Mock()
        comment = cc.Comment.find(id=self.comment['id']).retrieve()
        site = Site.objects.get_current()
        site_config = SiteConfigurationFactory.create(site=site)
        site_config.values[ENABLE_FORUM_NOTIFICATIONS_FOR_SITE_KEY] = True
        site_config.save()
        with waffle().override(FORUM_RESPONSE_NOTIFICATIONS):
            with mock.patch('lms.djangoapps.discussion.signals.handlers.get_current_site', return_value=site):
                comment_created.send(sender=None, user=user, post=comment)

        if user_subscribed:
            expected_message_context = get_base_template_context(site)
            expected_message_context.update({
                'comment_author_id': self.comment_author.id,
                'comment_body': self.comment['body'],
                'comment_created_at': ONE_HOUR_AGO,
                'comment_id': self.comment['id'],
                'comment_username': self.comment_author.username,
                'course_id': self.course.id,
                'thread_author_id': self.thread_author.id,
                'thread_created_at': TWO_HOURS_AGO,
                'thread_id': self.discussion_id,
                'thread_title': 'thread-title',
                'thread_username': self.thread_author.username,
                'thread_commentable_id': self.thread['commentable_id'],
                'post_link': self.mock_permalink.return_value,
                'site': site,
                'site_id': site.id
            })
            expected_recipient = Recipient(self.thread_author.username, self.thread_author.email)
            actual_message = self.mock_ace_send.call_args_list[0][0][0]
            self.assertEqual(expected_message_context, actual_message.context)
            self.assertEqual(expected_recipient, actual_message.recipient)
            self.assertEqual(self.course.language, actual_message.language)
            self._assert_rendered_email(actual_message)
        else:
            self.assertFalse(self.mock_ace_send.called)
Exemple #10
0
def _build_message_context(context):
    message_context = get_base_template_context(context['site'])
    message_context.update(context)
    thread_author = User.objects.get(id=context['thread_author_id'])
    comment_author = User.objects.get(id=context['comment_author_id'])
    message_context.update({
        'thread_username': thread_author.username,
        'comment_username': comment_author.username,
        'post_link': _get_thread_url(context),
        'comment_created_at': date.deserialize(context['comment_created_at']),
        'thread_created_at': date.deserialize(context['thread_created_at'])
    })
    return message_context
Exemple #11
0
def _upgrade_reminder_schedules_for_bin(site, target_day, bin_num, org_list, exclude_orgs=False):
    beginning_of_day = target_day.replace(hour=0, minute=0, second=0)

    schedules = get_schedules_with_target_date_by_bin_and_orgs(
        schedule_date_field='upgrade_deadline',
        target_date=beginning_of_day,
        bin_num=bin_num,
        num_bins=RECURRING_NUDGE_NUM_BINS,
        org_list=org_list,
        exclude_orgs=exclude_orgs,
    )

    LOG.debug('Upgrade Reminder: Query = %r', schedules.query.sql_with_params())

    for schedule in schedules:
        enrollment = schedule.enrollment
        user = enrollment.user

        course_id_str = str(enrollment.course_id)

        # TODO: group by schedule and user like recurring nudge
        course_id_strs = [course_id_str]
        first_schedule = schedule

        template_context = get_base_template_context(site)
        template_context.update({
            'student_name': user.profile.name,
            'user_personal_address': user.profile.name if user.profile.name else user.username,
            'user_schedule_upgrade_deadline_time': dateformat.format(
                schedule.upgrade_deadline,
                get_format(
                    'DATE_FORMAT',
                    lang=first_schedule.enrollment.course.language,
                    use_l10n=True
                )
            ),

            'course_name': first_schedule.enrollment.course.display_name,
            'course_url': absolute_url(site, reverse('course_root', args=[str(first_schedule.enrollment.course_id)])),

            # This is used by the bulk email optout policy
            'course_ids': course_id_strs,
            'cert_image': absolute_url(site, static('course_experience/images/verified-cert.png')),
        })

        yield (user, first_schedule.enrollment.course.language, template_context)
Exemple #12
0
    def schedules_for_bin(self):
        schedules = self.get_schedules_with_target_date_by_bin_and_orgs()
        template_context = get_base_template_context(self.site)

        for (user, user_schedules) in groupby(schedules, lambda s: s.enrollment.user):
            user_schedules = list(user_schedules)
            course_id_strs = [str(schedule.enrollment.course_id) for schedule in user_schedules]

            # This is used by the bulk email optout policy
            template_context['course_ids'] = course_id_strs

            first_schedule = user_schedules[0]
            try:
                template_context.update(self.get_template_context(user, user_schedules))
            except InvalidContextError:
                continue

            yield (user, first_schedule.enrollment.course.language, template_context)
Exemple #13
0
def _course_update_schedules_for_bin(site, current_datetime, target_datetime, day_offset, bin_num, org_list,
                                     exclude_orgs=False):
    week_num = abs(day_offset) / 7
    schedules = get_schedules_with_target_date_by_bin_and_orgs(
        schedule_date_field='start',
        current_datetime=current_datetime,
        target_datetime=target_datetime,
        bin_num=bin_num,
        num_bins=COURSE_UPDATE_NUM_BINS,
        org_list=org_list,
        exclude_orgs=exclude_orgs,
        order_by='enrollment__course',
    )

    LOG.debug('Course Update: Query = %r', schedules.query.sql_with_params())

    for schedule in schedules:
        enrollment = schedule.enrollment
        try:
            week_summary = get_course_week_summary(enrollment.course_id, week_num)
        except CourseUpdateDoesNotExist:
            continue

        user = enrollment.user
        course_id_str = str(enrollment.course_id)

        template_context = get_base_template_context(site)
        template_context.update({
            'student_name': user.profile.name,
            'user_personal_address': user.profile.name if user.profile.name else user.username,
            'course_name': schedule.enrollment.course.display_name,
            'course_url': absolute_url(site, reverse('course_root', args=[str(schedule.enrollment.course_id)])),
            'week_num': week_num,
            'week_summary': week_summary,

            # This is used by the bulk email optout policy
            'course_ids': [course_id_str],
        })

        yield (user, schedule.enrollment.course.language, template_context)
Exemple #14
0
def _upgrade_reminder_schedules_for_bin(site, current_datetime, target_datetime, bin_num, org_list, exclude_orgs=False):
    schedules = get_schedules_with_target_date_by_bin_and_orgs(
        schedule_date_field='upgrade_deadline',
        current_datetime=current_datetime,
        target_datetime=target_datetime,
        bin_num=bin_num,
        num_bins=RECURRING_NUDGE_NUM_BINS,
        org_list=org_list,
        exclude_orgs=exclude_orgs,
    )

    LOG.debug('Upgrade Reminder: Query = %r', schedules.query.sql_with_params())

    for schedule in schedules:
        enrollment = schedule.enrollment
        user = enrollment.user

        course_id_str = str(enrollment.course_id)

        # TODO: group by schedule and user like recurring nudge
        course_id_strs = [course_id_str]
        first_schedule = schedule

        template_context = get_base_template_context(site)
        template_context.update({
            'student_name': user.profile.name,
            'user_personal_address': user.profile.name if user.profile.name else user.username,

            'course_name': first_schedule.enrollment.course.display_name,
            'course_url': absolute_url(site, reverse('course_root', args=[str(first_schedule.enrollment.course_id)])),

            # This is used by the bulk email optout policy
            'course_ids': course_id_strs,
            'cert_image': absolute_url(site, static('course_experience/images/verified-cert.png')),
        })

        _add_upsell_button_information_to_template_context(user, first_schedule, template_context)

        yield (user, first_schedule.enrollment.course.language, template_context)
Exemple #15
0
    def schedules_for_bin(self):
        week_num = abs(self.day_offset) / 7
        schedules = self.get_schedules_with_target_date_by_bin_and_orgs(
            order_by='enrollment__course', )

        template_context = get_base_template_context(self.site)
        for schedule in schedules:
            enrollment = schedule.enrollment
            user = enrollment.user

            try:
                week_highlights = get_week_highlights(user,
                                                      enrollment.course_id,
                                                      week_num)
            except CourseUpdateDoesNotExist:
                LOG.exception(
                    'Weekly highlights for user {} in week {} of course {} does not exist or is disabled'
                    .format(user, week_num, enrollment.course_id))

            template_context.update({
                'course_name':
                schedule.enrollment.course.display_name,
                'course_url':
                _get_trackable_course_home_url(enrollment.course_id),
                'week_num':
                week_num,
                'week_highlights':
                week_highlights,

                # This is used by the bulk email optout policy
                'course_ids': [str(enrollment.course_id)],
            })
            template_context.update(
                _get_upsell_information_for_schedule(user, schedule))

            yield (user, schedule.enrollment.course.closest_released_language,
                   template_context)
Exemple #16
0
    def test_send_discussion_email_notification(self, user_subscribed):
        with mock_the_things() as mocked_items:
            mock_request, mock_ace_send, mock_permalink = mocked_items
            if user_subscribed:
                non_matching_id = 'not-a-match'
                # with per_page left with a default value of 1, this ensures
                # that we test a multiple page result when calling
                # comment_client.User.subscribed_threads()
                mock_request.side_effect = make_mock_responder([non_matching_id, self.discussion_id])
            else:
                mock_request.side_effect = make_mock_responder([])

            now = datetime.utcnow()
            one_hour_ago = now - timedelta(hours=1)
            thread = mock.Mock(
                id=self.discussion_id,
                course_id=self.course.id,
                created_at=one_hour_ago,
                title='thread-title',
                user_id=self.thread_author.id,
                username=self.thread_author.username,
                commentable_id='thread-commentable-id'
            )
            comment = mock.Mock(
                id='comment-id',
                body='comment-body',
                created_at=now,
                thread=thread,
                user_id=self.comment_author.id,
                username=self.comment_author.username
            )
            user = mock.Mock()

            with waffle().override(FORUM_RESPONSE_NOTIFICATIONS):
                comment_created.send(sender=None, user=user, post=comment)

            if user_subscribed:
                expected_message_context = get_base_template_context(Site.objects.get_current())
                expected_message_context.update({
                    'comment_author_id': self.comment_author.id,
                    'comment_body': 'comment-body',
                    'comment_created_at': now,
                    'comment_id': 'comment-id',
                    'comment_username': self.comment_author.username,
                    'course_id': self.course.id,
                    'thread_author_id': self.thread_author.id,
                    'thread_created_at': one_hour_ago,
                    'thread_id': self.discussion_id,
                    'thread_title': 'thread-title',
                    'thread_username': self.thread_author.username,
                    'thread_commentable_id': 'thread-commentable-id',
                    'post_link': urljoin(Site.objects.get_current().domain, mock_permalink.return_value),
                    'site': Site.objects.get_current(),
                    'site_id': Site.objects.get_current().id,
                })
                ga_tracking_pixel_url = _generate_ga_pixel_url(expected_message_context)
                expected_message_context.update({'ga_tracking_pixel_url': ga_tracking_pixel_url})
                expected_recipient = Recipient(self.thread_author.username, self.thread_author.email)
                actual_message = mock_ace_send.call_args_list[0][0][0]
                self.assertEqual(expected_message_context, actual_message.context)
                self.assertEqual(expected_recipient, actual_message.recipient)
                self.assertEqual(self.course.language, actual_message.language)
            else:
                self.assertFalse(mock_ace_send.called)
Exemple #17
0
def _build_message_context(context):
    message_context = get_base_template_context(context['site'])
    message_context.update(context)
    message_context['post_link'] = _get_thread_url(context)
    message_context['ga_tracking_pixel_url'] = _generate_ga_pixel_url(context)
    return message_context