diff --git a/src/calibre/ebooks/render_html.py b/src/calibre/ebooks/render_html.py
index 6d745a0eb1..ad367c6088 100644
--- a/src/calibre/ebooks/render_html.py
+++ b/src/calibre/ebooks/render_html.py
@@ -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')