django-pipeline-1.2.2.1/0000775000076500000240000000000011746266641014653 5ustar timstaff00000000000000django-pipeline-1.2.2.1/AUTHORS0000664000076500000240000000234211727103251015706 0ustar timstaff00000000000000Pipeline is a fork of django-compress which was originally created by Andreas Pelme in 2008. These people have provided bug fixes, new features, improved the documentation or just made Pipeline more awesome. * Adam Charnock * Alexander Artemenko * Alexander Pugachev * Andreas Cederström * Ara Anjargolian * Balazs Kossovics * Ben Vinegar * Bryan Chow * Casey Greene * Christian Hammond * David Charbonnier * David Cramer * Denis V Seleznyov * Kyle MacFarlane * Luke Yu-Po Chen * Matt Dennewitz * Max Klymyshyn * Patrick Altman * Peter Baumgartner * Remco Wendt * Sam Thomson * Sander Smits * Sander Smits * Steven Cummings * Timothée Peignier django-pipeline-1.2.2.1/django_pipeline.egg-info/0000775000076500000240000000000011746266641021474 5ustar timstaff00000000000000django-pipeline-1.2.2.1/django_pipeline.egg-info/dependency_links.txt0000664000076500000240000000000111746266635025545 0ustar timstaff00000000000000 django-pipeline-1.2.2.1/django_pipeline.egg-info/not-zip-safe0000664000076500000240000000000111662673026023716 0ustar timstaff00000000000000 django-pipeline-1.2.2.1/django_pipeline.egg-info/PKG-INFO0000664000076500000240000000140611746266635022575 0ustar timstaff00000000000000Metadata-Version: 1.0 Name: django-pipeline Version: 1.2.2.1 Summary: Pipeline is an asset packaging library for Django. Home-page: https://github.com/cyberdelia/django-pipeline Author: Timothée Peignier Author-email: timothee.peignier@tryphon.org License: UNKNOWN Description: Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript template support, and optional data-URI image and font embedding. Platform: UNKNOWN Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Utilities django-pipeline-1.2.2.1/django_pipeline.egg-info/SOURCES.txt0000664000076500000240000000265011746266637023370 0ustar timstaff00000000000000AUTHORS LICENSE MANIFEST.in setup.py django_pipeline.egg-info/PKG-INFO django_pipeline.egg-info/SOURCES.txt django_pipeline.egg-info/dependency_links.txt django_pipeline.egg-info/not-zip-safe django_pipeline.egg-info/top_level.txt docs/Makefile docs/changelog.rst docs/compilers.rst docs/compressors.rst docs/conf.py docs/configuration.rst docs/index.rst docs/installation.rst docs/make.bat docs/signals.rst docs/storages.rst docs/templates.rst docs/usage.rst docs/using.rst pipeline/__init__.py pipeline/glob.py pipeline/manifest.py pipeline/middleware.py pipeline/models.py pipeline/packager.py pipeline/signals.py pipeline/storage.py pipeline/utils.py pipeline/compilers/__init__.py pipeline/compilers/coffee.py pipeline/compilers/less.py pipeline/compilers/sass.py pipeline/compilers/stylus.py pipeline/compressors/__init__.py pipeline/compressors/closure.py pipeline/compressors/cssmin.py pipeline/compressors/csstidy.py pipeline/compressors/jsmin.py pipeline/compressors/uglifyjs.py pipeline/compressors/yui.py pipeline/conf/__init__.py pipeline/conf/settings.py pipeline/templates/pipeline/css.html pipeline/templates/pipeline/inline_js.html pipeline/templates/pipeline/js.html pipeline/templatetags/__init__.py pipeline/templatetags/compressed.py tests/__init__.py tests/models.py tests/settings.py tests/tests/__init__.py tests/tests/compiler.py tests/tests/compressor.py tests/tests/packager.py tests/tests/storage.py tests/tests/utils.pydjango-pipeline-1.2.2.1/django_pipeline.egg-info/top_level.txt0000664000076500000240000000001711746266635024227 0ustar timstaff00000000000000pipeline tests django-pipeline-1.2.2.1/docs/0000775000076500000240000000000011746266641015603 5ustar timstaff00000000000000django-pipeline-1.2.2.1/docs/changelog.rst0000664000076500000240000000227011746266556020272 0ustar timstaff00000000000000Changelog ========= 1.2.2.1 ------- * License clarification. Thanks to Dmitry Nezhevenko for the report. 1.2.2 ----- * Allow to disable javascript closure wrapper with ``PIPELINE_DISABLE_WRAPPER``. * Various improvements to documentation. * Slightly improve how we find where to write compiled file. * Simplify module hierarchy. * Allow templatetag to output mimetype to be able to use less.js and other javascript compilers. 1.2.1 ----- * Fixing a bug in ``FinderStorage`` when using prefix in staticfiles. Thanks to Christian Hammond for the report and testing. * Make ``PIPELINE_ROOT`` defaults more sane. Thanks to Konstantinos Pachnis for the report. 1.2.0 ----- * Dropped ``synccompress`` command in favor of staticfiles ``collecstatic`` command. * Added file versionning via staticfiles ``CachedStaticFilesStorage``. * Added a default js template language. * Dropped ``PIPELINE_AUTO`` settings in favor of simple ``PIPELINE``. * Renamed ``absolute_asset_paths`` to ``absolute_paths`` for brevity. * Made packages lazy to avoid doing unnecessary I/O. * Dropped ``external_urls`` support for now. * Add cssmin compressor. Thanks to Steven Cummings. * Jsmin is no more bundle with pipeline. django-pipeline-1.2.2.1/docs/compilers.rst0000664000076500000240000000636611727340172020334 0ustar timstaff00000000000000.. _ref-compilers: ========= Compilers ========= Coffee Script compiler ====================== The Coffee Script compiler use `Coffee Script `_ to compile your javascripts. To use it add this to your ``PIPELINE_COMPILERS`` :: PIPELINE_COMPILERS = ( 'pipeline.compilers.coffee.CoffeeScriptCompiler', ) ``PIPELINE_COFFEE_SCRIPT_BINARY`` --------------------------------- Command line to execute for coffee program. You will most likely change this to the location of coffee on your system. Defaults to ``'/usr/local/bin/coffee'``. ``PIPELINE_COFFEE_SCRIPT_ARGUMENTS`` ------------------------------------ Additional arguments to use when coffee is called. Defaults to ``''``. LESS compiler ============= The LESS compiler use `LESS `_ to compile your stylesheets. To use it add this to your ``PIPELINE_COMPILERS`` :: PIPELINE_COMPILERS = ( 'pipeline.compilers.less.LessCompiler', ) ``PIPELINE_LESS_BINARY`` ------------------------ Command line to execute for lessc program. You will most likely change this to the location of lessc on your system. Defaults to ``'/usr/local/bin/lessc'``. ``PIPELINE_LESS_ARGUMENTS`` --------------------------- Additional arguments to use when lessc is called. Defaults to ``''``. SASS compiler ============= The SASS compiler use `SASS `_ to compile your stylesheets. To use it add this to your ``PIPELINE_COMPILERS`` :: PIPELINE_COMPILERS = ( 'pipeline.compilers.sass.SASSCompiler', ) ``PIPELINE_SASS_BINARY`` ------------------------ Command line to execute for sass program. You will most likely change this to the location of sass on your system. Defaults to ``'/usr/local/bin/sass'``. ``PIPELINE_SASS_ARGUMENTS`` --------------------------- Additional arguments to use when sass is called. Defaults to ``''``. Stylus compiler =============== The Stylus compiler use `Stylus ` to compile your stylesheets. To use it add this to your ``PIPELINE_COMPILERS`` :: PIPELINE_COMPILERS = ( 'pipeline.compilers.stylus.StylusCompiler', ) ``PIPELINE_STYLUS_BINARY`` -------------------------- Command line to execute for stylus program. You will most likely change this to the location of stylus on your system. Defaults to ``'/usr/local/bin/stylus'``. ``PIPELINE_STYLUS_ARGUMENTS`` ----------------------------- Additional arguments to use when stylus is called. Defaults to ``''``. Write your own compiler class ============================= To write your own compiler class, for example want to implement other types of compilers. All you need to do is to create a class that inherits from ``pipeline.compilers.CompilerBase`` and implements ``match_file`` and ``compile_file`` when needed. Finally, specify it in the tuple of compilers ``PIPELINE_COMPILERS`` in the settings. Example ------- A custom compiler for a imaginary compiler called jam :: from pipeline.compilers import CompilerBase class JamCompiler(CompilerBase): output_extension = 'js' def match_file(self, filename): return filename.endswith('.jam') def compile_file(self, content, path): return jam.compile(content) django-pipeline-1.2.2.1/docs/compressors.rst0000664000076500000240000001157011730156135020705 0ustar timstaff00000000000000.. _ref-compressors: =========== Compressors =========== YUI Compressor compressor ========================= The YUI compressor use `yui-compressor `_ for compressing javascript and stylesheets. To use it for your stylesheets add this to your ``PIPELINE_CSS_COMPRESSOR`` :: PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.yui.YUICompressor' To use it for your javascripts add this to your ``PIPELINE_JS_COMPRESSOR`` :: PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.yui.YUICompressor' ``PIPELINE_YUI_BINARY`` ----------------------- Command line to execute for the YUI program. You will most likely change this to the location of yui-compressor on your system. Defaults to ``'/usr/local/bin/yuicompressor'``. .. warning:: Don't point to ``yuicompressor.jar`` directly, we expect to find a executable script. ``PIPELINE_YUI_CSS_ARGUMENTS`` ------------------------------ Additional arguments to use when compressing CSS. Defaults to ``''``. ``PIPELINE_YUI_JS_ARGUMENTS`` ----------------------------- Additional arguments to use when compressing JavaScript. Defaults to ``''``. Closure Compiler compressor =========================== The Closure compressor use `Google Closure Compiler `_ to compress javascripts. To use it add this to your ``PIPELINE_JS_COMPRESSOR`` :: PIPELINE_JS_COMPRESSOR = ( 'pipeline.compressors.closure.ClosureCompressor', ) ``PIPELINE_CLOSURE_BINARY`` --------------------------- Command line to execute for the Closure Compiler program. You will most likely change this to the location of closure on your system. Default to ``'/usr/local/bin/closure'`` .. warning:: Don't point to ``compiler.jar`` directly, we expect to find a executable script. ``PIPELINE_CLOSURE_ARGUMENTS`` ------------------------------ Additional arguments to use when closure is called. Default to ``''`` UglifyJS compressor =================== The UglifyJS compressor use `UglifyJS `_ to compress javascripts. To use it add this to your ``PIPELINE_JS_COMPRESSOR`` :: PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.uglifyjs.UglifyJSCompressor' ``PIPELINE_UGLIFYJS_BINARY`` ---------------------------- Command line to execute for the Closure Compiler program. You will most likely change this to the location of closure on your system. Defaults to ``'/usr/local/bin/uglifyjs'``. ``PIPELINE_UGLIFYJS_ARGUMENTS`` ------------------------------- Additional arguments to use when uglifyjs is called. Default to ``''`` JSMin compressor ================ The jsmin compressor use Douglas Crockford jsmin tool to compress javascripts. To use it add this to your ``PIPELINE_JS_COMPRESSOR`` :: PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.jsmin.JSMinCompressor' Install the jsmin library with your favorite Python package manager :: pip install jsmin CSSTidy compressor ================== The CSStidy compressor use `CSStidy `_ to compress stylesheets. To us it for your stylesheets add this to your ``PIPELINE_CSS_COMPRESSOR`` :: PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.csstidy.CSSTidyCompressor' ``PIPELINE_CSSTIDY_BINARY`` --------------------------- Command line to execute for csstidy program. You will most likely change this to the location of csstidy on your system. Defaults to ``'/usr/local/bin/csstidy'`` ``PIPELINE_CSSTIDY_ARGUMENTS`` ------------------------------ Additional arguments to use when csstidy is called. Default to ``'--template=highest'`` cssmin compressor ================= The cssmin compressor uses the `cssmin `_ Python library to compress stylesheets. To use it, specify this ``PIPELINE_CSS_COMPRESSOR`` :: PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.cssmin.CssminCompressor' Install the cssmin library with your favorite Python package manager. E.g. :: pip install cssmin Write your own compressor class =============================== To write your own compressor class, for example want to implement other types of compressors. All you need to do is to create a class that inherits from ``pipeline.compressors.CompressorBase`` and implements ``compress_css`` and/or a ``compress_js`` when needed. Finally, add it to ``PIPELINE_CSS_COMPRESSOR`` or ``PIPELINE_JS_COMPRESSOR`` settings (see :doc:`configuration` for more information). Example ------- A custom compressor for a imaginary compressor called jam :: from pipeline.compressors import CompressorBase class JamCompressor(CompressorBase): def compress_js(self, js): return jam.compress(js) def compress_css(self, css): return jam.compress(css) Add it to your settings :: PIPELINE_CSS_COMPRESSOR = 'jam.compressors.JamCompressor' PIPELINE_JS_COMPRESSOR = 'jam.compressors.JamCompressor' django-pipeline-1.2.2.1/docs/conf.py0000664000076500000240000001560011746266556017111 0ustar timstaff00000000000000# -*- coding: utf-8 -*- # # Pipeline documentation build configuration file, created by # sphinx-quickstart on Sat Apr 30 17:47:55 2011. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'django-pipeline' copyright = u'2011-2012, Timothée Peignier' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '1.2.2.1' # The full version, including alpha/beta/rc tags. release = '1.2.2.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # 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'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'django-pipelinedoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'django-pipeline.tex', u'Pipeline Documentation', u'Timothée Peignier', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'django-pipeline', u'Pipeline Documentation', [u'Timothée Peignier'], 1) ] django-pipeline-1.2.2.1/docs/configuration.rst0000664000076500000240000001172611745333523021204 0ustar timstaff00000000000000.. _ref-configuration: ============= Configuration ============= Configuration and list of available settings for Pipeline Specifying files ================ You specify groups of files to be compressed in your settings. You can use glob syntax to select multiples files. The basic syntax for specifying CSS/JavaScript groups files is :: PIPELINE_CSS = { 'colors': { 'source_filenames': ( 'css/core.css', 'css/colors/*.css', 'css/layers.css' ), 'output_filename': 'css/colors.css', 'extra_context': { 'media': 'screen,projection', }, }, } PIPELINE_JS = { 'stats': { 'source_filenames': ( 'js/jquery.js', 'js/d3.js', 'js/collections/*.js', 'js/application.js', ), 'output_filename': 'js/stats.js', } } Group options ------------- ``source_filenames`` .................... **Required** Is a tuple with the source files to be compressed. The files are concatenated in the order it is specified in the tuple. ``output_filename`` ................... **Required** Is the filename of the (to be) compressed file. ``variant`` ........... **Optional** Is the variant you want to apply to your CSS. This allow you to embed images and fonts in CSS with data-URI. Allowed values are : ``None`` and ``datauri``. Defaults to ``None``. ``template_name`` ................. **Optional** Name of the template used to render ``django-pipeline-1.2.2.1/pipeline/templates/pipeline/js.html0000664000076500000240000000020111740527446023553 0ustar timstaff00000000000000django-pipeline-1.2.2.1/pipeline/templatetags/0000775000076500000240000000000011746266641021152 5ustar timstaff00000000000000django-pipeline-1.2.2.1/pipeline/templatetags/__init__.py0000664000076500000240000000000011727103232023232 0ustar timstaff00000000000000django-pipeline-1.2.2.1/pipeline/templatetags/compressed.py0000664000076500000240000001005311740527446023664 0ustar timstaff00000000000000try: from staticfiles.storage import staticfiles_storage except ImportError: from django.contrib.staticfiles.storage import staticfiles_storage # noqa from django import template from django.template.loader import render_to_string from pipeline.conf import settings from pipeline.packager import Packager, PackageNotFound from pipeline.utils import guess_type register = template.Library() class CompressedCSSNode(template.Node): def __init__(self, name): self.name = name def render(self, context): package_name = template.Variable(self.name).resolve(context) package = settings.PIPELINE_CSS.get(package_name, {}) if package: package = {package_name: package} self.packager = Packager(css_packages=package, js_packages={}) try: package = self.packager.package_for('css', package_name) except PackageNotFound: return '' # fail silently, do not return anything if an invalid group is specified if settings.PIPELINE: return self.render_css(package, package.output_filename) else: paths = self.packager.compile(package.paths) return self.render_individual(package, paths) def render_css(self, package, path): template_name = package.template_name or "pipeline/css.html" context = package.extra_context context.update({ 'type': guess_type(path, 'text/css'), 'url': staticfiles_storage.url(path) }) return render_to_string(template_name, context) def render_individual(self, package, paths): tags = [self.render_css(package, path) for path in paths] return '\n'.join(tags) class CompressedJSNode(template.Node): def __init__(self, name): self.name = name def render(self, context): package_name = template.Variable(self.name).resolve(context) package = settings.PIPELINE_JS.get(package_name, {}) if package: package = {package_name: package} self.packager = Packager(css_packages={}, js_packages=package) try: package = self.packager.package_for('js', package_name) except PackageNotFound: return '' # fail silently, do not return anything if an invalid group is specified if settings.PIPELINE: return self.render_js(package, package.output_filename) else: paths = self.packager.compile(package.paths) templates = self.packager.pack_templates(package) return self.render_individual(package, paths, templates) def render_js(self, package, path): template_name = package.template_name or "pipeline/js.html" context = package.extra_context context.update({ 'type': guess_type(path, 'text/javascript'), 'url': staticfiles_storage.url(path) }) return render_to_string(template_name, context) def render_inline(self, package, js): context = package.extra_context context.update({ 'source': js }) return render_to_string("pipeline/inline_js.html", context) def render_individual(self, package, paths, templates=None): tags = [self.render_js(package, js) for js in paths] if templates: tags.append(self.render_inline(package, templates)) return '\n'.join(tags) def compressed_css(parser, token): try: tag_name, name = token.split_contents() except ValueError: raise template.TemplateSyntaxError, '%r requires exactly one argument: the name of a group in the PIPELINE_CSS setting' % token.split_contents()[0] return CompressedCSSNode(name) compressed_css = register.tag(compressed_css) def compressed_js(parser, token): try: tag_name, name = token.split_contents() except ValueError: raise template.TemplateSyntaxError, '%r requires exactly one argument: the name of a group in the PIPELINE_JS setting' % token.split_contents()[0] return CompressedJSNode(name) compressed_js = register.tag(compressed_js) django-pipeline-1.2.2.1/pipeline/utils.py0000664000076500000240000000521711740527446020174 0ustar timstaff00000000000000import mimetypes import os import sys import urllib from django.utils import importlib from django.utils.encoding import smart_str from pipeline.conf import settings def to_class(class_str): if not class_str: return None module_bits = class_str.split('.') module_path, class_name = '.'.join(module_bits[:-1]), module_bits[-1] module = importlib.import_module(module_path) return getattr(module, class_name, None) def filepath_to_uri(path): if path is None: return path return urllib.quote(smart_str(path).replace("\\", "/"), safe="/~!*()'#?") def guess_type(path, default=None): for type, ext in settings.PIPELINE_MIMETYPES: mimetypes.add_type(type, ext, strict=False) mimetype, _ = mimetypes.guess_type(path, strict=False) if not mimetype: return default return mimetype def _relpath_nt(path, start=os.path.curdir): """Return a relative version of a path""" if not path: raise ValueError("no path specified") start_list = os.path.abspath(start).split(os.path.sep) path_list = os.path.abspath(path).split(os.path.sep) if start_list[0].lower() != path_list[0].lower(): unc_path, rest = os.path.splitunc(path) unc_start, rest = os.path.splitunc(start) if bool(unc_path) ^ bool(unc_start): raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)" % (path, start)) else: raise ValueError("path is on drive %s, start on drive %s" % (path_list[0], start_list[0])) # Work out how much of the filepath is shared by start and path. for i in range(min(len(start_list), len(path_list))): if start_list[i].lower() != path_list[i].lower(): break else: i += 1 rel_list = [os.path.pardir] * (len(start_list) - i) + path_list[i:] if not rel_list: return os.path.curdir return os.path.join(*rel_list) def _relpath_posix(path, start=os.path.curdir): """Return a relative version of a path""" if not path: raise ValueError("no path specified") start_list = os.path.abspath(start).split(os.path.sep) path_list = os.path.abspath(path).split(os.path.sep) # Work out how much of the filepath is shared by start and path. i = len(os.path.commonprefix([start_list, path_list])) rel_list = [os.path.pardir] * (len(start_list) - i) + path_list[i:] if not rel_list: return os.path.curdir return os.path.join(*rel_list) if os.path is sys.modules.get('ntpath'): relpath = _relpath_nt else: relpath = _relpath_posix django-pipeline-1.2.2.1/PKG-INFO0000664000076500000240000000140611746266641015751 0ustar timstaff00000000000000Metadata-Version: 1.0 Name: django-pipeline Version: 1.2.2.1 Summary: Pipeline is an asset packaging library for Django. Home-page: https://github.com/cyberdelia/django-pipeline Author: Timothée Peignier Author-email: timothee.peignier@tryphon.org License: UNKNOWN Description: Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript template support, and optional data-URI image and font embedding. Platform: UNKNOWN Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Utilities django-pipeline-1.2.2.1/setup.cfg0000664000076500000240000000007311746266641016474 0ustar timstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 django-pipeline-1.2.2.1/setup.py0000664000076500000240000000164011746266556016373 0ustar timstaff00000000000000# -*- coding: utf-8 -*- from setuptools import setup, find_packages setup( name='django-pipeline', version='1.2.2.1', description='Pipeline is an asset packaging library for Django.', long_description="""Pipeline is an asset packaging library for Django, providing both CSS and JavaScript concatenation and compression, built-in JavaScript template support, and optional data-URI image and font embedding.""", author='Timothée Peignier', author_email='timothee.peignier@tryphon.org', url='https://github.com/cyberdelia/django-pipeline', packages=find_packages(), zip_safe=False, include_package_data=True, classifiers=[ 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Utilities', ] ) django-pipeline-1.2.2.1/tests/0000775000076500000240000000000011746266641016015 5ustar timstaff00000000000000django-pipeline-1.2.2.1/tests/__init__.py0000664000076500000240000000000011727103232020075 0ustar timstaff00000000000000django-pipeline-1.2.2.1/tests/models.py0000664000076500000240000000000011727103232017621 0ustar timstaff00000000000000django-pipeline-1.2.2.1/tests/settings.py0000664000076500000240000000240111736330555020217 0ustar timstaff00000000000000import os local_path = lambda path: os.path.join(os.path.dirname(__file__), path) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'TEST_NAME': ':memory:' } } SITE_ID = 1 INSTALLED_APPS = [ 'django.contrib.contenttypes', 'django.contrib.sites', 'staticfiles', 'django.contrib.auth', 'django.contrib.admin', 'pipeline', 'tests', ] MEDIA_URL = '/media/' MEDIA_ROOT = local_path('media') STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage' STATIC_ROOT = local_path('static/') STATIC_URL = '/static/' STATICFILES_DIRS = ( local_path('assets/'), ) STATICFILES_FINDERS = ( 'staticfiles.finders.FileSystemFinder', 'staticfiles.finders.AppDirectoriesFinder' ) SECRET_KEY = "django-pipeline" TEMPLATE_DIRS = ( local_path('templates'), ) PIPELINE_CSS = { 'screen': { 'source_filenames': ( 'css/first.css', 'css/second.css', 'css/urls.css', ), 'output_filename': 'screen.css' } } PIPELINE_JS = { 'scripts': { 'source_filenames': ( 'js/first.js', 'js/second.js', 'js/application.js', 'templates/**/*.jst' ), 'output_filename': 'scripts.css' } } django-pipeline-1.2.2.1/tests/tests/0000775000076500000240000000000011746266641017157 5ustar timstaff00000000000000django-pipeline-1.2.2.1/tests/tests/__init__.py0000664000076500000240000000022611740527446021265 0ustar timstaff00000000000000# -*- coding: utf-8 flake8: noqa -*- from packager import * from compressor import * from compiler import * from storage import * from utils import * django-pipeline-1.2.2.1/tests/tests/compiler.py0000664000076500000240000000220711736326265021342 0ustar timstaff00000000000000from django.test import TestCase from pipeline.conf import settings from pipeline.compilers import Compiler, CompilerBase class DummyCompiler(CompilerBase): output_extension = 'js' def match_file(self, path): return path.endswith('.coffee') def compile_file(self, content, path): return content class CompilerTest(TestCase): def setUp(self): self.compiler = Compiler() self.old_compilers = settings.PIPELINE_COMPILERS settings.PIPELINE_COMPILERS = ['tests.tests.compiler.DummyCompiler'] def test_output_path(self): output_path = self.compiler.output_path("js/helpers.coffee", "js") self.assertEquals(output_path, "js/helpers.js") def test_compilers_class(self): compilers_class = self.compiler.compilers self.assertEquals(compilers_class[0], DummyCompiler) def test_compile(self): paths = self.compiler.compile([ 'js/dummy.coffee', 'js/application.js', ]) self.assertEquals(['js/dummy.js', 'js/application.js'], paths) def tearDown(self): settings.PIPELINE_COMPILERS = self.old_compilers django-pipeline-1.2.2.1/tests/tests/compressor.py0000664000076500000240000001215511736330511021714 0ustar timstaff00000000000000# -*- coding: utf-8 -*- import base64 from mock import patch from django.test import TestCase from pipeline.compressors import Compressor, TEMPLATE_FUNC from pipeline.compressors.yui import YUICompressor class CompressorTest(TestCase): def setUp(self): self.compressor = Compressor() def test_js_compressor_class(self): self.assertEquals(self.compressor.js_compressor, YUICompressor) def test_css_compressor_class(self): self.assertEquals(self.compressor.css_compressor, YUICompressor) def test_concatenate_and_rewrite(self): css = self.compressor.concatenate_and_rewrite([ 'css/first.css', 'css/second.css' ], 'css/screen.css') self.assertEquals(""".concat {\n display: none;\n}\n\n.concatenate {\n display: block;\n}\n""", css) def test_concatenate(self): js = self.compressor.concatenate([ 'js/first.js', 'js/second.js' ]) self.assertEquals("""function concat() {\n console.log(arguments);\n}\n\nfunction cat() {\n console.log("hello world");\n}\n""", js) @patch.object(base64, 'b64encode') def test_encoded_content(self, mock): self.compressor.encoded_content('images/arrow.png') self.assertTrue(mock.called) mock.reset_mock() self.compressor.encoded_content('images/arrow.png') self.assertFalse(mock.called) def test_relative_path(self): relative_path = self.compressor.relative_path("images/sprite.png", 'css/screen.css') self.assertEquals(relative_path, '../images/sprite.png') def test_base_path(self): base_path = self.compressor.base_path([ 'js/templates/form.jst', 'js/templates/field.jst' ]) self.assertEquals(base_path, 'js/templates') def test_absolute_path(self): absolute_path = self.compressor.absolute_path('../../images/sprite.png', 'css/plugins/') self.assertEquals(absolute_path, 'images/sprite.png') absolute_path = self.compressor.absolute_path('/images/sprite.png', 'css/plugins/') self.assertEquals(absolute_path, '/images/sprite.png') def test_template_name(self): name = self.compressor.template_name('templates/photo/detail.jst', 'templates/') self.assertEquals(name, 'photo_detail') name = self.compressor.template_name('templates/photo_edit.jst', '') self.assertEquals(name, 'photo_edit') name = self.compressor.template_name('templates\photo\detail.jst', 'templates\\') self.assertEquals(name, 'photo_detail') def test_compile_templates(self): templates = self.compressor.compile_templates(['templates/photo/list.jst']) self.assertEquals(templates, """window.JST = window.JST || {};\n%s\nwindow.JST['list'] = template('
<%%= caption %%>
');\n""" % TEMPLATE_FUNC) templates = self.compressor.compile_templates([ 'templates/video/detail.jst', 'templates/photo/detail.jst' ]) self.assertEqual(templates, """window.JST = window.JST || {};\n%s\nwindow.JST['video_detail'] = template('
');\nwindow.JST[\'photo_detail\'] = template(\'
<%%= caption %%> by <%%= author %%>
\');\n""" % TEMPLATE_FUNC) def test_embeddable(self): self.assertFalse(self.compressor.embeddable('images/sprite.png', None)) self.assertFalse(self.compressor.embeddable('images/arrow.png', 'datauri')) self.assertTrue(self.compressor.embeddable('images/embed/arrow.png', 'datauri')) self.assertFalse(self.compressor.embeddable('images/arrow.dat', 'datauri')) def test_construct_asset_path(self): asset_path = self.compressor.construct_asset_path("../../images/sprite.png", "css/plugins/gallery.css", "css/gallery.css") self.assertEquals(asset_path, "../images/sprite.png") asset_path = self.compressor.construct_asset_path("/images/sprite.png", "css/plugins/gallery.css", "css/gallery.css") self.assertEquals(asset_path, "/images/sprite.png") def test_url_rewrite(self): output = self.compressor.concatenate_and_rewrite([ 'css/urls.css', ], 'css/screen.css') self.assertEquals("""@font-face { font-family: 'Pipeline'; src: url(../fonts/pipeline.eot); src: url(../fonts/pipeline.eot?#iefix) format('embedded-opentype'); src: local('☺'), url(../fonts/pipeline.woff) format('woff'), url(../fonts/pipeline.ttf) format('truetype'), url(../fonts/pipeline.svg#IyfZbseF) format('svg'); font-weight: normal; font-style: normal; } .relative-url { background-image: url(../images/sprite-buttons.png); } .absolute-url { background-image: url(/images/sprite-buttons.png); } .absolute-full-url { background-image: url(http://localhost/images/sprite-buttons.png); } .no-protocol-url { background-image: url(//images/sprite-buttons.png); }""", output) django-pipeline-1.2.2.1/tests/tests/packager.py0000664000076500000240000000212611727103232021270 0ustar timstaff00000000000000from django.test import TestCase from pipeline.packager import Packager, PackageNotFound class PackagerTest(TestCase): def test_package_for(self): packager = Packager() packager.packages['js'] = packager.create_packages({ 'application': { 'source_filenames': ( 'js/application.js', ), 'output_filename': 'application.js' } }) try: packager.package_for('js', 'application') except PackageNotFound: self.fail() try: packager.package_for('js', 'broken') self.fail() except PackageNotFound: pass def test_templates(self): packager = Packager() packages = packager.create_packages({ 'templates': { 'source_filenames': ( 'templates/photo/list.jst', ), 'output_filename': 'templates.js', } }) self.assertEqual(packages['templates'].templates, ['templates/photo/list.jst']) django-pipeline-1.2.2.1/tests/tests/storage.py0000664000076500000240000000246511743524520021172 0ustar timstaff00000000000000from django.test import TestCase from django.utils.datastructures import SortedDict from pipeline.conf import settings from pipeline.storage import PipelineStorage class StorageTest(TestCase): def setUp(self): settings.PIPELINE_CSS = { 'testing': { 'source_filenames': ( 'css/first.css', ), 'manifest': False, 'output_filename': 'testing.css', } } settings.PIPELINE_JS_COMPRESSOR = None settings.PIPELINE_CSS_COMPRESSOR = None self.storage = PipelineStorage() def test_post_process_dry_run(self): processed_files = self.storage.post_process([], True) self.assertEqual(processed_files, []) def test_post_process(self): processed_files = self.storage.post_process(SortedDict({ 'css/first.css': (self.storage, 'css/first.css'), 'images/arrow.png': (self.storage, 'images/arrow.png') })) self.assertEqual(processed_files, [ ('css/first.css', 'css/first.css', True), ('images/arrow.png', 'images/arrow.png', True), ('testing.css', 'testing.css', True), ('scripts.css', 'scripts.css', True) ]) def tearDown(self): settings.PIPELINE_CSS = {} django-pipeline-1.2.2.1/tests/tests/utils.py0000664000076500000240000000056311740527446020672 0ustar timstaff00000000000000# -*- coding: utf-8 -*- from django.test import TestCase from pipeline.utils import guess_type class UtilTest(TestCase): def test_guess_type(self): self.assertEqual('text/css', guess_type('stylesheet.css')) self.assertEqual('text/coffeescript', guess_type('application.coffee')) self.assertEqual('text/less', guess_type('stylesheet.less'))