Example #1
0
def render_html(path_to_html, width=590, height=750, as_xhtml=True):
    from PyQt5.QtWebKitWidgets import QWebPage
    from PyQt5.Qt import QEventLoop, QPalette, Qt, QUrl, QSize
    from calibre.gui2 import is_ok_to_use_qt, secure_web_page
    if not is_ok_to_use_qt():
        return None
    path_to_html = os.path.abspath(path_to_html)
    with CurrentDir(os.path.dirname(path_to_html)):
        page = QWebPage()
        settings = page.settings()
        secure_web_page(settings)
        pal = page.palette()
        pal.setBrush(QPalette.Background, Qt.white)
        page.setPalette(pal)
        page.setViewportSize(QSize(width, height))
        page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)
        page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        loop = QEventLoop()
        renderer = HTMLRenderer(page, loop)
        page.loadFinished.connect(renderer, type=Qt.QueuedConnection)
        if as_xhtml:
            page.mainFrame().setContent(open(path_to_html, 'rb').read(),
                    'application/xhtml+xml', QUrl.fromLocalFile(path_to_html))
        else:
            page.mainFrame().load(QUrl.fromLocalFile(path_to_html))
        loop.exec_()
    renderer.loop = renderer.page = None
    page.loadFinished.disconnect()
    del page
    del loop
    if isinstance(renderer.exception, ParserError) and as_xhtml:
        return render_html(path_to_html, width=width, height=height,
                as_xhtml=False)
    return renderer
Example #2
0
def render_html(path_to_html, width=590, height=750, as_xhtml=True):
    from PyQt5.QtWebKitWidgets import QWebPage
    from PyQt5.Qt import QEventLoop, QPalette, Qt, QUrl, QSize
    from calibre.gui2 import is_ok_to_use_qt
    if not is_ok_to_use_qt():
        return None
    path_to_html = os.path.abspath(path_to_html)
    with CurrentDir(os.path.dirname(path_to_html)):
        page = QWebPage()
        settings = page.settings()
        settings.setAttribute(settings.PluginsEnabled, False)
        pal = page.palette()
        pal.setBrush(QPalette.Background, Qt.white)
        page.setPalette(pal)
        page.setViewportSize(QSize(width, height))
        page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)
        page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        loop = QEventLoop()
        renderer = HTMLRenderer(page, loop)
        page.loadFinished.connect(renderer, type=Qt.QueuedConnection)
        if as_xhtml:
            page.mainFrame().setContent(open(path_to_html, 'rb').read(),
                    'application/xhtml+xml', QUrl.fromLocalFile(path_to_html))
        else:
            page.mainFrame().load(QUrl.fromLocalFile(path_to_html))
        loop.exec_()
    renderer.loop = renderer.page = None
    page.loadFinished.disconnect()
    del page
    del loop
    if isinstance(renderer.exception, ParserError) and as_xhtml:
        return render_html(path_to_html, width=width, height=height,
                as_xhtml=False)
    return renderer
Example #3
0
    def test02_check_scene1_webpage(self):
        """render exported web page and check page capture"""

        html_path = outputPath("scene1.html")

        url = QUrl.fromLocalFile(html_path)
        url = QUrl(url.toString() + "#cx=-20&cy=16&cz=-34&tx=-2&ty=0&tz=8")

        loop = QEventLoop()
        page = QWebPage()
        page.setViewportSize(QSize(OUT_WIDTH, OUT_HEIGHT))
        page.loadFinished.connect(loop.quit)
        page.mainFrame().setUrl(url)
        loop.exec_()

        page.mainFrame().evaluateJavaScript('document.getElementById("progress").style.display = "none";')

        timer = QTimer()
        timer.timeout.connect(loop.quit)
        timer.start(100)
        while page.mainFrame().evaluateJavaScript("app.loadingManager.isLoading"):
            loop.exec_()

        timer.stop()

        image = QImage(OUT_WIDTH, OUT_HEIGHT, QImage.Format_ARGB32_Premultiplied)
        painter = QPainter(image)
        page.mainFrame().render(painter)
        painter.end()

        filename = "scene1_qwebpage.png"
        image.save(outputPath(filename))
        assert QImage(outputPath(filename)) == QImage(expectedDataPath(filename)), "captured image is different from expected."
