Commit f4a48ed1 by Timothée Peignier

prototype based on static files app new features

parent b027c4d7
...@@ -2,23 +2,12 @@ from django.conf import settings ...@@ -2,23 +2,12 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
PIPELINE_ROOT = getattr(settings, 'PIPELINE_ROOT', settings.MEDIA_ROOT)
PIPELINE_URL = getattr(settings, 'PIPELINE_URL', settings.MEDIA_URL)
PIPELINE = getattr(settings, 'PIPELINE', not settings.DEBUG) PIPELINE = getattr(settings, 'PIPELINE', not settings.DEBUG)
PIPELINE_ROOT = getattr(settings, 'PIPELINE_ROOT', settings.STATIC_ROOT) PIPELINE_ROOT = getattr(settings, 'PIPELINE_ROOT', settings.STATIC_ROOT)
PIPELINE_URL = getattr(settings, 'PIPELINE_URL', settings.STATIC_URL) PIPELINE_URL = getattr(settings, 'PIPELINE_URL', settings.STATIC_URL)
PIPELINE_AUTO = getattr(settings, 'PIPELINE_AUTO', True)
PIPELINE_VERSION = getattr(settings, 'PIPELINE_VERSION', False)
PIPELINE_VERSION_PLACEHOLDER = getattr(settings, 'PIPELINE_VERSION_PLACEHOLDER', '?')
PIPELINE_VERSION_DEFAULT = getattr(settings, 'PIPELINE_VERSION_DEFAULT', '0')
PIPELINE_VERSION_REMOVE_OLD = getattr(settings, 'PIPELINE_VERSION_REMOVE_OLD', True)
PIPELINE_VERSIONING = getattr(settings, 'PIPELINE_VERSIONING', 'pipeline.versioning.mtime.MTimeVersioning')
PIPELINE_CACHE_TIMEOUT = getattr(settings, 'PIPELINE_CACHE_TIMEOUT', 63072000)
PIPELINE_STORAGE = getattr(settings, 'PIPELINE_STORAGE', PIPELINE_STORAGE = getattr(settings, 'PIPELINE_STORAGE',
'pipeline.storage.PipelineStorage') 'pipeline.storage.PipelineFinderStorage')
PIPELINE_CSS_COMPRESSOR = getattr(settings, 'PIPELINE_CSS_COMPRESSOR', PIPELINE_CSS_COMPRESSOR = getattr(settings, 'PIPELINE_CSS_COMPRESSOR',
'pipeline.compressors.yui.YUICompressor' 'pipeline.compressors.yui.YUICompressor'
......
import os
import urlparse import urlparse
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
...@@ -9,14 +8,12 @@ from pipeline.compressors import Compressor ...@@ -9,14 +8,12 @@ from pipeline.compressors import Compressor
from pipeline.glob import glob from pipeline.glob import glob
from pipeline.signals import css_compressed, js_compressed from pipeline.signals import css_compressed, js_compressed
from pipeline.storage import storage from pipeline.storage import storage
from pipeline.versioning import Versioning
class Packager(object): class Packager(object):
def __init__(self, verbose=False, css_packages=None, js_packages=None): def __init__(self, verbose=False, css_packages=None, js_packages=None):
self.verbose = verbose self.verbose = verbose
self.compressor = Compressor(verbose) self.compressor = Compressor(verbose)
self.versioning = Versioning(verbose)
self.compiler = Compiler(verbose) self.compiler = Compiler(verbose)
if css_packages is None: if css_packages is None:
css_packages = settings.PIPELINE_CSS css_packages = settings.PIPELINE_CSS
...@@ -53,28 +50,16 @@ class Packager(object): ...@@ -53,28 +50,16 @@ class Packager(object):
def compile(self, paths): def compile(self, paths):
return self.compiler.compile(paths) return self.compiler.compile(paths)
def pack(self, package, compress, signal, sync=False, force=False, **kwargs): def pack(self, package, compress, signal, **kwargs):
if settings.PIPELINE_AUTO or (force and sync): output_filename = package["output"]
need_update, version = self.versioning.need_update( if self.verbose:
package['output'], package['paths']) print "Saving: %s" % output_filename
if need_update or force: paths = self.compile(package['paths'])
output_filename = self.versioning.output_filename( content = compress(paths,
package['output'], asset_url=self.individual_url(output_filename), **kwargs)
version self.save_file(output_filename, content)
) signal.send(sender=self, package=package, **kwargs)
self.versioning.cleanup(package['output']) return output_filename
if self.verbose:
print "Version: %s" % version
print "Saving: %s" % output_filename
paths = self.compile(package['paths'])
content = compress(paths,
asset_url=self.individual_url(output_filename), **kwargs)
self.save_file(output_filename, content)
else:
filename_base, filename = os.path.split(package['output'])
version = self.versioning.version_from_file(filename_base, filename, force=force)
signal.send(sender=self, package=package, version=version, **kwargs)
return self.versioning.output_filename(package['output'], version)
def pack_javascripts(self, package, **kwargs): def pack_javascripts(self, package, **kwargs):
if 'externals' in package: if 'externals' in package:
......
import os from django.dispatch import Signal
from django.core.cache import cache
from django.dispatch import Signal, receiver
from pipeline.conf import settings
css_compressed = Signal(providing_args=["package", "version"]) css_compressed = Signal(providing_args=["package", "version"])
js_compressed = Signal(providing_args=["package", "version"]) js_compressed = Signal(providing_args=["package", "version"])
@receiver(css_compressed)
@receiver(js_compressed)
def invalidate_cache(sender, package, version, **kwargs):
filename_base, filename = os.path.split(package['output'])
cache.set("pipeline:%s" % filename, str(version),
settings.PIPELINE_CACHE_TIMEOUT)
import errno
import os
from datetime import datetime
from django.contrib.staticfiles import finders from django.contrib.staticfiles import finders
from django.contrib.staticfiles.storage import CachedStaticFilesStorage, StaticFilesStorage
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.core.files.storage import FileSystemStorage, get_storage_class from django.core.files.storage import get_storage_class
from django.utils.functional import LazyObject from django.utils.functional import LazyObject
from django.contrib.staticfiles.storage import CachedFilesMixin # FIXME : This break if django < 1.4
from pipeline.conf import settings from pipeline.conf import settings
class PipelineStorage(FileSystemStorage): class BaseFinderStorage(StaticFilesStorage):
def __init__(self, location=None, base_url=None, *args, **kwargs):
if location is None:
location = settings.PIPELINE_ROOT
if base_url is None:
base_url = settings.PIPELINE_URL
super(PipelineStorage, self).__init__(location, base_url, *args, **kwargs)
def accessed_time(self, name):
return datetime.fromtimestamp(os.path.getatime(self.path(name)))
def created_time(self, name):
return datetime.fromtimestamp(os.path.getctime(self.path(name)))
def modified_time(self, name):
return datetime.fromtimestamp(os.path.getmtime(self.path(name)))
def get_available_name(self, name):
if self.exists(name):
self.delete(name)
return name
def _open(self, name, mode='rb'):
full_path = self.path(name)
directory = os.path.dirname(full_path)
if not os.path.exists(directory):
try:
os.makedirs(directory)
except OSError, e:
if e.errno != errno.EEXIST:
raise
if not os.path.isdir(directory):
raise IOError("%s exists and is not a directory." % directory)
return super(PipelineStorage, self)._open(name, mode)
class BaseFinderStorage(PipelineStorage):
finders = None finders = None
def __init__(self, finders=None, *args, **kwargs): def __init__(self, finders=None, *args, **kwargs):
...@@ -76,15 +35,27 @@ class PipelineFinderStorage(BaseFinderStorage): ...@@ -76,15 +35,27 @@ class PipelineFinderStorage(BaseFinderStorage):
finders = finders finders = finders
class CachedFinderStorage(BaseFinderStorage, CachedFilesMixin): class PipelineStorage(CachedStaticFilesStorage):
finders = finders
def post_process(self, paths, dry_run=False, **options): def post_process(self, paths, dry_run=False, **options):
processed_files = [] from pipeline.packager import Packager
if dry_run: if dry_run:
return processed_files return []
# FIXME: Do some pipeline stuff packager = Packager()
return super(CachedFinderStorage, self).post_process(processed_files, dry_run, **options) for package_name in packager.packages['css']:
package = packager.package_for('css', package_name)
output_file = packager.pack_stylesheets(package)
for path in package["paths"]:
paths.remove(path)
paths.append(output_file)
for package_name in packager.packages['js']:
package = packager.package_for('js', package_name)
output_file = packager.pack_javascripts(package)
for path in package["paths"]:
paths.remove(path)
for path in package["templates"]:
paths.remove(path)
paths.append(output_file)
return super(PipelineStorage, self).post_process(paths, dry_run, **options)
class DefaultStorage(LazyObject): class DefaultStorage(LazyObject):
......
from django import template from django import template
from django.contrib.staticfiles.storage import staticfiles_storage
from django.template.loader import render_to_string from django.template.loader import render_to_string
from pipeline.conf import settings from pipeline.conf import settings
...@@ -24,20 +25,19 @@ class CompressedCSSNode(template.Node): ...@@ -24,20 +25,19 @@ class CompressedCSSNode(template.Node):
return '' # fail silently, do not return anything if an invalid group is specified return '' # fail silently, do not return anything if an invalid group is specified
if settings.PIPELINE: if settings.PIPELINE:
compressed_path = self.packager.pack_stylesheets(package) return self.render_css(package)
return self.render_css(package, compressed_path)
else: else:
package['paths'] = self.packager.compile(package['paths']) package['paths'] = self.packager.compile(package['paths'])
return self.render_individual(package) return self.render_individual(package)
def render_css(self, package, path): def render_css(self, package):
context = {} context = {}
if not 'template' in package: if not 'template' in package:
package['template'] = "pipeline/css.html" package['template'] = "pipeline/css.html"
if 'context' in package: if 'context' in package:
context = package['context'] context = package['context']
context.update({ context.update({
'url': self.packager.individual_url(path) 'url': staticfiles_storage.url(package["output"])
}) })
return render_to_string(package['template'], context) return render_to_string(package['template'], context)
...@@ -66,21 +66,20 @@ class CompressedJSNode(template.Node): ...@@ -66,21 +66,20 @@ class CompressedJSNode(template.Node):
return '\n'.join([self.render_external(package, url) for url in package['externals']]) return '\n'.join([self.render_external(package, url) for url in package['externals']])
if settings.PIPELINE: if settings.PIPELINE:
compressed_path = self.packager.pack_javascripts(package) return self.render_js(package)
return self.render_js(package, compressed_path)
else: else:
package['paths'] = self.packager.compile(package['paths']) package['paths'] = self.packager.compile(package['paths'])
templates = self.packager.pack_templates(package) templates = self.packager.pack_templates(package)
return self.render_individual(package, templates) return self.render_individual(package, templates)
def render_js(self, package, path): def render_js(self, package):
context = {} context = {}
if not 'template' in package: if not 'template' in package:
package['template'] = "pipeline/js.html" package['template'] = "pipeline/js.html"
if 'context' in package: if 'context' in package:
context = package['context'] context = package['context']
context.update({ context.update({
'url': self.packager.individual_url(path) 'url': staticfiles_storage.url(package["output"])
}) })
return render_to_string(package['template'], context) return render_to_string(package['template'], context)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment