openedx.core.djangoapps.schedules package#
Subpackages#
- openedx.core.djangoapps.schedules.management package
- Subpackages
- openedx.core.djangoapps.schedules.management.commands package
- Submodules
- openedx.core.djangoapps.schedules.management.commands.schedules_data_migration module
- openedx.core.djangoapps.schedules.management.commands.send_course_next_section_update module
- openedx.core.djangoapps.schedules.management.commands.send_course_update module
- openedx.core.djangoapps.schedules.management.commands.send_recurring_nudge module
- openedx.core.djangoapps.schedules.management.commands.send_upgrade_reminder module
- openedx.core.djangoapps.schedules.management.commands.setup_models_to_send_test_emails module
- Module contents
- openedx.core.djangoapps.schedules.management.commands package
- Module contents
- Subpackages
Submodules#
openedx.core.djangoapps.schedules.apps module#
openedx.core.djangoapps.schedules.config module#
Contains configuration for schedules app
- openedx.core.djangoapps.schedules.config.query_external_updates(user_id, course_id)#
Returns a queryset indicating whether the user get the “external course updates” experience for the given course.
This is designed for use as a subquery in a larger queryset, which is why it returns a queryset, rather than a boolean. But it can also be used to spot-check whether a user is in the external experience for a given course by casting the returned queryset to a bool.
This looks up the experiment data, saved at enrollment time.
- openedx.core.djangoapps.schedules.config.set_up_external_updates_for_enrollment(user, course_key)#
Returns and stores whether a user should be getting the “external course updates” experience.
See the description of this experiment with the waffle flag definition above. But basically, if a user is getting external course updates for a course, edx-platform just stops sending any updates, trustingn that the user is receiving them elsewhere.
This is basically just a wrapper around our experiment waffle flag, but only buckets users that directly enrolled (rather than users enrolled by staff), for technical “waffle-flags-can-only-get-the-user-from-the-request” reasons.
This saves the decision in experiment data tables. It is also idempotent and will not change after the first call for a given user/course, regardless of how the waffle answer changes.
openedx.core.djangoapps.schedules.content_highlights module#
Contains methods for accessing course highlights. Course highlights is a schedule experience built on the Schedules app.
- openedx.core.djangoapps.schedules.content_highlights.course_has_highlights(course)#
Does the course have any highlights for any section/week in it? This ignores access checks, since highlights may be lurking in currently inaccessible content.
- Parameters:
course (CourseBlock) – course block to check
- openedx.core.djangoapps.schedules.content_highlights.course_has_highlights_from_store(course_key)#
Does the course have any highlights for any section/week in it? This ignores access checks, since highlights may be lurking in currently inaccessible content.
- Parameters:
course_key (CourseKey) – course to lookup from the modulestore
- openedx.core.djangoapps.schedules.content_highlights.get_all_course_highlights(course_key)#
This ignores access checks, since highlights may be lurking in currently inaccessible content. Returns a list of all the section highlights in the course
- openedx.core.djangoapps.schedules.content_highlights.get_next_section_highlights(user, course_key, start_date, target_date)#
Get highlights (list of unicode strings) for a week, based upon the current date.
- Raises:
CourseUpdateDoeNotExist – if highlights do not exist for the requested date
- openedx.core.djangoapps.schedules.content_highlights.get_week_highlights(user, course_key, week_num)#
Get highlights (list of unicode strings) for a given week. week_num starts at 1.
- Raises:
CourseUpdateDoesNotExist – if highlights do not exist for the requested week_num.
openedx.core.djangoapps.schedules.exceptions module#
- exception openedx.core.djangoapps.schedules.exceptions.CourseUpdateDoesNotExist#
Bases:
Exception
openedx.core.djangoapps.schedules.message_types module#
ACE message types for the schedules module.
- class openedx.core.djangoapps.schedules.message_types.CourseUpdate(*args, **kwargs)#
Bases:
ScheduleMessageType
- class openedx.core.djangoapps.schedules.message_types.InstructorLedCourseUpdate(*args, **kwargs)#
Bases:
ScheduleMessageType
- class openedx.core.djangoapps.schedules.message_types.RecurringNudge(day, *args, **kwargs)#
Bases:
ScheduleMessageType
- class openedx.core.djangoapps.schedules.message_types.ScheduleMessageType(*args, **kwargs)#
Bases:
BaseMessageType
- class openedx.core.djangoapps.schedules.message_types.UpgradeReminder(*args, **kwargs)#
Bases:
ScheduleMessageType
openedx.core.djangoapps.schedules.models module#
- class openedx.core.djangoapps.schedules.models.Schedule(*args, **kwargs)#
Bases:
TimeStampedModel- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- active#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- created#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- enrollment#
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.placeis aForwardOneToOneDescriptorinstance.
- enrollment_id#
- experience#
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.restaurantis aReverseOneToOneDescriptorinstance.
- get_experience_type()#
- get_next_by_created(*, field=<model_utils.fields.AutoCreatedField: created>, is_next=True, **kwargs)#
- get_next_by_modified(*, field=<model_utils.fields.AutoLastModifiedField: modified>, is_next=True, **kwargs)#
- get_previous_by_created(*, field=<model_utils.fields.AutoCreatedField: created>, is_next=False, **kwargs)#
- get_previous_by_modified(*, field=<model_utils.fields.AutoLastModifiedField: modified>, is_next=False, **kwargs)#
- history = <django.db.models.manager.HistoryManagerFromHistoricalQuerySet object>#
- 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>#
- save_without_historical_record(*args, **kwargs)#
Save the model instance without creating a historical record.
Make sure you know what you’re doing before using this method.
- start_date#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- upgrade_deadline#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- class openedx.core.djangoapps.schedules.models.ScheduleConfig(*args, **kwargs)#
Bases:
ConfigurationModel- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- KEY_FIELDS = ('site',)#
- 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.parentis aForwardManyToOneDescriptorinstance.
- changed_by_id#
- deliver_course_update#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- deliver_recurring_nudge#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- deliver_upgrade_reminder#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- enabled#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- enqueue_course_update#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- enqueue_recurring_nudge#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- enqueue_upgrade_reminder#
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_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.
- site#
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.parentis aForwardManyToOneDescriptorinstance.
- site_id#
- class openedx.core.djangoapps.schedules.models.ScheduleExperience(*args, **kwargs)#
Bases:
Model- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- EXPERIENCES = Choices((0, 'default', 'Recurring Nudge and Upgrade Reminder'), (1, 'course_updates', 'Course Updates'))#
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- experience_type#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_experience_type_display(*, field=<django.db.models.fields.PositiveSmallIntegerField: experience_type>)#
- id#
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>#
- schedule#
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.placeis aForwardOneToOneDescriptorinstance.
- schedule_id#
openedx.core.djangoapps.schedules.resolvers module#
- class openedx.core.djangoapps.schedules.resolvers.BinnedSchedulesBaseResolver(async_send_task, site, target_datetime, day_offset, bin_num, override_recipient_email=None)#
Bases:
PrefixedDebugLoggerMixin,RecipientResolverIdentifies learners to send messages to, pulls all needed context and sends a message to each learner.
Note that for performance reasons, it actually enqueues a task to send the message instead of sending the message directly.
- Parameters:
message (async_send_task -- celery task function that sends the)
of (site -- Site object that filtered Schedules will be a part)
under (target_datetime -- datetime that the User's Schedule's schedule_date_field value should fall)
targeting (day_offset -- int number of days relative to the Schedule's schedule_date_field that we are)
bin_num (bin_num -- int for selecting the bin of Users whose id % num_bins ==)
names (org_list -- list of course_org) – (default: None)
exclude (exclude_orgs -- boolean indicating whether the returned Schedules should) – org_list or strictly include (False) them (default: False)
normal (override_recipient_email -- string email address that should receive all emails instead of the) – recipient. (default: None)
- Static attributes:
- schedule_date_field – the name of the model field that represents the date that offsets should be computed
relative to. For example, if this resolver finds schedules that started 7 days ago this variable should be set to “start”.
num_bins – the int number of bins to split the users into experience_filter – a queryset filter used to select only the users who should be getting this message as part
of their experience. This defaults to users without a specified experience type and those in the “recurring nudges and upgrade reminder” experience.
- classmethod bin_num_for_user_id(user_id)#
Returns the bin number used for the given (numeric) user ID.
- experience_filter = <Q: (OR: ('experience__experience_type', 0), ('experience__isnull', True))>#
- filter_by_org(schedules)#
Given the configuration of sites, get the list of orgs that should be included or excluded from this send.
- Returns:
- Returns a tuple (exclude_orgs, org_list). If exclude_orgs is True, then org_list is a list of the
only orgs that should be included in this send. If exclude_orgs is False, then org_list is a list of orgs that should be excluded from this send. All other orgs should be included.
- Return type:
tuple
- get_schedules_with_target_date_by_bin_and_orgs(order_by='enrollment__user__id')#
Returns Schedules with the target_date, related to Users whose id matches the bin_num, and filtered by org_list.
Arguments: order_by – string for field to sort the resulting Schedules by
- get_template_context(user, user_schedules)#
Given a user and their schedules, build the context needed to render the template for this message.
- Parameters:
message (user -- the User who will be receiving the)
by (user_schedules -- a list of Schedule objects representing all of their schedules that should be covered) – this message. For example, when a user enrolls in multiple courses on the same day, we don’t want to send them multiple reminder emails. Instead this list would have multiple elements, allowing us to send a single message for all of the courses.
- Returns:
- This dict must be JSON serializable (no datetime objects!). When rendering the message templates it
it will be used as the template context. Note that it will also include several default values that injected into all template contexts. See get_base_template_context for more information.
- Return type:
dict
- Raises:
InvalidContextError – If this user and set of schedules are not valid for this type of message. Raising this
exception will prevent this user from receiving the message, but allow other messages to be sent to other –
users. –
- num_bins = 24#
- schedule_date_field = None#
- schedules_for_bin()#
- send(msg_type)#
send()aMessagepersonalized frommsg_typeto all recipients selected by thisRecipientResolver.- Parameters:
msg_type (
MessageType) – An instantiatedMessageTypethat describes the message batch to send.
- class openedx.core.djangoapps.schedules.resolvers.CourseNextSectionUpdate(async_send_task, site, target_datetime, course_id, override_recipient_email=None)#
Bases:
PrefixedDebugLoggerMixin,RecipientResolverSend a message to all users whose schedule gives them a due date of yesterday.
Only used for Self-paced Courses
- experience_filter = <Q: (AND: ('experience__experience_type', 1))>#
- get_schedules()#
Grabs possible schedules that could receive a Course Next Section Update and if a next section highlight is applicable for the user, yields information needed to send the next section highlight email.
- log_prefix = 'Next Section Course Update'#
- send()#
send()aMessagepersonalized frommsg_typeto all recipients selected by thisRecipientResolver.- Parameters:
msg_type (
MessageType) – An instantiatedMessageTypethat describes the message batch to send.
- class openedx.core.djangoapps.schedules.resolvers.CourseUpdateResolver(async_send_task, site, target_datetime, day_offset, bin_num, override_recipient_email=None)#
Bases:
BinnedSchedulesBaseResolverSend a message to all users whose schedule started at
self.current_date+day_offsetand the course has updates.Only used for Instructor-paced Courses
- experience_filter = <Q: (AND: ('experience__experience_type', 1))>#
- log_prefix = 'Course Update'#
- num_bins = 24#
- schedule_date_field = 'start_date'#
- schedules_for_bin()#
- send(msg_type)#
send()aMessagepersonalized frommsg_typeto all recipients selected by thisRecipientResolver.- Parameters:
msg_type (
MessageType) – An instantiatedMessageTypethat describes the message batch to send.
- exception openedx.core.djangoapps.schedules.resolvers.InvalidContextError#
Bases:
Exception
- class openedx.core.djangoapps.schedules.resolvers.RecurringNudgeResolver(async_send_task, site, target_datetime, day_offset, bin_num, override_recipient_email=None)#
Bases:
BinnedSchedulesBaseResolverSend a message to all users whose schedule started at
self.current_date+day_offset.- property experience_filter#
Encapsulate filters as objects that can then be combined logically (using & and |).
- get_template_context(user, user_schedules)#
Given a user and their schedules, build the context needed to render the template for this message.
- Parameters:
message (user -- the User who will be receiving the)
by (user_schedules -- a list of Schedule objects representing all of their schedules that should be covered) – this message. For example, when a user enrolls in multiple courses on the same day, we don’t want to send them multiple reminder emails. Instead this list would have multiple elements, allowing us to send a single message for all of the courses.
- Returns:
- This dict must be JSON serializable (no datetime objects!). When rendering the message templates it
it will be used as the template context. Note that it will also include several default values that injected into all template contexts. See get_base_template_context for more information.
- Return type:
dict
- Raises:
InvalidContextError – If this user and set of schedules are not valid for this type of message. Raising this
exception will prevent this user from receiving the message, but allow other messages to be sent to other –
users. –
- log_prefix = 'Recurring Nudge'#
- num_bins = 24#
- schedule_date_field = 'start_date'#
- class openedx.core.djangoapps.schedules.resolvers.UpgradeReminderResolver(async_send_task, site, target_datetime, day_offset, bin_num, override_recipient_email=None)#
Bases:
BinnedSchedulesBaseResolverSend a message to all users whose verified upgrade deadline is at
self.current_date+day_offset.- get_template_context(user, user_schedules)#
Given a user and their schedules, build the context needed to render the template for this message.
- Parameters:
message (user -- the User who will be receiving the)
by (user_schedules -- a list of Schedule objects representing all of their schedules that should be covered) – this message. For example, when a user enrolls in multiple courses on the same day, we don’t want to send them multiple reminder emails. Instead this list would have multiple elements, allowing us to send a single message for all of the courses.
- Returns:
- This dict must be JSON serializable (no datetime objects!). When rendering the message templates it
it will be used as the template context. Note that it will also include several default values that injected into all template contexts. See get_base_template_context for more information.
- Return type:
dict
- Raises:
InvalidContextError – If this user and set of schedules are not valid for this type of message. Raising this
exception will prevent this user from receiving the message, but allow other messages to be sent to other –
users. –
- log_prefix = 'Upgrade Reminder'#
- num_bins = 24#
- schedule_date_field = 'upgrade_deadline'#
openedx.core.djangoapps.schedules.signals module#
CourseEnrollment related signal handlers.
- openedx.core.djangoapps.schedules.signals.create_schedule(sender, **kwargs)#
When a CourseEnrollment is created, create a Schedule if configured.
- openedx.core.djangoapps.schedules.signals.reset_schedule_on_mode_change(sender, user, course_key, mode, **kwargs)#
When a CourseEnrollment’s mode is changed, reset the user’s schedule if self-paced.
- openedx.core.djangoapps.schedules.signals.update_schedules_on_course_start_changed(sender, updated_course_overview, previous_start_date, **kwargs)#
Updates all course schedules start and upgrade_deadline dates based off of the new course overview start date.
openedx.core.djangoapps.schedules.tasks module#
- class openedx.core.djangoapps.schedules.tasks.BinnedScheduleMessageBaseTask#
Bases:
ScheduleMessageBaseTaskBase class for top-level Schedule tasks that create subtasks for each Bin.
- class_from_classpath(class_path)#
- classmethod enqueue(site, current_date, day_offset, override_recipient_email=None, override_middlewares=None)#
- make_message_type(day_offset)#
- num_bins = 24#
- priority = None#
Default task priority.
- rate_limit = None#
None(no rate limit), ‘100/s’ (hundred tasks a second), ‘100/m’ (hundred tasks a minute),`’100/h’` (hundred tasks an hour)- Type:
Rate limit for this task type. Examples
- reject_on_worker_lost = None#
Even if
acks_lateis enabled, the worker will acknowledge tasks when the worker process executing them abruptly exits or is signaled (e.g., :sig:`KILL`/:sig:`INT`, etc).Setting this to true allows the message to be re-queued instead, so that the task will execute again by the same worker, or another worker.
Warning: Enabling this can cause message loops; make sure you know what you’re doing.
- request_stack = <celery.utils.threads._LocalStack object>#
Task request stack, the current request will be the topmost.
- run(site_id, target_day_str, day_offset, bin_num, override_recipient_email=None, override_middlewares=None)#
The body of the task executed by workers.
- serializer = 'json'#
The name of a serializer that are registered with
kombu.serialization.registry. Default is ‘json’.
- store_errors_even_if_ignored = True#
When enabled errors will be stored even if the task is otherwise configured to ignore results.
- task_instance = None#
- track_started = True#
If enabled the task will report its status as ‘started’ when the task is executed by a worker. Disabled by default as the normal behavior is to not report that level of granularity. Tasks are either pending, finished, or waiting to be retried.
Having a ‘started’ status can be useful for when there are long running tasks and there’s a need to report what task is currently running.
The application default can be overridden using the :setting:`task_track_started` setting.
- typing = True#
Enable argument checking. You can set this to false if you don’t want the signature to be checked when calling the task. Defaults to
app.strict_typing.
- class openedx.core.djangoapps.schedules.tasks.ScheduleMessageBaseTask#
Bases:
LoggedTaskBase class for top-level Schedule tasks that create subtasks.
- async_send_task = None#
- enqueue_config_var = None#
- ignore_result = True#
If enabled the worker won’t store task state and return values for this task. Defaults to the :setting:`task_ignore_result` setting.
- classmethod is_enqueue_enabled(site)#
- classmethod log_debug(message, *args, **kwargs)#
Wrapper around LOG.debug that prefixes the message.
- classmethod log_info(message, *args, **kwargs)#
Wrapper around LOG.info that prefixes the message.
- log_prefix = None#
- priority = None#
Default task priority.
- rate_limit = None#
None(no rate limit), ‘100/s’ (hundred tasks a second), ‘100/m’ (hundred tasks a minute),`’100/h’` (hundred tasks an hour)- Type:
Rate limit for this task type. Examples
- reject_on_worker_lost = None#
Even if
acks_lateis enabled, the worker will acknowledge tasks when the worker process executing them abruptly exits or is signaled (e.g., :sig:`KILL`/:sig:`INT`, etc).Setting this to true allows the message to be re-queued instead, so that the task will execute again by the same worker, or another worker.
Warning: Enabling this can cause message loops; make sure you know what you’re doing.
- request_stack = <celery.utils.threads._LocalStack object>#
Task request stack, the current request will be the topmost.
- resolver = None#
- routing_key = 'edx.lms.core.default'#
- serializer = 'json'#
The name of a serializer that are registered with
kombu.serialization.registry. Default is ‘json’.
- store_errors_even_if_ignored = True#
When enabled errors will be stored even if the task is otherwise configured to ignore results.
- track_started = True#
If enabled the task will report its status as ‘started’ when the task is executed by a worker. Disabled by default as the normal behavior is to not report that level of granularity. Tasks are either pending, finished, or waiting to be retried.
Having a ‘started’ status can be useful for when there are long running tasks and there’s a need to report what task is currently running.
The application default can be overridden using the :setting:`task_track_started` setting.
- typing = True#
Enable argument checking. You can set this to false if you don’t want the signature to be checked when calling the task. Defaults to
app.strict_typing.
openedx.core.djangoapps.schedules.utils module#
- class openedx.core.djangoapps.schedules.utils.PrefixedDebugLoggerMixin(*args, **kwargs)#
Bases:
object- log_debug(message, *args, **kwargs)#
Wrapper around LOG.debug that prefixes the message.
- log_info(message, *args, **kwargs)#
Wrapper around LOG.info that prefixes the message.
- log_prefix = None#
- openedx.core.djangoapps.schedules.utils.reset_self_paced_schedule(user, course_key, use_enrollment_date=False)#
Reset the user’s schedule if self-paced.
It does not create a new schedule, just resets an existing one. This is used, for example, when a user requests it or when an enrollment mode changes.
- Parameters:
user (User)
course_key (CourseKey or str)
use_enrollment_date (bool) – if False, reset to now, else reset to original enrollment creation date