class WebLoader(QObject):
    
    _finished = pyqtSignal(str)
    
    def __init__(self, key):
        super(WebLoader, self).__init__()

#         if platform.python_version() < '3.0.0':
#             self._key = unicode(key)
  
        self._key = key
        self._percent = 0
        self._page = QWebPage()
        self._page.mainFrame().setScrollBarPolicy(Qt.Vertical,  Qt.ScrollBarAlwaysOff)
        self._page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self._page.loadProgress.connect(self.printProgress)
        
        
    def printProgress(self, percent):
        if self._percent >= percent:
            cout("\n")
            return
        else:
            cout('#' * (percent - self._percent))
            self._percent = percent
            
    def load(self, url):
        self._percent = 0
        self._url = QUrl.fromUserInput(url)
        self._page.mainFrame().load(self._url)
        self._page.setViewportSize(QSize(1920, 10000))  
        print("Loading... %s" % url)
Example #5
0
class HTMLTableRenderer(QObject):
    def __init__(self, html, base_dir, width, height, dpi, factor):
        '''
        `width, height`: page width and height in pixels
        `base_dir`: The directory in which the HTML file that contains the table resides
        '''
        from calibre.gui2 import secure_web_page
        QObject.__init__(self)

        self.app = None
        self.width, self.height, self.dpi = width, height, dpi
        self.base_dir = base_dir
        self.images = []
        self.tdir = tempfile.mkdtemp(prefix='calibre_render_table')
        self.loop = QEventLoop()
        self.page = QWebPage()
        secure_web_page(self.page.settings())
        self.page.loadFinished.connect(self.render_html)
        self.page.mainFrame().setTextSizeMultiplier(factor)
        self.page.mainFrame().setHtml(
            html, QUrl('file:' + os.path.abspath(self.base_dir)))

    def render_html(self, ok):
        try:
            if not ok:
                return
            cwidth, cheight = self.page.mainFrame().contentsSize().width(
            ), self.page.mainFrame().contentsSize().height()
            self.page.setViewportSize(QSize(cwidth, cheight))
            factor = float(self.width) / cwidth if cwidth > self.width else 1
            cutoff_height = int(self.height / factor) - 3
            image = QImage(self.page.viewportSize(), QImage.Format_ARGB32)
            image.setDotsPerMeterX(self.dpi * (100 / 2.54))
            image.setDotsPerMeterY(self.dpi * (100 / 2.54))
            painter = QPainter(image)
            self.page.mainFrame().render(painter)
            painter.end()
            cheight = image.height()
            cwidth = image.width()
            pos = 0
            while pos < cheight:
                img = image.copy(0, pos, cwidth,
                                 min(cheight - pos, cutoff_height))
                pos += cutoff_height - 20
                if cwidth > self.width:
                    img = img.scaledToWidth(self.width, Qt.SmoothTransform)
                f = os.path.join(self.tdir, '%d.png' % pos)
                img.save(f)
                self.images.append((f, img.width(), img.height()))
        finally:
            QApplication.quit()
