Esempio n. 1
0
 def run(
     self,
     site_id,
     target_day_str,
     day_offset,
     bin_num,
     override_recipient_email=None,
 ):
     msg_type = self.make_message_type(day_offset)
     site = Site.objects.select_related('configuration').get(id=site_id)
     middleware_classes = [
         CurrentRequestUserMiddleware,
         CurrentSiteThemeMiddleware,
     ]
     with emulate_http_request(site=site,
                               middleware_classes=middleware_classes):
         _annotate_for_monitoring(msg_type, site, bin_num, target_day_str,
                                  day_offset)
         return self.resolver(
             self.async_send_task,
             site,
             deserialize(target_day_str),
             day_offset,
             bin_num,
             override_recipient_email=override_recipient_email,
         ).send(msg_type)
Esempio n. 2
0
def send_ace_message_for_reported_content(context):  # lint-amnesty, pylint: disable=missing-function-docstring
    context['course_id'] = CourseKey.from_string(context['course_id'])
    context['course_name'] = modulestore().get_course(
        context['course_id']).display_name

    moderators = get_users_with_moderator_roles(context)
    context['site'] = Site.objects.get(id=context['site_id'])
    if not _is_content_still_reported(context):
        log.info(
            'Reported content is no longer in reported state. Email to moderators will not be sent.'
        )
        return
    for moderator in moderators:
        with emulate_http_request(
                site=context['site'],
                user=User.objects.get(id=context['user_id'])):
            message_context = _build_message_context_for_reported_content(
                context, moderator)
            message = ReportedContentNotification().personalize(
                Recipient(moderator.id, moderator.email),
                _get_course_language(context['course_id']), message_context)
            log.info(
                f'Sending forum reported content email notification with context {message_context}'
            )
            ace.send(message)
Esempio n. 3
0
 def run(  # pylint: disable=arguments-differ
     self,
     site_id,
     course_key,
     target_day_str,
     day_offset,
     bin_num,
     override_recipient_email=None,
 ):
     try:
         site = Site.objects.select_related('configuration').get(id=site_id)
         with emulate_http_request(site=site):
             msg_type = self.make_message_type(day_offset)
             _annotate_for_monitoring(msg_type, course_key, bin_num,
                                      target_day_str, day_offset)
             return self.resolver(  # pylint: disable=not-callable
                 self.async_send_task,
                 site,
                 course_key,
                 deserialize(target_day_str),
                 day_offset,
                 bin_num,
                 override_recipient_email=override_recipient_email,
             ).send(msg_type)
     except Exception:  # pylint: disable=broad-except
         LOG.exception("Task failed")
    def send_password_reset_email(self, user, site):
        """
        Send email to learner with reset password link
        :param user:
        :param site:
        """
        message_context = get_base_template_context(site)
        email = user.email
        message_context.update({
            'email':
            email,
            'platform_name':
            configuration_helpers.get_value('PLATFORM_NAME',
                                            settings.PLATFORM_NAME),
            'reset_link':
            '{protocol}://{site}{link}?track=pwreset'.format(
                protocol='http',
                site=configuration_helpers.get_value('SITE_NAME',
                                                     settings.SITE_NAME),
                link=reverse('password_reset_confirm',
                             kwargs={
                                 'uidb36': int_to_base36(user.id),
                                 'token':
                                 default_token_generator.make_token(user),
                             }),
            )
        })

        with emulate_http_request(site, user):
            msg = PasswordReset().personalize(
                recipient=Recipient(user.username, email),
                language=get_user_preference(user, LANGUAGE_KEY),
                user_context=message_context,
            )
            ace.send(msg)
Esempio n. 5
0
 def _assert_rendered_email(self, message):  # lint-amnesty, pylint: disable=missing-function-docstring
     # check that we can actually render the message
     with emulate_http_request(site=message.context['site'],
                               user=self.thread_author):
         rendered_email = EmailRenderer().render(
             get_channel_for_message(ChannelType.EMAIL, message), message)
         assert self.comment['body'] in rendered_email.body_html
         assert self.comment_author.username in rendered_email.body_html
         assert self.mock_permalink.return_value in rendered_email.body_html
         assert message.context['site'].domain in rendered_email.body_html
