The get_service_user method used to do a local call to the
get_user_model function because it was not guaranteed to be properly
initialized at the time of import. This was partly due to how we did
custom initialization using lms/startup.py, but it was also because
when it was implemented (commit f318661), the platform was still
running on Django 1.8.18. At that time, get_user_model was guaranteed to
work only after Django has imported all models.
In Django 1.11, the behavior of get_user_model was changed:
https://docs.djangoproject.com/en/1.11/releases/1.11/#django-contrib-auth
> get_user_model() can now be called at import time,
> even in modules that define models.
Now that lms/startup.py is gone and get_user_model is safe to call at
the module level, I'm refactoring the catalog app's models.py file to
follow the convention we use everywhere else in edx-platform with
respect to get_user_model.
The cms/startup.py and lms/startup.py files were created to
allow us to do a lot of custom initialization around things
like the ModuleStore, monkey-patching, adding MIME types to
our process, etc. As far back as 2017, we recognized that
this was a bad thing, marked these modules as "deprecated",
and started removing things or putting them in the standard
Django locations for them (0279181).
In its current state, these startup modules no longer do any
custom work, and just invoke django.startup(). But this is
meant for running Django code in "standalone" usage, e.g. if
you have a script that isn't a management command but needs
some Django functionality.
The "runserver" command used during development normally
launches a child process to serve requests and knows how to
kill and respawn that process when files are modified, so
that changes are reflected. It can also normally handle the
case where there's a SyntaxError in the child process, and
fixing that error will reload the code again.
Something about running django.startup() manually interferes
with this functionality in "runserver". It still reloads the
code in response to changes, but if the code gets into a
broken state for any reason (like a syntax error), the master
process itself dies. That causes the container to restart,
only to die again shortly afterwards in a loop until the
error is fixed. The container restarts will break any shell
you had opened into the container, as well as any IDE
integrations that connected to that container to access the
files and Python instance.
Getting rid of the custom startup code fixes this and moves
us one small step closer to being a more normal Django
project.
for Open edX operators who still have users with legacy PDF certificates, retirement requires first extracting information from the user's GeneratedCertificate record in order to delete the 4 associated files for each PDF certificate, and then removing the links to the relevant files. this creates a management command to do that work.
After thinking about it, I have removed the update to `status` from this management command, as per the original specification of the ticket. I added it for completeness originally, but was already uncomfortable, because it's not exactly accurate. The `CertificateStatuses` enum does define a `deleted` status:
```
deleted - The PDF certificate has been deleted.
```
but I think it's inappropriate to use here.
#### Why not use `CertificateStatuses.deleted` in the first place
There are multiple places in the code where it's clear that almost all of the statuses are legacy and unused (eg. [Example 1](6c6fd84e53/lms/djangoapps/certificates/data.py (L12-L34)), [Example 2](1029de5537/common/djangoapps/student/helpers.py (L491-L492))). There are innumerable APIs in the system that have expectations about what might possibly be returned from a `GeneratedCertificate.status` object, and none of them is expecting `deleted`
#### Why not revoke the certificate
Ultimately, the certificate isn't revoked, which has a specific meaning around saying it was unearned. The certificate was earned; it has simply been deleted. We should not be kicking off program certificate invalidation, because that's not what's happening. We should be trusting the normal user retirement process to remove/purge PII from any program certificates that might exist. The nature of web certificates simply means that we are going through this process outside of the normal retirement flow. The normal retirement flow can be trusted to implement any certificate object revocation/removal/PII-purging, and doing an extra step outside of that flow is counterproductive.
#### Why not robustly add a flow for `CertificateStatuses.deleted`
When PDF certificates were removed from the system, they weren't removed in their entirety. Instead, we have this vestigial remains of PDF certificates code, just enough to allow learners to display and use the ones that they already have, without any of the support systems for modifying them. Adding a `deleted` status, verifying that all other APIs wouldn't break in the presence of a certificate with that status, adding the signals to process and propagate the change: all of this would be adding more tech debt upon the already existing technical debt which is the PDF certs code. Better to simply add this one necessary data integrity change, and focus on a process which might allow us to eventually remove the web certificates code.
#### Why it is good enough to ignore the status
The original ask was simply to enforce data integrity: to remove links to files that have been deleted, as an indication that they've been deleted. I only added `status` update out of a (misplaced but well-intentioned) completionist urge.
FIXES: APER-3889
* Add error handler on save video to avoid creating sjson
* Support transcripts without edx_video_id in definition_to_xml
* When copying a video from a library to a course: Create a new edx_video_id
* Save transcripts as static assets in a video in a library when adding a new transcript.
* Delete transcripts as static assets in a video in a library when deleting transcripts.
* Support download transcript in a video in a library.
* Support replace transcript in a video in a library.
* Support updating transcripts in video in a library.
* Refactor the code of downloading YouTube transcripts to enable this feature in libraries.
* Support copy from a library to a course and a course to a library.
This commit fixes an inconsistency in the way an exam due date is computed for courses that do not use an LTI based proctoring provider.
The edx-exams microservice was released last year to provide support for LTI based proctoring providers. After the release of this microservice, all proctoring requests initiated by the platform began to be funneled through the microservice, which acted as a broker for these requests, routing them directly to the service for exams in courses using an LTI based proctoring provider or to the platform edx-proctoring plugin for all other cases.
There is an asynchronous task in the platform that syncs exams from the platform to either the edx-exams microservice or the edx-proctoring plugin. Prior to the release of the microservice, this task computed the due date on exams as the exam subsection due date if the course was instructor-paced or None. After the release of the microservice, the task computed due dates differently than before. The due date on exams was computed as the due date on the exam, if there was one, or the end date of the course, if there was one, or None. This differed from the prior definition.
This resulted in inconsistent due date behavior. The exams in courses that were published or republished after the edx-exams microservice was released had the new computation of due date, while exams in courses that were published or republished before the edx-exams microservice was released had the old computation of due date.
This causes an issue for all exams in courses using non-LTI based providers. This is because the due date on exams across all courses that either do not use proctoring or that use a non-LTI based provider are inconsistent, depending on when they were last published.
This commit reintroduces the old computation to the task for exams in courses using a non-LTI based proctoring provider (i.e. those courses whose exams are not powered by the edx-exams microservice). In order to maintain the functionality of edx-exams, we continue to compute the due date as before for exams in courses using an LTI based proctoring provider (i.e. those courses whose exams are powered by the edx-exams microservice).
* fix: Render Word cloud and conditional block editor
- The xmodule-type to render is MetadataOnlyEditingDescriptor
- The xmodule type `MetadataOnlyEditingDescriptor` renders a `<div>` with the block metadata in the `data-metadata` attribute. But is necessary to call `XBlockEditorView.xblockReady()` to run the scripts to build the editor using the metadata.
- To call XBlockEditorView.xblockReady() we need a specific require.config
* fix: Adding save and cancel button
* fix: save with studio_submit of conditional_block and word_cloud_block
* test: Tests for studio_submit of conditional and word cloud
* revert: Delete studio_submit of conditional block. It is not supported
* style: Fix lint
---------
Co-authored-by: Navin Karkera <navin@opencraft.com>
These app models get pulled in when trying to build the OpenAPI docs so
we need their relevant apps installed into the environment used to
generate the docs.