Example #6
0
class HTMLTableRenderer(QObject):

    def __init__(self, html, base_dir, width, height, dpi, factor):
        '''
        `width, height`: page width and height in pixels
        `base_dir`: The directory in which the HTML file that contains the table resides
        '''
        from calibre.gui2 import secure_web_page
        QObject.__init__(self)

        self.app = None
        self.width, self.height, self.dpi = width, height, dpi
        self.base_dir = base_dir
        self.images = []
        self.tdir = tempfile.mkdtemp(prefix='calibre_render_table')
        self.loop = QEventLoop()
        self.page = QWebPage()
        secure_web_page(self.page.settings())
        self.page.loadFinished.connect(self.render_html)
        self.page.mainFrame().setTextSizeMultiplier(factor)
        self.page.mainFrame().setHtml(html,
                                QUrl('file:'+os.path.abspath(self.base_dir)))

    def render_html(self, ok):
        try:
            if not ok:
                return
            cwidth, cheight = self.page.mainFrame().contentsSize().width(), self.page.mainFrame().contentsSize().height()
            self.page.setViewportSize(QSize(cwidth, cheight))
            factor = float(self.width)/cwidth if cwidth > self.width else 1
            cutoff_height = int(self.height/factor)-3
            image = QImage(self.page.viewportSize(), QImage.Format_ARGB32)
            image.setDotsPerMeterX(self.dpi*(100/2.54))
            image.setDotsPerMeterY(self.dpi*(100/2.54))
            painter = QPainter(image)
            self.page.mainFrame().render(painter)
            painter.end()
            cheight = image.height()
            cwidth = image.width()
            pos = 0
            while pos < cheight:
                img = image.copy(0, pos, cwidth, min(cheight-pos, cutoff_height))
                pos += cutoff_height-20
                if cwidth > self.width:
                    img = img.scaledToWidth(self.width, Qt.SmoothTransform)
                f = os.path.join(self.tdir, '%d.png'%pos)
                img.save(f)
                self.images.append((f, img.width(), img.height()))
        finally:
            QApplication.quit()
Example #7
0
class FrameCapture(QObject):

    finished = pyqtSignal()

    def __init__(self):
        super(FrameCapture, self).__init__()

        self._percent = 0
        self._page = QWebPage()
        self._page.mainFrame().setScrollBarPolicy(Qt.Vertical,
                                                  Qt.ScrollBarAlwaysOff)
        self._page.mainFrame().setScrollBarPolicy(Qt.Horizontal,
                                                  Qt.ScrollBarAlwaysOff)
        self._page.loadProgress.connect(self.printProgress)
        self._page.loadFinished.connect(self.saveResult)

    def load(self, url, outputFileName):
        cout("Loading %s\n" % url.toString())
        self._percent = 0
        index = outputFileName.rfind(".")
        self._fileName = index == -1 and outputFileName + ".png" or outputFileName
        self._page.mainFrame().load(url)
        self._page.setViewportSize(QSize(1024, 768))

    def printProgress(self, percent):
        if self._percent >= percent:
            return
        self._percent += 1
        while self._percent < percent:
            self._percent += 1
            cout("#")

    def saveResult(self, ok):
        cout("\n")
        # Crude error-checking.
        if not ok:
            cerr("Failed loading %s\n" %
                 self._page.mainFrame().url().toString())
            self.finished.emit()
            return

        # Save each frame in different image files.
        self._frameCounter = 0
        self.saveFrame(self._page.mainFrame())
        self.finished.emit()

    def saveFrame(self, frame):
        fileName = self._fileName
        if self._frameCounter:
            index = fileName.rfind(".")
            fileName = "%s_frame%s%s" % (
                fileName[:index],
                self._frameCounter,
                fileName[index:],
            )
        image = QImage(frame.contentsSize(),
                       QImage.Format_ARGB32_Premultiplied)
        image.fill(Qt.transparent)
        painter = QPainter(image)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setRenderHint(QPainter.TextAntialiasing, True)
        painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
        frame.documentElement().render(painter)
        painter.end()
        image.save(fileName)
        self._frameCounter += 1
        for childFrame in frame.childFrames():
            self.saveFrame(childFrame)
