%PDF- %PDF-
| Direktori : /usr/lib/calibre/calibre/ebooks/ |
| Current File : //usr/lib/calibre/calibre/ebooks/render_html.py |
#!/usr/bin/env python3
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
import os
import sys
from qt.core import (
QApplication, QMarginsF, QPageLayout, QPageSize, Qt, QTimer, QUrl
)
from qt.webengine import QWebEnginePage, QWebEngineScript
from calibre.ebooks.metadata.pdf import page_images
from calibre.gui2 import must_use_qt
from calibre.gui2.webengine import secure_webengine
from calibre.utils.filenames import atomic_rename
from calibre.utils.monotonic import monotonic
LOAD_TIMEOUT = 20
PRINT_TIMEOUT = 10
class Render(QWebEnginePage):
def __init__(self):
QWebEnginePage.__init__(self)
secure_webengine(self)
self.printing_started = False
self.loadFinished.connect(self.load_finished, type=Qt.ConnectionType.QueuedConnection)
self.pdfPrintingFinished.connect(self.print_finished)
self.hang_timer = t = QTimer(self)
t.setInterval(500)
t.timeout.connect(self.hang_check)
def load_finished(self, ok):
if ok:
self.runJavaScript('''
var ans = {};
var meta = document.querySelector('meta[name=calibre-html-render-data]');
if (meta) {
try {
ans = JSON.parse(meta.content);
console.log(ans);
} catch {}
}
ans;
''', QWebEngineScript.ScriptWorldId.ApplicationWorld, self.start_print)
else:
self.hang_timer.stop()
QApplication.instance().exit(1)
def javaScriptConsoleMessage(self, level, msg, linenumber, source_id):
pass
def start_load(self, path_to_html):
self.load(QUrl.fromLocalFile(path_to_html))
self.start_time = monotonic()
self.hang_timer.start()
def hang_check(self):
if self.printing_started:
if monotonic() - self.start_time > PRINT_TIMEOUT:
self.hang_timer.stop()
QApplication.instance().exit(4)
else:
if monotonic() - self.start_time > LOAD_TIMEOUT:
self.hang_timer.stop()
QApplication.instance().exit(3)
def start_print(self, data):
margins = QMarginsF(0, 0, 0, 0)
page_size = QPageSize(QPageSize.PageSizeId.A4)
if isinstance(data, dict):
try:
if 'margins' in data:
margins = QMarginsF(*data['margins'])
if 'size' in data:
sz = data['size']
if type(getattr(QPageSize, sz, None)) is type(QPageSize.PageSizeId.A4): # noqa
page_size = QPageSize(getattr(QPageSize, sz))
else:
from calibre.ebooks.pdf.image_writer import parse_pdf_page_size
ps = parse_pdf_page_size(sz, data.get('unit', 'inch'))
if ps is not None:
page_size = ps
except Exception:
pass
page_layout = QPageLayout(page_size, QPageLayout.Orientation.Portrait, margins)
self.printToPdf('rendered.pdf', page_layout)
self.printing_started = True
self.start_time = monotonic()
def print_finished(self, path, ok):
QApplication.instance().exit(0 if ok else 2)
self.hang_timer.stop()
def main(path_to_html, tdir, image_format='jpeg'):
if image_format not in ('jpeg', 'png'):
raise ValueError('Image format must be either jpeg or png')
must_use_qt()
path_to_html = os.path.abspath(path_to_html)
os.chdir(tdir)
renderer = Render()
renderer.start_load(path_to_html)
ret = QApplication.instance().exec()
if ret == 0:
page_images('rendered.pdf', image_format=image_format)
ext = {'jpeg': 'jpg'}.get(image_format, image_format)
atomic_rename('page-images-1.' + ext, 'rendered.' + image_format)
return ret == 0
if __name__ == '__main__':
if not main(sys.argv[-1], '.'):
raise SystemExit('Failed to render HTML')