Skip to content

Commit

Permalink
Merge branch 'release/0.6.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
jezdez committed Apr 13, 2011
2 parents 7130cd7 + 95eef66 commit 5b0fd7e
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 94 deletions.
10 changes: 9 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@ Brad Whittington
Chris Adams
David Ziegler
Eugene Mirotin
Fenn Bailey
Gert Van Gool
Jason Davies
Jeremy Dunck
Justin Lilly
Maciek Szczesniak
Mathieu Pillard
Mehmet S. Catalbas
Ulrich Petri
Petar Radosevic
Philipp Wollermann
Shabda Raaj
Thom Linton
Ulrich Petri
2 changes: 1 addition & 1 deletion compressor/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION = (0, 6, 0, "f", 0) # following PEP 386
VERSION = (0, 6, 1, "f", 0) # following PEP 386
DEV_N = None


Expand Down
15 changes: 13 additions & 2 deletions compressor/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from compressor.exceptions import CompressorError, UncompressableFileError
from compressor.filters import CompilerFilter
from compressor.storage import default_storage
from compressor.utils import get_class, cached_property
from compressor.utils import get_class, cached_property, get_staticfiles_finders


class Compressor(object):
Expand All @@ -30,6 +30,7 @@ def __init__(self, content=None, output_prefix="compressed"):
self.split_content = []
self.extra_context = {}
self.all_mimetypes = dict(settings.COMPRESS_PRECOMPILERS)
self.finders = get_staticfiles_finders()

def split_contents(self):
"""
Expand All @@ -50,9 +51,19 @@ def get_filename(self, url):
basename = url.replace(base_url, "", 1)
# drop the querystring, which is used for non-compressed cache-busting.
basename = basename.split("?", 1)[0]
# first try finding the file in the root
filename = os.path.join(settings.COMPRESS_ROOT, basename)
if not os.path.exists(filename):
raise UncompressableFileError("'%s' does not exist" % filename)
# if not found and staticfiles is installed, use it
if self.finders:
filename = self.finders.find(basename)
if filename:
return filename
# or just raise an exception as the last resort
raise UncompressableFileError(
"'%s' could not be found in the COMPRESS_ROOT '%s'%s" % (
basename, settings.COMPRESS_ROOT,
self.finders and " or with staticfiles." or "."))
return filename

@cached_property
Expand Down
17 changes: 8 additions & 9 deletions compressor/css.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,13 @@ def split_contents(self):

def output(self, *args, **kwargs):
# Populate self.split_content
self.split_contents()
if not hasattr(self, 'media_nodes'):
return super(CssCompressor, self).output(*args, **kwargs)
if (settings.COMPRESS_ENABLED or settings.COMPRESS_PRECOMPILERS or
kwargs.get('forced', False)):
ret = []
for media, subnode in self.media_nodes:
subnode.extra_context.update({'media': media})
ret.append(subnode.output(*args, **kwargs))
return ''.join(ret)
return self.content
self.split_contents()
if hasattr(self, 'media_nodes'):
ret = []
for media, subnode in self.media_nodes:
subnode.extra_context.update({'media': media})
ret.append(subnode.output(*args, **kwargs))
return ''.join(ret)
return super(CssCompressor, self).output(*args, **kwargs)
10 changes: 4 additions & 6 deletions compressor/finders.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@

from compressor.conf import settings
from compressor.storage import CompressorFileStorage
from compressor.utils import get_staticfiles_finders

if "django.contrib.staticfiles" in settings.INSTALLED_APPS:
from django.contrib.staticfiles.finders import BaseStorageFinder
elif "staticfiles" in settings.INSTALLED_APPS:
from staticfiles.finders import BaseStorageFinder
else:
finders = get_staticfiles_finders()
if finders is None:
raise ImproperlyConfigured("When using the compressor staticfiles finder"
"either django.contrib.staticfiles or the "
"standalone version django-staticfiles needs "
"to be installed.")


class CompressorFinder(BaseStorageFinder):
class CompressorFinder(finders.BaseStorageFinder):
"""
A staticfiles finder that looks in COMPRESS_ROOT
for compressed files, to be used during development
Expand Down
2 changes: 1 addition & 1 deletion compressor/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def configure_root(self, value):
if ("compressor.finders.CompressorFinder" not in
staticfiles_settings.STATICFILES_FINDERS):
raise ImproperlyConfigured(
"When using django_compressor together with staticfiles, "
"When using Django Compressor together with staticfiles, "
"please add 'compressor.finders.CompressorFinder' to the "
"STATICFILES_FINDERS setting.")
return value
Expand Down
75 changes: 52 additions & 23 deletions compressor/templatetags/compress.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,64 @@ 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, debug=False):
def debug_mode(self, context):
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
return settings.COMPRESS_DEBUG_TOGGLE in request.GET

def render_offline(self, forced):
"""
If enabled and in offline mode, and not forced or in debug mode
check the offline cache and return the result if given
"""
if (settings.COMPRESS_ENABLED and
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)
if output is None or forced:
try:
output = compressor.output(self.mode, forced=forced)
self.cache_set(cachekey, output)
except:
if settings.DEBUG or forced:
from traceback import format_exc
raise Exception(format_exc())
else:
return content
return output
settings.COMPRESS_OFFLINE) and not forced:
return cache.get(get_offline_cachekey(self.nodelist))

