Filters switched to define both input and output and passes type to filter initialization and filename to input filters.

This commit is contained in:
xian
2009-04-27 21:14:22 -05:00
parent 359ab14ba2
commit 3219f4a338
8 changed files with 56 additions and 29 deletions

View File

@@ -5,10 +5,10 @@ from django.conf import settings
MEDIA_URL = getattr(settings, 'COMPRESS_URL', settings.MEDIA_URL)
MEDIA_ROOT = getattr(settings, 'COMPRESS_ROOT', settings.MEDIA_ROOT)
PREFIX = getattr(settings, 'COMPRESS_PREFIX', 'compressed')
OUTPUT_DIR = getattr(settings, 'COMPRESS_OUTPUT_DIR', 'COMPRESSOR_CACHE')
OUTPUT_DIR = getattr(settings, 'COMPRESS_OUTPUT_DIR', 'CACHE')
COMPRESS = getattr(settings, 'COMPRESS', not settings.DEBUG)
COMPRESS_CSS_FILTERS = getattr(settings, 'COMPRESS_CSS_FILTERS', [])
COMPRESS_CSS_FILTERS = getattr(settings, 'COMPRESS_CSS_FILTERS', ['compressor.filters.css_absolute.CssAbsoluteFilter'])
COMPRESS_JS_FILTERS = getattr(settings, 'COMPRESS_JS_FILTERS', ['compressor.filters.jsmin.JSMinFilter'])
if COMPRESS_CSS_FILTERS is None:

View File

@@ -1,10 +1,12 @@
class FilterBase:
def __init__(self, verbose=0):
def __init__(self, content, filter_type=None, verbose=0):
self.type = filter_type
self.content = content
self.verbose = verbose
def filter_css(self, css):
def input(self, **kwargs):
raise NotImplementedError
def filter_js(self, js):
def output(self, **kwargs):
raise NotImplementedError
class FilterError(Exception):

View File

@@ -0,0 +1,10 @@
from compressor.filters import FilterBase, FilterError
from compressor.conf import settings
# steal bits from http://github.com/cjohansen/juicer/blob/35fe866c82d3f5e7804a6f2f4491c1e81da08820/lib/juicer/merger/stylesheet_merger.rb
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])

View File

@@ -12,7 +12,7 @@ ARGUMENTS = getattr(settings, 'CSSTIDY_ARGUMENTS', '--template=highest')
warnings.simplefilter('ignore', RuntimeWarning)
class CSSTidyFilter(FilterBase):
def filter_css(self, css):
def output(self, **kwargs):
tmp_file = tempfile.NamedTemporaryFile(mode='w+b')
tmp_file.write(css)
tmp_file.flush()

View File

@@ -2,5 +2,5 @@ from compressor.filters.jsmin.jsmin import jsmin
from compressor.filters import FilterBase
class JSMinFilter(FilterBase):
def filter_js(self, js):
return jsmin(js)
def output(self, **kwargs):
return jsmin(self.content)

View File

@@ -10,17 +10,23 @@ JS_ARGUMENTS = getattr(settings, 'COMPRESS_YUI_JS_ARGUMENTS', '')
class YUICompressorFilter(FilterBase):
def filter_common(self, content, type_, arguments):
def output(self, **kwargs):
arguments = ''
if self.type == 'js':
arguments = JS_ARGUMENTS
if self.type == 'css':
arguments = CSS_ARGUMENTS
command = '%s --type=%s %s' % (BINARY, type_, arguments)
if self.verbose:
command += ' --verbose'
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(content)
p.stdin.write(self.content)
p.stdin.close()
filtered_css = p.stdout.read()
filtered = p.stdout.read()
p.stdout.close()
err = p.stderr.read()
@@ -35,10 +41,4 @@ class YUICompressorFilter(FilterBase):
if self.verbose:
print err
return filtered_css
def filter_js(self, js):
return self.filter_common(js, 'js', JS_ARGUMENTS)
def filter_css(self, css):
return self.filter_common(css, 'css', CSS_ARGUMENTS)
return filtered

View File

@@ -15,6 +15,7 @@ class CompressedNode(template.Node):
def __init__(self, content, ouput_prefix="compressed"):
self.content = content
self.type = None
self.ouput_prefix = ouput_prefix
self.split_content = []
self.soup = BeautifulSoup(self.content)
@@ -41,10 +42,16 @@ class CompressedNode(template.Node):
self._hunks = []
for k, v in self.split_contents():
if k == 'hunk':
self._hunks.append(v)
input = v
if self.filters:
input = self.filter(input, 'input')
self._hunks.append(input)
if k == 'file':
fd = open(v, 'rb')
self._hunks.append(fd.read())
input = fd.read()
if self.filters:
input = self.filter(input, 'input', filename=v)
self._hunks.append(input)
fd.close()
return self._hunks
hunks = property(get_hunks)
@@ -52,16 +59,24 @@ 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:
filter = getattr(filters.get_class(f)(content, filter_type=self.type), method)
try:
if callable(filter):
content = filter(**kwargs)
except NotImplementedError:
pass
return content
def get_output(self):
if getattr(self, '_output', ''):
return self._output
output = self.concat()
filter_method = getattr(self, 'filter_method', None)
if filter_method and self.filters:
for f in self.filters:
filter = getattr(filters.get_class(f)(), filter_method)
if callable(filter):
output = filter(output)
if self.filters:
output = self.filter(output, 'output')
self._output = output
return self._output
output = property(get_output)
@@ -105,7 +120,7 @@ class CompressedCssNode(CompressedNode):
self.extension = ".css"
self.template_name = "compressor/css.html"
self.filters = settings.COMPRESS_CSS_FILTERS
self.filter_method = 'filter_css'
self.type = 'css'
super(CompressedCssNode, self).__init__(content, ouput_prefix)
def split_contents(self):
@@ -126,7 +141,7 @@ class CompressedJsNode(CompressedNode):
self.extension = ".js"
self.template_name = "compressor/js.html"
self.filters = settings.COMPRESS_JS_FILTERS
self.filter_method = 'filter_js'
self.type = 'js'
super(CompressedJsNode, self).__init__(content, ouput_prefix)
def split_contents(self):

View File

@@ -46,7 +46,7 @@ class CompressedNodeTestCase(TestCase):
self.assertEqual('f7c661b7a124', self.cssNode.hash)
def test_css_return_if_on(self):
output = u'<link rel="stylesheet" href="/media/COMPRESSOR_CACHE/css/f7c661b7a124.css" type="text/css" media="all" charset="utf-8">'
output = u'<link rel="stylesheet" href="/media/CACHE/css/f7c661b7a124.css" type="text/css" media="all" charset="utf-8">'
self.assertEqual(output, self.cssNode.render())
@@ -74,7 +74,7 @@ class CompressedNodeTestCase(TestCase):
self.assertEqual(self.js, self.jsNode.render())
def test_js_return_if_on(self):
output = u'<script type="text/javascript" src="/media/COMPRESSOR_CACHE/js/3f33b9146e12.js" charset="utf-8"></script>'
output = u'<script type="text/javascript" src="/media/CACHE/js/3f33b9146e12.js" charset="utf-8"></script>'
self.assertEqual(output, self.jsNode.render())