Repository navigation
XBlock asset support for new libraries experience (WIP) #35557
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
Changes from 3 commits
c2e1d24
55e7efc
fd21124
2da6e8a
aef0bc8
5f74348
4013341
cbe1792
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
|
|
||
| from django.core.exceptions import ObjectDoesNotExist | ||
| from django.db.transaction import atomic | ||
| from django.urls import reverse | ||
|
|
||
| from openedx_learning.api import authoring as authoring_api | ||
|
|
||
|
|
@@ -20,6 +21,7 @@ | |
| from xblock.field_data import FieldData | ||
|
|
||
| from openedx.core.lib.xblock_serializer.api import serialize_modulestore_block_for_learning_core | ||
| from openedx.core.lib.xblock_serializer.data import StaticFile | ||
| from ..learning_context.manager import get_learning_context_impl | ||
| from .runtime import XBlockRuntime | ||
|
|
||
|
|
@@ -215,6 +217,42 @@ def get_block(self, usage_key, for_parent=None): | |
|
|
||
| return block | ||
|
|
||
| def get_block_assets(self, usage_key): | ||
| """ | ||
| This currently doesn't copy any | ||
| """ | ||
| component = self._get_component_from_usage_key(usage_key) | ||
| component_version = component.versioning.draft | ||
|
|
||
| # If there is no Draft version, then this was soft-deleted | ||
| if component_version is None: | ||
| return [] | ||
|
|
||
| # cvc = the ComponentVersionContent through table | ||
| cvc_set = ( | ||
| component_version | ||
| .componentversioncontent_set | ||
| .filter(content__has_file=True) | ||
| .order_by('key') | ||
| .select_related('content') | ||
| ) | ||
|
|
||
| return [ | ||
| StaticFile( | ||
| name=cvc.key, | ||
| url=None, | ||
| # url=reverse( | ||
| # 'content_libraries:library-assets', | ||
| # kwargs={ | ||
| # 'component_version_uuid': component_version.uuid, | ||
| # 'asset_path': cvc.key, | ||
| # } | ||
| # ), | ||
| data=cvc.content.read_file().read() | ||
| ) | ||
| for cvc in cvc_set | ||
| ] | ||
|
|
||
| def save_block(self, block): | ||
| """ | ||
| Save any pending field data values to Learning Core data models. | ||
|
|
@@ -291,6 +329,44 @@ def _lookup_asset_url(self, block: XBlock, asset_path: str) -> str | None: # py | |
|
|
||
| This is called by the XBlockRuntime superclass in the .runtime module. | ||
|
|
||
| TODO: Implement as part of larger static asset effort. | ||
| TODO: Like get_block, we currently assume that we're using the Draft | ||
| version. This should be a runtime parameter. | ||
|
Comment on lines
+328
to
+329
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You probably know this, but here in It would be very cool if we could later override this default using a context manager when needed, but I don't know if that's a safe way to implement such an override.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it sufficient to do Draft vs. Published, or should we be able to do any stored version (for the sake of seeing what changed)? (I was assuming we'd eventually need the latter.)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Being able to see any stored version would be great, so I think we should do that. But more often I'll just want to specify "latest draft" or "latest published" so I hope we can have both options. |
||
| """ | ||
| return None | ||
| usage_key = block.scope_ids.usage_id | ||
| component = self._get_component_from_usage_key(usage_key) | ||
| component_version = component.versioning.draft | ||
| if component_version is None: | ||
| # This could happen if a Component was soft-deleted. | ||
| raise NoSuchUsage(usage_key) | ||
|
|
||
| return reverse( | ||
| 'library-assets', | ||
| kwargs={ | ||
| 'component_version_uuid': component_version.uuid, | ||
|
|
||
| # The standard XBlock "static/{asset_path}"" substitution | ||
| # strips out the leading "static/" part because it assumes that | ||
| # all files will exist in a flat namespace. Learning Core treats | ||
| # directories differently, and there may one day be other files | ||
| # that are not meant to be externally downloadable at the root | ||
| # (e.g. LaTeX source files or graders). | ||
| # | ||
| # So the transformation looks like this: | ||
| # | ||
| # 1. The Learning Core ComponentVersion has an asset stored as | ||
| # "static/test.png". | ||
| # 1. The original OLX content we store references | ||
| # "/static/test.png" or "static/test.png". | ||
| # 2. The ReplaceURLService XBlock runtime service invokes | ||
| # static_replace and strips out "/static/". | ||
| # 3. The method we're in now is invoked with a static_path of | ||
| # just "test.png", because that's the transformation that | ||
| # works for ModuleStore-based courses. | ||
| # 4. This method then builds a URL that adds the "static/" | ||
| # prefix back when creating the URL. | ||
| # | ||
| # Which is a very long explanation for why we're re-adding the | ||
| # "static/" to the asset path below. | ||
| 'asset_path': f"static/{asset_path}", | ||
| } | ||
| ) | ||
Uh oh!
There was an error while loading. Please reload this page.