Commit 943c7db1 by Troy Sankey

LMS collectstatic now runs under Django 1.11

* Avoid URL namespace collision for "wiki:*" by renaming the
  course-specific django-wiki instance to something we will hopefully
  never need to reverse.

* Update our custom implementation of the staticfiles app's
  CachedFilesMixin internal method `url_converter()` to be compatible
  with Django 1.11.  This installs a shim in order to maintain
  compatibility with previous django versions.
parent 6db93fc7
......@@ -218,7 +218,7 @@ if settings.WIKI_ENABLED:
# never be returned by a reverse() so they come after the other url patterns
url(r'^courses/{}/course_wiki/?$'.format(settings.COURSE_ID_PATTERN),
course_wiki_views.course_wiki_redirect, name='course_wiki'),
url(r'^courses/{}/wiki/'.format(settings.COURSE_KEY_REGEX), include(wiki_pattern())),
url(r'^courses/{}/wiki/'.format(settings.COURSE_KEY_REGEX), include(wiki_pattern(namespace='course_wiki_do_not_reverse'))),
]
COURSE_URLS = [
......
......@@ -4,12 +4,18 @@ See https://docs.djangoproject.com/en/1.8/ref/contrib/staticfiles/
"""
import os.path
import posixpath
import re
import django
from django.conf import settings
from django.contrib.staticfiles.finders import find
from django.contrib.staticfiles.storage import CachedFilesMixin, StaticFilesStorage
from django.utils._os import safe_join
from django.utils.six.moves.urllib.parse import unquote, urlsplit # pylint: disable=no-name-in-module, import-error
from django.utils.six.moves.urllib.parse import ( # pylint: disable=no-name-in-module, import-error
unquote,
urldefrag,
urlsplit
)
from pipeline.storage import PipelineMixin
from openedx.core.djangoapps.theming.helpers import (
......@@ -162,13 +168,14 @@ class ThemeCachedFilesMixin(CachedFilesMixin):
return super(ThemeCachedFilesMixin, self).url(asset_name, force)
def url_converter(self, name, template=None):
def _url_converter__lt_111(self, name, template=None):
"""
This is an override of url_converter from CachedFilesMixin.
It just comments out two lines at the end of the method.
The purpose of this override is to make converter method return absolute urls instead of relative urls.
This behavior is necessary for theme overrides, as we get 404 on assets with relative urls on a themed site.
There are two lines commented out in order to make the converter method
return absolute urls instead of relative urls. This behavior is
necessary for theme overrides, as we get 404 on assets with relative
urls on a themed site.
"""
if template is None:
template = self.default_template
......@@ -219,6 +226,88 @@ class ThemeCachedFilesMixin(CachedFilesMixin):
return converter
def _url_converter__gte_111(self, name, hashed_files, template=None):
"""
This is an override of url_converter from CachedFilesMixin.
It changes one line near the end of the method (see the NOTE) in order
to return absolute urls instead of relative urls. This behavior is
necessary for theme overrides, as we get 404 on assets with relative
urls on a themed site.
"""
if template is None:
template = self.default_template
def converter(matchobj):
"""
Convert the matched URL to a normalized and hashed URL.
This requires figuring out which files the matched URL resolves
to and calling the url() method of the storage.
"""
matched, url = matchobj.groups()
# Ignore absolute/protocol-relative and data-uri URLs.
if re.match(r'^[a-z]+:', url):
return matched
# Ignore absolute URLs that don't point to a static file (dynamic
# CSS / JS?). Note that STATIC_URL cannot be empty.
if url.startswith('/') and not url.startswith(settings.STATIC_URL):
return matched
# Strip off the fragment so a path-like fragment won't interfere.
url_path, fragment = urldefrag(url)
if url_path.startswith('/'):
# Otherwise the condition above would have returned prematurely.
assert url_path.startswith(settings.STATIC_URL)
target_name = url_path[len(settings.STATIC_URL):]
else:
# We're using the posixpath module to mix paths and URLs conveniently.
source_name = name if os.sep == '/' else name.replace(os.sep, '/')
target_name = posixpath.join(posixpath.dirname(source_name), url_path)
# Determine the hashed name of the target file with the storage backend.
hashed_url = self._url(
self._stored_name, unquote(target_name),
force=True, hashed_files=hashed_files,
)
# NOTE:
# The line below was commented out so that absolute urls are used instead of relative urls to make themed
# assets work correctly.
#
# The line is commented and not removed to make future django upgrade easier and show exactly what is
# changed in this method override
#
#transformed_url = '/'.join(url_path.split('/')[:-1] + hashed_url.split('/')[-1:])
transformed_url = hashed_url # This line was added.
# Restore the fragment that was stripped off earlier.
if fragment:
transformed_url += ('?#' if '?#' in url else '#') + fragment
# Return the hashed version to the file
return template % unquote(transformed_url)
return converter
# TODO: Remove Django 1.11 upgrade shim
# SHIM: This method switches the implementation of url_converter according
# to the Django version. After the 1.11 upgrade, do these things:
#
# 1. delete _url_converter__lt_111 and url_converter.
# 2. rename _url_converter__gte_111 to url_converter.
def url_converter(self, *args, **kwargs):
"""
An implementation selector for the url_converter method. This is in
place only for the Django 1.11 upgrade.
"""
if django.VERSION < (1, 11):
return self._url_converter__lt_111(*args, **kwargs)
else:
return self._url_converter__gte_111(*args, **kwargs)
class ThemePipelineMixin(PipelineMixin):
"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment