Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ python:
- "3.4"
- "3.3"
- "2.7"
- "2.6"
install:
- sudo apt-get install zlib1g-dev
- sudo ln -s /usr/lib/i386-linux-gnu/libz.so /usr/lib
Expand Down
4 changes: 2 additions & 2 deletions glue/bin.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ def add_deprecated_argument(*args, **kwargs):
extra = 0
# Get the source from the source option or the first positional argument
if not options.source and args:
options.source = args[0]
options.source = unicode(args[0])
extra += 1

# Get the output from the output option or the second positional argument
if not options.output and args[extra:]:
options.output = args[extra]
options.output = unicode(args[extra])

# Check if source is available
if options.source is None:
Expand Down
9 changes: 6 additions & 3 deletions glue/core.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# -*- coding: utf-8 -*-
import re
import os
import sys
import copy
import hashlib
import StringIO
import ConfigParser
import unicodedata

from PIL import Image as PILImage

Expand Down Expand Up @@ -48,7 +50,7 @@ def __init__(self, path, config):
with open(self.path, "rb") as img:
self._image_data = img.read()

print "\t{0} added to sprite".format(self.filename)
print u"\t{0} added to sprite".format(self.filename)

@cached_property
def image(self):
Expand Down Expand Up @@ -225,7 +227,7 @@ def hash(self):
hash_list.append(value)

if sys.version < '3':
return hashlib.sha1(''.join(map(str, hash_list))).hexdigest()[:10]
return hashlib.sha1(''.join([h.encode('utf-8') if isinstance(h, unicode) else str(h) for h in hash_list])).hexdigest()[:10]
return hashlib.sha1(''.join(map(str, hash_list)).encode('utf-8')).hexdigest()[:10]

@cached_property
Expand Down Expand Up @@ -258,11 +260,12 @@ def _locate_images(self):
"""
extensions = '|'.join(self.valid_extensions)
extension_re = re.compile('.+\.(%s)$' % extensions, re.IGNORECASE)
files = sorted(os.listdir(self.path))

images = []
for root, dirs, files in os.walk(self.path, followlinks=self.config['follow_links']):
for filename in sorted(files):
# normalize different unicode representations, see https://stackoverflow.com/a/33647372/193886
filename = unicodedata.normalize('NFC', filename)
if not filename.startswith('.') and extension_re.match(filename):
images.append(Image(path=os.path.join(root, filename), config=self.config))
if not self.config['recursive']:
Expand Down
2 changes: 1 addition & 1 deletion glue/formats/css.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def apply_cachebuster(path):
def generate_css_name(self, filename):
filename = filename.rsplit('.', 1)[0]
separator = self.sprite.config['css_separator']
namespace = [re.sub(r'[^\w\-_]', '', filename)]
namespace = [re.sub(r'[^\w\-_]', '', filename, flags=re.UNICODE)]

# Add sprite namespace if required
if self.sprite.config['css_sprite_namespace']:
Expand Down
2 changes: 2 additions & 0 deletions glue/managers/watch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
import signal
import hashlib
import unicodedata


class WatchManager(object):
Expand All @@ -29,6 +30,7 @@ def generate_hash(self):
hash_list = []
for root, dirs, files in os.walk(self.options['source']):
for f in sorted([f for f in files if not f.startswith('.')]):
f = unicodedata.normalize('NFC', f)
hash_list.append(os.path.join(root, f))
hash_list.append(str(os.path.getmtime(os.path.join(root, f))))
hash_list = ''.join(hash_list)
Expand Down
27 changes: 27 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
import os
import sys
import json
Expand Down Expand Up @@ -205,6 +206,31 @@ def test_output(self):
u'width': u'64px',
u'height': u'64px'})

def test_unicode_input_output(self):
self.create_image(u"simple/redöåä.png", RED)
self.create_image(u"simple/blueöåä.png", BLUE)
code = self.call("glue simple output")
self.assertEqual(code, 0)

self.assertExists("output/simple.png")
self.assertExists("output/simple.css")
self.assertColor("output/simple.png", RED, ((0, 0), (63, 63)))
self.assertColor("output/simple.png", BLUE, ((64, 0), (127, 63)))

self.assertCSS(u"output/simple.css", u'.sprite-simple-redöåä',
{u'background-image': u"url(simple.png)",
u'background-repeat': u'no-repeat',
u'background-position': u'0 0',
u'width': u'64px',
u'height': u'64px'})

self.assertCSS(u"output/simple.css", u'.sprite-simple-blueöåä',
{u'background-image': u"url(simple.png)",
u'background-repeat': u'no-repeat',
u'background-position': u'-64px 0',
u'width': u'64px',
u'height': u'64px'})

def test_quiet(self):
self.create_image("simple/red.png", RED)
self.create_image("simple/blue.png", BLUE)
Expand Down Expand Up @@ -1801,5 +1827,6 @@ def test_caat_ratios(self):
data = json.loads(f.read())
assert isinstance(data['sprites'], dict)


if __name__ == '__main__':
unittest.main()