Example #8
0
class FrameCapture(QObject):

    finished = pyqtSignal()

    def __init__(self):
        super(FrameCapture, self).__init__()

        self._percent = 0
        self._page = QWebPage()
        self._page.mainFrame().setScrollBarPolicy(Qt.Vertical,
                Qt.ScrollBarAlwaysOff)
        self._page.mainFrame().setScrollBarPolicy(Qt.Horizontal,
                Qt.ScrollBarAlwaysOff)
        self._page.loadProgress.connect(self.printProgress)
        self._page.loadFinished.connect(self.saveResult)
 
    def load(self, url, outputFileName):
        cout("Loading %s\n" % url.toString())
        self._percent = 0
        index = outputFileName.rfind('.')
        self._fileName = index == -1 and outputFileName + ".png" or outputFileName
        self._page.mainFrame().load(url)
        self._page.setViewportSize(QSize(1024, 768))
 
    def printProgress(self, percent):
        if self._percent >= percent:
            return
        self._percent += 1
        while self._percent < percent:
            self._percent += 1
            cout("#")
 
    def saveResult(self, ok):
        cout("\n")
        # Crude error-checking.
        if not ok:
            cerr("Failed loading %s\n" % self._page.mainFrame().url().toString())
            self.finished.emit()
            return

        # Save each frame in different image files.
        self._frameCounter = 0
        self.saveFrame(self._page.mainFrame())
        self.finished.emit()
 
    def saveFrame(self, frame):
        fileName = self._fileName
        if self._frameCounter:
            index = fileName.rfind('.')
            fileName = "%s_frame%s%s" % (fileName[:index], self._frameCounter, fileName[index:])
        image = QImage(frame.contentsSize(), QImage.Format_ARGB32_Premultiplied)
        image.fill(Qt.transparent)
        painter = QPainter(image)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setRenderHint(QPainter.TextAntialiasing, True)
        painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
        frame.documentElement().render(painter)
        painter.end()
        image.save(fileName)
        self._frameCounter += 1
        for childFrame in frame.childFrames():
            self.saveFrame(childFrame)
