From d0e0a5516c32dd156398dba3b9cb16f480d269e6 Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Thu, 10 Oct 2024 17:21:07 -0400 Subject: [PATCH] feat: add xblock api asset connection so that we can actually test this --- .../core/djangoapps/content_libraries/api.py | 41 +++++++++++++++++-- .../djangoapps/content_libraries/views.py | 6 ++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index b9f3779af539..60bcfdf2924f 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -68,6 +68,7 @@ from django.db.models import Q, QuerySet from django.utils.translation import gettext as _ from edx_rest_api_client.client import OAuthAPIClient +from django.urls import reverse from lxml import etree from opaque_keys.edx.keys import BlockTypeKey, UsageKey, UsageKeyV2 from opaque_keys.edx.locator import ( @@ -95,7 +96,11 @@ from xblock.core import XBlock from xblock.exceptions import XBlockNotFoundError -from openedx.core.djangoapps.xblock.api import get_component_from_usage_key, xblock_type_display_name +from openedx.core.djangoapps.xblock.api import ( + get_component_from_usage_key, + get_xblock_app_config, + xblock_type_display_name, +) from openedx.core.lib.xblock_serializer.api import serialize_modulestore_block_for_learning_core from xmodule.library_root_xblock import LibraryRoot as LibraryRootV1 from xmodule.modulestore import ModuleStoreEnum @@ -1001,10 +1006,40 @@ def get_library_block_static_asset_files(usage_key) -> list[LibraryXBlockStaticF Returns a list of LibraryXBlockStaticFile objects, sorted by path. - TODO: This is not yet implemented for Learning Core backed libraries. TODO: Should this be in the general XBlock API rather than the libraries API? """ - return [] + component = 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') + ) + + site_root_url = get_xblock_app_config().get_site_root_url() + + return [ + LibraryXBlockStaticFile( + path=cvc.key, + size=cvc.content.size, + url=site_root_url + reverse( + 'content_libraries:library-assets', + kwargs={ + 'component_version_uuid': component_version.uuid, + 'asset_path': cvc.key, + } + ), + ) + for cvc in cvc_set + ] def add_library_block_static_asset_file(usage_key, file_name, file_content) -> LibraryXBlockStaticFile: diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py index c571cce86be1..78ea7e9eb3a6 100644 --- a/openedx/core/djangoapps/content_libraries/views.py +++ b/openedx/core/djangoapps/content_libraries/views.py @@ -71,6 +71,7 @@ from django.conf import settings from django.contrib.auth import authenticate, get_user_model, login from django.contrib.auth.models import Group +from django.core.exceptions import ObjectDoesNotExist from django.db.transaction import atomic, non_atomic_requests from django.http import Http404, HttpResponse, HttpResponseBadRequest, JsonResponse, StreamingHttpResponse from django.shortcuts import get_object_or_404 @@ -87,6 +88,7 @@ import edx_api_doc_tools as apidocs from opaque_keys import InvalidKeyError from opaque_keys.edx.locator import LibraryLocatorV2, LibraryUsageLocatorV2 +from openedx_learning.api import authoring from organizations.api import ensure_organization from organizations.exceptions import InvalidOrganizationException from organizations.models import Organization @@ -1125,7 +1127,7 @@ def component_version_asset(request, component_version_uuid, asset_path): eventually). """ try: - component_version = authoring_api.get_component_version_by_uuid( + component_version = authoring.get_component_version_by_uuid( component_version_uuid ) except ObjectDoesNotExist: @@ -1144,7 +1146,7 @@ def component_version_asset(request, component_version_uuid, asset_path): # this response in conjunction with a media reverse proxy (Caddy or Nginx), # but in the short term we're just going to remove the redirect and stream # the content directly. - redirect_response = authoring_api.get_redirect_response_for_component_asset( + redirect_response = authoring.get_redirect_response_for_component_asset( component_version_uuid, asset_path, public=False,