static_replace.py 2.59 KB
Newer Older
1 2 3
import logging
import re

4
from staticfiles.storage import staticfiles_storage
5 6
from staticfiles import finders
from django.conf import settings
7

8 9 10 11
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.xml import XMLModuleStore
from xmodule.contentstore.content import StaticContent

12 13 14 15 16 17 18 19 20 21
log = logging.getLogger(__name__)

def try_staticfiles_lookup(path):
    """
    Try to lookup a path in staticfiles_storage.  If it fails, return
    a dead link instead of raising an exception.
    """
    try:
        url = staticfiles_storage.url(path)
    except Exception as err:
22
        log.warning("staticfiles_storage couldn't find path {0}: {1}".format(
23
            path, str(err)))
24 25
        # Just return the original path; don't kill everything.
        url = path
26
    return url
27 28


29
def replace(static_url, prefix=None, course_namespace=None):
30 31 32 33 34
    if prefix is None:
        prefix = ''
    else:
        prefix = prefix + '/'

35
    quote = static_url.group('quote')
36 37 38 39 40 41 42 43 44

    servable = (
        # If in debug mode, we'll serve up anything that the finders can find
        (settings.DEBUG and finders.find(static_url.group('rest'), True)) or
        # Otherwise, we'll only serve up stuff that the storages can find
        staticfiles_storage.exists(static_url.group('rest'))
    )

    if servable:
45 46
        return static_url.group(0)
    else:
47
        # don't error if file can't be found
48 49 50 51 52 53 54 55 56 57 58 59
        # cdodge: to support the change over to Mongo backed content stores, lets
        # use the utility functions in StaticContent.py
        if static_url.group('prefix') == '/static/' and not isinstance(modulestore(), XMLModuleStore):
            if course_namespace is None:
                raise BaseException('You must pass in course_namespace when remapping static content urls with MongoDB stores')
            url = StaticContent.convert_legacy_static_url(static_url.group('rest'), course_namespace)
        else:
            url = try_staticfiles_lookup(prefix + static_url.group('rest'))

        new_link = "".join([quote, url, quote])
        return new_link

60

61

62
def replace_urls(text, staticfiles_prefix=None, replace_prefix='/static/', course_namespace=None):
63

64
    def replace_url(static_url):
65
        return replace(static_url, staticfiles_prefix, course_namespace = course_namespace)
66 67

    return re.sub(r"""
68 69 70 71 72
        (?x)                 # flags=re.VERBOSE
        (?P<quote>\\?['"])   # the opening quotes
        (?P<prefix>{prefix}) # the prefix
        (?P<rest>.*?)        # everything else in the url
        (?P=quote)           # the first matching closing quote
73
        """.format(prefix=replace_prefix), replace_url, text)