diff --git a/old/README b/old/README
deleted file mode 100644
index 5f5bdad..0000000
--- a/old/README
+++ /dev/null
@@ -1,9 +0,0 @@
-Historical versions of WRP and prior art
-
-License: GNU
-
-Copyright (c) 2013-2018 Antoni Sawicki
-Copyright (c) 2012-2013 picidae.net
-Copyright (c) 2004-2013 Paul Hammond
-Copyright (c) 2017-2018 Natalia Portillo
-Copyright (c) 2018 //gir.st/
\ No newline at end of file
diff --git a/old/picidae.py b/old/picidae.py
deleted file mode 100644
index 3ddbd10..0000000
--- a/old/picidae.py
+++ /dev/null
@@ -1,392 +0,0 @@
-#!/usr/bin/env python
-
-# picidae.py - makes screenshots of webpages
-# and analyzes the webpage structure and writes image-maps of the links
-# as well as forms that are placed on the exact position of the old form.
-# It is a part of the art project www.picidae.net
-# http://www.picidae.net
-
-#
-# This script is based on webkit2png from Paul Hammond.
-# It was extended by picidae.net
-#
-# 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 2
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-__version__ = "1.0"
-
-
-import sys
-
-
-#print "hello ... "
-
-
-try:
- import Foundation
- import WebKit
- import AppKit
- import objc
- import urllib
-except ImportError:
- print "Cannot find pyobjc library files. Are you sure it is installed?"
- sys.exit()
-
-
-
-
-
-#try:
-# from optparse import OptionParser
-#except ImportError:
-# print "OptionParser not imported"
-# sys.exit()
-
-from optparse import OptionParser
-
-
-class AppDelegate (Foundation.NSObject):
- # what happens when the app starts up
- def applicationDidFinishLaunching_(self, aNotification):
- webview = aNotification.object().windows()[0].contentView()
- webview.frameLoadDelegate().getURL(webview)
-
-
-class WebkitLoad (Foundation.NSObject, WebKit.protocols.WebFrameLoadDelegate):
- # what happens if something goes wrong while loading
- def webView_didFailLoadWithError_forFrame_(self,webview,error,frame):
- print " ... something went wrong 1"
- self.getURL(webview)
- def webView_didFailProvisionalLoadWithError_forFrame_(self,webview,error,frame):
- print " ... something went wrong 2"
- self.getURL(webview)
-
- def makeFilename(self,URL,options):
- # make the filename
- if options.filename:
- filename = options.filename
- elif options.md5:
- try:
- import md5
- except ImportError:
- print "--md5 requires python md5 library"
- AppKit.NSApplication.sharedApplication().terminate_(None)
- filename = md5.new(URL).hexdigest()
- else:
- import re
- filename = re.sub('\W','',URL);
- filename = re.sub('^http','',filename);
- if options.datestamp:
- import time
- now = time.strftime("%Y%m%d")
- filename = now + "-" + filename
- import os
- dir = os.path.abspath(os.path.expanduser(options.dir))
- return os.path.join(dir,filename)
-
- def saveImages(self,bitmapdata,filename,options):
- # save the fullsize png
- if options.fullsize:
- bitmapdata.representationUsingType_properties_(AppKit.NSPNGFileType,None).writeToFile_atomically_(filename + ".png",objc.YES)
-
- if options.thumb or options.clipped:
- # work out how big the thumbnail is
- width = bitmapdata.pixelsWide()
- height = bitmapdata.pixelsHigh()
- thumbWidth = (width * options.scale)
- thumbHeight = (height * options.scale)
-
- # make the thumbnails in a scratch image
- scratch = AppKit.NSImage.alloc().initWithSize_(
- Foundation.NSMakeSize(thumbWidth,thumbHeight))
- scratch.lockFocus()
- AppKit.NSGraphicsContext.currentContext().setImageInterpolation_(
- AppKit.NSImageInterpolationHigh)
- thumbRect = Foundation.NSMakeRect(0.0, 0.0, thumbWidth, thumbHeight)
- clipRect = Foundation.NSMakeRect(0.0,
- thumbHeight-options.clipheight,
- options.clipwidth, options.clipheight)
- bitmapdata.drawInRect_(thumbRect)
- thumbOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(thumbRect)
- clipOutput = AppKit.NSBitmapImageRep.alloc().initWithFocusedViewRect_(clipRect)
- scratch.unlockFocus()
-
- # save the thumbnails as pngs
- if options.thumb:
- thumbOutput.representationUsingType_properties_(
- AppKit.NSPNGFileType,None
- ).writeToFile_atomically_(filename + "-thumb.png",objc.YES)
- if options.clipped:
- clipOutput.representationUsingType_properties_(
- AppKit.NSPNGFileType,None
- ).writeToFile_atomically_(filename + "-clipped.png",objc.YES)
-
- def getURL(self,webview):
- if self.urls:
- if self.urls[0] == '-':
- url = sys.stdin.readline().rstrip()
- if not url: AppKit.NSApplication.sharedApplication().terminate_(None)
- else:
- url = self.urls.pop(0)
- else:
- AppKit.NSApplication.sharedApplication().terminate_(None)
- #print "", url, "..."
- #print "" % (url)
- self.resetWebview(webview)
- webview.mainFrame().loadRequest_(Foundation.NSURLRequest.requestWithURL_(Foundation.NSURL.URLWithString_(url)))
- if not webview.mainFrame().provisionalDataSource():
- print ""
- self.getURL(webview)
-
- def resetWebview(self,webview):
- rect = Foundation.NSMakeRect(0,0,self.options.initWidth,self.options.initHeight)
- webview.window().setContentSize_((self.options.initWidth,self.options.initHeight))
- webview.setFrame_(rect)
-
- def resizeWebview(self,view):
- view.window().display()
- view.window().setContentSize_(view.bounds().size)
- view.setFrame_(view.bounds())
-
- def captureView(self,view):
- view.lockFocus()
- bitmapdata = AppKit.NSBitmapImageRep.alloc()
- bitmapdata.initWithFocusedViewRect_(view.bounds())
- view.unlockFocus()
- return bitmapdata
-
- # what happens when the page has finished loading
- def webView_didFinishLoadForFrame_(self,webview,frame):
- # don't care about subframes
- if (frame == webview.mainFrame()):
- view = frame.frameView().documentView()
-
- self.resizeWebview(view)
-
- URL = frame.dataSource().initialRequest().URL().absoluteString()
- filename = self.makeFilename(URL, self.options)
-
- bitmapdata = self.captureView(view)
- self.saveImages(bitmapdata,filename,self.options)
-
- # ----------------------------------
- # picidae my stuff
-
-
- #print "url"
- print ""
- print frame.dataSource().request().URL().absoluteString()
- print ""
-
-
- # Analyse HTML and get links
- xmloutput = ""
- xmloutput += ""
- f = open(filename +'.xml', 'w+')
- f.write(xmloutput)
- f.close()
-
- # ----------------------------------
- # get forms
- xmloutput = "\r";
- xmloutput += "\r"
-
- domdocument = frame.DOMDocument()
- domnodelist = domdocument.getElementsByTagName_('form')
- i = 0
- while i < domnodelist.length():
- # form
- action = domnodelist.item_(i).valueForKey_('action')
- method = domnodelist.item_(i).valueForKey_('method')
- xmloutput += "\r"
- i += 1
-
- xmloutput += ""
- f = open(filename +'.form.xml', 'w+')
- f.write(xmloutput)
- f.close()
-
-
- # End picidae
- # ----------------------------------
-
-
- #print " ... done"
- self.getURL(webview)
-
- #trying to give back the real url
-
-
-def main():
-
- # parse the command line
- usage = """%prog [options] [http://example.net/ ...]
-
-examples:
-%prog http://google.com/ # screengrab google
-%prog -W 1000 -H 1000 http://google.com/ # bigger screengrab of google
-%prog -T http://google.com/ # just the thumbnail screengrab
-%prog -TF http://google.com/ # just thumbnail and fullsize grab
-%prog -o foo http://google.com/ # save images as "foo-thumb.png" etc
-%prog - # screengrab urls from stdin"""
-
- cmdparser = OptionParser(usage, version=("webkit2png "+__version__))
- # TODO: add quiet/verbose options
- cmdparser.add_option("-W", "--width",type="float",default=800.0,
- help="initial (and minimum) width of browser (default: 800)")
- cmdparser.add_option("-H", "--height",type="float",default=600.0,
- help="initial (and minimum) height of browser (default: 600)")
- cmdparser.add_option("--clipwidth",type="float",default=200.0,
- help="width of clipped thumbnail (default: 200)",
- metavar="WIDTH")
- cmdparser.add_option("--clipheight",type="float",default=150.0,
- help="height of clipped thumbnail (default: 150)",
- metavar="HEIGHT")
- cmdparser.add_option("-s", "--scale",type="float",default=0.25,
- help="scale factor for thumbnails (default: 0.25)")
- cmdparser.add_option("-m", "--md5", action="store_true",
- help="use md5 hash for filename (like del.icio.us)")
- cmdparser.add_option("-o", "--filename", type="string",default="",
- metavar="NAME", help="save images as NAME.png,NAME-thumb.png etc")
- cmdparser.add_option("-F", "--fullsize", action="store_true",
- help="only create fullsize screenshot")
- cmdparser.add_option("-T", "--thumb", action="store_true",
- help="only create thumbnail sreenshot")
- cmdparser.add_option("-C", "--clipped", action="store_true",
- help="only create clipped thumbnail screenshot")
- cmdparser.add_option("-d", "--datestamp", action="store_true",
- help="include date in filename")
- cmdparser.add_option("-D", "--dir",type="string",default="./",
- help="directory to place images into")
- (options, args) = cmdparser.parse_args()
- if len(args) == 0:
- cmdparser.print_help()
- return
- if options.filename:
- if len(args) != 1 or args[0] == "-":
- print "--filename option requires exactly one url"
- return
- if options.scale == 0:
- cmdparser.error("scale cannot be zero")
- # make sure we're outputing something
- if not (options.fullsize or options.thumb or options.clipped):
- options.fullsize = True
- options.thumb = True
- options.clipped = True
- # work out the initial size of the browser window
- # (this might need to be larger so clipped image is right size)
- options.initWidth = (options.clipwidth / options.scale)
- options.initHeight = (options.clipheight / options.scale)
- if options.width>options.initWidth:
- options.initWidth = options.width
- if options.height>options.initHeight:
- options.initHeight = options.height
-
-
- app = AppKit.NSApplication.sharedApplication()
-
- # create an app delegate
- delegate = AppDelegate.alloc().init()
- AppKit.NSApp().setDelegate_(delegate)
-
- # create a window
- rect = Foundation.NSMakeRect(-16000,-16000,100,100)
- win = AppKit.NSWindow.alloc()
- win.initWithContentRect_styleMask_backing_defer_ (rect,
- AppKit.NSBorderlessWindowMask, 2, 0)
-
- # create a webview object
- webview = WebKit.WebView.alloc()
- webview.initWithFrame_(rect)
- # turn off scrolling so the content is actually x wide and not x-15
- webview.mainFrame().frameView().setAllowsScrolling_(objc.NO)
- # add the webview to the window
- win.setContentView_(webview)
-
-
- # create a LoadDelegate
- loaddelegate = WebkitLoad.alloc().init()
- loaddelegate.options = options
- loaddelegate.urls = args
- webview.setFrameLoadDelegate_(loaddelegate)
-
- app.run()
-
-if __name__ == '__main__' : main()
-
diff --git a/old/webkit2png.py b/old/webkit2png.py
deleted file mode 100644
index 7241be2..0000000
--- a/old/webkit2png.py
+++ /dev/null
@@ -1,506 +0,0 @@
-#!/usr/bin/python
-
-# webkit2png - makes screenshots of web pages
-# http://www.paulhammond.org/webkit2png
-
-__version__ = "dev"
-
-# Copyright (c) 2004-2013 Paul Hammond
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-
-import sys
-import optparse
-import re
-import os
-
-try:
- import Foundation
- import WebKit
- import AppKit
- import Quartz
- import objc
-except ImportError:
- print "Cannot find pyobjc library files. Are you sure it is installed?"
- sys.exit()
-
-
-class AppDelegate(Foundation.NSObject):
- # what happens when the app starts up
- def applicationDidFinishLaunching_(self, aNotification):
- webview = aNotification.object().windows()[0].contentView()
- webview.frameLoadDelegate().getURL(webview)
- self.performSelector_withObject_afterDelay_("timeout:", None,
- self.timeout)
-
- def timeout_(self, obj):
- Foundation.NSLog("timed out!")
- AppKit.NSApplication.sharedApplication().terminate_(None)
-
-
-class Webkit2PngScriptBridge(Foundation.NSObject):
- def init(self):
- self = super(Webkit2PngScriptBridge, self).init()
- self.is_stopped = False
- self.start_callback = False
- return self
-
- def stop(self):
- self.is_stopped = True
-
- def start(self):
- self.is_stopped = False
- self.start_callback()
-
- def isSelectorExcludedFromWebScript_(self, sel):
- if sel in ['stop', 'start']:
- return False
- else:
- return True
-
-
-class WebkitLoad (Foundation.NSObject, WebKit.protocols.WebFrameLoadDelegate):
-
- # what happens if something goes wrong while loading
- def webView_didFailLoadWithError_forFrame_(self, webview, error, frame):
- if error.code() == Foundation.NSURLErrorCancelled:
- return
- print " ... something went wrong: "+error.localizedDescription()
- self.getURL(webview)
-
- def webView_didFailProvisionalLoadWithError_forFrame_(self, webview, error,
- frame):
- if error.code() == Foundation.NSURLErrorCancelled:
- return
- print " ... something went wrong: "+error.localizedDescription()
- self.getURL(webview)
-
- def makeFilename(self, URL, options):
- # make the filename
- if options.filename:
- filename = options.filename
- elif options.md5:
- try:
- import md5
- except ImportError:
- print "--md5 requires python md5 library"
- AppKit.NSApplication.sharedApplication().terminate_(None)
- filename = md5.new(URL).hexdigest()
- else:
- filename = re.sub('^https?', '', URL)
- filename = re.sub('\W', '', filename)
- if options.datestamp:
- import time
- now = time.strftime("%Y%m%d")
- filename = now + "-" + filename
- dir = os.path.abspath(os.path.expanduser(options.dir))
- if not os.path.exists(options.dir):
- os.makedirs(dir)
- return os.path.join(dir, filename)
-
- def saveImages(self, bitmapdata, filename, options):
- # save the fullsize png
- if options.fullsize:
- bitmapdata.representationUsingType_properties_(
- AppKit.NSPNGFileType,
- None
- ).writeToFile_atomically_(filename + "-full.png", objc.YES)
-
- if options.thumb or options.clipped:
- # work out how big the thumbnail is
- width = bitmapdata.pixelsWide()
- height = bitmapdata.pixelsHigh()
- thumbWidth = (width * options.scale)
- thumbHeight = (height * options.scale)
-
- # make the thumbnails in a scratch image
- scratch = AppKit.NSImage.alloc().initWithSize_(
- Foundation.NSMakeSize(thumbWidth, thumbHeight))
- scratch.lockFocus()
- AppKit.NSGraphicsContext.currentContext().setImageInterpolation_(
- AppKit.NSImageInterpolationHigh)
- thumbRect = Foundation.NSMakeRect(0.0, 0.0, thumbWidth,
- thumbHeight)
- clipRect = Foundation.NSMakeRect(
- 0.0,
- thumbHeight-options.clipheight,
- options.clipwidth,
- options.clipheight)
- bitmapdata.drawInRect_(thumbRect)
- thumbOutput = AppKit.NSBitmapImageRep.alloc()\
- .initWithFocusedViewRect_(thumbRect)
- clipOutput = AppKit.NSBitmapImageRep.alloc()\
- .initWithFocusedViewRect_(clipRect)
- scratch.unlockFocus()
-
- # save the thumbnails as pngs
- if options.thumb:
- thumbOutput.representationUsingType_properties_(
- AppKit.NSPNGFileType, None).writeToFile_atomically_(
- filename + "-thumb.png", objc.YES)
- if options.clipped:
- clipOutput.representationUsingType_properties_(
- AppKit.NSPNGFileType, None).writeToFile_atomically_(
- filename + "-clipped.png", objc.YES)
-
- def getURL(self, webview):
- if self.urls:
- if self.urls[0] == '-':
- url = sys.stdin.readline().rstrip()
- if not url:
- AppKit.NSApplication.sharedApplication().terminate_(None)
- else:
- url = self.urls.pop(0)
- else:
- AppKit.NSApplication.sharedApplication().terminate_(None)
-
- nsurl = Foundation.NSURL.URLWithString_(url)
- if not (nsurl and nsurl.scheme()):
- nsurl = Foundation.NSURL.alloc().initFileURLWithPath_(url)
- nsurl = nsurl.absoluteURL()
-
- if self.options.ignore_ssl_check:
- Foundation.NSURLRequest.setAllowsAnyHTTPSCertificate_forHost_(objc.YES, nsurl.host())
-
- print "Fetching", nsurl, "..."
- self.resetWebview(webview)
- scriptobject = webview.windowScriptObject()
- scriptobject.setValue_forKey_(Webkit2PngScriptBridge.alloc().init(),
- 'webkit2png')
-
- webview.mainFrame().loadRequest_(Foundation.NSURLRequest.requestWithURL_(nsurl))
- if not webview.mainFrame().provisionalDataSource():
- print " ... not a proper url?"
- self.getURL(webview)
-
- def resetWebview(self, webview):
- rect = Foundation.NSMakeRect(0, 0, self.options.initWidth,
- self.options.initHeight)
- window = webview.window()
- window.setContentSize_((self.options.initWidth,
- self.options.initHeight))
-
- if self.options.transparent:
- window.setOpaque_(objc.NO)
- window.setBackgroundColor_(AppKit.NSColor.clearColor())
- webview.setDrawsBackground_(objc.NO)
-
- webview.setFrame_(rect)
-
- def captureView(self, view):
- bounds = view.bounds()
- if bounds.size.height > self.options.UNSAFE_max_height:
- print >> sys.stderr, "Error: page height greater than %s, " \
- "clipping to avoid crashing windowserver." % \
- self.options.UNSAFE_max_height
- bounds.size.height = self.options.UNSAFE_max_height
- if bounds.size.width > self.options.UNSAFE_max_width:
- print >> sys.stderr, "Error: page width greater than %s, " \
- "clipping to avoid crashing windowserver." % \
- self.options.UNSAFE_max_width
- bounds.size.width = self.options.UNSAFE_max_width
-
- view.window().display()
- view.window().setContentSize_(
- Foundation.NSSize(self.options.initWidth, self.options.initHeight))
- view.setFrame_(bounds)
-
- if hasattr(view, "bitmapImageRepForCachingDisplayInRect_"):
- bitmapdata = view.bitmapImageRepForCachingDisplayInRect_(bounds)
- view.cacheDisplayInRect_toBitmapImageRep_(bounds, bitmapdata)
- else:
- view.lockFocus()
- bitmapdata = AppKit.NSBitmapImageRep.alloc()
- bitmapdata.initWithFocusedViewRect_(bounds)
- view.unlockFocus()
- return bitmapdata
-
- # what happens when the page has finished loading
- def webView_didFinishLoadForFrame_(self, webview, frame):
- # don't care about subframes
- if (frame == webview.mainFrame()):
- scriptobject = webview.windowScriptObject()
- if self.options.js:
- scriptobject.evaluateWebScript_(self.options.js)
-
- bridge = scriptobject.valueForKey_('webkit2png')
-
- def doGrab():
- Foundation.NSTimer.\
- scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(
- self.options.delay, self, self.doGrab, webview, False)
-
- if bridge.is_stopped:
- bridge.start_callback = doGrab
- else:
- doGrab()
-
- def doGrab(self, timer):
- webview = timer.userInfo()
- frame = webview.mainFrame()
- view = frame.frameView().documentView()
-
- URL = webview.mainFrame().dataSource().initialRequest().URL()\
- .absoluteString()
- filename = self.makeFilename(URL, self.options)
-
- bitmapdata = self.captureView(view)
-
- if self.options.selector:
- doc = frame.DOMDocument()
- el = doc.querySelector_(self.options.selector)
-
- if not el:
- print " ... no element matching %s found?" % \
- self.options.selector
- self.getURL(webview)
- return
-
- left, top = 0, 0
- parent = el
- while parent:
- left += parent.offsetLeft()
- top += parent.offsetTop()
- parent = parent.offsetParent()
-
- zoom = self.options.zoom
-
- cropRect = view.window().convertRectToBacking_(Foundation.NSMakeRect(
- zoom * left, zoom * top,
- zoom * el.offsetWidth(), zoom * el.offsetHeight()))
-
- cropped = Quartz.CGImageCreateWithImageInRect(
- bitmapdata.CGImage(), cropRect)
- bitmapdata = AppKit.NSBitmapImageRep.alloc().initWithCGImage_(
- cropped)
- Quartz.CGImageRelease(cropped)
-
- self.saveImages(bitmapdata, filename, self.options)
-
- print " ... done"
- self.getURL(webview)
-
-
-def main():
-
- # parse the command line
- usage = """%prog [options] [http://example.net/ ...]
-
-Examples:
-%prog http://google.com/ # screengrab google
-%prog -W 1000 -H 1000 http://google.com/ # bigger screengrab of google
-%prog -T http://google.com/ # just the thumbnail screengrab
-%prog -TF http://google.com/ # just thumbnail and fullsize grab
-%prog -o foo http://google.com/ # save images as "foo-thumb.png" etc
-%prog - # screengrab urls from stdin
-%prog /path/to/file.html # screengrab local html file
-%prog -h | less # full documentation"""
-
- cmdparser = optparse.OptionParser(usage,
- version=("webkit2png " + __version__))
- # TODO: add quiet/verbose options
- cmdparser.add_option("--debug", action="store_true",
- help=optparse.SUPPRESS_HELP)
-
- # warning: setting these too high can crash your window server
- cmdparser.add_option("--UNSAFE-max-height", type="int", default=30000,
- help=optparse.SUPPRESS_HELP)
- cmdparser.add_option("--UNSAFE-max-width", type="int", default=30000,
- help=optparse.SUPPRESS_HELP)
-
- group = optparse.OptionGroup(cmdparser, "Network Options")
- group.add_option("--timeout", type="float", default=60.0,
- help="page load timeout (default: 60)")
- group.add_option("--user-agent", type="string", default=False,
- help="set user agent header")
- group.add_option("--ignore-ssl-check", action="store_true", default=False,
- help="ignore SSL Certificate name mismatches")
- cmdparser.add_option_group(group)
-
- group = optparse.OptionGroup(cmdparser, "Browser Window Options")
- group.add_option(
- "-W", "--width", type="float", default=800.0,
- help="initial (and minimum) width of browser (default: 800)")
- group.add_option(
- "-H", "--height", type="float", default=600.0,
- help="initial (and minimum) height of browser (default: 600)")
- group.add_option(
- "-z", "--zoom", type="float", default=1.0,
- help='zoom level of browser, equivalent to "Zoom In" and "Zoom Out" '
- 'in "View" menu (default: 1.0)')
- group.add_option(
- "--selector", type="string",
- help="CSS selector for a single element to capture (first matching "
- "element will be used)")
- cmdparser.add_option_group(group)
-
- group = optparse.OptionGroup(cmdparser, "Output size options")
- group.add_option(
- "-F", "--fullsize", action="store_true",
- help="only create fullsize screenshot")
- group.add_option(
- "-T", "--thumb", action="store_true",
- help="only create thumbnail sreenshot")
- group.add_option(
- "-C", "--clipped", action="store_true",
- help="only create clipped thumbnail screenshot")
- group.add_option(
- "--clipwidth", type="float", default=200.0,
- help="width of clipped thumbnail (default: 200)",
- metavar="WIDTH")
- group.add_option(
- "--clipheight", type="float", default=150.0,
- help="height of clipped thumbnail (default: 150)",
- metavar="HEIGHT")
- group.add_option(
- "-s", "--scale", type="float", default=0.25,
- help="scale factor for thumbnails (default: 0.25)")
- cmdparser.add_option_group(group)
-
- group = optparse.OptionGroup(cmdparser, "Output filename options")
- group.add_option(
- "-D", "--dir", type="string", default="./",
- help="directory to place images into")
- group.add_option(
- "-o", "--filename", type="string", default="",
- metavar="NAME", help="save images as NAME-full.png,NAME-thumb.png etc")
- group.add_option(
- "-m", "--md5", action="store_true",
- help="use md5 hash for filename (like del.icio.us)")
- group.add_option(
- "-d", "--datestamp", action="store_true",
- help="include date in filename")
- cmdparser.add_option_group(group)
-
- group = optparse.OptionGroup(cmdparser, "Web page functionality")
- group.add_option(
- "--delay", type="float", default=0,
- help="delay between page load finishing and screenshot")
- group.add_option(
- "--js", type="string", default=None,
- help="JavaScript to execute when the window finishes loading"
- "(example: --js='document.bgColor=\"red\";'). "
- "If you need to wait for asynchronous code to finish before "
- "capturing the screenshot, call webkit2png.stop() before the "
- "async code runs, then webkit2png.start() to capture the image.")
- group.add_option(
- "--noimages", action="store_true",
- help=optparse.SUPPRESS_HELP)
- group.add_option(
- "--no-images", action="store_true",
- help="don't load images")
- group.add_option(
- "--nojs", action="store_true",
- help=optparse.SUPPRESS_HELP)
- group.add_option(
- "--no-js", action="store_true",
- help="disable JavaScript support")
- group.add_option(
- "--transparent", action="store_true",
- help="render output on a transparent background (requires a web "
- "page with a transparent background)", default=False)
- cmdparser.add_option_group(group)
-
- (options, args) = cmdparser.parse_args()
- if len(args) == 0:
- cmdparser.print_usage()
- return
- if options.filename:
- if len(args) != 1 or args[0] == "-":
- print "--filename option requires exactly one url"
- return
-
- # deprecated options
- if options.nojs:
- print >> sys.stderr, 'Warning: --nojs will be removed in ' \
- 'webkit2png 1.0. Please use --no-js.'
- options.no_js = True
- if options.noimages:
- print >> sys.stderr, 'Warning: --noimages will be removed in ' \
- 'webkit2png 1.0. Please use --no-images.'
- options.no_images = True
-
- if options.scale == 0:
- cmdparser.error("scale cannot be zero")
- # make sure we're outputing something
- if not (options.fullsize or options.thumb or options.clipped):
- options.fullsize = True
- options.thumb = True
- options.clipped = True
- # work out the initial size of the browser window
- # (this might need to be larger so clipped image is right size)
- options.initWidth = (options.clipwidth / options.scale)
- options.initHeight = (options.clipheight / options.scale)
- options.width *= options.zoom
- if options.width > options.initWidth:
- options.initWidth = options.width
- if options.height > options.initHeight:
- options.initHeight = options.height
-
- # Hide the dock icon (needs to run before NSApplication.sharedApplication)
- AppKit.NSBundle.mainBundle().infoDictionary()['LSBackgroundOnly'] = '1'
-
- app = AppKit.NSApplication.sharedApplication()
-
- # create an app delegate
- delegate = AppDelegate.alloc().init()
- delegate.timeout = options.timeout
- AppKit.NSApp().setDelegate_(delegate)
-
- # create a window
- rect = Foundation.NSMakeRect(0, 0, 100, 100)
- win = AppKit.NSWindow.alloc()
- win.initWithContentRect_styleMask_backing_defer_(
- rect, AppKit.NSBorderlessWindowMask, 2, 0)
- if options.debug:
- win.orderFrontRegardless()
- # create a webview object
- webview = WebKit.WebView.alloc()
- webview.initWithFrame_(rect)
- # turn off scrolling so the content is actually x wide and not x-15
- webview.mainFrame().frameView().setAllowsScrolling_(objc.NO)
-
- if options.user_agent:
- webview.setCustomUserAgent_(options.user_agent)
- else:
- webkit_version = Foundation.NSBundle.bundleForClass_(WebKit.WebView)\
- .objectForInfoDictionaryKey_(WebKit.kCFBundleVersionKey)[1:]
- webview.setApplicationNameForUserAgent_(
- "Like-Version/6.0 Safari/%s webkit2png/%s" % (webkit_version, __version__))
- webview.setPreferencesIdentifier_('webkit2png')
- webview.preferences().setLoadsImagesAutomatically_(not options.no_images)
- webview.preferences().setJavaScriptEnabled_(not options.no_js)
-
- if options.zoom != 1.0:
- webview._setZoomMultiplier_isTextOnly_(options.zoom, False)
-
- # add the webview to the window
- win.setContentView_(webview)
-
- # create a LoadDelegate
- loaddelegate = WebkitLoad.alloc().init()
- loaddelegate.options = options
- loaddelegate.urls = args
- webview.setFrameLoadDelegate_(loaddelegate)
-
- app.run()
-
-if __name__ == '__main__':
- main()
diff --git a/old/webrender.py b/old/webrender.py
deleted file mode 100644
index 10d062a..0000000
--- a/old/webrender.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/env python
-
-# webrender.py - recursively render web pages to a gif+imagemap of clickable links
-# caveat: this script requires to be run as a regular user and cannot run as a daemon
-# from apache cgi-bin, you can use python built in http server instead
-# usage:
-# create cgi-bin directory, copy webrender.py to cgi-bin and chmod 755
-# python -m CGIHTTPServer 8000
-# navigate web browser to http://x.x.x.x:8000/cgi-bin/webrender.py
-# the webrender-xxx.gif images are created in the CWD of the http server
-
-
-__version__ = "1.0"
-
-#
-# This program is based on the software picidae.py 1.0 from http://www.picidae.net
-# It was modified by Antoni Sawicki
-#
-# This program is based on the software webkit2png 0.4 from Paul Hammond.
-# It was extended by picidae.net
-#
-# 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 2
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-try:
- import sys
- import os
- import glob
- import random
- import Foundation
- import WebKit
- import AppKit
- import objc
- import string
- import urllib
- import socket
- import cgi
- import cgitb; cgitb.enable() # for trubleshooting
-except ImportError:
- print "Cannot find pyobjc library files. Are you sure it is installed?"
- sys.exit()
-
-
-from optparse import OptionParser
-
-
-class AppDelegate (Foundation.NSObject):
- # what happens when the app starts up
- def applicationDidFinishLaunching_(self, aNotification):
- webview = aNotification.object().windows()[0].contentView()
- webview.frameLoadDelegate().getURL(webview)
-
-
-class WebkitLoad (Foundation.NSObject, WebKit.protocols.WebFrameLoadDelegate):
- # what happens if something goes wrong while loading
- def webView_didFailLoadWithError_forFrame_(self,webview,error,frame):
- print " ... something went wrong 1: " + error.localizedDescription()
- self.getURL(webview)
- def webView_didFailProvisionalLoadWithError_forFrame_(self,webview,error,frame):
- print " ... something went wrong 2: " + error.localizedDescription()
- self.getURL(webview)
-
- def getURL(self,webview):
- if self.urls:
- if self.urls[0] == '-':
- url = sys.stdin.readline().rstrip()
- if not url: AppKit.NSApplication.sharedApplication().terminate_(None)
- else:
- url = self.urls.pop(0)
- else:
- AppKit.NSApplication.sharedApplication().terminate_(None)
-
- self.resetWebview(webview)
- webview.mainFrame().loadRequest_(Foundation.NSURLRequest.requestWithURL_(Foundation.NSURL.URLWithString_(url)))
- if not webview.mainFrame().provisionalDataSource():
- print ""
- self.getURL(webview)
-
- def resetWebview(self,webview):
- rect = Foundation.NSMakeRect(0,0,1024,768)
- webview.window().setContentSize_((1024,768))
- webview.setFrame_(rect)
-
- def resizeWebview(self,view):
- view.window().display()
- view.window().setContentSize_(view.bounds().size)
- view.setFrame_(view.bounds())
-
- def captureView(self,view):
- view.lockFocus()
- bitmapdata = AppKit.NSBitmapImageRep.alloc()
- bitmapdata.initWithFocusedViewRect_(view.bounds())
- view.unlockFocus()
- return bitmapdata
-
- # what happens when the page has finished loading
- def webView_didFinishLoadForFrame_(self,webview,frame):
- # don't care about subframes
- if (frame == webview.mainFrame()):
- view = frame.frameView().documentView()
-
- self.resizeWebview(view)
-
- URL = frame.dataSource().initialRequest().URL().absoluteString()
-
- for fl in glob.glob("webrender-*.gif"):
- os.remove(fl)
-
- GIF = "webrender-%s.gif" % (random.randrange(0,1000))
-
- bitmapdata = self.captureView(view)
- bitmapdata.representationUsingType_properties_(AppKit.NSGIFFileType,None).writeToFile_atomically_(GIF,objc.YES)
-
- myurl = "http://%s:%s%s" % (socket.gethostbyname(socket.gethostname()), os.getenv("SERVER_PORT"), os.getenv("SCRIPT_NAME"))
-
- print "Content-type: text/html\r\n\r\n"
- print ""
- print "
Webrender - %s" % (URL)
- print " | "
- print " |
"
- print "" % (GIF)
-
-
- # Analyse HTML and get links
- print ""
- print ""
- self.getURL(webview)
-
-
-def main():
-
- # obtain url from cgi input
- form = cgi.FieldStorage()
- rawurl = form.getfirst("url", "http://www.google.com")
- rawsearch = form.getfirst("search")
- if rawsearch:
- url = "http://www.google.com/search?q=%s" % (rawsearch)
- else:
- url = string.replace( string.replace(rawurl, "TNXAMP", "&"), "TNXQUE", "?")
-
-
- AppKit.NSApplicationLoad();
-
- app = AppKit.NSApplication.sharedApplication()
-
- # create an app delegate
- delegate = AppDelegate.alloc().init()
- AppKit.NSApp().setDelegate_(delegate)
-
- # create a window
- rect = Foundation.NSMakeRect(-16000,-16000,100,100)
- win = AppKit.NSWindow.alloc()
- win.initWithContentRect_styleMask_backing_defer_ (rect, AppKit.NSBorderlessWindowMask, 2, 0)
-
- # create a webview object
- webview = WebKit.WebView.alloc()
- webview.initWithFrame_(rect)
- # turn off scrolling so the content is actually x wide and not x-15
- webview.mainFrame().frameView().setAllowsScrolling_(objc.NO)
- # add the webview to the window
- win.setContentView_(webview)
-
-
- # create a LoadDelegate
- loaddelegate = WebkitLoad.alloc().init()
- loaddelegate.options = [""]
- loaddelegate.urls = [url]
- webview.setFrameLoadDelegate_(loaddelegate)
-
- app.run()
-
-if __name__ == '__main__' : main()
-
diff --git a/old/wrp.py b/old/wrp.py
deleted file mode 100644
index ac3f061..0000000
--- a/old/wrp.py
+++ /dev/null
@@ -1,931 +0,0 @@
-#!/usr/bin/env python2.7
-
-# wrp.py - Web Rendering Proxy - https://github.com/tenox7/wrp
-# A HTTP proxy service that renders the requested URL in to a image associated
-# with an imagemap of clickable links. This is an adaptation of previous works by
-# picidae.net and Paul Hammond.
-
-__version__ = "2.0"
-
-#
-# This program is based on the software picidae.py from picidae.net
-# It was modified by Antoni Sawicki and Natalia Portillo
-#
-# This program is based on the software webkit2png from Paul Hammond.
-# It was extended by picidae.net
-#
-# Copyright (c) 2013-2018 Antoni Sawicki
-# Copyright (c) 2012-2013 picidae.net
-# Copyright (c) 2004-2013 Paul Hammond
-# Copyright (c) 2017-2018 Natalia Portillo
-# Copyright (c) 2018 //gir.st/
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-
-# Configuration options:
-PORT = 8080
-WIDTH = 1024
-HEIGHT = 768
-ISMAP = False # ISMAP=True is Server side for Mosaic 1.1 and up. HTML 3.2 supports Client side maps (ISMAP=False)
-WAIT = 1 # sleep for 1 second to allow javascript renders
-QUALITY = 75 # For JPEG: image quality 0-100; For PNG: sets compression level (leftmost digit 0 fastest, 9 best)
-AUTOWIDTH = True # Check for browser width using javascript
-FORMAT = "AUTO" # AUTO = GIF for mac OS, JPG for rest; PNG, GIF, JPG as supported values.
-SSLSTRIP = True # enable to automatically downgrade secure requests
-
-# PythonMagick configuration options
-MK_MONOCHROME = False # Convert the render to a black and white dithered image
-MK_GRAYSCALE = False # Convert the render to a grayscal dithered image
-MK_COLORS = 0 # Reduce number of colors in the image. 0 for not reducing. Less than 256 works in grayscale also.
-MK_DITHER = False # Dither the image to reduce size. GIFs will always be dithered. Ignored if MK_COLORS is not set.
-
-import re
-import random
-import os
-import time
-import string
-import urllib
-import socket
-import SocketServer
-import SimpleHTTPServer
-import threading
-import Queue
-import sys
-import logging
-import StringIO
-import subprocess
-
-try:
- import PythonMagick
- HasMagick = True
-except ImportError:
- HasMagick = False
-
-# Request queue (URLs go in here)
-REQ = Queue.Queue()
-# Response queue (dummy response objects)
-RESP = Queue.Queue()
-# Renders dictionary
-RENDERS = {}
-
-#######################
-### Linux CODEPATH ###
-#######################
-
-if sys.platform.startswith('linux') or sys.platform.startswith('freebsd'):
- 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 *
- IsPyQt5 = True
- except ImportError:
- from PyQt4.QtCore import *
- from PyQt4.QtGui import *
- from PyQt4.QtWebKit import *
- from PyQt4.QtNetwork import *
- IsPyQt5 = False
-
- # claunia: Check how to use this in macOS
- logging.basicConfig(filename='/dev/stdout', level=logging.WARN, )
- logger = logging.getLogger('wrp')
-
- # Class for Website-Rendering. Uses QWebPage, which
- # requires a running QtGui to work.
- class WebkitRenderer(QObject):
- def __init__(self, **kwargs):
- """Sets default values for the properties."""
-
- if not QApplication.instance():
- raise RuntimeError(self.__class__.__name__ + \
- " requires a running QApplication instance")
- QObject.__init__(self)
-
- # Initialize default properties
- self.width = kwargs.get('width', 0)
- self.height = kwargs.get('height', 0)
- self.timeout = kwargs.get('timeout', 0)
- self.wait = kwargs.get('wait', 0)
- 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.
- self.grabWholeWindow = kwargs.get('grabWholeWindow', False)
-
- # Set some default options for QWebPage
- self.qWebSettings = {
- QWebSettings.JavascriptEnabled : True,
- QWebSettings.PluginsEnabled : True,
- QWebSettings.PrivateBrowsingEnabled : True,
- QWebSettings.JavascriptCanOpenWindows : False
- }
-
- def render(self, url):
- """Renders the given URL into a QImage object"""
- # We have to use this helper object because
- # QApplication.processEvents may be called, causing
- # this method to get called while it has not returned yet.
- helper = _WebkitRendererHelper(self)
- helper._window.resize(self.width, self.height)
- image = helper.render(url)
-
- # Bind helper instance to this image to prevent the
- # object from being cleaned up (and with it the QWebPage, etc)
- # before the data has been used.
- image.helper = helper
-
- return image
-
- class _WebkitRendererHelper(QObject):
- """This helper class is doing the real work. It is required to
- allow WebkitRenderer.render() to be called "asynchronously"
- (but always from Qt's GUI thread).
- """
-
- def __init__(self, parent):
- """Copies the properties from the parent (WebkitRenderer) object,
- creates the required instances of QWebPage, QWebView and QMainWindow
- and registers some Slots.
- """
- QObject.__init__(self)
-
- # Copy properties from parent
- for key, value in parent.__dict__.items():
- setattr(self, key, value)
-
- # Create and connect required PyQt4 objects
- self._page = CustomWebPage(logger=self.logger)
- self._view = QWebView()
- self._view.setPage(self._page)
- self._window = QMainWindow()
- self._window.setCentralWidget(self._view)
-
- # Import QWebSettings
- for key, value in self.qWebSettings.iteritems():
- self._page.settings().setAttribute(key, value)
-
- # Connect required event listeners
- if IsPyQt5:
- 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)
- 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()
-
- def __del__(self):
- """Clean up Qt4 objects. """
- self._window.close()
- del self._window
- del self._view
- del self._page
-
- def render(self, url):
- """The real worker. Loads the page (_load_page) and awaits
- the end of the given 'delay'. While it is waiting outstanding
- QApplication events are processed.
- After the given delay, the Window or Widget (depends
- on the value of 'grabWholeWindow' is drawn into a QPixmap
- """
- self._load_page(url, self.width, self.height, self.timeout)
- # Wait for end of timer. In this time, process
- # other outstanding Qt events.
- if self.wait > 0:
- if self.logger: self.logger.debug("Waiting %d seconds " % self.wait)
- waitToTime = time.time() + self.wait
- while time.time() < waitToTime:
- if QApplication.hasPendingEvents():
- QApplication.processEvents()
-
- if self.grabWholeWindow:
- # Note that this does not fully ensure that the
- # window still has the focus when the screen is
- # grabbed. This might result in a race condition.
- self._view.activateWindow()
- if IsPyQt5:
- image = QScreen.grabWindow(self._window.winId())
- else:
- image = QPixmap.grabWindow(self._window.winId())
- else:
- if IsPyQt5:
- image = QWidget.grab(self._window)
- else:
- image = QPixmap.grabWidget(self._window)
-
- httpout = WebkitRenderer.httpout
-
- frame = self._view.page().currentFrame()
- web_url = frame.url().toString()
-
- # Write URL map
- httpout.write("\n"
- % (__version__))
- httpout.write("\n"
- % (WebkitRenderer.req_url, web_url))
- # Get title
- httpout.write("")
- for ttl in frame.findAllElements('title'):
- httpout.write((u"%s"
- % ttl.toPlainText()).encode('utf-8', errors='ignore'))
- break # Don't repeat bad HTML coding with several title marks
- httpout.write("\n\n")
-
- if AUTOWIDTH:
- httpout.write("\n")
-
- if ISMAP == True:
- httpout.write(""
- "\n"
- "\n" % (WebkitRenderer.req_map, WebkitRenderer.req_img))
- mapfile = StringIO.StringIO()
- mapfile.write("default %s\n" % (web_url))
- else:
- httpout.write("\n"
- "\n")
-
- httpout.write("\n\n")
-
- if ISMAP == True:
- RENDERS[WebkitRenderer.req_map] = mapfile
-
- return image
-
- def _load_page(self, url, width, height, timeout):
- """
- This method implements the logic for retrieving and displaying
- the requested page.
- """
-
- # This is an event-based application. So we have to wait until
- # "loadFinished(bool)" raised.
- cancelAt = time.time() + timeout
- self.__loading = True
- self.__loadingResult = False # Default
- self._page.mainFrame().load(QUrl(url))
- while self.__loading:
- if timeout > 0 and time.time() >= cancelAt:
- raise RuntimeError("Request timed out on %s" % url)
- while QApplication.hasPendingEvents() and self.__loading:
- QCoreApplication.processEvents()
-
- if self.logger: self.logger.debug("Processing result")
-
- if self.__loading_result == False:
- if self.logger: self.logger.warning("Failed to load %s" % url)
-
- # Set initial viewport (the size of the "window")
- 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)
-
- def _on_each_reply(self, reply):
- """Logs each requested uri"""
- self.logger.debug("Received %s" % (reply.url().toString()))
-
- # Eventhandler for "loadStarted()" signal
- def _on_load_started(self):
- """Slot that sets the '__loading' property to true."""
- if self.logger: self.logger.debug("loading started")
- self.__loading = True
-
- # Eventhandler for "loadFinished(bool)" signal
- def _on_load_finished(self, result):
- """Slot that sets the '__loading' property to false and stores
- the result code in '__loading_result'.
- """
- if self.logger: self.logger.debug("loading finished with result %s", result)
- self.__loading = False
- self.__loading_result = result
-
- # Eventhandler for "sslErrors(QNetworkReply *,const QList&)" signal
- def _on_ssl_errors(self, reply, errors):
- """Slot that writes SSL warnings into the log but ignores them."""
- for e in errors:
- if self.logger: self.logger.warn("SSL: " + e.errorString())
- reply.ignoreSslErrors()
-
- class CustomWebPage(QWebPage):
- def __init__(self, **kwargs):
- super(CustomWebPage, self).__init__()
- self.logger = kwargs.get('logger', None)
-
- def javaScriptAlert(self, frame, message):
- if self.logger: self.logger.debug('Alert: %s', message)
-
- def javaScriptConfirm(self, frame, message):
- if self.logger: self.logger.debug('Confirm: %s', message)
- return False
-
- def javaScriptPrompt(self, frame, message, default, result):
- """This function is called whenever a JavaScript program running inside frame tries to
- prompt the user for input. The program may provide an optional message, msg, as well
- as a default value for the input in defaultValue.
-
- If the prompt was cancelled by the user the implementation should return false;
- otherwise the result should be written to result and true should be returned.
- If the prompt was not cancelled by the user, the implementation should return true and
- the result string must not be null.
- """
- if self.logger: self.logger.debug('Prompt: %s (%s)' % (message, default))
- return False
-
- def shouldInterruptJavaScript(self):
- """This function is called when a JavaScript program is running for a long period of
- time. If the user wanted to stop the JavaScript the implementation should return
- true; otherwise false.
- """
- if self.logger: self.logger.debug("WebKit ask to interrupt JavaScript")
- return True
-
- #===============================================================================
-
- def init_qtgui(display=None, style=None, qtargs=None):
- """Initiates the QApplication environment using the given args."""
- if QApplication.instance():
- logger.debug("QApplication has already been instantiated. \
- Ignoring given arguments and returning existing QApplication.")
- return QApplication.instance()
-
- qtargs2 = [sys.argv[0]]
-
- if display:
- qtargs2.append('-display')
- qtargs2.append(display)
- # Also export DISPLAY var as this may be used
- # by flash plugin
- os.environ["DISPLAY"] = display
-
- if style:
- qtargs2.append('-style')
- qtargs2.append(style)
-
- qtargs2.extend(qtargs or [])
-
- return QApplication(qtargs2)
-
- # Technically, this is a QtGui application, because QWebPage requires it
- # to be. But because we will have no user interaction, and rendering can
- # not start before 'app.exec_()' is called, we have to trigger our "main"
- # by a timer event.
- def __main_qt():
- # Render the page.
- # If this method times out or loading failed, a
- # RuntimeException is thrown
- try:
- while True:
- req = REQ.get()
- WebkitRenderer.httpout = req[0]
- WebkitRenderer.req_url = req[1]
- WebkitRenderer.req_img = req[2]
- WebkitRenderer.req_map = req[3]
- if WebkitRenderer.req_url == "http://wrp.stop/" or WebkitRenderer.req_url == "http://www.wrp.stop/":
- print ">>> Terminate Request Received"
- QApplication.exit(0)
- break
-
- # Initialize WebkitRenderer object
- renderer = WebkitRenderer()
- renderer.logger = logger
- renderer.width = WIDTH
- renderer.height = HEIGHT
- renderer.timeout = 60
- renderer.wait = WAIT
- renderer.grabWholeWindow = False
-
- image = renderer.render(WebkitRenderer.req_url)
- qBuffer = QBuffer()
-
- if HasMagick:
- image.save(qBuffer, 'png', QUALITY)
- blob = PythonMagick.Blob(qBuffer.buffer().data())
- mimg = PythonMagick.Image(blob)
- mimg.quality(QUALITY)
-
- if FORMAT=="GIF" and not MK_MONOCHROME and not MK_GRAYSCALE and not MK_DITHER and MK_COLORS != 0 and not MK_COLORS <= 256:
- mimg.quantizeColors(256)
- mimg.quantizeDither()
- mimg.quantize()
-
- if MK_MONOCHROME:
- mimg.quantizeColorSpace(PythonMagick.ColorspaceType.GRAYColorspace)
- mimg.quantizeColors(2)
- mimg.quantizeDither()
- mimg.quantize()
- mimg.monochrome()
- elif MK_GRAYSCALE:
- mimg.quantizeColorSpace(PythonMagick.ColorspaceType.GRAYColorspace)
- if MK_COLORS > 0 and MK_COLORS < 256:
- mimg.quantizeColors(MK_COLORS)
- else:
- mimg.quantizeColors(256)
- mimg.quantizeDither()
- mimg.quantize()
- else:
- if MK_COLORS > 0:
- mimg.quantizeColors(MK_COLORS)
- if MK_DITHER:
- mimg.quantizeDither()
- mimg.quantize()
-
- if FORMAT=="AUTO" or FORMAT=="JPG":
- mimg.write(blob, "jpg")
- elif FORMAT=="PNG":
- mimg.write(blob, "png")
- elif FORMAT=="GIF":
- mimg.write(blob, "gif")
- output = StringIO.StringIO()
- output.write(blob.data)
- else:
- if FORMAT=="AUTO" or FORMAT=="JPG":
- image.save(qBuffer, 'jpg', QUALITY)
- elif FORMAT=="PNG":
- image.save(qBuffer, 'png', QUALITY)
-
- output = StringIO.StringIO()
- output.write(qBuffer.buffer().data())
-
- RENDERS[req[2]] = output
-
- del renderer
- print ">>> done: %s [%d kb]..." % (WebkitRenderer.req_img, output.len/1024)
-
- RESP.put('')
-
- QApplication.exit(0)
- except RuntimeError, e:
- logger.error("main: %s" % e)
- print >> sys.stderr, e
- QApplication.exit(1)
-
-######################
-### macOS CODEPATH ###
-######################
-
-elif sys.platform == "darwin":
- import Foundation
- import WebKit
- import AppKit
- import objc
-
- class AppDelegate(Foundation.NSObject):
- # what happens when the app starts up
- def applicationDidFinishLaunching_(self, aNotification):
- webview = aNotification.object().windows()[0].contentView()
- webview.frameLoadDelegate().getURL(webview)
-
- class WebkitLoad(Foundation.NSObject, WebKit.protocols.WebFrameLoadDelegate):
- # what happens if something goes wrong while loading
- def webView_didFailLoadWithError_forFrame_(self, webview, error, frame):
- if error.code() == Foundation.NSURLErrorCancelled:
- return
- print " ... something went wrong 1: " + error.localizedDescription()
- AppKit.NSApplication.sharedApplication().terminate_(None)
-
- def webView_didFailProvisionalLoadWithError_forFrame_(self, webview, error, frame):
- if error.code() == Foundation.NSURLErrorCancelled:
- return
- print " ... something went wrong 2: " + error.localizedDescription()
- AppKit.NSApplication.sharedApplication().terminate_(None)
-
- def getURL(self, webview):
- req = REQ.get()
- WebkitLoad.httpout = req[0]
- WebkitLoad.req_url = req[1]
- WebkitLoad.req_img = req[2]
- WebkitLoad.req_map = req[3]
-
- if WebkitLoad.req_url == "http://wrp.stop/" or WebkitLoad.req_url == "http://www.wrp.stop/":
- print ">>> Terminate Request Received"
- AppKit.NSApplication.sharedApplication().terminate_(None)
-
- nsurl = Foundation.NSURL.URLWithString_(WebkitLoad.req_url)
- if not (nsurl and nsurl.scheme()):
- nsurl = Foundation.NSURL.alloc().initFileURLWithPath_(WebkitLoad.req_url)
- nsurl = nsurl.absoluteURL()
-
- Foundation.NSURLRequest.setAllowsAnyHTTPSCertificate_forHost_(objc.YES, nsurl.host())
-
- self.resetWebview(webview)
- webview.mainFrame().loadRequest_(Foundation.NSURLRequest.requestWithURL_(nsurl))
- if not webview.mainFrame().provisionalDataSource():
- print " ... not a proper url?"
- RESP.put('')
- self.getURL(webview)
-
- def resetWebview(self, webview):
- rect = Foundation.NSMakeRect(0, 0, WIDTH, HEIGHT)
- webview.window().setContentSize_((WIDTH, HEIGHT))
- webview.setFrame_(rect)
-
- def captureView(self, view):
- view.window().display()
- view.window().setContentSize_(view.bounds().size)
- view.setFrame_(view.bounds())
-
- if hasattr(view, "bitmapImageRepForCachingDisplayInRect_"):
- bitmapdata = view.bitmapImageRepForCachingDisplayInRect_(view.bounds())
- view.cacheDisplayInRect_toBitmapImageRep_(view.bounds(), bitmapdata)
- else:
- view.lockFocus()
- bitmapdata = AppKit.NSBitmapImageRep.alloc()
- bitmapdata.initWithFocusedViewRect_(view.bounds())
- view.unlockFocus()
- return bitmapdata
-
- # what happens when the page has finished loading
- def webView_didFinishLoadForFrame_(self, webview, frame):
- # don't care about subframes
- if frame == webview.mainFrame():
- view = frame.frameView().documentView()
-
- output = StringIO.StringIO()
-
- if HasMagick:
- output.write(self.captureView(view).representationUsingType_properties_(
- AppKit.NSPNGFileType, None))
- blob = PythonMagick.Blob(output)
- mimg = PythonMagick.Image(blob)
- mimg.quality(QUALITY)
-
- if FORMAT=="GIF" and not MK_MONOCHROME and not MK_GRAYSCALE and not MK_DITHER and MK_COLORS != 0 and not MK_COLORS <= 256:
- mimg.quantizeColors(256)
- mimg.quantizeDither()
- mimg.quantize()
-
- if MK_MONOCHROME:
- mimg.quantizeColorSpace(PythonMagick.ColorspaceType.GRAYColorspace)
- mimg.quantizeColors(2)
- mimg.quantizeDither()
- mimg.quantize()
- mimg.monochrome()
- elif MK_GRAYSCALE:
- mimg.quantizeColorSpace(PythonMagick.ColorspaceType.GRAYColorspace)
- if MK_COLORS > 0 and MK_COLORS < 256:
- mimg.quantizeColors(MK_COLORS)
- else:
- mimg.quantizeColors(256)
- mimg.quantizeDither()
- mimg.quantize()
- else:
- if MK_COLORS > 0:
- mimg.quantizeColors(MK_COLORS)
- if MK_DITHER:
- mimg.quantizeDither()
- mimg.quantize()
-
- if FORMAT=="JPG":
- mimg.write(blob, "jpg")
- elif FORMAT=="PNG":
- mimg.write(blob, "png")
- elif FORMAT=="AUTO" or FORMAT=="GIF":
- mimg.write(blob, "gif")
- output = StringIO.StringIO()
- output.write(blob.data)
- else:
- if FORMAT=="AUTO" or FORMAT=="GIF":
- output.write(self.captureView(view).representationUsingType_properties_(
- AppKit.NSGIFFileType, None))
- elif FORMAT=="JPG":
- output.write(self.captureView(view).representationUsingType_properties_(
- AppKit.NSJPEGFileType, None))
- elif FORMAT=="PNG":
- output.write(self.captureView(view).representationUsingType_properties_(
- AppKit.NSPNGFileType, None))
-
- RENDERS[WebkitLoad.req_img] = output
-
- # url of the rendered page
- web_url = frame.dataSource().initialRequest().URL().absoluteString()
-
- httpout = WebkitLoad.httpout
-
- httpout.write("\n"
- % (__version__))
- httpout.write("\n"
- % (WebkitLoad.req_url, web_url))
-
- domdocument = frame.DOMDocument()
- # Get title
- httpout.write("")
- httpout.write((u"%s"
- % domdocument.title()).encode('utf-8', errors='ignore'))
- httpout.write("\n\n")
-
- if AUTOWIDTH:
- httpout.write("\n")
-
- if ISMAP == True:
- httpout.write(""
- "\n"
- "\n" % (WebkitLoad.req_map, WebkitLoad.req_img))
- mapfile = StringIO.StringIO()
- mapfile.write("default %s\n" % (web_url))
- else:
- httpout.write("\n"
- "\n")
-
- httpout.write("\n\n")
-
- if ISMAP == True:
- RENDERS[WebkitLoad.req_map] = mapfile
-
- # Return to Proxy thread and Loop...
- RESP.put('')
- self.getURL(webview)
-
- def main_cocoa():
- # Launch NS Application
- AppKit.NSApplicationLoad()
- app = AppKit.NSApplication.sharedApplication()
- delegate = AppDelegate.alloc().init()
- AppKit.NSApp().setDelegate_(delegate)
- AppKit.NSBundle.mainBundle().infoDictionary()['NSAppTransportSecurity'] = \
- dict(NSAllowsArbitraryLoads=True)
- rect = Foundation.NSMakeRect(-16000, -16000, 100, 100)
- win = AppKit.NSWindow.alloc()
- win.initWithContentRect_styleMask_backing_defer_(rect, AppKit.NSBorderlessWindowMask, 2, 0)
- webview = WebKit.WebView.alloc()
- webview.initWithFrame_(rect)
- webview.mainFrame().frameView().setAllowsScrolling_(objc.NO)
- webkit_version = Foundation.NSBundle.bundleForClass_(WebKit.WebView). \
- objectForInfoDictionaryKey_(WebKit.kCFBundleVersionKey)[1:]
- webview.setApplicationNameForUserAgent_("Like-Version/6.0 Safari/%s wrp/%s"
- % (webkit_version, __version__))
- win.setContentView_(webview)
- loaddelegate = WebkitLoad.alloc().init()
- loaddelegate.options = [""]
- webview.setFrameLoadDelegate_(loaddelegate)
- app.run()
-
-#######################
-### COMMON CODEPATH ###
-#######################
-class Proxy(SimpleHTTPServer.SimpleHTTPRequestHandler):
- def do_GET(self):
- req_url = self.path
- httpout = self.wfile
-
- map_re = re.match(r"http://(wrp-\d+\.map).*?(\d+),(\d+)", req_url)
- wid_re = re.match(r"http://(width-[0-9]+-px\.jpg).*", req_url)
- gif_re = re.match(r"http://(wrp-\d+\.gif).*", req_url)
- jpg_re = re.match(r"http://(wrp-\d+\.jpg).*", req_url)
- png_re = re.match(r"http://(wrp-\d+\.png).*", req_url)
-
- # Serve Rendered GIF
- if gif_re:
- img = gif_re.group(1)
- print ">>> request for rendered gif image... %s [%d kb]" \
- % (img, RENDERS[img].len/1024)
- self.send_response(200, 'OK')
- self.send_header('Content-type', 'image/gif')
- self.end_headers()
- httpout.write(RENDERS[img].getvalue())
- del RENDERS[img]
-
- elif jpg_re:
- img = jpg_re.group(1)
- print ">>> request for rendered jpg image... %s [%d kb]" \
- % (img, RENDERS[img].len/1024)
- self.send_response(200, 'OK')
- self.send_header('Content-type', 'image/jpeg')
- self.end_headers()
- httpout.write(RENDERS[img].getvalue())
- del RENDERS[img]
-
- elif png_re:
- img = png_re.group(1)
- print ">>> request for rendered png image... %s [%d kb]" \
- % (img, RENDERS[img].len/1024)
- self.send_response(200, 'OK')
- self.send_header('Content-type', 'image/png')
- self.end_headers()
- httpout.write(RENDERS[img].getvalue())
- del RENDERS[img]
-
- elif wid_re:
- global WIDTH
- try:
- wid = req_url.split("-")
- WIDTH = int(wid[1])
- print ">>> width request: %d" % WIDTH
- except:
- print ">>> width request error" % WIDTH
-
- self.send_error(404, "Width request")
- self.end_headers()
-
- # Process ISMAP Request
- elif map_re:
- map = map_re.group(1)
- req_x = int(map_re.group(2))
- req_y = int(map_re.group(3))
- print ">>> ISMAP request... %s [%d,%d] " % (map, req_x, req_y)
-
- mapf = RENDERS[map]
- mapf.seek(0)
- goto_url = "none"
- for line in mapf.readlines():
- if re.match(r"(\S+)", line).group(1) == "default":
- default_url = re.match(r"\S+\s+(\S+)", line).group(1)
-
- elif re.match(r"(\S+)", line).group(1) == "rect":
- try:
- rect = re.match(r"(\S+)\s+(\S+)\s+(\d+),(\d+)\s+(\d+),(\d+)", line)
- min_x = int(rect.group(3))
- min_y = int(rect.group(4))
- max_x = int(rect.group(5))
- max_y = int(rect.group(6))
- if (req_x >= min_x) and \
- (req_x <= max_x) and \
- (req_y >= min_y) and \
- (req_y <= max_y):
- goto_url = rect.group(2)
- except AttributeError:
- pass
-
- if goto_url == "none":
- goto_url = default_url
-
- print ">>> ISMAP redirect: %s\n" % (goto_url)
-
- self.send_response(302, "Found")
- self.send_header("Location", goto_url)
- self.send_header("Content-type", "text/html")
- self.end_headers()
- httpout.write("%s\n"
- % (goto_url, goto_url))
-
- # Process a web page request and generate image
- else:
- print ">>> URL request... " + req_url
-
- if req_url == "http://wrp.stop/" or req_url == "http://www.wrp.stop/":
- REQ.put((httpout, req_url, "", ""))
- RESP.get()
- else:
- reqst = urllib.urlopen(req_url)
-
- if reqst.info().type == "text/html" or reqst.info().type == "application/xhtml+xml":
- # If an error occurs, send error headers to the requester
- if reqst.getcode() >= 400:
- self.send_response(reqst.getcode())
- for hdr in reqst.info():
- self.send_header(hdr, reqst.info()[hdr])
- self.end_headers()
- else:
- self.send_response(200, 'OK')
- self.send_header('Content-type', 'text/html')
- self.end_headers()
-
- rnd = random.randrange(0, 1000)
-
- if FORMAT == "GIF":
- req_extension = ".gif"
- elif FORMAT == "JPG":
- req_extension = ".jpg"
- elif FORMAT == "PNG":
- req_extension = ".png"
- elif (sys.platform.startswith('linux') or sys.platform.startswitch('freebsd')) and FORMAT == "AUTO":
- req_extension = ".jpg"
- elif sys.platform == "darwin" and FORMAT == "AUTO":
- req_extension = ".gif"
-
- req_img = "wrp-%s%s" % (rnd, req_extension)
- req_map = "wrp-%s.map" % (rnd)
-
- # To WebKit Thread
- REQ.put((httpout, req_url, req_img, req_map))
- # Wait for completition
- RESP.get()
- # If the requested file is not HTML or XHTML, just return it as is.
- else:
- self.send_response(reqst.getcode())
- for hdr in reqst.info():
- self.send_header(hdr, reqst.info()[hdr])
- self.end_headers()
- httpout.write(reqst.read())
-
-def run_proxy():
- httpd = SocketServer.TCPServer(('', PORT), Proxy)
- print "Web Rendering Proxy v%s serving at port: %s" % (__version__, PORT)
- while 1:
- httpd.serve_forever()
-
-def main():
- if(FORMAT != "AUTO" and FORMAT != "GIF" and FORMAT != "JPG" and FORMAT != "PNG"):
- sys.exit("Unsupported image format \"%s\". Exiting." % FORMAT)
-
- if (sys.platform.startswith('linux') or sys.platform.startswith('freebsd')) and FORMAT == "GIF" and not HasMagick:
- sys.exit("GIF format is not supported on this platform. Exiting.")
-
- # run traffic through sslstrip as a quick workaround for getting SSL webpages to work
- # NOTE: modern browsers are doing their best to stop this kind of 'attack'. Firefox
- # supports an about:config flag test.currentTimeOffsetSeconds(int) = 12000000, which
- # you can use to circumvent those checks.
- if SSLSTRIP:
- try:
- subprocess.check_output(["pidof", "sslstrip"])
- except:
- subprocess.Popen(["sslstrip"], stdout=open(os.devnull,'w'), stderr=subprocess.STDOUT) # runs on port 10000 by default
- QNetworkProxy.setApplicationProxy(QNetworkProxy(QNetworkProxy.HttpProxy, "localhost", 10000))
- # Launch Proxy Thread
- threading.Thread(target=run_proxy).start()
-
- if sys.platform.startswith('linux') or sys.platform.startswith('freebsd'):
- import signal
- try:
- import PyQt5.QtCore
- except ImportError:
- import PyQt4.QtCore
- # Initialize Qt-Application, but make this script
- # abortable via CTRL-C
- app = init_qtgui(display=None, style=None)
- signal.signal(signal.SIGINT, signal.SIG_DFL)
-
- QTimer.singleShot(0, __main_qt)
- sys.exit(app.exec_())
- elif sys.platform == "darwin":
- main_cocoa()
- else:
- sys.exit("Unsupported platform: %s. Exiting." % sys.platform)
-
-if __name__ == '__main__': main()