Example #1
0
class Html2PdfConverter(QObject):
    def __init__(self, inputPath: str, outputPath: str) -> None:
        super().__init__()
        self.m_inputPath = inputPath
        self.m_outputPath = outputPath
        self.m_page = QWebEnginePage()

        self.m_page.loadFinished.connect(self.loadFinished)
        self.m_page.pdfPrintingFinished.connect(self.pdfPrintingFinished)

    def run(self) -> bool:
        self.m_page.load(QUrl.fromUserInput(self.m_inputPath))
        return QApplication.exec_()

    @pyqtSlot(bool)
    def loadFinished(self, ok: bool):
        if not ok:
            sys.stderr.write("failed to load URL '%s'" % (self.m_inputPath,))
            QCoreApplication.exit(1)
            return
        self.m_page.printToPdf(self.m_outputPath)

    @pyqtSlot(str, bool)
    def pdfPrintingFinished(self, filePath: str, success: bool):
        if not success:
            sys.stderr.write("failed to print to output file '%s'" % (filePath,))
            QCoreApplication.exit(1)
        else:
            QCoreApplication.quit()
Example #2
0
class PdfExport():
    def __init__(self, filename, book, status_bar):
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.filename = filename
        self.status_bar = status_bar

        html = "<html>\n<head>\n"
        html += "<link href=\"../css/pastie.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
        html += "<link href=\"../css/stylesheet.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
        html += "</head>\n<body>\n"
        for part in book._parts:
            self.status_bar.showMessage("Processing " + part.name)
            with open(os.path.join(book.source_path, "parts", part.src),
                      "r") as i:
                text = i.read()
                htm = markdown(text,
                               html4tags=False,
                               extras=[
                                   "fenced-code-blocks", "wiki-tables",
                                   "tables", "header-ids"
                               ])
                htm = addLineNumbers(htm)
                html += htm
        html += "\n</body>\n</html>"

        self.status_bar.showMessage("Loading HTML")
        self.page = QWebEnginePage()
        self.page.loadFinished.connect(self.loadFinished)
        self.page.pdfPrintingFinished.connect(self.printFinished)
        self.page.setHtml(
            html,
            QUrl(
                Path(os.path.join(book.source_path, "parts",
                                  "index.html")).as_uri()))

    def loadFinished(self, ok):
        if ok:
            self.status_bar.showMessage("Printing PDF")
            self.page.printToPdf(self.filename,
                                 pageLayout=QPageLayout(
                                     QPageSize(QPageSize.A5),
                                     QPageLayout.Portrait,
                                     QMarginsF(30.0, 30.0, 30.0, 30.0)))
        else:
            self.status_bar.showMessage("There was an error printing the PDF")

    def printFinished(self, filename, success):
        QApplication.restoreOverrideCursor()
        if success:
            self.status_bar.showMessage("PDF created")
        else:
            self.status_bar.showMessage("There was an error printing the PDF")
Example #3
0
    def test_qt(self):
        from PyQt5.QtCore import QTimer
        from PyQt5.QtWidgets import QApplication
        from PyQt5.QtWebEngineWidgets import QWebEnginePage
        from PyQt5.QtGui import QImageReader, QFontDatabase
        from PyQt5.QtNetwork import QNetworkAccessManager
        from calibre.utils.img import image_from_data, image_to_data, test
        # Ensure that images can be read before QApplication is constructed.
        # Note that this requires QCoreApplication.libraryPaths() to return the
        # path to the Qt plugins which it always does in the frozen build,
        # because Qt is patched to know the layout of the calibre application
        # package. On non-frozen builds, it should just work because the
        # hard-coded paths of the Qt installation should work. If they do not,
        # then it is a distro problem.
        fmts = set(map(lambda x: x.data().decode('utf-8'), QImageReader.supportedImageFormats()))  # no2to3
        testf = {'jpg', 'png', 'svg', 'ico', 'gif'}
        self.assertEqual(testf.intersection(fmts), testf, "Qt doesn't seem to be able to load some of its image plugins. Available plugins: %s" % fmts)
        data = P('images/blank.png', allow_user_override=False, data=True)
        img = image_from_data(data)
        image_from_data(P('catalog/mastheadImage.gif', allow_user_override=False, data=True))
        for fmt in 'png bmp jpeg'.split():
            d = image_to_data(img, fmt=fmt)
            image_from_data(d)
        # Run the imaging tests
        test()

        from calibre.gui2 import ensure_app, destroy_app
        display_env_var = os.environ.pop('DISPLAY', None)
        try:
            ensure_app()
            self.assertGreaterEqual(len(QFontDatabase().families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig')
            from calibre.ebooks.covers import create_cover
            create_cover('xxx', ['yyy'])
            na = QNetworkAccessManager()
            self.assertTrue(hasattr(na, 'sslErrors'), 'Qt not compiled with openssl')
            if iswindows:
                from PyQt5.Qt import QtWin
                QtWin
            p = QWebEnginePage()

            def callback(result):
                callback.result = result
                if hasattr(print_callback, 'result'):
                    QApplication.instance().quit()

            def print_callback(result):
                print_callback.result = result
                if hasattr(callback, 'result'):
                    QApplication.instance().quit()

            p.runJavaScript('1 + 1', callback)
            p.printToPdf(print_callback)
            QTimer.singleShot(5000, lambda: QApplication.instance().quit())
            QApplication.instance().exec_()
            test_flaky = ismacos and not is_ci
            if not test_flaky:
                self.assertEqual(callback.result, 2, 'Simple JS computation failed')
                self.assertIn(b'Skia/PDF', bytes(print_callback.result), 'Print to PDF failed')
            del p
            del na
            destroy_app()
            del QWebEnginePage
        finally:
            if display_env_var is not None:
                os.environ['DISPLAY'] = display_env_var