Esempio n. 6
0
def send_ace_message(context):
    context['course_id'] = CourseKey.from_string(context['course_id'])

    #Added by Mahendra
    course_authors = CourseAccessRole.objects.filter(
        course_id=context['course_id'],
        role='staff') | CourseAccessRole.objects.filter(
            course_id=context['course_id'], role='instructor')
    user_ids = []
    for userid in course_authors:
        user_ids.append(userid.user_id)

    user_emails = User.objects.filter(pk__in=user_ids).values()

    if _should_send_message(context):
        context['site'] = Site.objects.get(id=context['site_id'])
        thread_author = User.objects.get(id=context['thread_author_id'])
        with emulate_http_request(site=context['site'], user=thread_author):
            message_context = _build_message_context(context)
            message = ResponseNotification().personalize(
                Recipient(thread_author.username, thread_author.email),
                _get_course_language(context['course_id']), message_context)
            log.info(
                u'Sending forum comment email notification with context %s',
                message_context)
            ace.send(message)
            _track_notification_sent(message, context)

        #Added by Mahendra
        for user_email in user_emails:
            with emulate_http_request(site=context['site'],
                                      user=thread_author):
                message_context = _build_message_context(context)
                message = ResponseNotification().personalize(
                    Recipient(user_email['username'], user_email['email']),
                    _get_course_language(context['course_id']),
                    message_context)
                log.info(
                    'Testing forum comment email notification with context %s',
                    message_context)
                ace.send(message)
                _track_notification_sent(message, context)
Esempio n. 7
0
def _schedule_send(msg_str, site_id, delivery_config_var, log_prefix):
    site = Site.objects.select_related('configuration').get(pk=site_id)
    if _is_delivery_enabled(site, delivery_config_var, log_prefix):
        msg = Message.from_string(msg_str)

        user = User.objects.get(username=msg.recipient.username)
        with emulate_http_request(site=site, user=user):
            _annonate_send_task_for_monitoring(msg)
            LOG.debug('%s: Sending message = %s', log_prefix, msg_str)
            ace.send(msg)
            _track_message_sent(site, user, msg)
Esempio n. 8
0
 def run(self, site_id, target_day_str, course_key, override_recipient_email=None):
     site = Site.objects.select_related('configuration').get(id=site_id)
     with emulate_http_request(site=site):
         _annotate_for_monitoring(message_types.CourseUpdate(), site, 0, target_day_str, -1)
         return self.resolver(
             self.async_send_task,
             site,
             deserialize(target_day_str),
             str(course_key),
             override_recipient_email,
         ).send()
Esempio n. 9
0
 def _assert_rendered_email(self, message):
     # check that we can actually render the message
     with emulate_http_request(
         site=message.context['site'], user=self.thread_author
     ):
         # pylint: disable=unsupported-membership-test
         rendered_email = EmailRenderer().render(get_channel_for_message(ChannelType.EMAIL, message), message)
         assert self.comment['body'] in rendered_email.body_html
         assert self.comment_author.username in rendered_email.body_html
         assert self.mock_permalink.return_value in rendered_email.body_html
         assert message.context['site'].domain in rendered_email.body_html
Esempio n. 10
0
 def _assert_rendered_email(self, message):
     # check that we can actually render the message
     with emulate_http_request(
         site=message.context['site'], user=self.thread_author
     ):
         rendered_email = EmailRenderer().render(message)
         self.assertTrue(self.comment['body'] in rendered_email.body_html)
         self.assertTrue(self.comment_author.username in rendered_email.body_html)
         self.assertTrue(self.thread_author.username in rendered_email.body_html)
         self.assertTrue(self.mock_permalink in rendered_email.body_html)
         self.assertTrue(message.context['site'].domain in rendered_email.body_html)
