From ac67968bdceffd816e93c3b623c8cbdcba716db6 Mon Sep 17 00:00:00 2001 From: Josep Anguera Date: Thu, 2 Jun 2016 19:28:19 +0200 Subject: [PATCH 1/6] Do not mix tabs and spaces and remove trailing whitespace --- webkit2png/webkit2png.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/webkit2png/webkit2png.py b/webkit2png/webkit2png.py index e6a2b21..96c8d13 100755 --- a/webkit2png/webkit2png.py +++ b/webkit2png/webkit2png.py @@ -61,7 +61,7 @@ def __init__(self,**kwargs): self.scaleRatio = kwargs.get('scaleRatio', 'keep') self.format = kwargs.get('format', 'png') self.logger = kwargs.get('logger', None) - + # Set this to true if you want to capture flash. # Not that your desktop must be large enough for # fitting the whole window. @@ -123,16 +123,16 @@ def render_to_bytes(self, res): ## @brief The CookieJar class inherits QNetworkCookieJar to make a couple of functions public. class CookieJar(QNetworkCookieJar): - def __init__(self, cookies, qtUrl, parent=None): - QNetworkCookieJar.__init__(self, parent) - for cookie in cookies: - QNetworkCookieJar.setCookiesFromUrl(self, QNetworkCookie.parseCookies(QByteArray(cookie)), qtUrl) + def __init__(self, cookies, qtUrl, parent=None): + QNetworkCookieJar.__init__(self, parent) + for cookie in cookies: + QNetworkCookieJar.setCookiesFromUrl(self, QNetworkCookie.parseCookies(QByteArray(cookie)), qtUrl) + + def allCookies(self): + return QNetworkCookieJar.allCookies(self) - def allCookies(self): - return QNetworkCookieJar.allCookies(self) - - def setAllCookies(self, cookieList): - QNetworkCookieJar.setAllCookies(self, cookieList) + def setAllCookies(self, cookieList): + QNetworkCookieJar.setAllCookies(self, cookieList) class _WebkitRendererHelper(QObject): """ @@ -365,9 +365,9 @@ def _on_ssl_errors(self, reply, errors): class CustomWebPage(QWebPage): def __init__(self, **kwargs): - """ - Class Initializer - """ + """ + Class Initializer + """ super(CustomWebPage, self).__init__() self.logger = kwargs.get('logger', None) self.ignore_alert = kwargs.get('ignore_alert', True) From 735f7c2c8a194b8c94069450b1123e1cc6bd656d Mon Sep 17 00:00:00 2001 From: Josep Anguera Date: Thu, 2 Jun 2016 19:50:45 +0200 Subject: [PATCH 2/6] Add PyQT5 support --- README.md | 2 ++ webkit2png/scripts.py | 16 +++++++++++---- webkit2png/webkit2png.py | 43 ++++++++++++++++++++++++++++++---------- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index dc88b84..8e81a0e 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Ubuntu - Add following packages: ``apt-get install python-qt4 libqt4-webkit xvfb`` - Install the flash plugin to screenshot Adobe Flash files: ``apt-get install flashplugin-installer`` +To use QT5 instead of QT4 add following packages: ``apt-get install python-pyqt5.qtwebkit xvfb`` + Automated installation via ```pip``` ------------------------------------- - Install pip: ```apt-get install python-pip``` diff --git a/webkit2png/scripts.py b/webkit2png/scripts.py index 7a4bfb4..6b6167f 100755 --- a/webkit2png/scripts.py +++ b/webkit2png/scripts.py @@ -33,10 +33,18 @@ import logging from optparse import OptionParser -from PyQt4.QtCore import * -from PyQt4.QtGui import * -from PyQt4.QtWebKit import * -from PyQt4.QtNetwork import * +try: + from PyQt5.QtCore import * + from PyQt5.QtGui import * + from PyQt5.QtWebKit import * + from PyQt5.QtNetwork import * + from PyQt5.QtWidgets import * +except ImportError: + from PyQt4.QtCore import * + from PyQt4.QtGui import * + from PyQt4.QtWebKit import * + from PyQt4.QtNetwork import * + VERSION="20091224" LOG_FILENAME = 'webkit2png.log' diff --git a/webkit2png/webkit2png.py b/webkit2png/webkit2png.py index 96c8d13..053237e 100755 --- a/webkit2png/webkit2png.py +++ b/webkit2png/webkit2png.py @@ -26,10 +26,21 @@ import time import os -from PyQt4.QtCore import * -from PyQt4.QtGui import * -from PyQt4.QtWebKit import * -from PyQt4.QtNetwork import * +try: + from PyQt5.QtCore import * + from PyQt5.QtGui import * + from PyQt5.QtWebKit import * + from PyQt5.QtWebKitWidgets import * + from PyQt5.QtNetwork import * + from PyQt5.QtWidgets import * + PYQT5 = True +except ImportError: + from PyQt4.QtCore import * + from PyQt4.QtGui import * + from PyQt4.QtWebKit import * + from PyQt4.QtNetwork import * + PYQT5 = False + # Class for Website-Rendering. Uses QWebPage, which # requires a running QtGui to work. @@ -185,10 +196,16 @@ def __init__(self, parent): self._page.settings().setAttribute(key, value) # Connect required event listeners - self.connect(self._page, SIGNAL("loadFinished(bool)"), self._on_load_finished) - self.connect(self._page, SIGNAL("loadStarted()"), self._on_load_started) - self.connect(self._page.networkAccessManager(), SIGNAL("sslErrors(QNetworkReply *,const QList&)"), self._on_ssl_errors) - self.connect(self._page.networkAccessManager(), SIGNAL("finished(QNetworkReply *)"), self._on_each_reply) + if PYQT5: + self._page.loadFinished.connect(self._on_load_finished) + self._page.loadStarted.connect(self._on_load_started) + self._page.networkAccessManager().sslErrors.connect(self._on_ssl_errors) + self._page.networkAccessManager().finished.connect(self._on_each_reply) + else: + self.connect(self._page, SIGNAL("loadFinished(bool)"), self._on_load_finished) + self.connect(self._page, SIGNAL("loadStarted()"), self._on_load_started) + self.connect(self._page.networkAccessManager(), SIGNAL("sslErrors(QNetworkReply *,const QList&)"), self._on_ssl_errors) + self.connect(self._page.networkAccessManager(), SIGNAL("finished(QNetworkReply *)"), self._on_each_reply) # The way we will use this, it seems to be unesseccary to have Scrollbars enabled self._page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) @@ -247,9 +264,15 @@ def render(self, res): # window still has the focus when the screen is # grabbed. This might result in a race condition. self._view.activateWindow() - image = QPixmap.grabWindow(self._window.winId()) + if PYQT5: + image = QScreen.grabWindow(self._window.winId()) + else: + image = QPixmap.grabWindow(self._window.winId()) else: - image = QPixmap.grabWidget(self._window) + if PYQT5: + image = QWidget.grab(self._window) + else: + image = QPixmap.grabWidget(self._window) return self._post_process_image(image) From 40d0285acbda2270686bea2656c805202c15e1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Carrasqueira?= Date: Sat, 22 Jul 2017 19:26:12 -0300 Subject: [PATCH 3/6] Adding support to Qt5.9 --- webkit2png/scripts.py | 4 +- webkit2png/webkit2png.py | 90 +++++++++++++++++++++++++++------------- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/webkit2png/scripts.py b/webkit2png/scripts.py index 6b6167f..1995c12 100755 --- a/webkit2png/scripts.py +++ b/webkit2png/scripts.py @@ -36,14 +36,16 @@ try: from PyQt5.QtCore import * from PyQt5.QtGui import * - from PyQt5.QtWebKit import * + from PyQt5.QtWebEngineWidgets import * from PyQt5.QtNetwork import * from PyQt5.QtWidgets import * + PYQT5 = True except ImportError: from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.QtWebKit import * from PyQt4.QtNetwork import * + PYQT5 = False VERSION="20091224" diff --git a/webkit2png/webkit2png.py b/webkit2png/webkit2png.py index 053237e..ed449f9 100755 --- a/webkit2png/webkit2png.py +++ b/webkit2png/webkit2png.py @@ -29,8 +29,7 @@ try: from PyQt5.QtCore import * from PyQt5.QtGui import * - from PyQt5.QtWebKit import * - from PyQt5.QtWebKitWidgets import * + from PyQt5.QtWebEngineWidgets import * from PyQt5.QtNetwork import * from PyQt5.QtWidgets import * PYQT5 = True @@ -41,7 +40,6 @@ from PyQt4.QtNetwork import * PYQT5 = False - # Class for Website-Rendering. Uses QWebPage, which # requires a running QtGui to work. class WebkitRenderer(QObject): @@ -84,14 +82,25 @@ def __init__(self,**kwargs): self.interruptJavaScript = kwargs.get('interruptJavaScript', True) self.encodedUrl = kwargs.get('encodedUrl', False) self.cookies = kwargs.get('cookies', []) + + if PYQT5: - # Set some default options for QWebPage - self.qWebSettings = { - QWebSettings.JavascriptEnabled : False, - QWebSettings.PluginsEnabled : False, - QWebSettings.PrivateBrowsingEnabled : True, - QWebSettings.JavascriptCanOpenWindows : False - } + # Set some default options for QWebPage + self.qWebSettings = { + QWebEngineSettings.JavascriptEnabled : False, + QWebEngineSettings.PluginsEnabled : False, + #QWebEngineSettings.PrivateBrowsingEnabled : True, + QWebEngineSettings.JavascriptCanOpenWindows : False + } + + else: + + self.qWebSettings = { + QWebSettings.JavascriptEnabled : False, + QWebSettings.PluginsEnabled : False, + QWebSettings.PrivateBrowsingEnabled : True, + QWebSettings.JavascriptCanOpenWindows : False + } def render(self, res): @@ -185,8 +194,14 @@ def __init__(self, parent): self._page = CustomWebPage(logger=self.logger, ignore_alert=self.ignoreAlert, ignore_confirm=self.ignoreConfirm, ignore_prompt=self.ignorePrompt, interrupt_js=self.interruptJavaScript) - self._page.networkAccessManager().setProxy(proxy) - self._view = QWebView() + + if PYQT5: + self._page.networkAccessManager = QNetworkAccessManager() + self._page.networkAccessManager.setProxy(proxy) + else: + self._page.networkAccessManager().setProxy(proxy) + + self._view = QWebEngineView() self._view.setPage(self._page) self._window = QMainWindow() self._window.setCentralWidget(self._view) @@ -199,18 +214,20 @@ def __init__(self, parent): if PYQT5: self._page.loadFinished.connect(self._on_load_finished) self._page.loadStarted.connect(self._on_load_started) - self._page.networkAccessManager().sslErrors.connect(self._on_ssl_errors) - self._page.networkAccessManager().finished.connect(self._on_each_reply) + self._page.networkAccessManager.sslErrors.connect(self._on_ssl_errors) + self._page.networkAccessManager.finished.connect(self._on_each_reply) else: self.connect(self._page, SIGNAL("loadFinished(bool)"), self._on_load_finished) self.connect(self._page, SIGNAL("loadStarted()"), self._on_load_started) self.connect(self._page.networkAccessManager(), SIGNAL("sslErrors(QNetworkReply *,const QList&)"), self._on_ssl_errors) self.connect(self._page.networkAccessManager(), SIGNAL("finished(QNetworkReply *)"), self._on_each_reply) + + if not PYQT5: - # The way we will use this, it seems to be unesseccary to have Scrollbars enabled - self._page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) - self._page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) - self._page.settings().setUserStyleSheetUrl(QUrl("data:text/css,html,body{overflow-y:hidden !important;}")) + # The way we will use this, it seems to be unesseccary to have Scrollbars enabled + self._page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) + self._page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) + self._page.settings().setUserStyleSheetUrl(QUrl("data:text/css,html,body{overflow-y:hidden !important;}")) # Show this widget self._window.show() @@ -256,7 +273,10 @@ def render(self, res): painter = QPainter(image) painter.setBackgroundMode(Qt.TransparentMode) - self._page.mainFrame().render(painter) + if PYQT5: + self._page.render(painter) + else: + self._page.mainFrame().render(painter) painter.end() else: if self.grabWholeWindow: @@ -305,13 +325,19 @@ def _load_page(self, res, width, height, timeout): # Set the required cookies, if any self.cookieJar = CookieJar(self.cookies, qtUrl) - self._page.networkAccessManager().setCookieJar(self.cookieJar) - - # Load the page - if type(res) == tuple: - self._page.mainFrame().setHtml(res[0], qtUrl) # HTML, baseUrl + + if PYQT5: + self._page.networkAccessManager.setCookieJar(self.cookieJar) + if type(res) == tuple: + self._page.setHtml(res[0], qtUrl) # HTML, baseUrl + else: + self._page.load(qtUrl) else: - self._page.mainFrame().load(qtUrl) + self._page.networkAccessManager().setCookieJar(self.cookieJar) + if type(res) == tuple: + self._page.mainFrame().setHtml(res[0], qtUrl) # HTML, baseUrl + else: + self._page.mainFrame().load(qtUrl) while self.__loading: if timeout > 0 and time.time() >= cancelAt: @@ -325,14 +351,22 @@ def _load_page(self, res, width, height, timeout): if self.logger: self.logger.warning("Failed to load %s" % res) # Set initial viewport (the size of the "window") - size = self._page.mainFrame().contentsSize() + if PYQT5: + size = self._page.contentsSize() + else: + size = self._page.mainFrame().contentsSize() + if self.logger: self.logger.debug("contentsSize: %s", size) + if width > 0: size.setWidth(width) if height > 0: size.setHeight(height) - self._window.resize(size) + if PYQT5: + self._window.resize(int(size.width()), int(size.height())) + else: + self._window.resize(size) def _post_process_image(self, qImage): """ @@ -386,7 +420,7 @@ def _on_ssl_errors(self, reply, errors): reply.ignoreSslErrors() -class CustomWebPage(QWebPage): +class CustomWebPage(QWebEnginePage): def __init__(self, **kwargs): """ Class Initializer From 99c292c4b06586097a5444bef58c1528757df624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Carrasqueira?= Date: Sat, 22 Jul 2017 20:02:27 -0300 Subject: [PATCH 4/6] Adjusting ClassWebPage --- webkit2png/webkit2png.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webkit2png/webkit2png.py b/webkit2png/webkit2png.py index ed449f9..5b985db 100755 --- a/webkit2png/webkit2png.py +++ b/webkit2png/webkit2png.py @@ -32,11 +32,13 @@ from PyQt5.QtWebEngineWidgets import * from PyQt5.QtNetwork import * from PyQt5.QtWidgets import * + from PyQt5.QtWebEngineWidgets import QWebEnginePage as ClassWebPage PYQT5 = True except ImportError: from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.QtWebKit import * + from PyQt5.QtWebKit import QWebPage as ClassWebPage from PyQt4.QtNetwork import * PYQT5 = False @@ -420,7 +422,8 @@ def _on_ssl_errors(self, reply, errors): reply.ignoreSslErrors() -class CustomWebPage(QWebEnginePage): +class CustomWebPage(ClassWebPage): + def __init__(self, **kwargs): """ Class Initializer From b41a7693b7202fda1f0bd317a0d6eb3ad557b4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Carrasqueira?= Date: Sat, 22 Jul 2017 20:16:54 -0300 Subject: [PATCH 5/6] Adjusting ClassWebPage --- webkit2png/webkit2png.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webkit2png/webkit2png.py b/webkit2png/webkit2png.py index 5b985db..24fbd31 100755 --- a/webkit2png/webkit2png.py +++ b/webkit2png/webkit2png.py @@ -38,7 +38,7 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.QtWebKit import * - from PyQt5.QtWebKit import QWebPage as ClassWebPage + from PyQt4.QtWebKit import QWebPage as ClassWebPage from PyQt4.QtNetwork import * PYQT5 = False From 88e813c02c45ada4de29c577846809411275546d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rog=C3=A9rio=20Carrasqueira?= Date: Sat, 22 Jul 2017 20:53:40 -0300 Subject: [PATCH 6/6] Adjusting ClassWebPage --- webkit2png/webkit2png.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webkit2png/webkit2png.py b/webkit2png/webkit2png.py index 24fbd31..946a914 100755 --- a/webkit2png/webkit2png.py +++ b/webkit2png/webkit2png.py @@ -203,7 +203,10 @@ def __init__(self, parent): else: self._page.networkAccessManager().setProxy(proxy) - self._view = QWebEngineView() + if PYQT5: + self._view = QWebEngineView() + else: + self._view = QWebView() self._view.setPage(self._page) self._window = QMainWindow() self._window.setCentralWidget(self._view)