-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This alters the data model in the components app in a number of ways in order to support static assets, along with some refactoring: * Content has been renamed to RawContent to make it more clear when we are talking about "content" as a general concept and the actual data model that holds the raw bytes. * RawContent now uses FileField instead of BinaryField, giving us more cheaply scalable storage in exchange for higher latency. This is offset by the new TextContent model that will be used to store the text versions of RawContent that needs low-latency access (like XBlock OLX). * A primitive media_server app now exists to view static assets during development. It is NOT safe to use on a running site yet.
- Loading branch information
David Ormsbee
committed
Apr 14, 2023
1 parent
867ea8d
commit d18dc2d
Showing
30 changed files
with
1,016 additions
and
558 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,3 +65,5 @@ dev.db | |
|
||
.vscode | ||
|
||
# Media files (for uploads) | ||
media/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from django.apps import AppConfig | ||
from django.core.exceptions import ImproperlyConfigured | ||
from django.conf import settings | ||
|
||
|
||
class MediaServerConfig(AppConfig): | ||
""" | ||
Configuration for the Media Server application. | ||
""" | ||
|
||
name = "openedx_learning.contrib.media_server" | ||
verbose_name = "Learning Core: Media Server" | ||
default_auto_field = "django.db.models.BigAutoField" | ||
|
||
def ready(self): | ||
if not settings.DEBUG: | ||
# Until we get proper security and support for running this app | ||
# under a separate domain, just don't allow it to be run in | ||
# production environments. | ||
raise ImproperlyConfigured( | ||
"The media_server app should only be run in DEBUG mode!" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Media Server App | ||
================ | ||
|
||
The ``media_server`` app exists to serve media files that are ultimately backed by the RawContent model, *for development purposes and for sites with light-to-moderate traffic*. It also provides an API that can be used by CDNs for high traffic sites. | ||
|
||
Motivation | ||
---------- | ||
|
||
The ``components`` app stores large binary file data by calculating the hash and creating a django-storages backed file named after that hash. This is efficient from a storage point of view, because we don't store redundant copies for every version of a Component. There are at least two drawbacks: | ||
|
||
* We have unintelligibly named files that are confusing for clients. | ||
* Intra-file links between media files break. For instance, if we have a piece of HTML that makes a reference to a VTT file, that filename will have changed. | ||
|
||
This app tries to bridge that gap by serving URLs that preserve the original file names and give the illusion that there is a seprate set of media files for every version of a Component, but does a lookup behind the scenes to serve the correct hash-based-file. | ||
|
||
The big caveat on this is that Django is not really optimized to do this sort of asset serving. The most scalable approach is to have a CDN-backed solution where ``media_server`` serves the locations of files that are converted by worker code to serving the actual assets. (More details to follow when that part gets built out.) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from django.urls import path | ||
|
||
from .views import component_asset | ||
|
||
urlpatterns = [ | ||
path( | ||
( | ||
"component_asset/" | ||
"<str:learning_package_identifier>/" | ||
"<str:component_identifier>/" | ||
"<int:version_num>/" | ||
"<path:asset_path>" | ||
), | ||
component_asset, | ||
) | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
""" | ||
Early views | ||
""" | ||
from django.http import FileResponse | ||
from django.http import Http404 | ||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied | ||
|
||
from openedx_learning.core.components.api import get_component_version_content | ||
|
||
|
||
def component_asset( | ||
request, learning_package_identifier, component_identifier, version_num, asset_path | ||
): | ||
try: | ||
cvc = get_component_version_content( | ||
learning_package_identifier, component_identifier, version_num, asset_path | ||
) | ||
except ObjectDoesNotExist: | ||
raise Http404("File not found") | ||
|
||
if not cvc.learner_downloadable and not ( | ||
request.user and request.user.is_superuser | ||
): | ||
raise PermissionDenied("This file is not publicly downloadable.") | ||
|
||
# TODO: Etag support | ||
return FileResponse(cvc.raw_content.file, filename=cvc.identifier) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Contrib Package | ||
=============== | ||
|
||
The ``contrib`` package holds Django apps that *could* be implemented in separate repos, but are bundled here because it's more convenient to do so. | ||
|
||
Guidelines | ||
---------- | ||
|
||
Nothing from ``lib`` or ``core`` should *ever* import from ``contrib``. |
Oops, something went wrong.