Permalink
Browse files

Merge branch 'release/0.6'

  • Loading branch information...
2 parents 0ab45f0 + a8672b4 commit 7130cd74526d2a5ed54e730e179a33a6fa891efc @jezdez jezdez committed Apr 12, 2011
View
@@ -1,7 +1,7 @@
build
compressor/tests/media/CACHE
compressor/tests/media/custom
-compressor/tests/media/js/3f33b9146e12.js
+compressor/tests/media/js/dc78a3f5af20.js
dist
MANIFEST
*.pyc
View
@@ -1,7 +1,7 @@
-Django compressor
-==================
+Django Compressor
+=================
-Compresses linked and inline javascript or CSS into a single cached file.
+Compresses linked and inline JavaCcript or CSS into a single cached file.
The main website for django-compressor is
`github.com/jezdez/django_compressor`_ where you can also file tickets.
@@ -1,4 +1,4 @@
-VERSION = (0, 6, 0, "b", 7) # following PEP 386
+VERSION = (0, 6, 0, "f", 0) # following PEP 386
DEV_N = None
View
@@ -48,6 +48,8 @@ def get_filename(self, url):
"'%s' isn't accesible via COMPRESS_URL ('%s') and can't be"
" compressed" % (url, base_url))
basename = url.replace(base_url, "", 1)
+ # drop the querystring, which is used for non-compressed cache-busting.
+ basename = basename.split("?", 1)[0]
filename = os.path.join(settings.COMPRESS_ROOT, basename)
if not os.path.exists(filename):
raise UncompressableFileError("'%s' does not exist" % filename)
@@ -109,9 +111,10 @@ def precompile(self, content, kind=None, elem=None, filename=None, **kwargs):
command = self.all_mimetypes.get(mimetype)
if command is None:
if mimetype not in ("text/css", "text/javascript"):
- raise CompressorError(
- "Couldn't find any configured precompiler "
- "for mimetype '%s'." % mimetype)
+ error = ("Couldn't find any precompiler in "
+ "COMPRESS_PRECOMPILERS setting for "
+ "mimetype '%s'." % mimetype)
+ raise CompressorError(error)
else:
content = CompilerFilter(content, filter_type=self.type,
command=command).output(**kwargs)
@@ -166,23 +169,23 @@ def output(self, mode='file', forced=False):
# Then check for the appropriate output method and call it
output_func = getattr(self, "output_%s" % mode, None)
if callable(output_func):
- return output_func(mode, content)
+ return output_func(mode, content, forced)
# Total failure, raise a general exception
raise CompressorError(
"Couldn't find output method for mode '%s'" % mode)
- def output_file(self, mode, content):
+ def output_file(self, mode, content, forced=False):
"""
The output method that saves the content to a file and renders
the appropriate template with the file's URL.
"""
- new_filepath = self.filepath(content)
- if not self.storage.exists(new_filepath):
+ new_filepath = self.filepath(self.content)
+ if not self.storage.exists(new_filepath) or forced:
self.storage.save(new_filepath, ContentFile(content))
url = self.storage.url(new_filepath)
return self.render_output(mode, {"url": url})
- def output_inline(self, mode, content):
+ def output_inline(self, mode, content, forced=False):
"""
The output method that directly returns the content for inline
display.
View
@@ -9,7 +9,7 @@
def get_hexdigest(plaintext, length=None):
- digest = sha_constructor(plaintext).hexdigest()
+ digest = sha_constructor(smart_str(plaintext)).hexdigest()
if length:
return digest[:length]
return digest
View
@@ -37,7 +37,7 @@ def split_contents(self):
if self.media_nodes and self.media_nodes[-1][0] == media:
self.media_nodes[-1][1].split_content.append(data)
else:
- node = CssCompressor()
+ node = CssCompressor(str(elem))
node.split_content.append(data)
self.media_nodes.append((media, node))
return self.split_content
@@ -1,6 +1,5 @@
import os
import sys
-import warnings
from fnmatch import fnmatch
from optparse import make_option
@@ -144,7 +143,11 @@ def compress(self, log=None, **options):
for nodes in compressor_nodes.values():
for node in nodes:
key = get_offline_cachekey(node.nodelist)
- result = node.render(context, forced=True)
+ try:
+ result = node.render(context, forced=True)
+ except Exception, e:
+ raise CommandError("An error occured during rending: "
+ "%s" % e)
cache.set(key, result, settings.COMPRESS_OFFLINE_TIMEOUT)
results.append(result)
count += 1
@@ -192,7 +195,4 @@ def handle_noargs(self, **options):
raise CommandError(
"Offline compressiong is disabled. Set "
"COMPRESS_OFFLINE or use the --force to override.")
- warnings.warn(
- "COMPRESS_OFFLINE is not set to True. "
- "Offline generated cache will not be used.")
self.compress(sys.stdout, **options)
@@ -9,6 +9,8 @@ class CompressorSettings(AppSettings):
ENABLED = not settings.DEBUG
# Allows changing verbosity from the settings.
VERBOSE = False
+ # GET variable that disables compressor e.g. "nocompress"
+ DEBUG_TOGGLE = "None"
# the backend to use when parsing the JavaScript or Stylesheet files
PARSER = 'compressor.parser.BeautifulSoupParser'
OUTPUT_DIR = 'CACHE'
@@ -48,13 +48,21 @@ def cache_set(self, key, val, refreshed=False,
def cache_key(self, compressor):
return "%s.%s.%s" % (compressor.cachekey, self.mode, self.kind)
- def render(self, context, forced=False):
+ def render(self, context, forced=False, debug=False):
+ if settings.COMPRESS_DEBUG_TOGGLE:
+ # Only check for the debug parameter
+ # if a RequestContext was used
+ request = context.get('request', None)
+ if request is not None:
+ debug = settings.COMPRESS_DEBUG_TOGGLE in request.GET
if (settings.COMPRESS_ENABLED and
- settings.COMPRESS_OFFLINE) and not forced:
+ settings.COMPRESS_OFFLINE) and not forced and not debug:
content = cache.get(get_offline_cachekey(self.nodelist))
if content:
return content
content = self.nodelist.render(context)
+ if debug:
+ return content
compressor = self.compressor_cls(content)
cachekey = self.cache_key(compressor)
output = self.cache_get(cachekey)
@@ -63,7 +71,7 @@ def render(self, context, forced=False):
output = compressor.output(self.mode, forced=forced)
self.cache_set(cachekey, output)
except:
- if settings.DEBUG:
+ if settings.DEBUG or forced:
from traceback import format_exc
raise Exception(format_exc())
else:
@@ -25,7 +25,8 @@ class CompressorTestCase(TestCase):
def setUp(self):
settings.COMPRESS_ENABLED = True
- settings.PRECOMPILERS = {}
+ settings.COMPRESS_PRECOMPILERS = {}
+ settings.COMPRESS_DEBUG_TOGGLE = 'nocompress'
self.css = """
<link rel="stylesheet" href="/media/css/one.css" type="text/css" charset="utf-8">
<style type="text/css">p { border:5px solid green;}</style>
@@ -72,10 +73,10 @@ def test_cachekey(self):
self.assert_(is_cachekey.match(self.css_node.cachekey), "cachekey is returning something that doesn't look like r'django_compressor\.%s\.\w{12}'" % host_name)
def test_css_hash(self):
- self.assertEqual('f7c661b7a124', self.css_node.hash(self.css_node.concat))
+ self.assertEqual('666f3aa8eacd', self.css_node.hash(self.css))
def test_css_return_if_on(self):
- output = u'<link rel="stylesheet" href="/media/CACHE/css/f7c661b7a124.css" type="text/css">'
+ output = u'<link rel="stylesheet" href="/media/CACHE/css/277b26db9a98.css" type="text/css">'
self.assertEqual(output, self.css_node.output().strip())
def test_js_split(self):
@@ -110,20 +111,20 @@ def test_js_return_if_off(self):
settings.COMPRESS_PRECOMPILERS = precompilers
def test_js_return_if_on(self):
- output = u'<script type="text/javascript" src="/media/CACHE/js/3f33b9146e12.js" charset="utf-8"></script>'
+ output = u'<script type="text/javascript" src="/media/CACHE/js/dc78a3f5af20.js" charset="utf-8"></script>'
self.assertEqual(output, self.js_node.output())
def test_custom_output_dir(self):
try:
old_output_dir = settings.COMPRESS_OUTPUT_DIR
settings.COMPRESS_OUTPUT_DIR = 'custom'
- output = u'<script type="text/javascript" src="/media/custom/js/3f33b9146e12.js" charset="utf-8"></script>'
+ output = u'<script type="text/javascript" src="/media/custom/js/dc78a3f5af20.js" charset="utf-8"></script>'
self.assertEqual(output, JsCompressor(self.js).output())
settings.COMPRESS_OUTPUT_DIR = ''
- output = u'<script type="text/javascript" src="/media/js/3f33b9146e12.js" charset="utf-8"></script>'
+ output = u'<script type="text/javascript" src="/media/js/dc78a3f5af20.js" charset="utf-8"></script>'
self.assertEqual(output, JsCompressor(self.js).output())
settings.COMPRESS_OUTPUT_DIR = '/custom/nested/'
- output = u'<script type="text/javascript" src="/media/custom/nested/js/3f33b9146e12.js" charset="utf-8"></script>'
+ output = u'<script type="text/javascript" src="/media/custom/nested/js/dc78a3f5af20.js" charset="utf-8"></script>'
self.assertEqual(output, JsCompressor(self.js).output())
finally:
settings.COMPRESS_OUTPUT_DIR = old_output_dir
@@ -290,7 +291,7 @@ def test_css_tag(self):
{% endcompress %}
"""
context = { 'MEDIA_URL': settings.COMPRESS_URL }
- out = u'<link rel="stylesheet" href="/media/CACHE/css/f7c661b7a124.css" type="text/css">'
+ out = u'<link rel="stylesheet" href="/media/CACHE/css/277b26db9a98.css" type="text/css">'
self.assertEqual(out, render(template, context))
def test_nonascii_css_tag(self):
@@ -300,7 +301,7 @@ def test_nonascii_css_tag(self):
{% endcompress %}
"""
context = { 'MEDIA_URL': settings.COMPRESS_URL }
- out = '<link rel="stylesheet" href="/media/CACHE/css/1c1c0855907b.css" type="text/css">'
+ out = '<link rel="stylesheet" href="/media/CACHE/css/14e62fd8dc94.css" type="text/css">'
self.assertEqual(out, render(template, context))
def test_js_tag(self):
@@ -310,7 +311,7 @@ def test_js_tag(self):
{% endcompress %}
"""
context = { 'MEDIA_URL': settings.COMPRESS_URL }
- out = u'<script type="text/javascript" src="/media/CACHE/js/3f33b9146e12.js" charset="utf-8"></script>'
+ out = u'<script type="text/javascript" src="/media/CACHE/js/dc78a3f5af20.js" charset="utf-8"></script>'
self.assertEqual(out, render(template, context))
def test_nonascii_js_tag(self):
@@ -320,7 +321,7 @@ def test_nonascii_js_tag(self):
{% endcompress %}
"""
context = { 'MEDIA_URL': settings.COMPRESS_URL }
- out = u'<script type="text/javascript" src="/media/CACHE/js/5d5c0e1cb25f.js" charset="utf-8"></script>'
+ out = u'<script type="text/javascript" src="/media/CACHE/js/52e783c7eb25.js" charset="utf-8"></script>'
self.assertEqual(out, render(template, context))
def test_nonascii_latin1_js_tag(self):
@@ -330,7 +331,7 @@ def test_nonascii_latin1_js_tag(self):
{% endcompress %}
"""
context = { 'MEDIA_URL': settings.COMPRESS_URL }
- out = u'<script type="text/javascript" src="/media/CACHE/js/40a8e9ffb476.js" charset="utf-8"></script>'
+ out = u'<script type="text/javascript" src="/media/CACHE/js/e33dbf2e2457.js" charset="utf-8"></script>'
self.assertEqual(out, render(template, context))
def test_compress_tag_with_illegal_arguments(self):
@@ -339,6 +340,18 @@ def test_compress_tag_with_illegal_arguments(self):
{% endcompress %}"""
self.assertRaises(TemplateSyntaxError, render, template, {})
+ def test_debug_toggle(self):
+ template = u"""{% load compress %}{% compress js %}
+ <script src="{{ MEDIA_URL }}js/one.js" type="text/javascript" charset="utf-8"></script>
+ <script type="text/javascript" charset="utf-8">obj.value = "value";</script>
+ {% endcompress %}
+ """
+ class MockDebugRequest(object):
+ GET = {settings.COMPRESS_DEBUG_TOGGLE: 'true'}
+ context = { 'MEDIA_URL': settings.COMPRESS_URL, 'request': MockDebugRequest()}
+ out = u"""<script src="/media/js/one.js" type="text/javascript" charset="utf-8"></script>
+ <script type="text/javascript" charset="utf-8">obj.value = "value";</script>"""
+ self.assertEqual(out, render(template, context))
class StorageTestCase(TestCase):
def setUp(self):
@@ -357,7 +370,7 @@ def test_css_tag_with_storage(self):
{% endcompress %}
"""
context = { 'MEDIA_URL': settings.COMPRESS_URL }
- out = u'<link rel="stylesheet" href="/media/CACHE/css/5b231a62e9a6.css.gz" type="text/css">'
+ out = u'<link rel="stylesheet" href="/media/CACHE/css/277b26db9a98.css.gz" type="text/css">'
self.assertEqual(out, render(template, context))
@@ -377,6 +390,7 @@ def test_correct_backend(self):
class OfflineGenerationTestCase(TestCase):
"""Uses templates/test_compressor_offline.html"""
+ maxDiff = None
def setUp(self):
self._old_compress = settings.COMPRESS_ENABLED
@@ -389,8 +403,8 @@ def test_offline(self):
count, result = CompressCommand().compress()
self.assertEqual(2, count)
self.assertEqual([
- u'<link rel="stylesheet" href="/media/CACHE/css/a55e1cf95000.css" type="text/css">\n',
- u'<script type="text/javascript" src="/media/CACHE/js/bf53fa5b13e2.js" charset="utf-8"></script>',
+ u'<link rel="stylesheet" href="/media/CACHE/css/4208e0ded309.css" type="text/css">\n',
+ u'<script type="text/javascript" src="/media/CACHE/js/f57529d83f3a.js" charset="utf-8"></script>',
], result)
def test_offline_with_context(self):
@@ -401,7 +415,7 @@ def test_offline_with_context(self):
count, result = CompressCommand().compress()
self.assertEqual(2, count)
self.assertEqual([
- u'<link rel="stylesheet" href="/media/CACHE/css/8a2405e029de.css" type="text/css">\n',
- u'<script type="text/javascript" src="/media/CACHE/js/bf53fa5b13e2.js" charset="utf-8"></script>',
+ u'<link rel="stylesheet" href="/media/CACHE/css/777d7c22e67c.css" type="text/css">\n',
+ u'<script type="text/javascript" src="/media/CACHE/js/f57529d83f3a.js" charset="utf-8"></script>',
], result)
settings.COMPRESS_OFFLINE_CONTEXT = self._old_offline_context
View
@@ -40,8 +40,8 @@
master_doc = 'index'
# General information about the project.
-project = u'Django compressor'
-copyright = u'2011, Django compressor authors'
+project = u'Django Compressor'
+copyright = u'2011, Django Compressor authors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -50,7 +50,7 @@
# The short X.Y version.
version = '0.6'
# The full version, including alpha/beta/rc tags.
-release = '0.6b7'
+release = '0.6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -120,7 +120,7 @@
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+# html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
@@ -178,8 +178,8 @@
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
- ('index', 'django-compressor.tex', u'Django compressor Documentation',
- u'Django compressor authors', 'manual'),
+ ('index', 'django-compressor.tex', u'Django Compressor Documentation',
+ u'Django Compressor authors', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -211,6 +211,6 @@
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- ('index', 'django-compressor', u'Django compressor Documentation',
- [u'Django compressor authors'], 1)
+ ('index', 'django-compressor', u'Django Compressor Documentation',
+ [u'Django Compressor authors'], 1)
]
View
@@ -5,7 +5,7 @@ Django Compressor
Compresses linked and inline JavaScript or CSS into a single cached file.
Why another static file combiner for Django?
---------------------------------------------
+============================================
Short version: None of them did exactly what I needed.
@@ -79,6 +79,7 @@ integrated.
.. _boto: http://boto.cloudhackers.com/
.. _django-storages: http://code.welldev.org/django-storages/
.. _django-staticfiles: http://github.com/jezdez/django-staticfiles/
+.. _staticfiles: http://docs.djangoproject.com/en/dev/howto/static-files/
.. _STATIC_ROOT: http://docs.djangoproject.com/en/dev/ref/settings/#static-root
.. _STATIC_URL: http://docs.djangoproject.com/en/dev/ref/settings/#static-url
.. _STATICFILES_STORAGE: http://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-storage
Oops, something went wrong.

0 comments on commit 7130cd7

Please sign in to comment.