lms.djangoapps.bulk_email package

Contents

lms.djangoapps.bulk_email package#

Submodules#

lms.djangoapps.bulk_email.api module#

Python APIs exposed by the bulk_email app to other in-process apps.

lms.djangoapps.bulk_email.api.create_course_email(course_id, sender, targets, subject, html_message, text_message=None, template_name=None, from_addr=None)#

Python API for creating a new CourseEmail instance.

Parameters:
  • course_id (CourseKey) – The CourseKey of the course.

  • sender (String) – Email author.

  • targets (List[String]) – Recipient groups the message should be sent to.

  • subject (String)) – Email subject.

  • html_message (String) – Email body. Includes HTML markup.

  • text_message (String, optional) – Plaintext version of email body. Defaults to None.

  • template_name (String, optional) – Name of custom email template to use. Defaults to None.

  • from_addr (String, optional) – Custom sending address, if desired. Defaults to None.

Returns:

Returns the created CourseEmail instance.

Return type:

CourseEmail

lms.djangoapps.bulk_email.api.determine_targets_for_course_email(course_id, subject, targets)#

Utility function to determine the targets (recipient groups) selected by an author of a course email.

Historically, this used to be a piece of logic in the CourseEmail model’s create function but has been extracted here so it can be used by a REST API of the instructor_task app.

lms.djangoapps.bulk_email.api.get_course_email(email_id)#

Utility function for retrieving a CourseEmail instance from a given CourseEmail id.

Parameters:

email_id (int) – The ID of the CourseEmail instance you want to retrieve.

Returns:

The CourseEmail instance, if it exists.

Return type:

CourseEmail

lms.djangoapps.bulk_email.api.get_emails_enabled(user, course_id)#

Get whether or not emails are enabled in the context of a course.

Parameters:
  • user – the user object for which we want to check whether emails are enabled

  • course_id (string) – the course id of the course

Returns:

True if emails are enabled for the course associated with course_id for the user; False otherwise

Return type:

(bool)

Parameters:
  • username – username

  • course_id

Returns:

AES encrypted token based on the user email

lms.djangoapps.bulk_email.api.update_course_email(course_id, email_id, targets, subject, html_message, plaintext_message=None)#

Utility function that allows a course_email instance to be updated after it has been created.

course_id (CourseKey): The CourseKey of the course. email_id (Int): The PK id value of the course_email instance that is to be updated. targets (List[String]): Recipient groups the message should be sent to. subject (String)): Email subject. html_message (String): Email body. Includes HTML markup. text_message (String, optional): Plaintext version of email body. Defaults to None.

lms.djangoapps.bulk_email.apps module#

class lms.djangoapps.bulk_email.apps.BulkEmailConfig(app_name, app_module)#

Bases: AppConfig

Application Configuration for bulk_email.

name = 'lms.djangoapps.bulk_email'#
ready()#

Override this method in subclasses to run code when Django starts.

lms.djangoapps.bulk_email.data module#

Bulk Email Data

This provides Data models to represent Bulk Email data.

class lms.djangoapps.bulk_email.data.BulkEmailTargetChoices#

Bases: object

Enum for the available targets (recipient groups) of an email authored with the bulk course email tool.

SEND_TO_MYSELF - Message intended for author of the message SEND_TO_STAFF - Message intended for all course staff SEND_TO_LEARNERS - Message intended for all enrolled learners SEND_TO_COHORT - Message intended for a specific cohort SEND_TO_TRACK - Message intended for all learners in a specific track (e.g. audit or verified)

SEND_TO_COHORT = 'cohort'#
SEND_TO_LEARNERS = 'learners'#
SEND_TO_MYSELF = 'myself'#
SEND_TO_STAFF = 'staff'#
SEND_TO_TRACK = 'track'#
TARGET_CHOICES = ('myself', 'staff', 'learners', 'cohort', 'track')#
classmethod is_valid_target(target)#

Given the target of a message, return a boolean indicating whether the target choice is valid.

lms.djangoapps.bulk_email.forms module#

Defines a form for providing validation of CourseEmail templates.