Esempio n. 11
0
def send_ace_message(goal):
    """
    Send an email reminding users to stay on track for their learning goal in this course

    Arguments:
        goal (CourseGoal): Goal object
    """
    user = goal.user
    try:
        course = CourseOverview.get_from_id(goal.course_key)
    except CourseOverview.DoesNotExist:
        log.error("Goal Reminder course not found.")

    course_name = course.display_name

    site = Site.objects.get_current()
    message_context = get_base_template_context(site)

    course_home_url = reverse(course_home_url_name(course.id),
                              args=[str(course.id)])
    course_home_absolute_url_parts = ("https", site.name, course_home_url, '',
                                      '', '')
    course_home_absolute_url = six.moves.urllib.parse.urlunparse(
        course_home_absolute_url_parts)

    goals_unsubscribe_url = reverse('course-home:unsubscribe-from-course-goal',
                                    kwargs={'token': goal.unsubscribe_token})

    message_context.update({
        'email':
        user.email,
        'platform_name':
        configuration_helpers.get_value('PLATFORM_NAME',
                                        settings.PLATFORM_NAME),
        'course_name':
        course_name,
        'days_per_week':
        goal.days_per_week,
        'course_url':
        course_home_absolute_url,
        'goals_unsubscribe_url':
        goals_unsubscribe_url,
        'unsubscribe_url':
        None,  # We don't want to include the default unsubscribe link
    })

    msg = Message(name="goalreminder",
                  app_label="course_goals",
                  recipient=Recipient(user.id, user.email),
                  language=get_user_preference(user, LANGUAGE_KEY),
                  context=message_context)

    with emulate_http_request(site, user):
        ace.send(msg)
    def send_verification_expiry_email(self, batch_verifications,
                                       email_config):
        """
        Sends verification expiry email to the learners in the batch using edx_ace
        If the email is successfully sent change the expiry_email_date to reflect when the
        email was sent

        :param batch_verifications: verification objects for which email will be sent
        :param email_config: Contains configuration like dry-run flag value, which determines whether actual email will
                             be sent or not
        """
        if email_config['dry_run']:
            logger.info(
                u"This was a dry run, no email was sent. For the actual run email would have been sent "
                u"to {} learner(s)".format(len(batch_verifications)))
            return True

        site = Site.objects.get_current()
        message_context = get_base_template_context(site)
        message_context.update({
            'platform_name':
            settings.PLATFORM_NAME,
            'lms_verification_link':
            '{}{}'.format(settings.LMS_ROOT_URL,
                          reverse("verify_student_reverify")),
            'help_center_link':
            settings.ID_VERIFICATION_SUPPORT_LINK
        })

        expiry_email = VerificationExpiry(context=message_context)
        users = User.objects.filter(pk__in=[
            verification.user_id for verification in batch_verifications
        ])

        success = True
        for verification in batch_verifications:
            try:
                user = users.get(pk=verification.user_id)
                with emulate_http_request(site=site, user=user):
                    msg = expiry_email.personalize(
                        recipient=Recipient(user.username, user.email),
                        language=get_user_preference(user, LANGUAGE_KEY),
                        user_context={
                            'full_name': user.profile.name,
                        })
                    ace.send(msg)
                    self._set_email_expiry_date(verification, user,
                                                email_config)
            except Exception:  # pylint: disable=broad-except
                logger.exception('Could not send email for verification id %d',
                                 verification.id)
                success = False

        return success
Esempio n. 13
0
def _schedule_send(msg_str, site_id, delivery_config_var, log_prefix):
    site = Site.objects.select_related('configuration').get(pk=site_id)
    if _is_delivery_enabled(site, delivery_config_var, log_prefix):
        msg = Message.from_string(msg_str)

        user = User.objects.get(username=msg.recipient.username)
        with emulate_http_request(site=site, user=user):
            _annonate_send_task_for_monitoring(msg)
            LOG.debug(u'%s: Sending message = %s', log_prefix, msg_str)
            ace.send(msg)
            _track_message_sent(site, user, msg)
Esempio n. 14
0
def _schedule_send(msg_str, site_id, delivery_config_var, log_prefix):  # lint-amnesty, pylint: disable=missing-function-docstring
    site = Site.objects.select_related('configuration').get(pk=site_id)
    if _is_delivery_enabled(site, delivery_config_var, log_prefix):
        msg = Message.from_string(msg_str)

        user = User.objects.get(id=msg.recipient.lms_user_id)
        with emulate_http_request(site=site, user=user):
            _annonate_send_task_for_monitoring(msg)
            LOG.debug('%s: Sending message = %s', log_prefix, msg_str)
            ace.send(msg)
            _track_message_sent(site, user, msg)
