Skip to content
This repository was archived by the owner on May 30, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 106 additions & 30 deletions python/pyphantomjs.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
'''

import argparse, os, sys, resources
from math import ceil, floor

from PyQt4.QtCore import *
from PyQt4.QtGui import *
Expand All @@ -37,10 +38,33 @@
version_patch = 0
version = '%d.%d.%d' % (version_major, version_minor, version_patch)

# Different defaults.
# OSX: 72, X11: 75(?), Windows: 96
pdf_dpi = 72

license = '''
PyPhantomJS Version %s

Copyright (C) 2011 James Roe <roejames12@hotmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
''' % version

def argParser():
parser = argparse.ArgumentParser(
description='Minimalistic headless WebKit-based JavaScript-driven tool',
usage='%(prog)s [options] script.js [argument [argument ...]]',
usage='%(prog)s [options] script.[js|coffee] [script argument [script argument ...]]',
formatter_class=argparse.RawTextHelpFormatter
)

Expand All @@ -58,30 +82,13 @@ def argParser():
parser.add_argument('--upload-file', nargs='*',
metavar='tag:file', help='Upload 1 or more files'
)
parser.add_argument('script', metavar='script.js', nargs='*',
parser.add_argument('script', metavar='script.[js|coffee]', nargs='*',
help='The script to execute, and any args to pass to it'
)
parser.add_argument('--version',
action='version',
help='show this program\'s version and license',
version='''
PyPhantomJS Version %s

Copyright (C) 2011 James Roe <roejames12@hotmail.com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
''' % version)
action='version', version=license,
help='show this program\'s version and license'
)
return parser

class WebPage(QWebPage):
Expand Down Expand Up @@ -121,7 +128,7 @@ def __init__(self, args, parent = None):
# variable declarations
self.m_loadStatus = self.m_state = self.m_userAgent = QString()
self.m_page = WebPage(self)
self.m_var = self.m_loadScript_cache = {}
self.m_var = self.m_paperSize = self.m_loadScript_cache = {}
# setup the values from args
self.m_script = QString.fromUtf8(args.script[0].read())
self.m_scriptFile = args.script[0].name
Expand Down Expand Up @@ -183,9 +190,69 @@ def finish(self, success):
def inject(self):
self.m_page.mainFrame().addToJavaScriptWindowObject('phantom', self)

def renderPdf(self, fileName):
p = QPrinter()
p.setOutputFormat(QPrinter.PdfFormat)
p.setOutputFileName(fileName)
p.setResolution(pdf_dpi)
paperSize = self.m_paperSize

if not len(paperSize):
pageSize = QSize(self.m_page.mainFrame().contentsSize())
paperSize['width'] = str(pageSize.width()) + 'px'
paperSize['height'] = str(pageSize.height()) + 'px'
paperSize['border'] = '0px'

if paperSize.get('width') and paperSize.get('height'):
sizePt = QSizeF(ceil(self.stringToPointSize(paperSize['width'])),
ceil(self.stringToPointSize(paperSize['height'])))
p.setPaperSize(sizePt, QPrinter.Point)
elif 'format' in paperSize:
orientation = QPrinter.Landscape if paperSize.get('orientation') and paperSize['orientation'].lower() == 'landscape' else QPrinter.Portrait
orientation = QPrinter.Orientation(orientation)
p.setOrientation(orientation)

formats = {
'A3': QPrinter.A3,
'A4': QPrinter.A4,
'A5': QPrinter.A5,
'Legal': QPrinter.Legal,
'Letter': QPrinter.Letter,
'Tabloid': QPrinter.Tabloid
}

p.setPaperSize(QPrinter.A4) # fallback
for format, size in formats.items():
if format.lower() == paperSize['format'].lower():
p.setPaperSize(size)
break
else:
return False

border = floor(self.stringToPointSize(paperSize['border'])) if paperSize.get('border') else 0
p.setPageMargins(border, border, border, border, QPrinter.Point)

self.m_page.mainFrame().print_(p)
return True

def returnValue(self):
return self.m_returnValue

def stringToPointSize(self, string):
units = (
('mm', 72 / 25.4),
('cm', 72 / 2.54),
('in', 72.0),
('px', 72.0 / pdf_dpi / 2.54),
('', 72.0 / pdf_dpi / 2.54)
)

for unit, format in units:
if string.endswith(unit):
value = string.rstrip(unit)
return float(value) * format
return 0

##
# Properties and methods exposed to JavaScript
##
Expand Down Expand Up @@ -243,18 +310,27 @@ def open_(self, address):
self.m_loadStatus = 'loading'
self.m_page.mainFrame().setUrl(QUrl(address))

@pyqtSlot(str)
@pyqtProperty('QVariantMap')
def paperSize(self):
return self.m_paperSize

@paperSize.setter
def paperSize(self, size):
# convert QString to str
buffer = {}
for key, value in size.items():
buffer[str(key)] = str(value)

self.m_paperSize = buffer

@pyqtSlot(str, result=bool)
def render(self, fileName):
fileInfo = QFileInfo(fileName)
dir = QDir()
dir.mkpath(fileInfo.absolutePath())

if fileName.toLower().endsWith('.pdf'):
p = QPrinter()
p.setOutputFormat(QPrinter.PdfFormat)
p.setOutputFileName(fileName)
self.m_page.mainFrame().print_(p)
return True
if fileName.endsWith('.pdf', Qt.CaseInsensitive):
return self.renderPdf(fileName)

viewportSize = QSize(self.m_page.viewportSize())
pageSize = QSize(self.m_page.mainFrame().contentsSize())
Expand Down