Split modulestore persists data in three MongoDB "collections": course_index (list of courses and the current version of each), structure (outline of the courses, and some XBlock fields), and definition (other XBlock fields). While "structure" and "definition" data can get very large, which is one of the reasons MongoDB was chosen for modulestore, the course index data is very small.
By moving course index data to MySQL / a django model, we get these advantages:
* Full history of changes to the course index data is now preserved
* Includes a django admin view to inspect the list of courses and libraries
* It's much easier to "reset" a corrupted course to a known working state, by using the simple-history revert tools from the django admin.
* The remaining MongoDB collections (structure and definition) are essentially just used as key-value stores of large JSON data structures. This paves the way for future changes that allow migrating courses one at a time from MongoDB to S3, and thus eliminating any use of MongoDB by split modulestore, simplifying the stack.
The Referrer header from the MFE hosted on a different origin does not
include the path, so make sure to ignore the path portion of the
learning MFE base URL when determining whether the request is coming
from the new MFE or the old courseware view.
For self-paced courses, we have decided to switch to showing the end
date as long as it is within 365 days rather than the expected
duration of the course.
Also removes the remove_course_goal method as it is no longer
used anywhere and removes the functionality of deleting course goals
if a user unenrolls. Adds in fields for eventing to make them more
useful.
We discovered a subsection that contained a unit without any content
inside, but because of our logic requiring children, it would never be
marked complete (meaning the subsection, section, and course could thus
never be marked complete). This fixes that by removing the children
check from setting completion, but first gating that code path on the
xblock being an aggregator (to prevent leaves from marking as true
simply because there are no children).
Test fixes include adding a test for the empty aggregator case as
well as some changes to not have an entire course marked complete
because they are all empty aggregators.
We have been bucketing all users into the relative dates experiment
since May 18, 2020. We no longer need to keep this as an
ExperimentWaffleFlag and can convert to a CourseWaffleFlag (so it
continues to support exemptions).
For now only the discussion blocks were supported. If we had a custom XBlock that specified `completion_mode = XBlockCompletionMode.EXCLUDED`, then it could never be marked as completed on the course outline page, despite being marked as such inside the learning sequence.
Centralize the logic for choosing between
MFE and Legacy-frontend courseware within
three new functions:
* courseware_mfe_is_active
* courseware_mfe_is_visible
* courseware_legacy_is_visible
This allows us to create another new function:
* get_courseware_url
which can be called anywhere in LMS/Studio
to get the canonical URL to courseware
content (whether it be MFE or Legacy).
In future commits we we begin using
get_courseware_url throughout the platform.
TNL-7796
This commit removes several waffle toggles that have been enabled
on edx.org for years. It's time to remove the rollout gating for
these features and enable them by default.
This doesn't directly change any behavior. But it does create new
database objects by default now and allows for enabling other
schedule based features more easily.
Specifically, the following toggles were affected.
schedules.create_schedules_for_course
- Waffle flag removed as always-enabled
- We now always create a schedule when an enrollment is created
schedules.send_updates_for_course
- Waffle flag removed as always-enabled
- Course update emails are sent as long as the ScheduleConfig
allows it.
- This is not a change in default behavior, because ScheduleConfig
is off by default.
dynamic_pacing.studio_course_update
- Waffle switch removed as always-enabled
- Course teams can now always edit course updates directly in Studio
ScheduleConfig.create_schedules
ScheduleConfig.hold_back_ratio
- Model fields for rolling out the schedules feature
- Schedules are now always created
- This commit only removes references to these fields, they still
exist in the database. A future commit will remove them entirely
This commit also adds a new has_highlights field to CourseOverview.
This is used to cache whether a course has highlights, used to
decide which course update email behavior they get. Previously every
enrollment had to dig into the modulestore to determine that.
This PR also removes the exemption for staff from seeing the reset
deadlines banner (staff will now see the banner). Staff users would
still be unable to submit problems and wouldn't have a way of resetting
their deadlines while enrolled.
These changes were initially made to make it easier to do SECRET_KEY rotations. Along the way, we found it made sense to refractor the code as well.
Changes made:
- changed get_to_create to create because now the code should only get to this block when a write is necessary
- added a lookup for anonymous_user_id. This is to return an existing anonymous_user_id rather than calculating. This will mitigate the results of SECRET_KEY rotation.
- Added monitoring to help us make better decisions: should we not sue SECRET_KEY, performance considerations...
- put old function behind toggle in case something goes wrong in production with new code
- refractoring function structure for better understanding
This PR lays the groundwork for a an LTI tab that can embed any LTI1.1-based
tool as an course tab. It also adds another tab based on this LTI Tab that
offers special support for embedding LTI-based discussion tools in a course
tab. If enabled this will replace the existing discussion tab.
Specifically, send data versions of course_expired_message and
offer_html.
The rendered HTML is still being sent for now, until the learning
MFE is updated to consume the data objects.
Waffle classes no longer have namespaces. All features are moved to the
WaffleFlag/WaffleSwitch classes.
Here we use the edx_toggles.toggles.__future__ API, which is available
in 1.2.0. This means that we don't have to upgrade edx-toggles. We
should remove the __future__ imports as soon as we upgrade to 2.0.0.
This is required because edx-platform uses the waffle API from
completion, which itself depends on edx-toggles. So if we change
edx-toggles import paths, we also need to upgrade our usage of
completion here.
Previously, dismissing one course update would disable all future
updates. But that feels a bit limiting.
Instead, these are the new rules:
- If the newest update has not been dismissed yet, it gets displayed.
- If the newest update has been dismissed, we display nothing.
- Editing the newest update will cause it to be displayed again.
- New updates get displayed, even if previous updates were dismissed.
This commit includes a light refactoring and addition of some utility
methods to help manage the above.
It also notes that the learning MFE does not use the "latest_update"
waffle option, which controls the labeling of the update message.
* Generate common/djangoapps import shims for LMS
* Generate common/djangoapps import shims for Studio
* Stop appending project root to sys.path
* Stop appending common/djangoapps to sys.path
* Import from common.djangoapps.course_action_state instead of course_action_state
* Import from common.djangoapps.course_modes instead of course_modes
* Import from common.djangoapps.database_fixups instead of database_fixups
* Import from common.djangoapps.edxmako instead of edxmako
* Import from common.djangoapps.entitlements instead of entitlements
* Import from common.djangoapps.pipline_mako instead of pipeline_mako
* Import from common.djangoapps.static_replace instead of static_replace
* Import from common.djangoapps.student instead of student
* Import from common.djangoapps.terrain instead of terrain
* Import from common.djangoapps.third_party_auth instead of third_party_auth
* Import from common.djangoapps.track instead of track
* Import from common.djangoapps.util instead of util
* Import from common.djangoapps.xblock_django instead of xblock_django
* Add empty common/djangoapps/__init__.py to fix pytest collection
* Fix pylint formatting violations
* Exclude import_shims/ directory tree from linting
* Use full LMS imports paths in LMS settings and urls modules
* Use full LMS import paths in Studio settings and urls modules
* Import from lms.djangoapps.badges instead of badges
* Import from lms.djangoapps.branding instead of branding
* Import from lms.djangoapps.bulk_email instead of bulk_email
* Import from lms.djangoapps.bulk_enroll instead of bulk_enroll
* Import from lms.djangoapps.ccx instead of ccx
* Import from lms.djangoapps.course_api instead of course_api
* Import from lms.djangoapps.course_blocks instead of course_blocks
* Import from lms.djangoapps.course_wiki instead of course_wiki
* Import from lms.djangoapps.courseware instead of courseware
* Import from lms.djangoapps.dashboard instead of dashboard
* Import from lms.djangoapps.discussion import discussion
* Import from lms.djangoapps.email_marketing instead of email_marketing
* Import from lms.djangoapps.experiments instead of experiments
* Import from lms.djangoapps.gating instead of gating
* Import from lms.djangoapps.grades instead of grades
* Import from lms.djangoapps.instructor_analytics instead of instructor_analytics
* Import form lms.djangoapps.lms_xblock instead of lms_xblock
* Import from lms.djangoapps.lti_provider instead of lti_provider
* Import from lms.djangoapps.mobile_api instead of mobile_api
* Import from lms.djangoapps.rss_proxy instead of rss_proxy
* Import from lms.djangoapps.static_template_view instead of static_template_view
* Import from lms.djangoapps.survey instead of survey
* Import from lms.djangoapps.verify_student instead of verify_student
* Stop suppressing EdxPlatformDeprecatedImportWarnings
This is part of a removal of the many override methods of toggle
flag/namespace classes. This allows us to remove imports of test modules
from production code.