class lms.djangoapps.bulk_email.forms.CourseAuthorizationAdminForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)#

Bases: ModelForm

Input form for email enabling, allowing us to verify data.

class Meta#

Bases: object

fields = '__all__'#
model#

alias of CourseAuthorization

base_fields = {'course_id': <django.forms.fields.CharField object>, 'email_enabled': <django.forms.fields.BooleanField object>}#
clean_course_id()#

Validate the course id

declared_fields = {}#
property media#

Return all media required to render the widgets on this form.

class lms.djangoapps.bulk_email.forms.CourseEmailTemplateForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)#

Bases: ModelForm

Form providing validation of CourseEmail templates.

class Meta#

Bases: object

fields = ('html_template', 'plain_template', 'name')#
model#

alias of CourseEmailTemplate

base_fields = {'html_template': <django.forms.fields.CharField object>, 'name': <django.forms.fields.CharField object>, 'plain_template': <django.forms.fields.CharField object>}#
clean_html_template()#

Validate the HTML template.

clean_name()#

Validate the name field. Enforce uniqueness constraint on ‘name’ field

clean_plain_template()#

Validate the plaintext template.

declared_fields = {'name': <django.forms.fields.CharField object>}#
property media#

Return all media required to render the widgets on this form.

lms.djangoapps.bulk_email.message_types module#

ACE message types for bulk course emails.

class lms.djangoapps.bulk_email.message_types.BulkEmail(*args, **kwargs)#

Bases: BaseMessageType

Course message to list of recepient by instructors.

lms.djangoapps.bulk_email.messages module#

Module to define email message related classes and methods

class lms.djangoapps.bulk_email.messages.ACEEmail(site, email_context)#

Bases: CourseEmailMessage

Email message class to send email using edx-ace.

send()#

Send message by emulating request in the context of site and user

class lms.djangoapps.bulk_email.messages.CourseEmailMessage#

Bases: ABC

Abstract base class for course email messages

abstractmethod send()#

Triggers sending of email message

class lms.djangoapps.bulk_email.messages.DjangoEmail(connection, course_email, email_context)#

Bases: CourseEmailMessage

Email message class to send email directly using django mail API.

send()#

send email using already opened connection

lms.djangoapps.bulk_email.models module#

Models for bulk email

class lms.djangoapps.bulk_email.models.BulkEmailFlag(*args, **kwargs)#

Bases: ConfigurationModel

Enables site-wide configuration for the bulk_email feature.

Staff can only send bulk email for a course if all the following conditions are true: 1. BulkEmailFlag is enabled. 2. Course-specific authorization not required, or course authorized to use bulk email.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

change_date#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

changed_by#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

changed_by_id#
enabled#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod feature_enabled(course_id=None)#

Looks at the currently active configuration model to determine whether the bulk email feature is available.

If the flag is not enabled, the feature is not available. If the flag is enabled, course-specific authorization is required, and the course_id is either not provided

or not authorixed, the feature is not available.

If the flag is enabled, course-specific authorization is required, and the provided course_id is authorized,

the feature is available.

If the flag is enabled and course-specific authorization is not required, the feature is available.

get_next_by_change_date(*, field=<django.db.models.fields.DateTimeField: change_date>, is_next=True, **kwargs)#
get_previous_by_change_date(*, field=<django.db.models.fields.DateTimeField: change_date>, is_next=False, **kwargs)#
id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

require_course_email_auth#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class lms.djangoapps.bulk_email.models.CohortTarget(*args, **kwargs)#

Bases: Target

Subclass of Target, specifically referring to a cohort.

exception DoesNotExist#

Bases: DoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

cohort#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

cohort_id#
classmethod ensure_valid_cohort(cohort_name, course_id)#

Ensures cohort_name is a valid cohort for course_id.

Returns the cohort if valid, raises an error otherwise.

long_display()#

Returns a long display name

short_display()#

Returns a short display name

target_ptr#

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

target_ptr_id#
class lms.djangoapps.bulk_email.models.CourseAuthorization(*args, **kwargs)#

Bases: Model

