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)
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)
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)
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
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)
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)
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()
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
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)
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
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)
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)
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)
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
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)
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)
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)
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)
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)
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)
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()
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
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")
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
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')
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))
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
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())
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
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)
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)