Example #9
0
class PageThumbnailer(QObject):
    """
    Class implementing a thumbnail creator for web sites.
    
    @signal thumbnailCreated(QPixmap) emitted after the thumbnail has been
        created
    """
    thumbnailCreated = pyqtSignal(QPixmap)
    
    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent object (QObject)
        """
        super(PageThumbnailer, self).__init__(parent)
        
        self.__page = QWebPage(self)
        self.__size = QSize(231, 130)
        self.__loadTitle = False
        self.__title = ""
        self.__url = QUrl()
        
        self.__proxy = NetworkAccessManagerProxy(self)
        import Helpviewer.HelpWindow
        self.__proxy.setPrimaryNetworkAccessManager(
            Helpviewer.HelpWindow.HelpWindow.networkAccessManager())
        self.__page.setNetworkAccessManager(self.__proxy)
        
        self.__page.mainFrame().setScrollBarPolicy(
            Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.__page.mainFrame().setScrollBarPolicy(
            Qt.Vertical, Qt.ScrollBarAlwaysOff)
        
        # Full HD
        # Every page should fit in this resolution
        self.__page.setViewportSize(QSize(1920, 1080))
    
    def setSize(self, size):
        """
        Public method to set the size of the image.
        
        @param size size of the image (QSize)
        """
        if size.isValid():
            self.__size = QSize(size)
    
    def setUrl(self, url):
        """
        Public method to set the URL of the site to be thumbnailed.
        
        @param url URL of the web site (QUrl)
        """
        if url.isValid():
            self.__url = QUrl(url)
    
    def url(self):
        """
        Public method to get the URL of the thumbnail.
        
        @return URL of the thumbnail (QUrl)
        """
        return QUrl(self.__url)
    
    def loadTitle(self):
        """
        Public method to check, if the title is loaded from the web site.
        
        @return flag indicating, that the title is loaded (boolean)
        """
        return self.__loadTitle
    
    def setLoadTitle(self, load):
        """
        Public method to set a flag indicating to load the title from
        the web site.
        
        @param load flag indicating to load the title (boolean)
        """
        self.__loadTitle = load
    
    def title(self):
        """
        Public method to get the title of the thumbnail.
        
        @return title of the thumbnail (string)
        """
        return self.__title
    
    def start(self):
        """
        Public method to start the thumbnailing action.
        """
        self.__page.loadFinished.connect(self.__createThumbnail)
        self.__page.mainFrame().load(self.__url)
    
    def __createThumbnail(self, status):
        """
        Private slot creating the thumbnail of the web site.
        
        @param status flag indicating a successful load of the web site
            (boolean)
        """
        if not status:
            self.thumbnailCreated.emit(QPixmap())
            return
        
        self.__title = self.__page.mainFrame().title()
        
        image = QImage(self.__page.viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        self.__page.mainFrame().render(painter)
        painter.end()
        
        scaledImage = image.scaled(self.__size,
                                   Qt.KeepAspectRatioByExpanding,
                                   Qt.SmoothTransformation)
        
        self.thumbnailCreated.emit(QPixmap.fromImage(scaledImage))
Example #10
0
class PageThumbnailer(QObject):
    """
    Class implementing a thumbnail creator for web sites.
    
    @signal thumbnailCreated(QPixmap) emitted after the thumbnail has been
        created
    """
    thumbnailCreated = pyqtSignal(QPixmap)

    def __init__(self, parent=None):
        """
        Constructor
        
        @param parent reference to the parent object (QObject)
        """
        super(PageThumbnailer, self).__init__(parent)

        self.__page = QWebPage(self)
        self.__size = QSize(231, 130)
        self.__loadTitle = False
        self.__title = ""
        self.__url = QUrl()

        self.__proxy = NetworkAccessManagerProxy(self)
        import Helpviewer.HelpWindow
        self.__proxy.setPrimaryNetworkAccessManager(
            Helpviewer.HelpWindow.HelpWindow.networkAccessManager())
        self.__page.setNetworkAccessManager(self.__proxy)

        self.__page.mainFrame().setScrollBarPolicy(Qt.Horizontal,
                                                   Qt.ScrollBarAlwaysOff)
        self.__page.mainFrame().setScrollBarPolicy(Qt.Vertical,
                                                   Qt.ScrollBarAlwaysOff)

        # Full HD
        # Every page should fit in this resolution
        self.__page.setViewportSize(QSize(1920, 1080))

    def setSize(self, size):
        """
        Public method to set the size of the image.
        
        @param size size of the image (QSize)
        """
        if size.isValid():
            self.__size = QSize(size)

    def setUrl(self, url):
        """
        Public method to set the URL of the site to be thumbnailed.
        
        @param url URL of the web site (QUrl)
        """
        if url.isValid():
            self.__url = QUrl(url)

    def url(self):
        """
        Public method to get the URL of the thumbnail.
        
        @return URL of the thumbnail (QUrl)
        """
        return QUrl(self.__url)

    def loadTitle(self):
        """
        Public method to check, if the title is loaded from the web site.
        
        @return flag indicating, that the title is loaded (boolean)
        """
        return self.__loadTitle

    def setLoadTitle(self, load):
        """
        Public method to set a flag indicating to load the title from
        the web site.
        
        @param load flag indicating to load the title (boolean)
        """
        self.__loadTitle = load

    def title(self):
        """
        Public method to get the title of the thumbnail.
        
        @return title of the thumbnail (string)
        """
        return self.__title

    def start(self):
        """
        Public method to start the thumbnailing action.
        """
        self.__page.loadFinished.connect(self.__createThumbnail)
        self.__page.mainFrame().load(self.__url)

    def __createThumbnail(self, status):
        """
        Private slot creating the thumbnail of the web site.
        
        @param status flag indicating a successful load of the web site
            (boolean)
        """
        if not status:
            self.thumbnailCreated.emit(QPixmap())
            return

        self.__title = self.__page.mainFrame().title()

        image = QImage(self.__page.viewportSize(), QImage.Format_ARGB32)
        painter = QPainter(image)
        self.__page.mainFrame().render(painter)
        painter.end()

        scaledImage = image.scaled(self.__size, Qt.KeepAspectRatioByExpanding,
                                   Qt.SmoothTransformation)

        self.thumbnailCreated.emit(QPixmap.fromImage(scaledImage))