Ensure rendering of HTML does not hang

This commit is contained in:
Kovid Goyal 2019-06-27 05:44:52 +05:30
parent 4c365f7a31
commit 055c2a9f2f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -7,12 +7,18 @@ from __future__ import absolute_import, division, print_function, unicode_litera
import os
import sys
from PyQt5.Qt import QApplication, QMarginsF, QPageLayout, QPageSize, Qt, QUrl
from PyQt5.Qt import (
QApplication, QMarginsF, QPageLayout, QPageSize, Qt, QTimer, QUrl
)
from PyQt5.QtWebEngineWidgets import QWebEnginePage
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.monotonic import monotonic
LOAD_TIMEOUT = 20
PRINT_TIMEOUT = 10
class Render(QWebEnginePage):
@ -20,8 +26,12 @@ class Render(QWebEnginePage):
def __init__(self):
QWebEnginePage.__init__(self)
secure_webengine(self)
self.printing_started = False
self.loadFinished.connect(self.load_finished, type=Qt.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:
@ -29,13 +39,29 @@ class Render(QWebEnginePage):
else:
QApplication.instance().exit(1)
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:
QApplication.instance().exit(4)
else:
if monotonic() - self.start_time > LOAD_TIMEOUT:
QApplication.instance().exit(3)
def start_print(self):
margins = QMarginsF(0, 0, 0, 0)
page_layout = QPageLayout(QPageSize(QPageSize.A4), QPageLayout.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'):
@ -45,7 +71,7 @@ def main(path_to_html, tdir, image_format='jpeg'):
path_to_html = os.path.abspath(path_to_html)
os.chdir(tdir)
renderer = Render()
renderer.load(QUrl.fromLocalFile(path_to_html))
renderer.start_load(path_to_html)
ret = QApplication.instance().exec_()
if ret == 0:
page_images('rendered.pdf', image_format=image_format)
@ -55,4 +81,5 @@ def main(path_to_html, tdir, image_format='jpeg'):
if __name__ == '__main__':
main(sys.argv[-1], '.')
if not main(sys.argv[-1], '.'):
raise SystemExit('Failed to render HTML')