123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #!/usr/bin/python2.7
- # Compresses the Blockscad files into a single javascript file.
- #
- '''
- Copyright (C) 2014-2015 H3XL, Inc
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- '''
- import errno, httplib, json, os, re, subprocess, sys, threading, urllib
- # Define the parameters for the POST request and encode them in
- # a URL-safe format.
- HEADER = ('// Do not edit this file; automatically generated by blockscad_build.py.\n'
- '"use strict";');
- class Gen_compressed(threading.Thread):
- """Generate a JavaScript file that contains all of Blockly's core and all
- required parts of Closure, compiled together.
- Uses the Closure Compiler's online API.
- Runs in a separate thread.
- """
- def __init__(self, search_paths):
- threading.Thread.__init__(self)
- self.search_paths = search_paths
- def run(self):
- self.gen_blockscad()
- self.gen_viewer()
- def gen_blockscad(self):
- target_filename = 'blockscad_compressed.js'
- # Define the parameters for the POST request.
- params = [
- ('compilation_level', 'SIMPLE_OPTIMIZATIONS'),
- ('output_format', 'json'),
- ('language', 'ECMASCRIPT5'),
- ('output_info', 'compiled_code'),
- ('output_info', 'warnings'),
- ('output_info', 'errors'),
- ('output_info', 'statistics'),
- ]
- # Read in all the source files.
- filenames = ['bsPage.js','storage.js','utils.js','blockscad.js',
- 'text.js','lightgl.js','toolbox.js','deflate.js', 'stl.js']
- for filename in filenames:
- f = open(filename)
- print filename
- params.append(('js_code', ''.join(f.readlines())))
- f.close()
- self.do_compile(params, target_filename, filenames, '')
- def gen_viewer(self):
- target_filename = 'viewer_compressed.js'
- # Define the parameters for the POST request.
- params = [
- ('compilation_level', 'SIMPLE_OPTIMIZATIONS'),
- ('output_format', 'json'),
- ('language', 'ECMASCRIPT5'),
- ('output_info', 'compiled_code'),
- ('output_info', 'warnings'),
- ('output_info', 'errors'),
- ('output_info', 'statistics'),
- ]
- # Read in all the source files.
- filenames = ['viewer.js', 'csg.js', 'formats.js']
- for filename in filenames:
- f = open(filename)
- print filename
- params.append(('js_code', ''.join(f.readlines())))
- f.close()
- self.do_compile(params, target_filename, filenames, '')
- def do_compile(self, params, target_filename, filenames, remove):
- # Send the request to Google.
- headers = {'Content-type': 'application/x-www-form-urlencoded'}
- conn = httplib.HTTPConnection('closure-compiler.appspot.com')
- conn.request('POST', '/compile', urllib.urlencode(params), headers)
- response = conn.getresponse()
- json_str = response.read()
- conn.close()
- # Parse the JSON response.
- json_data = json.loads(json_str)
- def file_lookup(name):
- if not name.startswith('Input_'):
- return '???'
- n = int(name[6:])
- return filenames[n]
- if json_data.has_key('serverErrors'):
- errors = json_data['serverErrors']
- for error in errors:
- print('SERVER ERROR: %s' % target_filename)
- print(error['error'])
- elif json_data.has_key('errors'):
- errors = json_data['errors']
- for error in errors:
- print('FATAL ERROR')
- print(error['error'])
- if error['file']:
- print('%s at line %d:' % (
- file_lookup(error['file']), error['lineno']))
- print(error['line'])
- print((' ' * error['charno']) + '^')
- sys.exit(1)
- else:
- if json_data.has_key('warnings'):
- warnings = json_data['warnings']
- for warning in warnings:
- print('WARNING')
- print(warning['warning'])
- if warning['file']:
- print('%s at line %d:' % (
- file_lookup(warning['file']), warning['lineno']))
- print(warning['line'])
- print((' ' * warning['charno']) + '^')
- print()
- if not json_data.has_key('compiledCode'):
- print('FATAL ERROR: Compiler did not return compiledCode.')
- sys.exit(1)
- code = HEADER + '\n' + json_data['compiledCode']
- # code = code.replace(remove, '')
- stats = json_data['statistics']
- original_b = stats['originalSize']
- compressed_b = stats['compressedSize']
- if original_b > 0 and compressed_b > 0:
- f = open(target_filename, 'w')
- f.write(code)
- f.close()
- original_kb = int(original_b / 1024 + 0.5)
- compressed_kb = int(compressed_b / 1024 + 0.5)
- ratio = int(float(compressed_b) / float(original_b) * 100 + 0.5)
- print('SUCCESS: ' + target_filename)
- print('Size changed from %d KB to %d KB (%d%%).' % (
- original_kb, compressed_kb, ratio))
- else:
- print('UNKNOWN ERROR')
- def file_lookup(name):
- if not name.startswith('Input_'):
- return '???'
- n = int(name[6:])
- return filenames[n]
- if __name__ == '__main__':
- Gen_compressed('').start()
|