def render_cached(self, compressor, forced):
"""
If enabled checks the cache for the given compressor's cache key
and return a tuple of cache key and output
"""
if settings.COMPRESS_ENABLED and not forced:
cache_key = self.cache_key(compressor)
cache_content = self.cache_get(cache_key)
return cache_key, cache_content
return None, None

def render(self, context, forced=False):
# 1. Check if in debug mode
if self.debug_mode(context):
return self.nodelist.render(context)

# 2. Try offline cache.
cached_offline = self.render_offline(forced)
if cached_offline:
return cached_offline

# 3. Prepare the actual compressor and check cache
compressor = self.compressor_cls(self.nodelist.render(context))
cache_key, cache_content = self.render_cached(compressor, forced)
if cache_content is not None:
return cache_content

# 4. call compressor output method and handle exceptions
try:
rendered_output = compressor.output(self.mode, forced=forced)
if cache_key:
self.cache_set(cache_key, rendered_output)
return rendered_output
except:
if settings.DEBUG or forced:
# Be very loud about the exception we just encountered
from traceback import format_exc
raise Exception(format_exc())

# 5. Or don't do anything in production
return self.nodelist.render(context)

@register.tag
def compress(parser, token):
Expand Down
14 changes: 14 additions & 0 deletions compressor/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,17 @@ def format(self, *args, **kwargs):
params[str(id(item))] = _format_field(value, parts, conv, spec,
want_bytes)
return self._string % params


def get_staticfiles_finders():
finders = None
if ('staticfiles' in settings.INSTALLED_APPS or
'django.contrib.staticfiles' in settings.INSTALLED_APPS):
try:
from django.contrib.staticfiles import finders
except ImportError:
try:
from staticfiles import finders
except ImportError:
pass
return finders
69 changes: 69 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Changelog
=========

0.6.1
-----

- Fixed staticfiles support to also use its finder API to find files during
developement -- when the static files haven't been collected in
``STATIC_ROOT``.

- Fixed regression with the ``COMPRESS`` setting, pre-compilation and
staticfiles.

0.6
---

Major improvements and a lot of bugfixes, some of which are:

- New precompilation support, which allows compilation of files and
hunks with easily configurable compilers before calling the actual
output filters. See the
:ref:`COMPRESS_PRECOMPILERS <compress_precompilers>` for more details.

- New staticfiles support. With the introduction of the staticfiles app
to Django 1.3, compressor officially supports finding the files to
compress using the app's finder API. Have a look at the documentation
about :ref:`remote storages <remote_storages>` in case you want to use
those together with compressor.

- New ``compress`` management command which allows pre-running of what the
compress template tag does. See the
:ref:`pre-compression <pre-compression>` docs for more information.

- Various perfomance improvements by better caching and mtime cheking.

- Deprecated ``COMPRESS_LESSC_BINARY`` setting because it's now
superseded by the :ref:`COMPRESS_PRECOMPILERS <compress_precompilers>`
setting. Just make sure to use the correct mimetype when linking to less
files or adding inline code and add the following to your settings::

COMPRESS_PRECOMPILERS = (
('text/less', 'lessc {infile} {outfile}'),
)

- Added cssmin_ filter (``compressor.filters.CSSMinFilter``) based on
Zachary Voase's Python port of the YUI CSS compression algorithm.

- Reimplemented the dog-piling prevention.

- Make sure the CssAbsoluteFilter works for relative paths.

- Added inline render mode. See :ref:`usage <usage>` docs.

- Added ``mtime_cache`` management command to add and/or remove all mtimes
from the cache.

- Moved docs to Read The Docs: http://django_compressor.readthedocs.org

- Added optional ``compressor.storage.GzipCompressorFileStorage`` storage
backend that gzips of the saved files automatically for easier deployment.

- Reimplemented a few filters on top of the new
``compressor.filters.base.CompilerFilter`` to be a bit more DRY.

- Added tox based test configuration, testing on Django 1.1-1.3 and Python
2.5-2.7.

.. _cssmin: http://pypi.python.org/pypi/cssmin/

2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
# The short X.Y version.
version = '0.6'
# The full version, including alpha/beta/rc tags.
release = '0.6'
release = '0.6.1'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion docs/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ Contents
settings
remote-storages
behind-the-scenes

changelog
10 changes: 1 addition & 9 deletions docs/installation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Installation
default behaviour and make adjustements for your website.

* In case you use Django 1.3's staticfiles_ contrib app (or its standalone
clone django-staticfiles_) you have to add django_compressor's file finder
clone django-staticfiles_) you have to add Django Compressor's file finder
to the ``STATICFILES_FINDERS`` setting::

STATICFILES_FINDERS = (
Expand Down Expand Up @@ -58,11 +58,3 @@ Deprecation
This section lists features and settings that are deprecated or removed
in newer versions of Django Compressor.

* ``COMPRESS_LESSC_BINARY``
Superseded by the :ref:`COMPRESS_PRECOMPILERS <compress_precompilers>`
setting. Just make sure to use the correct mimetype when linking to less
files or adding inline code and add the following to your settings::

COMPRESS_PRECOMPILERS = (
('text/less', 'lessc {infile} {outfile}'),
)
2 changes: 2 additions & 0 deletions docs/remote-storages.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _remote_storages:

Remote storages
---------------

Expand Down
Loading

0 comments on commit 5b0fd7e

Please sign in to comment.