Esempio n. 15
0
 def _assert_rendered_email(self, message):
     # check that we can actually render the message
     with emulate_http_request(
         site=message.context['site'], user=self.thread_author
     ):
         rendered_email = EmailRenderer().render(message)
         self.assertTrue(self.comment['body'] in rendered_email.body_html)
         self.assertTrue(self.comment_author.username in rendered_email.body_html)
         self.assertTrue(self.thread_author.username in rendered_email.body_html)
         self.assertTrue(self.mock_permalink in rendered_email.body_html)
         self.assertTrue(message.context['site'].domain in rendered_email.body_html)
Esempio n. 16
0
def send_calendar_sync_email(self, msg_string, from_address=None):
    """
    Sending calendar sync email to the user.
    """
    msg = Message.from_string(msg_string)

    max_retries = settings.RETRY_CALENDAR_SYNC_EMAIL_MAX_ATTEMPTS
    retries = self.request.retries

    if from_address is None:
        from_address = configuration_helpers.get_value(
            'ACTIVATION_EMAIL_FROM_ADDRESS') or (
                configuration_helpers.get_value('email_from_address',
                                                settings.DEFAULT_FROM_EMAIL))
    msg.options['from_address'] = from_address

    dest_addr = msg.recipient.email_address

    site = Site.objects.get_current()
    user = User.objects.get(username=msg.recipient.username)

    try:
        with emulate_http_request(site=site, user=user):
            ace.send(msg)
        # Log that the Activation Email has been sent to user without an exception
        log.info(
            "Calendar Sync Email has been sent to User {user_email}".format(
                user_email=dest_addr))
    except RecoverableChannelDeliveryError:
        log.info(
            'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}'
            .format(dest_addr=dest_addr,
                    attempt=retries,
                    max_attempts=max_retries))
        try:
            self.retry(countdown=settings.RETRY_ACTIVATION_EMAIL_TIMEOUT,
                       max_retries=max_retries)
        except MaxRetriesExceededError:
            log.error(
                'Unable to send calendar sync email to user from "%s" to "%s"',
                from_address,
                dest_addr,
                exc_info=True)
    except Exception:
        log.exception(
            'Unable to send calendar sync email to user from "%s" to "%s"',
            from_address,
            dest_addr,
        )
        raise Exception
Esempio n. 17
0
def send_ace_message(context):
    context['course_id'] = CourseKey.from_string(context['course_id'])

    if _should_send_message(context):
        context['site'] = Site.objects.get(id=context['site_id'])
        thread_author = User.objects.get(id=context['thread_author_id'])
        with emulate_http_request(site=context['site'], user=thread_author):
            message_context = _build_message_context(context)
            message = ResponseNotification().personalize(
                Recipient(thread_author.username, thread_author.email),
                _get_course_language(context['course_id']),
                message_context
            )
            log.info('Sending forum comment email notification with context %s', message_context)
            ace.send(message)
Esempio n. 18
0
 def run(
     self, site_id, target_day_str, day_offset, bin_num, override_recipient_email=None,
 ):
     site = Site.objects.select_related('configuration').get(id=site_id)
     with emulate_http_request(site=site):
         msg_type = self.make_message_type(day_offset)
         _annotate_for_monitoring(msg_type, site, bin_num, target_day_str, day_offset)
         return self.resolver(
             self.async_send_task,
             site,
             deserialize(target_day_str),
             day_offset,
             bin_num,
             override_recipient_email=override_recipient_email,
         ).send(msg_type)
Esempio n. 19
0
def send_ace_message(context):
    context['course_id'] = CourseKey.from_string(context['course_id'])

    if _should_send_message(context):
        context['site'] = Site.objects.get(id=context['site_id'])
        thread_author = User.objects.get(id=context['thread_author_id'])
        with emulate_http_request(site=context['site'], user=thread_author):
            message_context = _build_message_context(context)
            message = ResponseNotification().personalize(
                Recipient(thread_author.username, thread_author.email),
                _get_course_language(context['course_id']),
                message_context
            )
            log.info('Sending forum comment email notification with context %s', message_context)
            ace.send(message)
Esempio n. 20
0
 def _assert_rendered_email(self, message):
     # check that we can actually render the message
     middleware_classes = [
         CurrentRequestUserMiddleware,
         CurrentSiteThemeMiddleware,
     ]
     with emulate_http_request(
         site=message.context['site'], user=self.thread_author, middleware_classes=middleware_classes
     ):
         rendered_email = EmailRenderer().render(message)
         self.assertTrue(self.comment['body'] in rendered_email.body_html)
         self.assertTrue(self.comment_author.username in rendered_email.body_html)
         self.assertTrue(self.thread_author.username in rendered_email.body_html)
         self.assertTrue(self.mock_permalink in rendered_email.body_html)
         self.assertTrue(message.context['site'].domain in rendered_email.body_html)
Esempio n. 21
0
def send_course_enrollment_email_for_user(self, site_id, user_id, course_id,
                                          message_type):
    """
    Send out a course enrollment email for the given user.
    Arguments:
        site_id: Django Site object id
        user_id: Django User object id
        course_id: Course id
        message_type: 'enroll' or 'unenroll'
    """
    site = Site.objects.get(id=site_id)
    user = User.objects.get(id=user_id)
    with emulate_http_request(site=site, user=user):
        course_key = CourseKey.from_string(course_id)
        course = modulestore().get_course(course_key)
        request = get_current_request()
        message_context = get_base_template_context(site)
        message_context.update({
            'request':
            request,
            'platform_name':
            configuration_helpers.get_value('PLATFORM_NAME',
                                            settings.PLATFORM_NAME),
            'site_name':
            configuration_helpers.get_value('SITE_NAME', settings.SITE_NAME),
            'username':
            user.username,
            'course_name':
            course.display_name,
            'course_url':
            '{protocol}://{site}{link}'.format(
                protocol='https' if request.is_secure() else 'http',
                site=configuration_helpers.get_value('SITE_NAME',
                                                     settings.SITE_NAME),
                link=reverse('course_root', kwargs={'course_id': course_id})),
        })

        ace_messages_dict = {
            'enroll': CourseEnrollment,
            'unenroll': CourseUnenrollment,
        }
        message_class = ace_messages_dict[message_type]
        msg = message_class().personalize(
            recipient=Recipient(user.username, user.email),
            language=preferences_api.get_user_preference(user, LANGUAGE_KEY),
            user_context=message_context,
        )
        ace.send(msg)
Esempio n. 22
0
def _schedule_send(msg_str, site_id, delivery_config_var, log_prefix):
    site = Site.objects.get(pk=site_id)
    if _is_delivery_enabled(site, delivery_config_var, log_prefix):
        msg = Message.from_string(msg_str)

        user = User.objects.get(username=msg.recipient.username)
        middleware_classes = [
            CurrentRequestUserMiddleware,
            CurrentSiteThemeMiddleware,
        ]
        with emulate_http_request(site=site,
                                  user=user,
                                  middleware_classes=middleware_classes):
            _annonate_send_task_for_monitoring(msg)
            LOG.debug('%s: Sending message = %s', log_prefix, msg_str)
            ace.send(msg)
Esempio n. 23
0
 def run(self,
         site_id,
         target_day_str,
         course_key,
         override_recipient_email=None):  # lint-amnesty, pylint: disable=arguments-differ
     set_code_owner_attribute_from_module(__name__)
     site = Site.objects.select_related('configuration').get(id=site_id)
     with emulate_http_request(site=site):
         _annotate_for_monitoring(message_types.CourseUpdate(), site, 0,
                                  target_day_str, -1)
         return self.resolver(
             self.async_send_task,
             site,
             deserialize(target_day_str),
             str(course_key),
             override_recipient_email,
         ).send()
Esempio n. 24
0
def send_activation_email(self, msg_string, from_address=None):
    """
    Sending an activation email to the user.
    """
    msg = Message.from_string(msg_string)

    max_retries = settings.RETRY_ACTIVATION_EMAIL_MAX_ATTEMPTS
    retries = self.request.retries

    if from_address is None:
        from_address = configuration_helpers.get_value(
            'ACTIVATION_EMAIL_FROM_ADDRESS') or (
                configuration_helpers.get_value('email_from_address',
                                                settings.DEFAULT_FROM_EMAIL))
    msg.options['from_address'] = from_address

    dest_addr = msg.recipient.email_address

    site = Site.objects.get_current()
    user = User.objects.get(id=msg.recipient.lms_user_id)

    try:
        with emulate_http_request(site=site, user=user):
            ace.send(msg)
    except RecoverableChannelDeliveryError:
        log.info(
            'Retrying sending email to user {dest_addr}, attempt # {attempt} of {max_attempts}'
            .format(dest_addr=dest_addr,
                    attempt=retries,
                    max_attempts=max_retries))
        try:
            self.retry(countdown=settings.RETRY_ACTIVATION_EMAIL_TIMEOUT,
                       max_retries=max_retries)
        except MaxRetriesExceededError:
            log.error(
                'Unable to send activation email to user from "%s" to "%s"',
                from_address,
                dest_addr,
                exc_info=True)
    except Exception:
        log.exception(
            'Unable to send activation email to user from "%s" to "%s"',
            from_address,
            dest_addr,
        )
        raise Exception  # lint-amnesty, pylint: disable=raise-missing-from