Enable the course email feature on a course-by-course basis.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

course_id#

DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!

A placeholder class that provides a way to set the attribute on the model.

email_enabled#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod instructor_email_enabled(course_id)#

Returns whether or not email is enabled for the given course id.

objects = <django.db.models.manager.Manager object>#
class lms.djangoapps.bulk_email.models.CourseEmail(*args, **kwargs)#

Bases: Email

Stores information for an email to a course.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

course_id#

DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!

A placeholder class that provides a way to set the attribute on the model.

classmethod create(course_id, sender, targets, subject, html_message, text_message=None, template_name=None, from_addr=None)#

Create an instance of CourseEmail.

created#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

from_addr#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)#
get_next_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=True, **kwargs)#
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)#
get_previous_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=False, **kwargs)#
get_template()#

Returns the corresponding CourseEmailTemplate for this CourseEmail.

get_to_option_display(*, field=<django.db.models.fields.CharField: to_option>)#
html_message#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

modified#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>#
sender#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

sender_id#
slug#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

subject#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

targets#

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

template_name#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

text_message#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

to_option#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class lms.djangoapps.bulk_email.models.CourseEmailTemplate(*args, **kwargs)#

Bases: Model

Stores templates for all emails to a course to use.

This is expected to be a singleton, to be shared across all courses. Initialization takes place in a migration that in turn loads a fixture. The admin console interface disables add and delete operations. Validation is handled in the CourseEmailTemplateForm class.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

static get_template(name=None)#

Fetch the current template

If one isn’t stored, an exception is thrown.

html_template#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

name#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>#
plain_template#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

render_htmltext(htmltext, context)#

Create HTML text message.

Convert HTML text body (htmltext) into HTML email message using the stored HTML template and the provided context dict.

render_plaintext(plaintext, context)#

Create plain text message.

Convert plain text body (plaintext) into plaintext email message using the stored plain template and the provided context dict.

class lms.djangoapps.bulk_email.models.CourseModeTarget(*args, **kwargs)#

Bases: Target

Subclass of Target, specifically for course modes.

exception DoesNotExist#

Bases: DoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

classmethod ensure_valid_mode(mode_slug, course_id)#

Ensures mode_slug is a valid mode for course_id. Will raise an error if invalid.

long_display()#

Returns a long display name

short_display()#

Returns a short display name

target_ptr#

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

target_ptr_id#
track#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

track_id#
class lms.djangoapps.bulk_email.models.DisabledCourse(*args, **kwargs)#

Bases: Model

Disable the bulk email feature for specific courses.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

course_id#

DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!

A placeholder class that provides a way to set the attribute on the model.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod instructor_email_disabled_for_course(course_id)#

Returns whether or not email is disabled for the given course id.

objects = <django.db.models.manager.Manager object>#
class lms.djangoapps.bulk_email.models.Email(*args, **kwargs)#

Bases: Model

Abstract base class for common information for an email.

class Meta#

Bases: object

abstract = False#
app_label = 'bulk_email'#
created#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)#
get_next_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=True, **kwargs)#
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)#
get_previous_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=False, **kwargs)#
html_message#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

modified#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

sender#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

sender_id#
slug#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

subject#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

text_message#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class lms.djangoapps.bulk_email.models.Optout(*args, **kwargs)#

Bases: Model

Stores users that have opted out of receiving emails from a course.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

course_id#

DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!

A placeholder class that provides a way to set the attribute on the model.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod is_user_opted_out_for_course(user, course_id)#
objects = <django.db.models.manager.Manager object>#
user#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

user_id#
class lms.djangoapps.bulk_email.models.Target(*args, **kwargs)#

Bases: Model

A way to refer to a particular group (within a course) as a “Send to:” target.

Django hackery in this class - polymorphism does not work well in django, for reasons relating to how each class is represented by its own database table. Due to this, we can’t just override methods of Target in CohortTarget and get the child method, as one would expect. The workaround is to check to see that a given target is a CohortTarget (self.target_type == SEND_TO_COHORT), then explicitly call the method on self.cohorttarget, which is created by django as part of this inheritance setup. These calls require pylint disable no-member in several locations in this class.

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

