Commit 59dbe419 by Timothée Peignier

improve how we deal with unix and windows path

parent 385c978f
...@@ -7,7 +7,7 @@ from itertools import takewhile ...@@ -7,7 +7,7 @@ from itertools import takewhile
from pipeline.conf import settings from pipeline.conf import settings
from pipeline.storage import storage from pipeline.storage import storage
from pipeline.utils import to_class, relpath from pipeline.utils import filepath_to_uri, to_class, relpath
MAX_IMAGE_SIZE = 32700 MAX_IMAGE_SIZE = 32700
...@@ -112,13 +112,12 @@ class Compressor(object): ...@@ -112,13 +112,12 @@ class Compressor(object):
path = os.path.basename(path) path = os.path.basename(path)
if path == base: if path == base:
base = os.path.dirname(path) base = os.path.dirname(path)
name = re.sub(r"^%s\/?(.*)%s$" % ( name = re.sub(r"^%s[\/\\]?(.*)%s$" % (
re.escape(base), re.escape(settings.PIPELINE_TEMPLATE_EXT) re.escape(base), re.escape(settings.PIPELINE_TEMPLATE_EXT)
), r"\1", path) ), r"\1", path)
return re.sub(r"[\/\\]", "_", name) return re.sub(r"[\/\\]", "_", name)
def concatenate_and_rewrite(self, paths, variant=None, def concatenate_and_rewrite(self, paths, variant=None, absolute_asset_paths=True):
absolute_asset_paths=True):
"""Concatenate together files and rewrite urls""" """Concatenate together files and rewrite urls"""
stylesheets = [] stylesheets = []
for path in paths: for path in paths:
...@@ -126,8 +125,8 @@ class Compressor(object): ...@@ -126,8 +125,8 @@ class Compressor(object):
asset_path = match.group(1) asset_path = match.group(1)
if asset_path.startswith("http") or asset_path.startswith("//"): if asset_path.startswith("http") or asset_path.startswith("//"):
return "url(%s)" % asset_path return "url(%s)" % asset_path
asset_url = self.construct_asset_path(asset_path, path, variant, asset_url = self.construct_asset_path(asset_path, path,
absolute_asset_paths) variant, absolute_asset_paths)
return "url(%s)" % asset_url return "url(%s)" % asset_url
content = self.read_file(path) content = self.read_file(path)
content = re.sub(URL_DETECTOR, reconstruct, content) content = re.sub(URL_DETECTOR, reconstruct, content)
...@@ -138,8 +137,7 @@ class Compressor(object): ...@@ -138,8 +137,7 @@ class Compressor(object):
"""Concatenate together a list of files""" """Concatenate together a list of files"""
return '\n'.join([self.read_file(path) for path in paths]) return '\n'.join([self.read_file(path) for path in paths])
def construct_asset_path(self, asset_path, css_path, variant=None, def construct_asset_path(self, asset_path, css_path, variant=None, absolute_asset_paths=True):
absolute_asset_paths=True):
"""Return a rewritten asset URL for a stylesheet""" """Return a rewritten asset URL for a stylesheet"""
public_path = self.absolute_path(asset_path, os.path.dirname(css_path)) public_path = self.absolute_path(asset_path, os.path.dirname(css_path))
if self.embeddable(public_path, variant): if self.embeddable(public_path, variant):
...@@ -148,7 +146,7 @@ class Compressor(object): ...@@ -148,7 +146,7 @@ class Compressor(object):
return asset_path return asset_path
if not os.path.isabs(asset_path): if not os.path.isabs(asset_path):
asset_path = self.relative_path(public_path) asset_path = self.relative_path(public_path)
asset_url = asset_path.replace(os.sep, '/') asset_url = filepath_to_uri(asset_path)
return settings.PIPELINE_URL + asset_url[1:] return settings.PIPELINE_URL + asset_url[1:]
def embeddable(self, path, variant): def embeddable(self, path, variant):
......
...@@ -9,6 +9,7 @@ from pipeline.compressors import Compressor ...@@ -9,6 +9,7 @@ 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.utils import filepath_to_uri
from pipeline.versioning import Versioning from pipeline.versioning import Versioning
...@@ -39,9 +40,8 @@ class Packager(object): ...@@ -39,9 +40,8 @@ class Packager(object):
def individual_url(self, filename): def individual_url(self, filename):
relative_path = self.compressor.relative_path(filename)[1:] relative_path = self.compressor.relative_path(filename)[1:]
relative_url = relative_path.replace(os.sep, '/')
return urlparse.urljoin(settings.PIPELINE_URL, return urlparse.urljoin(settings.PIPELINE_URL,
relative_url) filepath_to_uri(relative_path))
def pack_stylesheets(self, package, **kwargs): def pack_stylesheets(self, package, **kwargs):
variant = package.get('variant', None) variant = package.get('variant', None)
......
import os import os
import sys import sys
import urllib
from django.utils import importlib from django.utils import importlib
from django.utils.encoding import smart_str
def to_class(class_str): def to_class(class_str):
...@@ -14,6 +16,12 @@ def to_class(class_str): ...@@ -14,6 +16,12 @@ def to_class(class_str):
return getattr(module, class_name, None) 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 _relpath_nt(path, start=os.path.curdir): def _relpath_nt(path, start=os.path.curdir):
"""Return a relative version of a path""" """Return a relative version of a path"""
if not path: if not path:
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import base64 import base64
import sys
from mock import patch from mock import patch
from django.test import TestCase from django.test import TestCase
from django.utils import unittest
from pipeline.conf import settings from pipeline.conf import settings
from pipeline.compressors import Compressor from pipeline.compressors import Compressor
...@@ -70,6 +72,9 @@ class CompressorTest(TestCase): ...@@ -70,6 +72,9 @@ class CompressorTest(TestCase):
self.assertEquals(name, 'photo_detail') self.assertEquals(name, 'photo_detail')
name = self.compressor.template_name('templates/photo_edit.jst', '') name = self.compressor.template_name('templates/photo_edit.jst', '')
self.assertEquals(name, 'photo_edit') 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): def test_compile_templates(self):
templates = self.compressor.compile_templates(['templates/photo/list.jst']) templates = self.compressor.compile_templates(['templates/photo/list.jst'])
...@@ -93,6 +98,12 @@ class CompressorTest(TestCase): ...@@ -93,6 +98,12 @@ class CompressorTest(TestCase):
asset_path = self.compressor.construct_asset_path("/images/sprite.png", asset_path = self.compressor.construct_asset_path("/images/sprite.png",
"css/plugins/gallery.css") "css/plugins/gallery.css")
self.assertEquals(asset_path, "http://localhost/static/images/sprite.png") self.assertEquals(asset_path, "http://localhost/static/images/sprite.png")
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_construct_asset_path_windows(self):
asset_path = self.compressor.construct_asset_path("\image\sprite.png",
"css\plugins\gallery.css")
self.assertEquals(asset_path, "http://localhost/static/images/sprite.png")
def test_construct_asset_path_relative(self): def test_construct_asset_path_relative(self):
asset_path = self.compressor.construct_asset_path("../../images/sprite.png", asset_path = self.compressor.construct_asset_path("../../images/sprite.png",
......
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