Merge pull request #11413 from edx/ormsbee/course_image_cdn
Allow course images to be served from the CDN.
This commit is contained in:
@@ -3,6 +3,7 @@ Declaration of CourseOverview model
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
from urlparse import urlunparse
|
||||
|
||||
from django.db import models, transaction
|
||||
from django.db.models.fields import BooleanField, DateTimeField, DecimalField, TextField, FloatField, IntegerField
|
||||
@@ -17,6 +18,7 @@ from opaque_keys.edx.keys import CourseKey
|
||||
from config_models.models import ConfigurationModel
|
||||
from lms.djangoapps import django_comment_client
|
||||
from openedx.core.djangoapps.models.course_details import CourseDetails
|
||||
from static_replace.models import AssetBaseUrlConfig
|
||||
from util.date_utils import strftime_localized
|
||||
from xmodule import course_metadata_utils
|
||||
from xmodule.course_module import CourseDescriptor, DEFAULT_START_DATE
|
||||
@@ -549,7 +551,28 @@ class CourseOverview(TimeStampedModel):
|
||||
urls['small'] = self.image_set.small_url or raw_image_url
|
||||
urls['large'] = self.image_set.large_url or raw_image_url
|
||||
|
||||
return urls
|
||||
return self._apply_cdn(urls)
|
||||
|
||||
def _apply_cdn(self, image_urls):
|
||||
"""
|
||||
Given a dict of resolutions -> urls, return a copy with CDN applied.
|
||||
|
||||
If CDN does not exist or is disabled, just returns the original. The
|
||||
URLs that we store in CourseOverviewImageSet are all already top level
|
||||
paths, so we don't need to go through the /static remapping magic that
|
||||
happens with other course assets. We just need to add the CDN server if
|
||||
appropriate.
|
||||
"""
|
||||
cdn_config = AssetBaseUrlConfig.current()
|
||||
if not cdn_config.enabled:
|
||||
return image_urls
|
||||
|
||||
base_url = cdn_config.base_url
|
||||
|
||||
return {
|
||||
resolution: urlunparse((None, base_url, url, None, None, None))
|
||||
for resolution, url in image_urls.items()
|
||||
}
|
||||
|
||||
def __unicode__(self):
|
||||
"""Represent ourselves with the course key."""
|
||||
|
||||
@@ -17,6 +17,7 @@ from PIL import Image
|
||||
from lms.djangoapps.certificates.api import get_active_web_certificate
|
||||
from openedx.core.djangoapps.models.course_details import CourseDetails
|
||||
from openedx.core.lib.courses import course_image_url
|
||||
from static_replace.models import AssetBaseUrlConfig
|
||||
from xmodule.assetstore.assetmgr import AssetManager
|
||||
from xmodule.contentstore.django import contentstore
|
||||
from xmodule.contentstore.content import StaticContent
|
||||
@@ -643,6 +644,32 @@ class CourseOverviewImageSetTestCase(ModuleStoreTestCase):
|
||||
}
|
||||
)
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
|
||||
def test_cdn(self, modulestore_type):
|
||||
"""
|
||||
Test that we return CDN prefixed URLs if it is enabled.
|
||||
"""
|
||||
with self.store.default_store(modulestore_type):
|
||||
course = CourseFactory.create(default_store=modulestore_type)
|
||||
overview = CourseOverview.get_from_id(course.id)
|
||||
|
||||
# First the behavior when there's no CDN enabled...
|
||||
AssetBaseUrlConfig.objects.all().delete()
|
||||
if modulestore_type == ModuleStoreEnum.Type.mongo:
|
||||
expected_path_start = "/c4x/"
|
||||
elif modulestore_type == ModuleStoreEnum.Type.split:
|
||||
expected_path_start = "/asset-v1:"
|
||||
|
||||
for url in overview.image_urls.values():
|
||||
self.assertTrue(url.startswith(expected_path_start))
|
||||
|
||||
# Now enable the CDN...
|
||||
AssetBaseUrlConfig.objects.create(enabled=True, base_url='fakecdn.edx.org')
|
||||
expected_cdn_url = "//fakecdn.edx.org" + expected_path_start
|
||||
|
||||
for url in overview.image_urls.values():
|
||||
self.assertTrue(url.startswith(expected_cdn_url))
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
|
||||
def test_error_generating_thumbnails(self, modulestore_type):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user