Drop dependency on node.js for compiling coffeescript

This commit is contained in:
Kovid Goyal 2012-01-07 11:35:35 +05:30
parent 143025bb82
commit 0312261cc5
4 changed files with 84 additions and 7 deletions

View File

@ -15,6 +15,7 @@ resources/scripts.pickle
resources/ebook-convert-complete.pickle resources/ebook-convert-complete.pickle
resources/builtin_recipes.xml resources/builtin_recipes.xml
resources/builtin_recipes.zip resources/builtin_recipes.zip
resources/coffee-script.js.bz2
resources/template-functions.json resources/template-functions.json
resources/display/*.js resources/display/*.js
setup/installer/windows/calibre/build.log setup/installer/windows/calibre/build.log

View File

@ -10,15 +10,68 @@ __docformat__ = 'restructuredtext en'
''' '''
Utilities to help with developing coffeescript based apps Utilities to help with developing coffeescript based apps
''' '''
import time, SimpleHTTPServer, SocketServer, os, subprocess import time, SimpleHTTPServer, SocketServer, os, bz2, sys
from io import BytesIO from io import BytesIO
from PyQt4.QtWebKit import QWebPage
try:
from calibre.gui2 import must_use_qt
must_use_qt
except ImportError:
import init_calibre
init_calibre
from calibre.gui2 import must_use_qt
from calibre import force_unicode
from calibre.gui2 import FunctionDispatcher
must_use_qt()
class Compiler(QWebPage): # {{{
def __init__(self):
QWebPage.__init__(self)
self.frame = self.mainFrame()
self.filename = self._src = ''
compiler = bz2.decompress(P('coffee-script.js.bz2', data=True))
self.frame.evaluateJavaScript(compiler)
self.frame.addToJavaScriptWindowObject("cs_compiler", self)
self.dispatcher = FunctionDispatcher(self.__evalcs, parent=self)
self.errors = []
def shouldInterruptJavaScript(self):
return True
def javaScriptConsoleMessage(self, msg, lineno, sourceid):
sourceid = sourceid or self.filename or '<script>'
self.errors.append('%s:%s'%(sourceid, msg))
def __evalcs(self, raw, filename=None):
# This method is NOT thread safe
self.filename = filename
self.setProperty('source', raw)
self.errors = []
res = self.frame.evaluateJavaScript('''
raw = document.getElementById("raw");
raw = cs_compiler.source;
CoffeeScript.compile(raw);
''')
ans = ''
if res.type() == res.String:
ans = unicode(res.toString())
return ans, self.errors
def __call__(self, raw, filename=None):
raw = force_unicode(raw)
return self.dispatcher(raw, filename=filename)
# }}}
# FAVICON {{{ # FAVICON {{{
FAVICON = \ FAVICON = \
b'\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x01\x00 \x00\x9c\x04\x00\x00\x16\x00\x00\x00\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00(-\x0fS\x00\x00\x02IPLTE\x00\x00\x00888\x0c\x0c\x0c\x12\x12\x12\x1b\x1b\x1b\x16\x16\x16I\x00\x00J\x00\x00\x17\x17\x17\x14\x14\x14\x10\x10\x10$$$""" ##\x19\x1c\x1c\x02\x07\x07\x81\x06\x0eT\t\x0e\x08\x11\x10\x0e\x0e\x0e\x1e\x1e\x1e\t\t\t\x06\x06\x06\xae\x1c\x1d\xa5\x1d\x1e\x8b\x18\x19\x87\x15\x15,\x16\x16!\x14\x15KJJ\x1f\x1f\x1f\x1d\x1d\x1d333\x05\x05\x05\x04\x04\x04"\x02\x03\x0f\x00\x02\x13\x13\x13\x0f\x0f\x0f\x0c\x0c\x0c\x0c\x0c\x0c\x11\x11\x11\x11\x11\x11\x0f\x10\x10"\n\nR\x00\x00L\x00\x00\x1c\r\r\x12\x13\x13\x13\x16\x16$\x13\x136\x04\x07!\x1a\x14)\x1c\x118\x04\x04\x1f\x15\x15\x10\x14\x14\x1e\x1f#74\x1e\x7fn\x1c5.\x172+\x11|j\x12<:\'\x1e\x1f#\r\x14$_S\x11\x8a|.[N\x05UJ\x0e\x03\x0b\x1f$\n\x0cO\r\x0bL\t\x080\x13\x15\x07\x07\x07\x13\x1f\x1fd\x12\x17\xd2\x05\nl\x15\x1b\n\x1b\x1a$##\x08\x08\x08\x12\x14\x14*\x17\x19X\x1a\x1fw %\'\x16\x18\x12\x13\x13\x05\x05\x05\n\n\n\x00\x0e\r\x91\x17\x1c\\"#l#%\x9a\x17\x1d\x00\t\t\x08\x08\x08\xa4$%\xc5"#\xbb \xa1#$\x8a&\'\xbe&&\xbc))\x83\x1d\x1d$\x18\x18w\x1e\x1fp\x1f\x1f\x1d\x13\x14\x1d\x1e\x1e8\x15\x18!\x07\x08)\t\n=\x14\x17\x19\x1b\x1b\x16\x16\x16\x15\x16\x16$\x0c\x0e9\x02\x04[\x00\x01T\x00\x01=\x02\x04+\x1c\x1d%%%\'\'\'\x01\x01\x01\x10\x10\x10\x16\x16\x16\x00\x05\x02H\x00\x04S\x01\x02Y\x05\x05F\x02\x03C\x00\x01I\x00\x03\n\x16\x15%%%###\x00\x00\x00\x08\x08\x08\n\n\n!\x01\x023\x08\t\x1e\x04\x04\x0e\x00\x00\x16\x16\x16\x1a\x1a\x1aXWR\x18\x17\x12R+#JG:-)\x1c9\x10\x0b\xd2\x03\x07\xdd4(`M7[E1\xd8\x1d\x14\xb2\x14\x14\xf1`ak?@`,-\xe1\x1b\x1c\x9c\x15\x15\xa3\r\r\xe1!"\xcb,,\xd623\xdc\x16\x16\x99\r\rq\n\n<\x0f\x0f\xa4\x0e\x0e\x92\x13\x131\x11\x11\x92\x08\x08x\x07\x07<\x08\x08\x9c\x03\x03~\x06\x06\x1e\x0b\x0b\x83\n\n\x89\x04\x04\xb3\x00\x00\xb5\x02\x02\xb7\x03\x03\x9b\x01\x01\x81\x08\x08w\x00\x00\x86\x02\x02\x85\x02\x02r\x01\x01[\x02\x02N\x02\x02WT>\xb4\x00\x00\x00\x94tRNS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x06\t\x112@\n\x10A*\x1al:22>h\x12%r\x90\xe8\xe5\x86v\x1b\x1a\xad\xf9\xf8\xa5\x120\xd5\xc5\x1e\x03.\xc5\xfc\xa8"\x02\x06E[\xd8\xcc[B\x04\x04\x11(\xe4\xde$\x16\x030\xeb\xe6\'#\xe2\xda\x1b:\xd3\xd7-Q|\xf7\xf3\x90U\x11p*\x9f\xfe\xfd\x96?m\t\x03=.\x01\x15\x83\xc7\xc6|\x12\x0665\x01\x01\n\x03\x11\x10\x02\x02\nEu\xb9r\x00\x00\x00\tpHYs\x00\x00\x00H\x00\x00\x00H\x00F\xc9k>\x00\x00\x00\xf7IDAT\x18\xd3c````T\xd7`b``\xd6\xd4ba\x80\x00Vm\x1d]6v=}\x03\x0e\xa8\x00\xa7\xa1\x91\xb1\x89\xa9\x99\xb9\x05\x17T\x80\xdb\xd2\xca\xda\xc6\xd6\xce\xde\x81\x07*\xc0\xeb\xe8\xe4<e\xaa\x8b\xab\x1b\x1f\x84\xcf/\xe0\xee1m\xfa\x8c\x99\x9e^\x82B \xbe\xb0\xb7\x8f\xef\xac\xd9s\xe6\xce\xf3\xf3\x0f\x08\x14a`\x10\r\n\x0e\t\x9d\xbf`\xe1\xa2\xc5K\xc2\xc2#"E\x19D\xa3\xa2cb\x97.[\xbeb\xe5\xaa\xb8\xf8\x84D1\xa0\x1e\xf1\xa4\xe4\xd5k\xd6\xae[\xbf!%U\x02l\xa8dZ\xfa\xc6M\x9b\xb7l\xdd\x96\x91)\x05\x16\x90\xce\xca\xde\xbec\xe7\xae\xdd{rre\xc0\x02\xb2y\xf9\x05{\xf7\xed?PXT,\x07\xe2\xcb\x97\x94\x96\x95W\x1c<TYU]S\xab\xc0\xc0\xa0XW\xdf\xd0\xd8\xd4\xdc\xd2\xda\xd6\xde\xd1\xd9\xd5\xad\xc4\xa0\xd8\xd3\xdb\xa3\xa4\xdc\xd7?a\xa2\x8a\xea\xa4\xc9j\x8a\x00W\xf7J\xfe\xc9Y\x97\xae\x00\x00\x00%tEXtdate:create\x002011-11-06T14:56:51+05:00t\xf3K\xf2\x00\x00\x00%tEXtdate:modify\x002011-11-06T14:56:51+05:00\x05\xae\xf3N\x00\x00\x00\x00IEND\xaeB`\x82' b'\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x01\x00 \x00\x9c\x04\x00\x00\x16\x00\x00\x00\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00(-\x0fS\x00\x00\x02IPLTE\x00\x00\x00888\x0c\x0c\x0c\x12\x12\x12\x1b\x1b\x1b\x16\x16\x16I\x00\x00J\x00\x00\x17\x17\x17\x14\x14\x14\x10\x10\x10$$$""" ##\x19\x1c\x1c\x02\x07\x07\x81\x06\x0eT\t\x0e\x08\x11\x10\x0e\x0e\x0e\x1e\x1e\x1e\t\t\t\x06\x06\x06\xae\x1c\x1d\xa5\x1d\x1e\x8b\x18\x19\x87\x15\x15,\x16\x16!\x14\x15KJJ\x1f\x1f\x1f\x1d\x1d\x1d333\x05\x05\x05\x04\x04\x04"\x02\x03\x0f\x00\x02\x13\x13\x13\x0f\x0f\x0f\x0c\x0c\x0c\x0c\x0c\x0c\x11\x11\x11\x11\x11\x11\x0f\x10\x10"\n\nR\x00\x00L\x00\x00\x1c\r\r\x12\x13\x13\x13\x16\x16$\x13\x136\x04\x07!\x1a\x14)\x1c\x118\x04\x04\x1f\x15\x15\x10\x14\x14\x1e\x1f#74\x1e\x7fn\x1c5.\x172+\x11|j\x12<:\'\x1e\x1f#\r\x14$_S\x11\x8a|.[N\x05UJ\x0e\x03\x0b\x1f$\n\x0cO\r\x0bL\t\x080\x13\x15\x07\x07\x07\x13\x1f\x1fd\x12\x17\xd2\x05\nl\x15\x1b\n\x1b\x1a$##\x08\x08\x08\x12\x14\x14*\x17\x19X\x1a\x1fw %\'\x16\x18\x12\x13\x13\x05\x05\x05\n\n\n\x00\x0e\r\x91\x17\x1c\\"#l#%\x9a\x17\x1d\x00\t\t\x08\x08\x08\xa4$%\xc5"#\xbb \xa1#$\x8a&\'\xbe&&\xbc))\x83\x1d\x1d$\x18\x18w\x1e\x1fp\x1f\x1f\x1d\x13\x14\x1d\x1e\x1e8\x15\x18!\x07\x08)\t\n=\x14\x17\x19\x1b\x1b\x16\x16\x16\x15\x16\x16$\x0c\x0e9\x02\x04[\x00\x01T\x00\x01=\x02\x04+\x1c\x1d%%%\'\'\'\x01\x01\x01\x10\x10\x10\x16\x16\x16\x00\x05\x02H\x00\x04S\x01\x02Y\x05\x05F\x02\x03C\x00\x01I\x00\x03\n\x16\x15%%%###\x00\x00\x00\x08\x08\x08\n\n\n!\x01\x023\x08\t\x1e\x04\x04\x0e\x00\x00\x16\x16\x16\x1a\x1a\x1aXWR\x18\x17\x12R+#JG:-)\x1c9\x10\x0b\xd2\x03\x07\xdd4(`M7[E1\xd8\x1d\x14\xb2\x14\x14\xf1`ak?@`,-\xe1\x1b\x1c\x9c\x15\x15\xa3\r\r\xe1!"\xcb,,\xd623\xdc\x16\x16\x99\r\rq\n\n<\x0f\x0f\xa4\x0e\x0e\x92\x13\x131\x11\x11\x92\x08\x08x\x07\x07<\x08\x08\x9c\x03\x03~\x06\x06\x1e\x0b\x0b\x83\n\n\x89\x04\x04\xb3\x00\x00\xb5\x02\x02\xb7\x03\x03\x9b\x01\x01\x81\x08\x08w\x00\x00\x86\x02\x02\x85\x02\x02r\x01\x01[\x02\x02N\x02\x02WT>\xb4\x00\x00\x00\x94tRNS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x06\t\x112@\n\x10A*\x1al:22>h\x12%r\x90\xe8\xe5\x86v\x1b\x1a\xad\xf9\xf8\xa5\x120\xd5\xc5\x1e\x03.\xc5\xfc\xa8"\x02\x06E[\xd8\xcc[B\x04\x04\x11(\xe4\xde$\x16\x030\xeb\xe6\'#\xe2\xda\x1b:\xd3\xd7-Q|\xf7\xf3\x90U\x11p*\x9f\xfe\xfd\x96?m\t\x03=.\x01\x15\x83\xc7\xc6|\x12\x0665\x01\x01\n\x03\x11\x10\x02\x02\nEu\xb9r\x00\x00\x00\tpHYs\x00\x00\x00H\x00\x00\x00H\x00F\xc9k>\x00\x00\x00\xf7IDAT\x18\xd3c````T\xd7`b``\xd6\xd4ba\x80\x00Vm\x1d]6v=}\x03\x0e\xa8\x00\xa7\xa1\x91\xb1\x89\xa9\x99\xb9\x05\x17T\x80\xdb\xd2\xca\xda\xc6\xd6\xce\xde\x81\x07*\xc0\xeb\xe8\xe4<e\xaa\x8b\xab\x1b\x1f\x84\xcf/\xe0\xee1m\xfa\x8c\x99\x9e^\x82B \xbe\xb0\xb7\x8f\xef\xac\xd9s\xe6\xce\xf3\xf3\x0f\x08\x14a`\x10\r\n\x0e\t\x9d\xbf`\xe1\xa2\xc5K\xc2\xc2#"E\x19D\xa3\xa2cb\x97.[\xbeb\xe5\xaa\xb8\xf8\x84D1\xa0\x1e\xf1\xa4\xe4\xd5k\xd6\xae[\xbf!%U\x02l\xa8dZ\xfa\xc6M\x9b\xb7l\xdd\x96\x91)\x05\x16\x90\xce\xca\xde\xbec\xe7\xae\xdd{rre\xc0\x02\xb2y\xf9\x05{\xf7\xed?PXT,\x07\xe2\xcb\x97\x94\x96\x95W\x1c<TYU]S\xab\xc0\xc0\xa0XW\xdf\xd0\xd8\xd4\xdc\xd2\xda\xd6\xde\xd1\xd9\xd5\xad\xc4\xa0\xd8\xd3\xdb\xa3\xa4\xdc\xd7?a\xa2\x8a\xea\xa4\xc9j\x8a\x00W\xf7J\xfe\xc9Y\x97\xae\x00\x00\x00%tEXtdate:create\x002011-11-06T14:56:51+05:00t\xf3K\xf2\x00\x00\x00%tEXtdate:modify\x002011-11-06T14:56:51+05:00\x05\xae\xf3N\x00\x00\x00\x00IEND\xaeB`\x82'
# }}} # }}}
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): # {{{
special_resources = {} special_resources = {}
compiled_cs = {} compiled_cs = {}
@ -67,9 +120,12 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
raw, mtime = self.compiled_cs.get(src, (None, 0)) raw, mtime = self.compiled_cs.get(src, (None, 0))
if self.newer(src, mtime): if self.newer(src, mtime):
mtime = time.time() mtime = time.time()
try: with open(src, 'rb') as f:
raw = subprocess.check_output(['coffee', '-c', '-p', src]) raw = f.read()
except: cs, errors = compile_coffeescript(raw)
for line in errors:
print(line, file=sys.stderr)
if not cs:
print('Compilation of %s failed'%src) print('Compilation of %s failed'%src)
cs = ''' cs = '''
// Compilation of coffeescript failed // Compilation of coffeescript failed
@ -90,4 +146,24 @@ def serve(resources={}, port=8000):
httpd.serve_forever() httpd.serve_forever()
except KeyboardInterrupt: except KeyboardInterrupt:
raise SystemExit(0) raise SystemExit(0)
# }}}
compile_coffeescript = Compiler()
def main():
import argparse
parser = argparse.ArgumentParser(description=
'Compile coffeescript to javascript and print to stdout. Errors '
'and warnings are printed to stderr.')
parser.add_argument('src', type=argparse.FileType('rb'),
metavar='path/to/script.coffee', help='The coffee script to compile. Use '
' - for stdin')
args = parser.parse_args()
ans, errors = compile_coffeescript(args.src.read(), filename=args.src.name)
for line in errors:
print(line, file=sys.stderr)
if ans:
print (ans.encode(sys.stdout.encoding or 'utf-8'))
if __name__ == '__main__':
main()

View File

@ -8,7 +8,6 @@ __docformat__ = 'restructuredtext en'
import os, locale, re, cStringIO, cPickle import os, locale, re, cStringIO, cPickle
from gettext import GNUTranslations, NullTranslations from gettext import GNUTranslations, NullTranslations
from zipfile import ZipFile
_available_translations = None _available_translations = None
@ -79,6 +78,7 @@ def set_translators():
buf = cStringIO.StringIO(buf.getvalue()) buf = cStringIO.StringIO(buf.getvalue())
if mpath is not None: if mpath is not None:
from zipfile import ZipFile
with ZipFile(P('localization/locales.zip', with ZipFile(P('localization/locales.zip',
allow_user_override=False), 'r') as zf: allow_user_override=False), 'r') as zf:
if buf is None: if buf is None: