url() normalizing is go.
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
from compressor.filters import FilterBase, FilterError
|
||||
from compressor.conf import settings
|
||||
|
||||
@@ -6,5 +9,25 @@ class CssAbsoluteFilter(FilterBase):
|
||||
def input(self, filename=None, **kwargs):
|
||||
if not filename or not filename.startswith(settings.MEDIA_ROOT):
|
||||
return self.content
|
||||
filename = filename[len(settings.MEDIA_ROOT):]
|
||||
return "\n".join([filename, self.content])
|
||||
self.media_path = filename[len(settings.MEDIA_ROOT):]
|
||||
self.media_path = self.media_path.lstrip('/')
|
||||
self.media_url = settings.MEDIA_URL.rstrip('/')
|
||||
self.has_http = False
|
||||
if self.media_url.startswith('http://'):
|
||||
self.has_http = True
|
||||
self.media_url = self.media_url[7:]
|
||||
self.directory_name = '/'.join([self.media_url, os.path.dirname(self.media_path)])
|
||||
url_pattern = re.compile(r'url\(([^\)]+)\)')
|
||||
output = url_pattern.sub(self.url_converter, self.content)
|
||||
return output
|
||||
|
||||
def url_converter(self, matchobj):
|
||||
url = matchobj.group(1)
|
||||
url = url.strip(' \'"')
|
||||
if url.startswith('http://') or url.startswith('/'):
|
||||
return "url('%s')" % url
|
||||
full_url = '/'.join([self.directory_name, url])
|
||||
full_url = os.path.normpath(full_url)
|
||||
if self.has_http:
|
||||
full_url = "http://%s" % full_url
|
||||
return "url('%s')" % full_url
|
||||
|
||||
@@ -3,13 +3,16 @@ from hashlib import sha1 as hash
|
||||
from BeautifulSoup import BeautifulSoup
|
||||
|
||||
from django import template
|
||||
from django.conf import settings as django_settings
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
|
||||
from compressor.conf import settings
|
||||
from compressor import filters
|
||||
|
||||
register = template.Library()
|
||||
|
||||
class UncompressableFileError(Exception):
|
||||
pass
|
||||
|
||||
class CompressedNode(template.Node):
|
||||
|
||||
@@ -23,15 +26,13 @@ class CompressedNode(template.Node):
|
||||
def content_hash(self):
|
||||
"""docstring for content_hash"""
|
||||
pass
|
||||
|
||||
|
||||
def split_contents(self):
|
||||
raise NotImplementedError('split_contents must be defined in a subclass')
|
||||
|
||||
def get_filename(self, url):
|
||||
if not url.startswith(settings.MEDIA_URL):
|
||||
# TODO: Put a proper exception here. Maybe one that only shows up
|
||||
# if debug is on.
|
||||
raise Exception('FIX THIS EXCPETIONS@!@')
|
||||
raise UncompressableFileError('"%s" is not in COMPRESS_MEDIA_URL ("%s") and can not be compressed' % (url, settings.COMPRESS_MEDIA_URL))
|
||||
basename = url[len(settings.MEDIA_URL):]
|
||||
filename = os.path.join(settings.MEDIA_ROOT, basename)
|
||||
return filename
|
||||
@@ -58,7 +59,7 @@ class CompressedNode(template.Node):
|
||||
|
||||
def concat(self):
|
||||
return "\n".join(self.get_hunks())
|
||||
|
||||
|
||||
def filter(self, content, method, **kwargs):
|
||||
content = content
|
||||
for f in self.filters:
|
||||
@@ -74,7 +75,7 @@ class CompressedNode(template.Node):
|
||||
if getattr(self, '_output', ''):
|
||||
return self._output
|
||||
output = self.concat()
|
||||
filter_method = getattr(self, 'filter_method', None)
|
||||
filter_method = getattr(self, 'filter_method', None)
|
||||
if self.filters:
|
||||
output = self.filter(output, 'output')
|
||||
self._output = output
|
||||
@@ -90,7 +91,7 @@ class CompressedNode(template.Node):
|
||||
filepath = "%s/%s/%s" % (settings.OUTPUT_DIR.strip('/'), self.ouput_prefix, filename)
|
||||
return filepath
|
||||
new_filepath = property(get_new_filepath)
|
||||
|
||||
|
||||
def save_file(self):
|
||||
filename = "%s/%s" % (settings.MEDIA_ROOT.rstrip('/'), self.new_filepath)
|
||||
if os.path.exists(filename):
|
||||
@@ -129,7 +130,11 @@ class CompressedCssNode(CompressedNode):
|
||||
split = self.soup.findAll({'link' : True, 'style' : True})
|
||||
for elem in split:
|
||||
if elem.name == 'link' and elem['rel'] == 'stylesheet':
|
||||
self.split_content.append(('file', self.get_filename(elem['href'])))
|
||||
try:
|
||||
self.split_content.append(('file', self.get_filename(elem['href'])))
|
||||
except UncompressableFileError:
|
||||
if django_settings.DEBUG:
|
||||
raise
|
||||
if elem.name == 'style':
|
||||
self.split_content.append(('hunk', elem.string))
|
||||
return self.split_content
|
||||
@@ -150,7 +155,11 @@ class CompressedJsNode(CompressedNode):
|
||||
split = self.soup.findAll('script')
|
||||
for elem in split:
|
||||
if elem.has_key('src'):
|
||||
self.split_content.append(('file', self.get_filename(elem['src'])))
|
||||
try:
|
||||
self.split_content.append(('file', self.get_filename(elem['src'])))
|
||||
except UncompressableFileError:
|
||||
if django_settings.DEBUG:
|
||||
raise
|
||||
else:
|
||||
self.split_content.append(('hunk', elem.string))
|
||||
return self.split_content
|
||||
|
||||
@@ -3,10 +3,11 @@ import os
|
||||
from django.test import TestCase
|
||||
from compressor.templatetags.compress import CompressedCssNode, CompressedJsNode
|
||||
from compressor.conf import settings
|
||||
from django.conf import settings as django_settings
|
||||
|
||||
|
||||
class CompressedNodeTestCase(TestCase):
|
||||
|
||||
|
||||
def setUp(self):
|
||||
settings.COMPRESS = True
|
||||
self.css = """
|
||||
@@ -21,7 +22,7 @@ class CompressedNodeTestCase(TestCase):
|
||||
<script type="text/javascript" charset="utf-8">obj.value = "value";</script>
|
||||
"""
|
||||
self.jsNode = CompressedJsNode(self.js)
|
||||
|
||||
|
||||
def test_css_split(self):
|
||||
out = [
|
||||
('file', os.path.join(settings.MEDIA_ROOT, u'css/one.css')),
|
||||
@@ -76,16 +77,33 @@ class CompressedNodeTestCase(TestCase):
|
||||
def test_js_return_if_on(self):
|
||||
output = u'<script type="text/javascript" src="/media/CACHE/js/3f33b9146e12.js" charset="utf-8"></script>'
|
||||
self.assertEqual(output, self.jsNode.render())
|
||||
|
||||
|
||||
|
||||
class CssAbsolutizingTestCase(TestCase):
|
||||
def setUp(self):
|
||||
settings.COMPRESS = True
|
||||
django_settings.DEBUG = True
|
||||
settings.MEDIA_URL = '/media/'
|
||||
self.css = """
|
||||
<link rel="stylesheet" href="/media/css/backgrounded.css" type="text/css" media="screen" charset="utf-8">
|
||||
<link rel="stylesheet" href="/media/css/url/url1.css" type="text/css" media="screen" charset="utf-8">
|
||||
<link rel="stylesheet" href="/media/css/url/2/url2.css" type="text/css" media="screen" charset="utf-8">
|
||||
"""
|
||||
self.cssNode = CompressedCssNode(self.css)
|
||||
|
||||
def test_fail(self):
|
||||
settings.COMPRESS = False
|
||||
self.assertEqual(self.js, self.jsNode.render())
|
||||
def test_css_absolute_filter(self):
|
||||
from compressor.filters.css_absolute import CssAbsoluteFilter
|
||||
filename = os.path.join(settings.MEDIA_ROOT, 'css/url/test.css')
|
||||
content = "p { background: url('../../images/image.gif') }"
|
||||
output = "p { background: url('%simages/image.gif') }" % settings.MEDIA_URL
|
||||
filter = CssAbsoluteFilter(content)
|
||||
self.assertEqual(output, filter.input(filename=filename))
|
||||
settings.MEDIA_URL = 'http://media.example.com/'
|
||||
filename = os.path.join(settings.MEDIA_ROOT, 'css/url/test.css')
|
||||
output = "p { background: url('%simages/image.gif') }" % settings.MEDIA_URL
|
||||
self.assertEqual(output, filter.input(filename=filename))
|
||||
|
||||
def test_css_hunks(self):
|
||||
out = [u"p { background: url('/media/images/test.png'); }\np { background: url('/media/images/test.png'); }\np { background: url('/media/images/test.png'); }\np { background: url('/media/images/test.png'); }\n",
|
||||
u"p { background: url('/media/images/test.png'); }\np { background: url('/media/images/test.png'); }\np { background: url('/media/images/test.png'); }\np { background: url('/media/images/test.png'); }\n",
|
||||
]
|
||||
self.assertEqual(out, self.cssNode.hunks)
|
||||
|
||||
4
tests/media/css/url/2/url2.css
Normal file
4
tests/media/css/url/2/url2.css
Normal file
@@ -0,0 +1,4 @@
|
||||
p { background: url('../../../images/test.png'); }
|
||||
p { background: url(../../../images/test.png); }
|
||||
p { background: url( ../../../images/test.png ); }
|
||||
p { background: url( '../../../images/test.png' ); }
|
||||
4
tests/media/css/url/url1.css
Normal file
4
tests/media/css/url/url1.css
Normal file
@@ -0,0 +1,4 @@
|
||||
p { background: url('../../images/test.png'); }
|
||||
p { background: url(../../images/test.png); }
|
||||
p { background: url( ../../images/test.png ); }
|
||||
p { background: url( '../../images/test.png' ); }
|
||||
Reference in New Issue
Block a user