diff --git a/gluon/contrib/minify/cssmin.py b/gluon/contrib/minify/cssmin.py index f9ed89f9..15d97a0b 100644 --- a/gluon/contrib/minify/cssmin.py +++ b/gluon/contrib/minify/cssmin.py @@ -10,8 +10,11 @@ Original author: Zachary Voase Modified for inclusion into web2py by: Ross Peoples """ +try: + from StringIO import StringIO +except ImportError: + from io import StringIO -from StringIO import StringIO # The pure-Python StringIO supports unicode. import re diff --git a/gluon/contrib/minify/minify.py b/gluon/contrib/minify/minify.py index 8749acd7..134cc664 100644 --- a/gluon/contrib/minify/minify.py +++ b/gluon/contrib/minify/minify.py @@ -8,30 +8,40 @@ Created by: Ross Peoples Modified by: Massimo Di Pierro """ -import cssmin -import jsmin +from . import cssmin +from . import jsmin import os import hashlib import re +import sys +PY2 = sys.version_info[0] == 2 +if PY2: + hashlib_md5 = hashlib.md5 +else: + hashlib_md5 = lambda s: hashlib.md5(bytes(s, 'utf8')) + +def open_py23(filename, mode): + if PY2: + f = open(filename, mode + 'b') + else: + f = open(filename, mode, encoding="utf8") + return f def read_binary_file(filename): - f = open(filename, 'rb') + f = open_py23(filename, 'r') data = f.read() f.close() return data - def write_binary_file(filename, data): - f = open(filename, 'wb') + f = open_py23(filename, 'w') f.write(data) f.close() - def fix_links(css, static_path): return re.sub(r'url\((["\'])\.\./', 'url(\\1' + static_path, css) - def minify(files, path_info, folder, optimize_css, optimize_js, ignore_concat=[], ignore_minify=['/jquery.js', '/anytime.js']): @@ -109,7 +119,7 @@ def minify(files, path_info, folder, optimize_css, optimize_js, js.append(contents) else: js.append(filename) - dest_key = hashlib.md5(repr(processed)).hexdigest() + dest_key = hashlib_md5(repr(processed)).hexdigest() if css and concat_css: css = '\n\n'.join(contents for contents in css) if not inline_css: diff --git a/gluon/globals.py b/gluon/globals.py index 9d17fae6..5b963f0a 100644 --- a/gluon/globals.py +++ b/gluon/globals.py @@ -13,7 +13,7 @@ Contains the classes for the global used variables: - Session """ -from gluon._compat import pickle, StringIO, copyreg, Cookie, urlparse, PY2, iteritems, to_unicode, to_native, unicodeT, long +from gluon._compat import pickle, StringIO, copyreg, Cookie, urlparse, PY2, iteritems, to_unicode, to_native, unicodeT, long, hashlib_md5 from gluon.storage import Storage, List from gluon.streamer import streamer, stream_file_or_304_or_206, DEFAULT_CHUNK_SIZE from gluon.contenttype import contenttype @@ -457,7 +457,6 @@ class Response(Storage): self.write(s, escape=False) def include_files(self, extensions=None): - """ Includes files (usually in the head). Can minify and cache local files @@ -484,8 +483,7 @@ class Response(Storage): if have_minify and ((self.optimize_css and has_css) or (self.optimize_js and has_js)): # cache for 5 minutes by default - key = hashlib.md5(repr(files)).hexdigest() - + key = hashlib_md5(repr(files)).hexdigest() cache = self.cache_includes or (current.cache.ram, 60 * 5) def call_minify(files=files): @@ -523,6 +521,7 @@ class Response(Storage): tmpl = template_mapping.get(f) if tmpl: s.append(tmpl % item[1]) + self.write(''.join(s), escape=False) def stream(self, diff --git a/gluon/tests/test_appadmin.py b/gluon/tests/test_appadmin.py index 41613152..22b1d05a 100644 --- a/gluon/tests/test_appadmin.py +++ b/gluon/tests/test_appadmin.py @@ -17,6 +17,7 @@ from gluon import fileutils from gluon.dal import DAL, Field, Table from gluon.http import HTTP from gluon.fileutils import open_file +from gluon.cache import CacheInRam DEFAULT_URI = os.getenv('DB', 'sqlite:memory') @@ -104,6 +105,21 @@ class TestAppAdmin(unittest.TestCase): self._test_index() remove_compiled_application(appname_path) + def test_index_minify(self): + # test for gluon/contrib/minify + self.env['response'].optimize_css = 'concat|minify' + self.env['response'].optimize_js = 'concat|minify' + self.env['current'].cache = Storage({'ram':CacheInRam()}) + appname_path = os.path.join(os.getcwd(), 'applications', 'welcome') + self._test_index() + file_l = os.listdir(os.path.join(appname_path, 'static', 'temp')) + file_l.sort() + self.assertTrue(len(file_l) == 2) + self.assertEqual(file_l[0][0:10], 'compressed') + self.assertEqual(file_l[1][0:10], 'compressed') + self.assertEqual(file_l[0][-3:], 'css') + self.assertEqual(file_l[1][-2:], 'js') + def test_select(self): request = self.env['request'] request.args = List(['db'])