Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: provide option to query asset using storage default url or through the LMS #100

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ This should be added both to the LMS and the CMS settings. Instead of a function

Note that the SCORM XBlock comes with extended S3 storage support out of the box. See the following section:

Default storage URL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This additional setting is not needed we can rely on S3_QUERY_AUTH

~~~~~~~~~~~~~~~~~~

By default, scorm will proxy assets through the LMS. This is done for security and to make the backend generic enough to be used with different storage backends. However, to utilize the default storage defined url, add the following to the ScormXBlock settings::

.. code-block:: python

XBLOCK_SETTINGS["ScormXBlock"] = {
"DEFAULT_STORAGE_URL": True,
}

Scorm will now use the configured storages default `url` method instead of proxying the data through the LMS. The url method must be defined on the configured storage class for this work.

S3 storage
~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions changelog.d/20250307_193543_danyal.faheem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- [Improvement] Provide an option to use the default storage url to get scorm assets or proxy them through the LMS. (by @Danyal-Faheem)
47 changes: 8 additions & 39 deletions openedxscorm/scormxblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,43 +55,6 @@ def _(text):
@XBlock.wants("settings")
@XBlock.wants("user")
class ScormXBlock(XBlock, CompletableXBlockMixin):
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we need to remove this docstring?

When a user uploads a Scorm package, the zip file is stored in:

media/{org}/{course}/{block_type}/{block_id}/{sha1}{ext}

This zip file is then extracted to the media/{scorm_location}/{block_id}.

The scorm location is defined by the LOCATION xblock setting. If undefined, this is
"scorm". This setting can be set e.g:

XBLOCK_SETTINGS["ScormXBlock"] = {
"LOCATION": "alternatevalue",
}

Note that neither the folder the folder nor the package file are deleted when the
xblock is removed.

By default, static assets are stored in the default Django storage backend. To
override this behaviour, you should define a custom storage function. This
function must take the xblock instance as its first and only argument. For instance,
you can store assets in different directories depending on the XBlock organization with::

def scorm_storage(xblock):
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration

subfolder = SiteConfiguration.get_value_for_org(
xblock.location.org, "SCORM_STORAGE_NAME", "default"
)
storage_location = os.path.join(settings.MEDIA_ROOT, subfolder)
return get_storage_class(settings.DEFAULT_FILE_STORAGE)(location=storage_location)

XBLOCK_SETTINGS["ScormXBlock"] = {
"STORAGE_FUNC": scorm_storage,
}
"""

display_name = String(
display_name=_("Display Name"),
Expand Down Expand Up @@ -420,14 +383,20 @@ def extract_package(self, package_file):
def index_page_url(self):
if not self.package_meta or not self.index_page_path:
return ""

if not self.xblock_settings.get("DEFAULT_STORAGE_URL", False):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use S3_QUERY_AUTH setting to determinse whetere we should serve static assets vis lms or not. because this setting is used for signing urls in case of private bucket.

Suggested change
if not self.xblock_settings.get("DEFAULT_STORAGE_URL", False):
if self.xblock_settings.get("S3_QUERY_AUTH",True)

return f"{self.proxy_base_url}/{self.index_page_path}"

folder = self.extract_folder_path
if self.storage.exists(
os.path.join(self.extract_folder_base_path, self.clean_path(self.index_page_path))
):
# For backward-compatibility, we must handle the case when the xblock data
# is stored in the base folder.
logger.warning("Serving SCORM content from old-style path: %s", self.extract_folder_base_path)
folder = self.extract_folder_base_path
logger.warning("Serving SCORM content from old-style path: %s", folder)

return f"{self.proxy_base_url}/{self.index_page_path}"
return self.storage.url(os.path.join(folder, self.index_page_path))

@property
def proxy_base_url(self):
Expand Down