diff --git a/python/csconverter.py b/python/csconverter.py index 135c7fa0..4e5de086 100644 --- a/python/csconverter.py +++ b/python/csconverter.py @@ -18,7 +18,7 @@ along with this program. If not, see . ''' -from PyQt4.QtCore import QObject, QFile, QVariant, QString +from PyQt4.QtCore import QObject, QFile from PyQt4.QtWebKit import QWebPage class CSConverter(QObject): @@ -29,7 +29,7 @@ class CSConverter(QObject): converter = QFile(':/resources/coffee-script.js') converter.open(QFile.ReadOnly) - script = QString.fromUtf8(converter.readAll()) + script = str(converter.readAll()) converter.close() self.m_webPage.mainFrame().evaluateJavaScript(script) self.m_webPage.mainFrame().addToJavaScriptWindowObject('converter', self) @@ -37,6 +37,6 @@ class CSConverter(QObject): def convert(self, script): self.setProperty('source', script) result = self.m_webPage.mainFrame().evaluateJavaScript('this.CoffeeScript.compile(converter.source)') - if result.type() == QVariant.String: - return result.toString() - return QString() + if len(result): + return result + return '' diff --git a/python/networkaccessmanager.py b/python/networkaccessmanager.py index c8b63e4c..24a495d4 100644 --- a/python/networkaccessmanager.py +++ b/python/networkaccessmanager.py @@ -19,14 +19,14 @@ ''' from PyQt4.QtGui import QDesktopServices -from PyQt4.QtCore import SIGNAL, QString, qDebug, qWarning +from PyQt4.QtCore import qDebug, qWarning from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkDiskCache, \ QNetworkRequest class NetworkAccessManager(QNetworkAccessManager): def __init__(self, diskCacheEnabled, parent = None): QNetworkAccessManager.__init__(self, parent) - self.connect(self, SIGNAL('finished(QNetworkReply *)'), self.handleFinished) + self.finished.connect(self.handleFinished) if diskCacheEnabled == 'yes': m_networkDiskCache = QNetworkDiskCache() @@ -49,16 +49,16 @@ class NetworkAccessManager(QNetworkAccessManager): else: qWarning('Unexpected HTTP Operation Type') - qDebug(QString('URL %s' % req.url().toString())) + qDebug('URL %s' % req.url().toString()) return QNetworkAccessManager.createRequest(self, op, req, outgoingData) def handleFinished(self, reply): qDebug('HTTP/1.1 Response') - qDebug(QString('URL %s' % reply.url().toString())) - code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute).toString() + qDebug('URL %s' % reply.url().toString()) + code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if code: - qDebug('Status code: %s' % code) + qDebug('Status code: %d' % code) headerPairs = reply.rawHeaderPairs() for pair in headerPairs: diff --git a/python/phantom.py b/python/phantom.py index d2ca811c..808fcdaa 100644 --- a/python/phantom.py +++ b/python/phantom.py @@ -18,17 +18,18 @@ along with this program. If not, see . ''' -import os +import sys, os +from utils import version_major, version_minor, version_patch from csconverter import CSConverter from math import ceil, floor from time import sleep as usleep from webpage import WebPage from networkaccessmanager import NetworkAccessManager -from PyQt4.QtCore import pyqtProperty, pyqtSlot, Qt, QObject, QString, \ - QRect, SIGNAL, SLOT, QTimer, QUrl, QFileInfo, \ - QDir, QSize, QSizeF, QTime, QEventLoop, qDebug +from PyQt4.QtCore import pyqtProperty, pyqtSlot, Qt, QObject, QRect, \ + SLOT, QTimer, QUrl, QFileInfo, QDir, QSize, \ + QSizeF, QTime, QEventLoop, qDebug from PyQt4.QtGui import QPalette, QDesktopServices, qApp, QPrinter, \ QImage, QPainter, QRegion, QApplication, qRgba from PyQt4.QtWebKit import QWebSettings, QWebPage @@ -43,14 +44,19 @@ class Phantom(QObject): QObject.__init__(self, parent) # variable declarations - self.m_loadStatus = self.m_state = QString() + self.m_loadStatus = self.m_state = '' self.m_var = self.m_paperSize = self.m_loadScript_cache = {} self.m_verbose = args.verbose self.m_page = WebPage(self) self.m_clipRect = QRect() # setup the values from args - self.m_script = QString.fromUtf8(args.script.read()) + self.m_script = args.script.read() self.m_scriptFile = args.script.name + self.m_scriptDir = os.path.dirname(args.script.name) + if sys.platform.startswith('win'): + self.m_scriptDir += '\\' + else: + self.m_scriptDir += '/' self.m_args = args.script_args self.m_upload_file = args.upload_file autoLoadImages = False if args.load_images == 'no' else True @@ -82,24 +88,19 @@ class Phantom(QObject): self.m_page.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff) self.m_page.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff) - # if our script was called in a different directory, change to it - # to make any dealings with files be relative to the scripts directory - if os.path.dirname(self.m_scriptFile): - os.chdir(os.path.dirname(self.m_scriptFile)) - if self.m_verbose: m_netAccessMan = NetworkAccessManager(args.disk_cache, self) self.m_page.setNetworkAccessManager(m_netAccessMan) # inject our properties and slots into javascript - self.connect(self.m_page.mainFrame(), SIGNAL('javaScriptWindowObjectCleared()'), self.inject) - self.connect(self.m_page, SIGNAL('loadFinished(bool)'), self.finish) + self.m_page.mainFrame().javaScriptWindowObjectCleared.connect(self.inject) + self.m_page.loadFinished.connect(self.finish) def execute(self): - if self.m_script.startsWith('#!'): - self.m_script.prepend('//') + if self.m_script.startswith('#!'): + self.m_script = '//' + self.m_script - if self.m_scriptFile.endswith('.coffee'): + if self.m_scriptFile.lower().endswith('.coffee'): coffee = CSConverter(self) self.m_script = coffee.convert(self.m_script) @@ -195,15 +196,19 @@ class Phantom(QObject): @clipRect.setter def clipRect(self, size): - w = int(size[QString('width')]) - h = int(size[QString('height')]) - top = int(size[QString('top')]) - left = int(size[QString('left')]) + names = ('width', 'height', 'top', 'left') + for item in names: + try: + globals()[item] = int(size[item]) + if globals()[item] < 0: + if item not in ('top', 'left'): + globals()[item] = 0 + except KeyError: + globals()[item] = getattr(self.m_clipRect, item)() - if w >= 0 and h >= 0: - self.m_clipRect = QRect(left, top, w, h) + self.m_clipRect = QRect(left, top, width, height) - @pyqtProperty('QString') + @pyqtProperty(str) def content(self): return self.m_page.mainFrame().toHtml() @@ -215,7 +220,7 @@ class Phantom(QObject): @pyqtSlot(int) def exit(self, code = 0): self.m_returnValue = code - self.disconnect(self.m_page, SIGNAL('loadFinished(bool)'), self.finish) + self.m_page.loadFinished.disconnect(self.finish) QTimer.singleShot(0, qApp, SLOT('quit()')) @pyqtProperty(str) @@ -228,19 +233,19 @@ class Phantom(QObject): self.m_page.mainFrame().evaluateJavaScript(self.m_loadScript_cache[script]) return True - scriptFile = QString(script) + scriptFile = script try: - script = open(script) - script = QString.fromUtf8(script.read()) + script = open(self.m_scriptDir + script) + script = script.read() except IOError: return False - if script.startsWith('#!'): - script.prepend('//') + if script.startswith('#!'): + script = '//' + script - if scriptFile.endsWith('.coffee'): + if scriptFile.lower().endswith('.coffee'): coffee = CSConverter(self) - script = QString.fromUtf8(coffee.convert(script)) + script = coffee.convert(script) self.m_loadScript_cache[scriptFile] = script self.m_page.mainFrame().evaluateJavaScript(script) @@ -259,12 +264,7 @@ class Phantom(QObject): @paperSize.setter def paperSize(self, size): - # convert QString to str - size_buffer = {} - for key, value in size.items(): - size_buffer[str(key)] = str(value) - - self.m_paperSize = size_buffer + self.m_paperSize = size @pyqtSlot(str, result=bool) def render(self, fileName): @@ -272,7 +272,7 @@ class Phantom(QObject): path = QDir() path.mkpath(fileInfo.absolutePath()) - if fileName.endsWith('.pdf', Qt.CaseInsensitive): + if fileName.lower().endswith('.pdf'): return self.renderPdf(fileName) viewportSize = QSize(self.m_page.viewportSize()) @@ -361,7 +361,7 @@ class Phantom(QObject): @pyqtProperty('QVariantMap') def viewportSize(self): - size = QSize(self.m_page.viewportSize()) + size = self.m_page.viewportSize() result = { 'width': size.width(), 'height': size.height() @@ -370,7 +370,13 @@ class Phantom(QObject): @viewportSize.setter def viewportSize(self, size): - w = int(size[QString('width')]) - h = int(size[QString('height')]) - if w > 0 and h > 0: - self.m_page.setViewportSize(QSize(w, h)) + names = ('width', 'height') + for item in names: + try: + globals()[item] = int(size[item]) + if globals()[item] < 0: + globals()[item] = 0 + except KeyError: + globals()[item] = getattr(self.m_page.viewportSize(), item)() + + self.m_page.setViewportSize(QSize(width, height)) diff --git a/python/pyphantomjs.py b/python/pyphantomjs.py index b7eefba2..8251bd25 100644 --- a/python/pyphantomjs.py +++ b/python/pyphantomjs.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python ''' This file is part of the PyPhantomJS project. @@ -19,35 +19,40 @@ along with this program. If not, see . ''' +# automatically convert Qt types by using api 2 +import sip +sip.setapi('QString', 2) +sip.setapi('QVariant', 2) + import os, sys, resources from phantom import Phantom from utils import argParser, MessageHandler, version -from PyQt4.QtCore import QString, qInstallMsgHandler, qFatal +from PyQt4.QtCore import qInstallMsgHandler from PyQt4.QtGui import QIcon, QApplication # make keyboard interrupt quit program import signal signal.signal(signal.SIGINT, signal.SIG_DFL) -if __name__ == '__main__': +def parseArgs(args): # Handle all command-line options p = argParser() - arg_data = p.parse_known_args(sys.argv[1:]) + arg_data = p.parse_known_args(args) args = arg_data[0] args.script_args = arg_data[1] - # register an alternative Message Handler - messageHandler = MessageHandler(args.verbose) - qInstallMsgHandler(messageHandler.process) - if args.upload_file: + # process the tags item_buffer = {} for i in range(len(args.upload_file)): item = args.upload_file[i].split('=') if len(item) < 2 or not len(item[1]): - if len(item_buffer) == 0: + # if buffer is empty, or tag has no + # value 'tag=', print help and exit + if not len(item_buffer) or \ + item[1:] and not item[1:][0]: p.print_help() sys.exit(1) @@ -75,12 +80,18 @@ if __name__ == '__main__': else: args.script = args.upload_file[i] args.script_args = args.upload_file[i+1:] - break - item_buffer[QString(item[0])] = QString(item[1]) + + # duplicate tag checking + if item[0] in item_buffer: + sys.exit('Multiple tags named \'%s\' were found' % item[0]) + + item_buffer[item[0]] = item[1] + + # make sure files exist for tag in item_buffer: if not os.path.exists(item_buffer[tag]): - qFatal('No such file or directory: \'%s\'' % item_buffer[tag]) + sys.exit('No such file or directory: \'%s\'' % item_buffer[tag]) args.upload_file = item_buffer if args.proxy: @@ -97,7 +108,16 @@ if __name__ == '__main__': try: args.script = open(args.script) except IOError as (errno, stderr): - qFatal(str(stderr) + ': \'%s\'' % args.script) + sys.exit('%s: \'%s\'' % (stderr, args.script)) + + return args + +def main(): + args = parseArgs(sys.argv[1:]) + + # register an alternative Message Handler + messageHandler = MessageHandler(args.verbose) + qInstallMsgHandler(messageHandler.process) app = QApplication(sys.argv) @@ -111,3 +131,6 @@ if __name__ == '__main__': phantom.execute() app.exec_() sys.exit(phantom.returnValue()) + +if __name__ == '__main__': + main() diff --git a/python/utils.py b/python/utils.py index 9cafb222..5fc0bd8f 100644 --- a/python/utils.py +++ b/python/utils.py @@ -62,7 +62,7 @@ def argParser(): ) parser.add_argument('--load-plugins', default='no', choices=['yes', 'no'], - help='Load all plugins (i.e. Flash, Silverlight, ...)\n(default: %(default)s)' + help='Load all plugins (i.e. Flash, Silverlight, ...) (default: %(default)s)' ) parser.add_argument('--proxy', metavar='address:port', help='Set the network proxy' diff --git a/python/webpage.py b/python/webpage.py index 289eece0..5022add8 100644 --- a/python/webpage.py +++ b/python/webpage.py @@ -18,7 +18,7 @@ along with this program. If not, see . ''' -from PyQt4.QtCore import SIGNAL, QString, QUrl, QEventLoop, qDebug +from PyQt4.QtCore import QUrl, QEventLoop, qDebug from PyQt4.QtGui import QApplication from PyQt4.QtWebKit import QWebPage @@ -27,12 +27,12 @@ class WebPage(QWebPage): QWebPage.__init__(self, parent) self.parent = parent - self.m_nextFileTag = QString() + self.m_nextFileTag = '' self.m_userAgent = QWebPage.userAgentForUrl(self, QUrl()) if self.parent.m_verbose: - self.connect(self.currentFrame(), SIGNAL('urlChanged(const QUrl&)'), self.handleFrameUrlChanged) - self.connect(self, SIGNAL('linkClicked(const QUrl&)'), self.handleLinkClicked) + self.currentFrame().urlChanged.connect(self.handleFrameUrlChanged) + self.linkClicked.connect(self.handleLinkClicked) def handleFrameUrlChanged(self, url): qDebug('URL Changed: %s' % url.toString()) @@ -45,9 +45,9 @@ class WebPage(QWebPage): def javaScriptConsoleMessage(self, message, lineNumber, sourceID): if sourceID: - print sourceID + ':%s' % lineNumber + ' %s' % message.toUtf8() + print '%s:%s %s' % (sourceID, lineNumber, message) else: - print message.toUtf8() + print message def shouldInterruptJavaScript(self): QApplication.processEvents(QEventLoop.AllEvents, 42) @@ -59,4 +59,4 @@ class WebPage(QWebPage): def chooseFile(self, webframe, suggestedFile): if self.m_nextFileTag in self.parent.m_upload_file: return self.parent.m_upload_file[self.m_nextFileTag] - return QString() + return ''