Esempio n. 25
0
 def run(  # pylint: disable=arguments-differ
     self, site_id, course_key_str, target_day_str, day_offset, override_recipient_email=None,
 ):
     try:
         site = Site.objects.select_related('configuration').get(id=site_id)
         with emulate_http_request(site=site):
             msg_type = self.make_message_type(day_offset)
             _annotate_for_monitoring(msg_type, course_key_str, target_day_str, day_offset)
             return self.resolver(  # pylint: disable=not-callable
                 self.async_send_task,
                 site,
                 CourseKey.from_string(course_key_str),
                 deserialize(target_day_str),
                 day_offset,
                 override_recipient_email=override_recipient_email,
             ).send(msg_type)
     except Exception:  # pylint: disable=broad-except
         LOG.exception("Task failed")
Esempio n. 26
0
def send_verification_confirmation_email(context):
    """Send an email confirming that the user submitted photos for initial verification."""
    site = Site.objects.get_current()
    message_context = get_base_template_context(site)
    message_context.update(context)
    user = context['user']
    try:
        with emulate_http_request(site=site, user=user):
            msg = VerificationSubmitted(context=message_context).personalize(
                recipient=Recipient(user.id, user.email),
                language=get_user_preference(user, LANGUAGE_KEY),
                user_context={'full_name': user.profile.name}
            )
            ace.send(msg)
            log.info('Verification confirmation email sent to user: %r', user.username)
            return True
    except Exception:  # pylint: disable=broad-except
        log.exception('Could not send email for verification confirmation to user %s', user.username)
        return False
Esempio n. 27
0
    def handle(self, *args, **options):
        """
        Docstring

        Helpful notes for the function:
            weekday() returns an int 0-6 with Monday being 0 and Sunday being 6
        """
        today = date.today()
        sunday_date = today + timedelta(days=SUNDAY_WEEKDAY - today.weekday())
        monday_date = today - timedelta(days=today.weekday())

        # Monday is the start of when we consider user's activity towards counting towards their weekly
        # goal. As such, we use Mondays to clear out the email reminders sent from the previous week.
        if today.weekday() == MONDAY_WEEKDAY:
            CourseGoalReminderStatus.objects.filter(
                email_reminder_sent=True).update(email_reminder_sent=False)
            log.info('Cleared all reminder statuses')
            return

        course_goals = CourseGoal.objects.filter(
            days_per_week__gt=0,
            subscribed_to_reminders=True,
        ).exclude(reminder_status__email_reminder_sent=True, )
        all_goal_course_keys = course_goals.values_list('course_key',
                                                        flat=True).distinct()
        # Exclude all courses whose end dates are earlier than Sunday so we don't send an email about hitting
        # a course goal when it may not even be possible.
        courses_to_exclude = CourseOverview.objects.filter(
            id__in=all_goal_course_keys,
            end__date__lte=sunday_date).values_list('id', flat=True)

        count = 0
        course_goals = course_goals.exclude(
            course_key__in=courses_to_exclude).select_related('user').order_by(
                'user')
        for goal in course_goals:
            # emulate a request for waffle's benefit
            with emulate_http_request(site=Site.objects.get_current(),
                                      user=goal.user):
                if self.handle_goal(goal, today, sunday_date, monday_date):
                    count += 1

        log.info(f'Sent {count} emails')
