seitime-frappe/py/build/bundle.py
2012-01-09 16:00:49 +05:30

113 lines
2.6 KiB
Python

from minify import JavascriptMinify
class Bundle:
"""
Concatenate, compress and mix (if required) js+css files from build.json
"""
def concat(self, filelist, outfile=None, is_js=False):
"""
Concat css and js files into a bundle
"""
import os
from cStringIO import StringIO
from build import verbose
out_type = outfile and outfile.split('.')[-1] or 'js'
temp = StringIO()
for f in filelist:
if verbose:
print f + ' | ' + str(int(os.path.getsize(f)/1024)) + 'k'
fh = open(f)
# get file type
ftype = f.split('.')[-1]
# special concat (css inside js)
if is_js and ftype =='css':
css = fh.read()
data = "\nwn.assets.handler.css('%s');\n" % css.replace("'", "\\'").replace('\n', '\\\n')
# plain concat
else:
data = fh.read() + '\n'
fh.close()
temp.write(data)
if outfile:
f = open(outfile, 'w')
f.write(temp.getvalue())
f.close()
if verbose: print 'Wrote %s' % outfile
return temp
def minify(self, in_files, outfile, concat=False):
"""
Compress in_files into outfile,
give some stats
"""
from build import verbose
import os
# concat everything into temp
outtype = outfile.split('.')[-1]
temp = self.concat(in_files, is_js=True)
out = open(outfile, 'w')
org_size = len(temp.getvalue())
temp.seek(0)
# minify
jsm = JavascriptMinify()
jsm.minify(temp, out)
out.close()
new_size = os.path.getsize(outfile)
if verbose:
print '=> %s' % outfile
print 'Original: %.2f kB' % (org_size / 1024.0)
print 'Compressed: %.2f kB' % (new_size / 1024.0)
print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100)
def make(self, bpath):
"""
Build (stitch + compress) the file defined in build.json
"""
import os, sys, json
from build import no_minify
# open the build.json file and read
# the dict
print "making %s ..." % bpath
with open(bpath, 'r') as bfile:
bdata = json.loads(bfile.read())
path = os.path.dirname(bpath)
for outfile in bdata:
prefix, fname = False, outfile
# check if there is a prefix
if ':' in outfile:
prefix, fname = outfile.split(':')
# build the file list relative to the main folder
fl = [os.path.relpath(os.path.join(path, f), os.curdir) for f in bdata[outfile]]
# js files are minified by default unless explicitly
# mentioned in the prefix.
# some files may not work if minified (known jsmin bug)
if fname.split('.')[-1]=='js' and prefix!='concat' and not no_minify:
self.minify(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
else:
self.concat(fl, os.path.relpath(os.path.join(path, fname), os.curdir))