cohorttarget#

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

courseemail_set#

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

coursemodetarget#

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

get_target_type_display(*, field=<django.db.models.fields.CharField: target_type>)#
get_users(course_id, user_id=None)#

Gets the users for a given target.

Result is returned in the form of a queryset, and may contain duplicates.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

long_display()#

Returns a long display name

objects = <django.db.models.manager.Manager object>#
short_display()#

Returns a short display name

target_type#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

lms.djangoapps.bulk_email.models_api module#

Provides Python APIs exposed from Bulk Email models.

lms.djangoapps.bulk_email.models_api.is_bulk_email_disabled_for_course(course_id)#
Parameters:

course_id – the course id of the course

Returns:

True if the Bulk Email feature is disabled for the course associated with the course_id; False otherwise

Return type:

bool

lms.djangoapps.bulk_email.models_api.is_bulk_email_enabled_for_course(course_id)#
Parameters:

course_id – the course id of the course

Returns:

True if the Bulk Email feature is enabled for the course associated with the course_id; False otherwise

Return type:

bool

lms.djangoapps.bulk_email.models_api.is_bulk_email_feature_enabled(course_id=None)#

Looks at the currently active configuration model to determine whether the bulk email feature is available.

Parameters:

course_id (string; optional) – the course id of the course

Returns:

True or False, depending on the following:

If the flag is not enabled, the feature is not available. If the flag is enabled, course-specific authorization is required, and the course_id is either not provided

or not authorixed, the feature is not available.

If the flag is enabled, course-specific authorization is required, and the provided course_id is authorized,

the feature is available.

If the flag is enabled and course-specific authorization is not required, the feature is available.

Return type:

bool

lms.djangoapps.bulk_email.models_api.is_user_opted_out_for_course(user, course_id)#
Parameters:
  • user – user whose opt out status is to be returned

  • course_id (CourseKey) – id of the course

Returns:

True if user has opted out of e-mails for the course associated with course_id, False otherwise.

Return type:

bool

lms.djangoapps.bulk_email.policies module#

Course Email optOut Policy

class lms.djangoapps.bulk_email.policies.CourseEmailOptout#

Bases: Policy

check(message)#

Validate the supplied Message against a specific delivery policy.

Parameters:

message (Message) – The message to run the policy against.

Returns: PolicyResult

A PolicyResult that represents what channels the message should not be delivered over.

lms.djangoapps.bulk_email.signals module#

Signal handlers for the bulk_email app

lms.djangoapps.bulk_email.signals.ace_email_sent_handler(sender, **kwargs)#

When an email is sent using ACE, this method will create an event to detect ace email success status

lms.djangoapps.bulk_email.signals.force_optout_all(sender, **kwargs)#

When a user is retired from all mailings this method will create an Optout row for any courses they may be enrolled in.

lms.djangoapps.bulk_email.tasks module#

This module contains celery task functions for handling the sending of bulk email to a course.

lms.djangoapps.bulk_email.tasks.perform_delegate_email_batches(entry_id, course_id, task_input, action_name)#

Delegates emails by querying for the list of recipients who should get the mail, chopping up into batches of no more than settings.BULK_EMAIL_EMAILS_PER_TASK in size, and queueing up worker jobs.

lms.djangoapps.bulk_email.toggles module#

Toggles for bulk_email app

lms.djangoapps.bulk_email.toggles.is_bulk_email_edx_ace_enabled()#
lms.djangoapps.bulk_email.toggles.is_email_use_course_id_from_for_bulk_enabled()#

lms.djangoapps.bulk_email.urls module#

URLs for bulk_email app

lms.djangoapps.bulk_email.views module#

Views to support bulk email functionalities like opt-out.

lms.djangoapps.bulk_email.views.opt_out_email_updates(request, token, course_id)#

A view that let users opt out of any email updates.

This meant is meant to be the target of an opt-out link or button. The token parameter must decrypt to a valid username. The course_id is the string course key of any course.

Raises a 404 if there are any errors parsing the input.

Module contents#