Fixed #18050 -- Fixed a rather glaring bug in the handling of @import statements when using the cached staticfiles storage.

This commit is contained in:
Jannis Leidel 2012-07-08 18:17:53 +02:00
parent effc2cad95
commit 3047981517
3 changed files with 23 additions and 6 deletions

View File

@ -45,10 +45,11 @@ class StaticFilesStorage(FileSystemStorage):
class CachedFilesMixin(object): class CachedFilesMixin(object):
default_template = """url("%s")"""
patterns = ( patterns = (
("*.css", ( ("*.css", (
br"""(url\(['"]{0,1}\s*(.*?)["']{0,1}\))""", br"""(url\(['"]{0,1}\s*(.*?)["']{0,1}\))""",
br"""(@import\s*["']\s*(.*?)["'])""", (br"""(@import\s*["']\s*(.*?)["'])""", """@import url("%s")"""),
)), )),
) )
@ -62,8 +63,12 @@ class CachedFilesMixin(object):
self._patterns = SortedDict() self._patterns = SortedDict()
for extension, patterns in self.patterns: for extension, patterns in self.patterns:
for pattern in patterns: for pattern in patterns:
if isinstance(pattern, (tuple, list)):
pattern, template = pattern
else:
template = self.default_template
compiled = re.compile(pattern) compiled = re.compile(pattern)
self._patterns.setdefault(extension, []).append(compiled) self._patterns.setdefault(extension, []).append((compiled, template))
def file_hash(self, name, content=None): def file_hash(self, name, content=None):
""" """
@ -140,10 +145,13 @@ class CachedFilesMixin(object):
return unquote(final_url) return unquote(final_url)
def url_converter(self, name): def url_converter(self, name, template=None):
""" """
Returns the custom URL converter for the given file name. Returns the custom URL converter for the given file name.
""" """
if template is None:
template = self.default_template
def converter(matchobj): def converter(matchobj):
""" """
Converts the matched URL depending on the parent level (`..`) Converts the matched URL depending on the parent level (`..`)
@ -178,7 +186,8 @@ class CachedFilesMixin(object):
relative_url = '/'.join(url.split('/')[:-1] + file_name) relative_url = '/'.join(url.split('/')[:-1] + file_name)
# Return the hashed version to the file # Return the hashed version to the file
return 'url("%s")' % unquote(relative_url) return template % unquote(relative_url)
return converter return converter
def post_process(self, paths, dry_run=False, **options): def post_process(self, paths, dry_run=False, **options):
@ -229,9 +238,9 @@ class CachedFilesMixin(object):
# ..to apply each replacement pattern to the content # ..to apply each replacement pattern to the content
if name in adjustable_paths: if name in adjustable_paths:
content = original_file.read().decode(settings.FILE_CHARSET) content = original_file.read().decode(settings.FILE_CHARSET)
converter = self.url_converter(name)
for patterns in self._patterns.values(): for patterns in self._patterns.values():
for pattern in patterns: for pattern, template in patterns:
converter = self.url_converter(name, template)
content = pattern.sub(converter, content) content = pattern.sub(converter, content)
if hashed_file_exists: if hashed_file_exists:
self.delete(hashed_name) self.delete(hashed_name)

View File

@ -0,0 +1 @@
@import 'styles.css';

View File

@ -446,6 +446,13 @@ class TestCollectionCachedStorage(BaseCollectionTestCase,
self.assertIn(b'url("img/relative.acae32e4532b.png")', content) self.assertIn(b'url("img/relative.acae32e4532b.png")', content)
self.assertIn(b"../cached/styles.93b1147e8552.css", content) self.assertIn(b"../cached/styles.93b1147e8552.css", content)
def test_import_replacement(self):
"See #18050"
relpath = self.cached_file_path("cached/import.css")
self.assertEqual(relpath, "cached/import.2b1d40b0bbd4.css")
with storage.staticfiles_storage.open(relpath) as relfile:
self.assertIn(b"""import url("styles.93b1147e8552.css")""", relfile.read())
def test_template_tag_deep_relative(self): def test_template_tag_deep_relative(self):
relpath = self.cached_file_path("cached/css/window.css") relpath = self.cached_file_path("cached/css/window.css")
self.assertEqual(relpath, "cached/css/window.9db38d5169f3.css") self.assertEqual(relpath, "cached/css/window.9db38d5169f3.css")