Esempio n. 28
0
def send_verification_expiry_email(batch_verifications, dry_run=False):
    """
    Spins a task to send verification expiry email to the learners in the batch using edx_ace
    If the email is successfully sent change the expiry_email_date to reflect when the
    email was sent
    """
    if dry_run:
        logger.info(
            u"This was a dry run, no email was sent. For the actual run email would have been sent "
            u"to {} learner(s)".format(len(batch_verifications)))
        return

    site = Site.objects.get_current()
    message_context = get_base_template_context(site)
    message_context.update({
        'platform_name':
        settings.PLATFORM_NAME,
        'lms_verification_link':
        '{}{}'.format(settings.LMS_ROOT_URL,
                      reverse("verify_student_reverify")),
        'help_center_link':
        settings.ID_VERIFICATION_SUPPORT_LINK
    })

    expiry_email = VerificationExpiry(context=message_context)
    users = User.objects.filter(
        pk__in=[verification.user_id for verification in batch_verifications])

    for verification in batch_verifications:
        user = users.get(pk=verification.user_id)
        with emulate_http_request(site=site, user=user):
            msg = expiry_email.personalize(
                recipient=Recipient(user.username, user.email),
                language=get_user_preference(user, LANGUAGE_KEY),
                user_context={
                    'full_name': user.profile.name,
                })
            ace.send(msg)
            verification_qs = SoftwareSecurePhotoVerification.objects.filter(
                pk=verification.pk)
            verification_qs.update(expiry_email_date=datetime.now(UTC))
Esempio n. 29
0
def send_verification_approved_email(context):
    """
    Sends email to a learner when ID verification has been approved.
    """
    site = Site.objects.get_current()
    message_context = get_base_template_context(site)
    message_context.update(context)
    user = context['user']
    try:
        with emulate_http_request(site=site, user=user):
            msg = VerificationApproved(context=message_context).personalize(
                recipient=Recipient(user.id, user.email),
                language=get_user_preference(user, LANGUAGE_KEY),
                user_context={'full_name': user.profile.name}
            )
            ace.send(msg)
            log.info('Verification approved email sent to user: %r', user.username)
            return True
    except Exception:  # pylint: disable=broad-except
        log.exception('Could not send email for verification approved to user %s', user.username)
        return False
Esempio n. 30
0
 def run(  # lint-amnesty, pylint: disable=arguments-differ
     self,
     site_id,
     target_day_str,
     day_offset,
     bin_num,
     override_recipient_email=None,
 ):
     set_code_owner_attribute_from_module(__name__)
     site = Site.objects.select_related('configuration').get(id=site_id)
     with emulate_http_request(site=site):
         msg_type = self.make_message_type(day_offset)
         _annotate_for_monitoring(msg_type, site, bin_num, target_day_str,
                                  day_offset)
         return self.resolver(  # lint-amnesty, pylint: disable=not-callable
             self.async_send_task,
             site,
             deserialize(target_day_str),
             day_offset,
             bin_num,
             override_recipient_email=override_recipient_email,
         ).send(msg_type)
def send_verification_expiry_email(batch_verifications, dry_run=False):
    """
    Spins a task to send verification expiry email to the learners in the batch using edx_ace
    If the email is successfully sent change the expiry_email_date to reflect when the
    email was sent
    """
    if dry_run:
        logger.info(
            u"This was a dry run, no email was sent. For the actual run email would have been sent "
            u"to {} learner(s)".format(len(batch_verifications))
        )
        return

    site = Site.objects.get_current()
    message_context = get_base_template_context(site)
    message_context.update({
        'platform_name': settings.PLATFORM_NAME,
        'lms_verification_link': '{}{}'.format(settings.LMS_ROOT_URL, reverse("verify_student_reverify")),
        'help_center_link': settings.ID_VERIFICATION_SUPPORT_LINK
    })

    expiry_email = VerificationExpiry(context=message_context)
    users = User.objects.filter(pk__in=[verification.user_id for verification in batch_verifications])

    for verification in batch_verifications:
        user = users.get(pk=verification.user_id)
        with emulate_http_request(site=site, user=user):
            msg = expiry_email.personalize(
                recipient=Recipient(user.username, user.email),
                language=get_user_preference(user, LANGUAGE_KEY),
                user_context={
                    'full_name': user.profile.name,
                }
            )
            ace.send(msg)
            verification_qs = SoftwareSecurePhotoVerification.objects.filter(pk=verification.pk)
            verification_qs.update(expiry_email_date=now())
Esempio n. 32
0
def enroll_user_to_course(request_info, course_id, username_or_email):
    """
    Look up the given user, and if successful, enroll them to the specified course.

    Arguments:
        request_info (dict): Dict containing task request information
        course_id (str): The ID string of the course
        username_or_email: user's username or email string

    Returns:
        User object (or None if user in not registered,
        and whether the user is already enrolled or not

    """
    # First try to get a user object from the identifier (email)
    user = None
    user_already_enrolled = False
    language = None
    email_students = True
    auto_enroll = True
    thread_site = Site.objects.get(domain=request_info['host'])
    thread_author = User.objects.get(username=request_info['username'])

    try:
        user = get_student_from_identifier(username_or_email)
    except User.DoesNotExist:
        email = username_or_email
    else:
        email = user.email
        language = get_user_email_language(user)

    if user:
        course_enrollment = CourseEnrollment.get_enrollment(
            user=user, course_key=course_id)
        if course_enrollment:
            user_already_enrolled = True
            # Set the enrollment to active if its not already active
            if not course_enrollment.is_active:
                course_enrollment.update_enrollment(is_active=True)

    if not user or not user_already_enrolled:
        course = get_course_by_id(course_id, depth=0)
        try:
            with emulate_http_request(site=thread_site, user=thread_author):
                email_params = get_email_params(course, auto_enroll)
                __ = enroll_email(course_id,
                                  email,
                                  auto_enroll,
                                  email_students,
                                  email_params,
                                  language=language)
                if user:
                    TASK_LOG.info(
                        u'User %s enrolled successfully in course %s via CSV bulk enrollment',
                        username_or_email, course_id)
        except:
            TASK_LOG.exception(
                u'There was an error enrolling user %s in course %s via CSV bulk enrollment',
                username_or_email, course_id)
            return None, None

    return user, user_already_enrolled
Esempio n. 33
0
def send_ace_message(goal):
    """
    Send an email reminding users to stay on track for their learning goal in this course

    Arguments:
        goal (CourseGoal): Goal object
    """
    user = goal.user
    try:
        course = CourseOverview.get_from_id(goal.course_key)
    except CourseOverview.DoesNotExist:
        log.error("Goal Reminder course not found.")

    course_name = course.display_name

    site = Site.objects.get_current()
    message_context = get_base_template_context(site)

    course_home_url = get_learning_mfe_home_url(course_key=goal.course_key,
                                                url_fragment='home')

    goals_unsubscribe_url = f'{settings.LEARNING_MICROFRONTEND_URL}/goal-unsubscribe/{goal.unsubscribe_token}'

    language = get_user_preference(user, LANGUAGE_KEY)

    # Code to allow displaying different banner images for different languages
    # However, we'll likely want to develop a better way to do this within edx-ace
    image_url = settings.STATIC_URL
    if image_url:
        # If the image url is a relative url prepend the LMS ROOT
        if 'http' not in image_url:
            image_url = settings.LMS_ROOT_URL + settings.STATIC_URL
        image_url += 'images/'

        if language and language in ['es', 'es-419']:
            image_url += 'spanish-'

    message_context.update({
        'email':
        user.email,
        'platform_name':
        configuration_helpers.get_value('PLATFORM_NAME',
                                        settings.PLATFORM_NAME),
        'course_name':
        course_name,
        'days_per_week':
        goal.days_per_week,
        'course_url':
        course_home_url,
        'goals_unsubscribe_url':
        goals_unsubscribe_url,
        'image_url':
        image_url,
        'unsubscribe_url':
        None,  # We don't want to include the default unsubscribe link
        'omit_unsubscribe_link':
        True,
        'courses_url':
        getattr(settings, 'ACE_EMAIL_COURSES_URL', None),
        'programs_url':
        getattr(settings, 'ACE_EMAIL_PROGRAMS_URL', None),
    })

    msg = Message(
        name="goalreminder",
        app_label="course_goals",
        recipient=Recipient(user.id, user.email),
        language=language,
        context=message_context,
        options={'transactional': True},
    )

    with emulate_http_request(site, user):
        ace.send(msg)
Esempio n. 34
0
 def send(self):
     """
     Send message by emulating request in the context of site and user
     """
     with emulate_http_request(site=self.site, user=self.user):
         ace.send(self.message)