def compiler(): c = getattr(tls, 'compiler', None) if c is None: c = tls.compiler = Context() c.eval('exports = {}; sha1sum = Duktape.sha1sum;', noreturn=True) buf = BytesIO() decompress(P(COMPILER_PATH, data=True, allow_user_override=False), buf) c.eval(buf.getvalue(), fname=COMPILER_PATH, noreturn=True) return c
def get_mathjax_manifest(tdir=None): global mathjax_manifest with mathjax_lock: if mathjax_manifest is None: mathjax_manifest = {} f = decompress(P('content-server/mathjax.zip.xz', data=True, allow_user_override=False)) f.seek(0) tdir = os.path.join(tdir, 'mathjax') os.mkdir(tdir) zf = ZipFile(f) zf.extractall(tdir) mathjax_manifest['etag'] = type('')(zf.comment) mathjax_manifest['files'] = {type('')(zi.filename):zi.file_size for zi in zf.infolist()} zf.close(), f.close() return mathjax_manifest
def commit_changes(): dt.seek(0) f = decompress(dt) f.seek(0) remove_icon_theme() install_icon_theme(theme, f)
def compiler(): from lzma.xz import decompress ans = getattr(compiler, 'ans', None) if ans is not None: return ans from calibre import walk from calibre.gui2 import must_use_qt from calibre.gui2.webengine import secure_webengine from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineScript from PyQt5.Qt import QApplication, QEventLoop must_use_qt() buf = BytesIO() decompress(P(COMPILER_PATH, data=True, allow_user_override=False), buf) base = base_dir() rapydscript_dir = os.path.join(base, 'src', 'pyj') cache_path = os.path.join(module_cache_dir(), 'embedded-compiler-write-cache.json') def create_vfs(): ans = {} for x in walk(rapydscript_dir): if x.endswith('.pyj'): r = os.path.relpath(x, rapydscript_dir).replace('\\', '/') with open(x, 'rb') as f: ans['__stdlib__/' + r] = f.read().decode('utf-8') return ans def vfs_script(): try: with open(cache_path, 'rb') as f: write_cache = f.read().decode('utf-8') except Exception: write_cache = '{}' return ''' (function() { "use strict"; var vfs = VFS; function read_file_sync(name) { var ans = vfs[name]; if (typeof ans === "string") return ans; ans = write_cache[name]; if (typeof ans === "string") return ans; return null; } function write_file_sync(name, data) { write_cache[name] = data; } RapydScript.virtual_file_system = { 'read_file_sync': read_file_sync, 'write_file_sync': write_file_sync }; window.compiler = RapydScript.create_embedded_compiler(); document.title = 'compiler initialized'; })(); '''.replace('VFS', json.dumps(create_vfs()) + ';\n' + 'window.write_cache = ' + write_cache, 1) def create_script(src, name): s = QWebEngineScript() s.setName(name) s.setInjectionPoint(QWebEngineScript.DocumentReady) s.setWorldId(QWebEngineScript.ApplicationWorld) s.setRunsOnSubFrames(True) s.setSourceCode(src) return s class Compiler(QWebEnginePage): def __init__(self): QWebEnginePage.__init__(self) self.errors = [] secure_webengine(self) script = buf.getvalue().decode('utf-8') script += '\n\n;;\n\n' + vfs_script() self.scripts().insert(create_script(script, 'rapydscript.js')) self.setHtml('<p>initialize') while self.title() != 'compiler initialized': self.spin_loop() def spin_loop(self): QApplication.instance().processEvents(QEventLoop.ExcludeUserInputEvents) def javaScriptConsoleMessage(self, level, msg, line_num, source_id): if level: self.errors.append(msg) else: print('{}:{}:{}'.format(source_id, line_num, msg)) def __call__(self, src, options): self.compiler_result = null = object() self.errors = [] self.working = True options['basedir'] = '__stdlib__' options['write_name'] = True options['keep_docstrings'] = False src = 'var js = window.compiler.compile({}, {}); [js, window.write_cache]'.format(*map(json.dumps, (src, options))) self.runJavaScript(src, QWebEngineScript.ApplicationWorld, self.compilation_done) while self.working: self.spin_loop() if self.compiler_result is null or self.compiler_result is None: raise CompileFailure('Failed to compile rapydscript code with error: ' + '\n'.join(self.errors)) write_cache = self.compiler_result[1] with open(cache_path, 'wb') as f: f.write(as_bytes(json.dumps(write_cache))) return self.compiler_result[0] def eval(self, js): self.compiler_result = null = object() self.errors = [] self.working = True self.runJavaScript(js, QWebEngineScript.ApplicationWorld, self.compilation_done) while self.working: self.spin_loop() if self.compiler_result is null: raise CompileFailure('Failed to eval JS with error: ' + '\n'.join(self.errors)) return self.compiler_result def compilation_done(self, js): self.working = False self.compiler_result = js compiler.ans = Compiler() return compiler.ans