Merged pull request #39 from Roejames12/1.1.

My *last* changes for 1.1 :)
1.1
Ariya Hidayat 2011-04-27 17:10:05 -07:00
commit 16a0cd36e3
6 changed files with 104 additions and 75 deletions

View File

@ -18,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
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 ''

View File

@ -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:

View File

@ -18,17 +18,18 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
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))

View File

@ -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 <http://www.gnu.org/licenses/>.
'''
# 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()

View File

@ -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'

View File

@ -18,7 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
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 ''