fix: SCORM block files survive OLX roundtrip and course rerun#116
Conversation
| cur = stack.pop() | ||
| try: | ||
| dirs, files = self.storage.listdir(cur) | ||
| except (FileNotFoundError, NotImplementedError): |
There was a problem hiding this comment.
I do not understand the need for a NotImplementedError. What method are we expecting to not be implemented?
There was a problem hiding this comment.
Yes i have removed it.
| if not self.package_meta or not self.index_page_path: | ||
| return "" | ||
|
|
||
| self._rehydrate_extract_folder_if_missing() |
There was a problem hiding this comment.
The index_page_url method is called in the student_view meaning it is called every time someone opens a scorm unit in the LMS.
For this reason, I don't think it is optimal that we should be calling a rehydrate method that is only required once after a course import.
Is there a way to call this only once per xblock after a course import?
There was a problem hiding this comment.
I have cached its so rehydrate does not run everytime.
Danyal-Faheem
left a comment
There was a problem hiding this comment.
LGTM!
Thank you for bearing with my incessant commenting 🙇.
Summary
Fixes #108 (SCORM block 404s after OLX export/import) and extends the same fix to course rerun.
When an author uploads a SCORM zip, the block extracts it into
default_storageand discards the original zip. The block's metadata is persisted in the modulestore, but the underlying files aren't tracked by anything else. As a result:extract_folder_path(keyed to the rerun course'susage_id), while files remain at the source course's path. Same 404 symptom.Approach
Two complementary hooks, both implemented inside the XBlock — no
openedx-platformchanges required:OLX export/import. Override
add_xml_to_nodeto bundle a fresh re-zip of the extracted SCORM tree into the export tarball atscorm/<url_name>/package.zip, and overrideparse_xmlto re-extract on import.parse_xmltemporarily re-keysscope_ids.usage_idto the target course's coordinates during extraction so files land where the rendered block will look for them (otherwise extract uses the source course's hash and the rendered block 404s).Course rerun. Rerun bypasses OLX entirely (
store.clone_courseoperates at the modulestore level — neitheradd_xml_to_nodenorparse_xmlfires). Added a lazy_rehydrate_extract_folder_if_missinghelper that runs on first render. If files are missing but the block knows its SHA1, it scansscorm_location()for another bucket containing the same SHA1 directory and copies the tree in. Self-healing, no signal handlers, no Django app conversion.Wired into
index_page_urlandassets_proxy. A per-instance_extract_folder_verifiedflag ensures the search only runs once per block instance.What this fixes
What this does not fix
scorm_package_pathattribute, so the import-time rehydrate doesn't fire. If no other course on the destination instance has the same package, the block requires a re-upload. (Re-export of the same course on this code produces a self-contained tarball that works anywhere.)Builds on #71
#71 introduced the
usage_id-hashedextract_folder_base_path. The re-keying trick inparse_xmldepends on that hash being deterministic. This PR closes the export/import and rerun caveats listed in #71's description.Co-Authored-By: Claude noreply@anthropic.com