Example #1
0
 def __init__(self):
     logging.debug("-->")
     super(WebBrowser, self).__init__()
     self.app = QApplication.instance()
     if self.app is None:
         self.app = QApplication(sys.argv)
         self.app.setQuitOnLastWindowClosed(False)
     self.event_loop = QEventLoop()
     self.cookie_jar = CookieJar()
     self.proxy = QNetworkProxy(QNetworkProxy.HttpProxy, "127.0.1.1", 8888)
     self.network_manager = NetworkAccessManager() 
     self.network_manager.setCookieJar(self.cookie_jar)
     # self.network_manager.setProxy(self.proxy)
     self.web_page = WebPage()        
     self.web_page.setNetworkAccessManager(self.network_manager)
     self.web_view = QWebView()
     self.web_view.setPage(self.web_page)        
     self.web_view.settings().setAttribute(QWebSettings.AutoLoadImages,False)
     self.web_view.settings().setAttribute(QWebSettings.PluginsEnabled, True)
     self.web_view.settings().setAttribute(QWebSettings.JavascriptEnabled, True)
     # self.web_view.settings().setAttribute(QWebSettings.XSSAuditingEnabled, False)
     self.web_view.settings().setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True) 
     self.connect(self.web_view.page().networkAccessManager(),SIGNAL("finished(QNetworkReply*)"),self.network_reply_finished)
     self.page_loaded_validator = None
     self.page_loaded_handler = None
     self.page_loaded_handler_kwargs = None
     self.timeout_message = None
     self.timer = None
     self.event_loop_exception = None
     logging.debug("<--")
Example #2
0
    def __init__(self, args, parent=None):
        QObject.__init__(self, parent)

        # variable declarations
        self.m_defaultPageSettings = {}
        self.m_pages = []
        self.m_verbose = args.verbose
        self.m_page = WebPage(self)
        self.m_returnValue = 0
        self.m_terminated = False
        # setup the values from args
        self.m_scriptFile = args.script
        self.m_args = args.script_args

        self.m_filesystem = FileSystem(self)
        self.m_pages.append(self.m_page)

        do_action('PhantomInitPre')

        if not args.proxy:
            QNetworkProxyFactory.setUseSystemConfiguration(True)
        else:
            proxy = QNetworkProxy(QNetworkProxy.HttpProxy, args.proxy[0],
                                  int(args.proxy[1]))
            QNetworkProxy.setApplicationProxy(proxy)

        # Provide WebPage with a non-standard Network Access Manager
        self.m_netAccessMan = NetworkAccessManager(args.disk_cache,
                                                   args.ignore_ssl_errors,
                                                   self)
        self.m_page.setNetworkAccessManager(self.m_netAccessMan)

        self.m_page.javaScriptConsoleMessageSent.connect(
            self.printConsoleMessage)

        self.m_defaultPageSettings['loadImages'] = args.load_images
        self.m_defaultPageSettings['loadPlugins'] = args.load_plugins
        self.m_defaultPageSettings['userAgent'] = self.m_page.userAgent()
        self.m_defaultPageSettings[
            'localAccessRemote'] = args.local_access_remote
        self.m_page.applySettings(self.m_defaultPageSettings)

        self.libraryPath = os.path.dirname(os.path.abspath(self.m_scriptFile))

        # inject our properties and slots into javascript
        self.m_page.mainFrame().addToJavaScriptWindowObject('phantom', self)
        self.m_page.mainFrame().addToJavaScriptWindowObject(
            'fs', self.m_filesystem)

        bootstrap = QFile(':/bootstrap.js')
        if not bootstrap.open(QFile.ReadOnly):
            sys.exit('Can not bootstrap!')
        bootstrapper = str(bootstrap.readAll())
        bootstrap.close()
        if not bootstrapper:
            sys.exit('Can not bootstrap!')
        self.m_page.mainFrame().evaluateJavaScript(bootstrapper)

        do_action('PhantomInitPost')
Example #3
0
 def __init__(self, settings):
     super(Browser, self).__init__()
     self._settings = settings
     self._cookie_jar = CookieJar()
     self._network_access_manager = NetworkAccessManager(self._cookie_jar)
     self._web_page = WebPage(settings)
     self._web_page.setNetworkAccessManager(self._network_access_manager)
     self._web_view = WebView(settings)
     self._web_view.setPage(self._web_page)
Example #4
0
    def __init__(self, parent, args):
        super(WebPage, self).__init__(parent)

        # variable declarations
        self.m_paperSize = {}
        self.m_clipRect = QRect()
        self.m_libraryPath = ''
        self.m_scrollPosition = QPoint()

        self.setObjectName('WebPage')
        self.m_webPage = CustomPage(self)
        self.m_mainFrame = self.m_webPage.mainFrame()

        self.m_mainFrame.javaScriptWindowObjectCleared.connect(self.initialized)
        self.m_webPage.loadStarted.connect(self.loadStarted)
        self.m_webPage.loadFinished.connect(self.finish)

        # Start with transparent background
        palette = self.m_webPage.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.m_webPage.setPalette(palette)

        # Page size does not need to take scrollbars into account
        self.m_webPage.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.m_webPage.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)

        self.m_webPage.settings().setAttribute(QWebSettings.OfflineStorageDatabaseEnabled, True)
        self.m_webPage.settings().setOfflineStoragePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_webPage.settings().setAttribute(QWebSettings.LocalStorageDatabaseEnabled, True)
        self.m_webPage.settings().setAttribute(QWebSettings.OfflineWebApplicationCacheEnabled, True)
        self.m_webPage.settings().setOfflineWebApplicationCachePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_webPage.settings().setAttribute(QWebSettings.FrameFlatteningEnabled, True)
        self.m_webPage.settings().setAttribute(QWebSettings.LocalStorageEnabled, True)
        self.m_webPage.settings().setLocalStoragePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))

        # Ensure we have a document.body.
        self.m_webPage.mainFrame().setHtml(self.blankHtml)

        # Custom network access manager to allow traffic monitoring
        self.m_networkAccessManager = NetworkAccessManager(self.parent(), args)
        self.m_webPage.setNetworkAccessManager(self.m_networkAccessManager)
        self.m_networkAccessManager.resourceRequested.connect(self.resourceRequested)
        self.m_networkAccessManager.resourceReceived.connect(self.resourceReceived)

        self.m_webPage.setViewportSize(QSize(400, 300))

        do_action('WebPageInit')
Example #5
0
    def __init__(self, parent, args):
        super(WebPage, self).__init__(parent)

        # variable declarations
        self.m_paperSize = {}
        self.m_clipRect = QRect()
        self.m_libraryPath = ''
        self.m_scrollPosition = QPoint()

        self.setObjectName('WebPage')
        self.m_webPage = CustomPage(self)
        self.m_mainFrame = self.m_webPage.mainFrame()

        self.m_mainFrame.javaScriptWindowObjectCleared.connect(self.initialized)
        self.m_webPage.loadStarted.connect(self.loadStarted)
        self.m_webPage.loadFinished.connect(self.finish)

        # Start with transparent background
        palette = self.m_webPage.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.m_webPage.setPalette(palette)

        # Page size does not need to take scrollbars into account
        self.m_webPage.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.m_webPage.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)

        self.m_webPage.settings().setAttribute(QWebSettings.OfflineStorageDatabaseEnabled, True)
        self.m_webPage.settings().setOfflineStoragePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_webPage.settings().setAttribute(QWebSettings.LocalStorageDatabaseEnabled, True)
        self.m_webPage.settings().setAttribute(QWebSettings.OfflineWebApplicationCacheEnabled, True)
        self.m_webPage.settings().setOfflineWebApplicationCachePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_webPage.settings().setAttribute(QWebSettings.FrameFlatteningEnabled, True)
        self.m_webPage.settings().setAttribute(QWebSettings.LocalStorageEnabled, True)
        self.m_webPage.settings().setLocalStoragePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))

        # Ensure we have a document.body.
        self.m_webPage.mainFrame().setHtml(self.blankHtml)

        # Custom network access manager to allow traffic monitoring
        self.m_networkAccessManager = NetworkAccessManager(self.parent(), args)
        self.m_webPage.setNetworkAccessManager(self.m_networkAccessManager)
        self.m_networkAccessManager.resourceRequested.connect(self.resourceRequested)
        self.m_networkAccessManager.resourceReceived.connect(self.resourceReceived)

        self.m_webPage.setViewportSize(QSize(400, 300))

        do_action('WebPageInit')
Example #6
0
    def __init__(self, args, parent=None):
        QObject.__init__(self, parent)

        # variable declarations
        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 = args.script.read()
        self.m_scriptFile = args.script.name
        self.m_scriptDir = os.path.dirname(args.script.name) + '/'
        self.m_args = args.script_args
        self.m_upload_file = args.upload_file
        autoLoadImages = False if args.load_images == 'no' else True
        pluginsEnabled = True if args.load_plugins == 'yes' else False

        args.script.close()

        do_action('PhantomInitPre', Bunch(locals()))

        palette = self.m_page.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.m_page.setPalette(palette)

        if not args.proxy:
            QNetworkProxyFactory.setUseSystemConfiguration(True)
        else:
            proxy = QNetworkProxy(QNetworkProxy.HttpProxy, args.proxy[0],
                                  int(args.proxy[1]))
            QNetworkProxy.setApplicationProxy(proxy)

        self.m_page.settings().setAttribute(QWebSettings.AutoLoadImages,
                                            autoLoadImages)
        self.m_page.settings().setAttribute(QWebSettings.PluginsEnabled,
                                            pluginsEnabled)
        self.m_page.settings().setAttribute(
            QWebSettings.FrameFlatteningEnabled, True)
        self.m_page.settings().setAttribute(
            QWebSettings.OfflineStorageDatabaseEnabled, True)
        self.m_page.settings().setAttribute(QWebSettings.LocalStorageEnabled,
                                            True)
        self.m_page.settings().setLocalStoragePath(
            QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_page.settings().setOfflineStoragePath(
            QDesktopServices.storageLocation(QDesktopServices.DataLocation))

        # Ensure we have a document.body.
        self.m_page.mainFrame().setHtml('<html><body></body></html>')

        self.m_page.mainFrame().setScrollBarPolicy(Qt.Horizontal,
                                                   Qt.ScrollBarAlwaysOff)
        self.m_page.mainFrame().setScrollBarPolicy(Qt.Vertical,
                                                   Qt.ScrollBarAlwaysOff)

        m_netAccessMan = NetworkAccessManager(args.disk_cache,
                                              args.ignore_ssl_errors, self)
        self.m_page.setNetworkAccessManager(m_netAccessMan)

        # inject our properties and slots into javascript
        self.m_page.mainFrame().javaScriptWindowObjectCleared.connect(
            self.inject)
        self.m_page.loadFinished.connect(self.finish)

        do_action('PhantomInitPost', Bunch(locals()))
Example #7
0
    def __init__(self, args, parent=None):
        QObject.__init__(self, parent)

        # variable declarations
        self.m_loadStatus = self.m_state = QString()
        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[0].read())
        self.m_scriptFile = args.script[0].name
        self.m_args = args.script[1:]
        self.m_upload_file = args.upload_file
        autoLoadImages = False if args.load_images == 'no' else True
        pluginsEnabled = True if args.load_plugins == 'yes' else False

        args.script[0].close()

        palette = self.m_page.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.m_page.setPalette(palette)

        if not args.proxy:
            QNetworkProxyFactory.setUseSystemConfiguration(True)
        else:
            proxy = QNetworkProxy(QNetworkProxy.HttpProxy, args.proxy[0],
                                  int(args.proxy[1]))
            QNetworkProxy.setApplicationProxy(proxy)

        self.m_page.settings().setAttribute(QWebSettings.AutoLoadImages,
                                            autoLoadImages)
        self.m_page.settings().setAttribute(QWebSettings.PluginsEnabled,
                                            pluginsEnabled)
        self.m_page.settings().setAttribute(
            QWebSettings.FrameFlatteningEnabled, True)
        self.m_page.settings().setAttribute(
            QWebSettings.OfflineStorageDatabaseEnabled, True)
        self.m_page.settings().setAttribute(QWebSettings.LocalStorageEnabled,
                                            True)
        self.m_page.settings().setLocalStoragePath(
            QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_page.settings().setOfflineStoragePath(
            QDesktopServices.storageLocation(QDesktopServices.DataLocation))

        # Ensure we have a document.body.
        self.m_page.mainFrame().setHtml('<html><body></body></html>')

        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(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)
Example #8
0
class WebBrowser(QObject):    
    def __init__(self):
        logging.debug("-->")
        super(WebBrowser, self).__init__()
        self.app = QApplication.instance()
        if self.app is None:
            self.app = QApplication(sys.argv)
            self.app.setQuitOnLastWindowClosed(False)
        self.event_loop = QEventLoop()
        self.cookie_jar = CookieJar()
        self.proxy = QNetworkProxy(QNetworkProxy.HttpProxy, "127.0.1.1", 8888)
        self.network_manager = NetworkAccessManager() 
        self.network_manager.setCookieJar(self.cookie_jar)
        # self.network_manager.setProxy(self.proxy)
        self.web_page = WebPage()        
        self.web_page.setNetworkAccessManager(self.network_manager)
        self.web_view = QWebView()
        self.web_view.setPage(self.web_page)        
        self.web_view.settings().setAttribute(QWebSettings.AutoLoadImages,False)
        self.web_view.settings().setAttribute(QWebSettings.PluginsEnabled, True)
        self.web_view.settings().setAttribute(QWebSettings.JavascriptEnabled, True)
        # self.web_view.settings().setAttribute(QWebSettings.XSSAuditingEnabled, False)
        self.web_view.settings().setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True) 
        self.connect(self.web_view.page().networkAccessManager(),SIGNAL("finished(QNetworkReply*)"),self.network_reply_finished)
        self.page_loaded_validator = None
        self.page_loaded_handler = None
        self.page_loaded_handler_kwargs = None
        self.timeout_message = None
        self.timer = None
        self.event_loop_exception = None
        logging.debug("<--")
                
    def network_reply_finished(self,reply):
        logging.debug("Reply received for: " + reply.request().url().toString())
        self.network_manager.request_queue[reply.request().url()] = "Completed"
        redirect_url = self.get_redirect_url(reply.attribute(QNetworkRequest.RedirectionTargetAttribute),reply.request().url())
        if redirect_url is not None:
            self.redirect(redirect_url,reply.request())
            
    def redirect(self,url,request):
        frame = self.find_frame_to_redirect(self.web_view.page().mainFrame(),request)
        if frame is not None:
            logging.debug("Redirecting to: " + url.toString())
            frame.load(url)                
    
    def find_frame_to_redirect(self,frame,request):
        if frame.requestedUrl() == request.url():
            return frame
        else:
            children = frame.childFrames()
            for child in children:
                frame_to_redirect = self.find_frame_to_redirect(child,request)
                if frame_to_redirect is not None:
                    return frame_to_redirect
            
    def get_redirect_url(self,possible_redirect_url, orig_requested_url):
        if possible_redirect_url is not None:
            if possible_redirect_url.isRelative():
                if orig_requested_url.isRelative():
                    return None
                possible_redirect_url.setScheme(orig_requested_url.scheme())
                possible_redirect_url.setHost(orig_requested_url.host())
            if orig_requested_url != possible_redirect_url:
                return possible_redirect_url
        
    def get_cookies(self):
        cookies = self.cookie_jar.allCookies()
        raw_cookies = []
        first = True
        for cookie in cookies:
            raw_cookies.append(cookie.toRawForm())
        return raw_cookies
        
    def set_cookies(self,raw_cookies):
        cookies = []
        for raw_cookie in raw_cookies:
            cookie_list = QNetworkCookie.parseCookies(raw_cookie)
            for cookie in cookie_list:
                cookies.append(cookie)
        self.cookie_jar.setAllCookies(cookies)
            
    def cleanup(self):
        logging.debug("-->")
        self.disconnect(self.web_view.page().networkAccessManager(),SIGNAL("finished(QNetworkReply*)"),self.network_reply_finished)        
        self.web_view.setParent(None)
        self.web_page.setParent(None)
        self.network_manager.setParent(None)        
        self.event_loop.setParent(None)
        self.setParent(None)        
        del self.web_view
        del self.web_page
        del self.network_manager
        del self.event_loop
        del self.app
        logging.debug("<--")
 def __init__(self, iface):
     self.nam = NetworkAccessManager()
class PDOKGeoLocator:
    def __init__(self, iface):
        self.nam = NetworkAccessManager()
        #self.canvas = iface.mapCanvas()

    def search(self, searchstring):
        # https://github.com/PDOK/locatieserver/wiki/API-Locatieserver
        url = 'http://geodata.nationaalgeoregister.nl/locatieserver/v3/free?q={}'.format(
            searchstring)
        addressesarray = []
        try:
            # TODO: Provide a valid HTTP Referer or User-Agent identifying the application (QGIS geocoder)
            (response, content) = self.nam.request(url)
            #print('xx response: {}'.format(response))
            # TODO: check statuscode etc in RESPONSE
            #print('xx content: {}'.format(content))

            content_string = content.decode('utf-8')
            obj = json.loads(content_string)
            docs = obj['response']['docs']
            for doc in docs:
                #print(doc)
                straat = u''
                adres = u''
                postcode = u''
                plaats = u''
                gemeente = doc['gemeentenaam']
                provincie = doc['provincienaam']
                x = u""
                y = u""
                centroide_rd = doc['centroide_rd']
                if doc['type'] == 'adres':
                    adrestekst = 'adres: ' + doc['weergavenaam']
                    adres = doc['weergavenaam']
                    straat = doc['straatnaam']
                    plaats = doc['woonplaatsnaam']
                elif doc['type'] == 'weg':
                    adrestekst = 'straat: ' + doc['weergavenaam']
                    straat = doc['straatnaam']
                    plaats = doc['woonplaatsnaam']
                elif doc['type'] == 'postcode':
                    adrestekst = 'postcode: ' + doc['weergavenaam']
                    postcode = doc['postcode']
                    straat = doc['straatnaam']
                    plaats = doc['woonplaatsnaam']
                elif doc['type'] == 'woonplaats':
                    adrestekst = 'plaats: ' + doc['woonplaatsnaam']
                    plaats = doc['woonplaatsnaam']
                elif doc['type'] == 'gemeente':
                    adrestekst = 'gemeente: ' + doc['gemeentenaam']

                addressdict = {
                    'straat': straat,
                    'adres': adres,
                    'postcode': postcode,
                    'plaats': plaats,
                    'gemeente': gemeente,
                    'provincie': provincie,
                    'x': x,
                    'y': y,
                    'centroide_rd': centroide_rd,
                    'adrestekst': adrestekst
                }
                addressesarray.append(addressdict)

        except RequestsException:
            # Handle exception
            #errno, strerror = RequestsException.args
            #print('!!!!!!!!!!! EXCEPTION !!!!!!!!!!!!!: \n{}\n{}'. format(errno, strerror))
            pass

        return addressesarray
Example #11
0
class WebPage(QObject):
    initialized = pyqtSignal()
    javaScriptAlertSent = pyqtSignal(str)
    javaScriptConsoleMessageSent = pyqtSignal(str, int, str)
    loadStarted = pyqtSignal()
    loadFinished = pyqtSignal(str)
    resourceReceived = pyqtSignal('QVariantMap')
    resourceRequested = pyqtSignal('QVariantMap')

    blankHtml = '<html><head></head><body></body></html>'

    def __init__(self, parent, args):
        super(WebPage, self).__init__(parent)

        # variable declarations
        self.m_paperSize = {}
        self.m_clipRect = QRect()
        self.m_libraryPath = ''
        self.m_scrollPosition = QPoint()

        self.setObjectName('WebPage')
        self.m_webPage = CustomPage(self)
        self.m_mainFrame = self.m_webPage.mainFrame()

        self.m_mainFrame.javaScriptWindowObjectCleared.connect(self.initialized)
        self.m_webPage.loadStarted.connect(self.loadStarted)
        self.m_webPage.loadFinished.connect(self.finish)

        # Start with transparent background
        palette = self.m_webPage.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.m_webPage.setPalette(palette)

        # Page size does not need to take scrollbars into account
        self.m_webPage.mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.m_webPage.mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)

        self.m_webPage.settings().setAttribute(QWebSettings.OfflineStorageDatabaseEnabled, True)
        self.m_webPage.settings().setOfflineStoragePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_webPage.settings().setAttribute(QWebSettings.LocalStorageDatabaseEnabled, True)
        self.m_webPage.settings().setAttribute(QWebSettings.OfflineWebApplicationCacheEnabled, True)
        self.m_webPage.settings().setOfflineWebApplicationCachePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))
        self.m_webPage.settings().setAttribute(QWebSettings.FrameFlatteningEnabled, True)
        self.m_webPage.settings().setAttribute(QWebSettings.LocalStorageEnabled, True)
        self.m_webPage.settings().setLocalStoragePath(QDesktopServices.storageLocation(QDesktopServices.DataLocation))

        # Ensure we have a document.body.
        self.m_webPage.mainFrame().setHtml(self.blankHtml)

        # Custom network access manager to allow traffic monitoring
        self.m_networkAccessManager = NetworkAccessManager(self.parent(), args)
        self.m_webPage.setNetworkAccessManager(self.m_networkAccessManager)
        self.m_networkAccessManager.resourceRequested.connect(self.resourceRequested)
        self.m_networkAccessManager.resourceReceived.connect(self.resourceReceived)

        self.m_webPage.setViewportSize(QSize(400, 300))

        do_action('WebPageInit')

    def applySettings(self, defaults):
        opt = self.m_webPage.settings()

        opt.setAttribute(QWebSettings.AutoLoadImages, defaults['loadImages'])
        opt.setAttribute(QWebSettings.PluginsEnabled, defaults['loadPlugins'])
        opt.setAttribute(QWebSettings.JavascriptEnabled, defaults['javascriptEnabled'])
        opt.setAttribute(QWebSettings.XSSAuditingEnabled, defaults['XSSAuditingEnabled'])
        opt.setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, defaults['localToRemoteUrlAccessEnabled'])

        if 'userAgent' in defaults:
            self.m_webPage.m_userAgent = defaults['userAgent']

        if 'userName' in defaults:
            self.m_networkAccessManager.setUserName(defaults['userName'])

        if 'password' in defaults:
            self.m_networkAccessManager.setPassword(defaults['password'])

    def finish(self, ok):
        status = 'success' if ok else 'fail'
        self.loadFinished.emit(status)

    def mainFrame(self):
        return self.m_mainFrame

    def renderImage(self):
        contentsSize = self.m_mainFrame.contentsSize()
        contentsSize -= QSize(self.m_scrollPosition.x(), self.m_scrollPosition.y())
        frameRect = QRect(QPoint(0, 0), contentsSize)
        if not self.m_clipRect.isEmpty():
            frameRect = self.m_clipRect

        viewportSize = self.m_webPage.viewportSize()
        self.m_webPage.setViewportSize(contentsSize)

        image = QImage(frameRect.size(), QImage.Format_ARGB32)
        image.fill(qRgba(255, 255, 255, 0))

        painter = QPainter()

        # We use tiling approach to work-around Qt software rasterizer bug
        # when dealing with very large paint device.
        # See http://code.google.com/p/phantomjs/issues/detail?id=54.
        tileSize = 4096
        htiles = (image.width() + tileSize - 1) / tileSize
        vtiles = (image.height() + tileSize - 1) / tileSize
        for x in range(htiles):
            for y in range(vtiles):
                tileBuffer = QImage(tileSize, tileSize, QImage.Format_ARGB32)
                tileBuffer.fill(qRgba(255, 255, 255, 0))

                # Render the web page onto the small tile first
                painter.begin(tileBuffer)
                painter.setRenderHint(QPainter.Antialiasing, True)
                painter.setRenderHint(QPainter.TextAntialiasing, True)
                painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
                painter.translate(-frameRect.left(), -frameRect.top())
                painter.translate(-x * tileSize, -y * tileSize)
                self.m_mainFrame.render(painter, QRegion(frameRect))
                painter.end()

                # Copy the tile to the main buffer
                painter.begin(image)
                painter.setCompositionMode(QPainter.CompositionMode_Source)
                painter.drawImage(x * tileSize, y * tileSize, tileBuffer)
                painter.end()

        self.m_webPage.setViewportSize(viewportSize)
        return image

    # Different defaults.
    # OSX: 72, X11: 75(?), Windows: 96
    pdf_dpi = 72
    def renderPdf(self, fileName):
        p = QPrinter()
        p.setOutputFormat(QPrinter.PdfFormat)
        p.setOutputFileName(fileName)
        p.setResolution(self.pdf_dpi)
        paperSize = self.m_paperSize

        if not len(paperSize):
            pageSize = QSize(self.m_webPage.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 = {
                'A0': QPrinter.A0,
                'A1': QPrinter.A1,
                'A2': QPrinter.A2,
                'A3': QPrinter.A3,
                'A4': QPrinter.A4,
                'A5': QPrinter.A5,
                'A6': QPrinter.A6,
                'A7': QPrinter.A7,
                'A8': QPrinter.A8,
                'A9': QPrinter.A9,
                'B0': QPrinter.B0,
                'B1': QPrinter.B1,
                'B2': QPrinter.B2,
                'B3': QPrinter.B3,
                'B4': QPrinter.B4,
                'B5': QPrinter.B5,
                'B6': QPrinter.B6,
                'B7': QPrinter.B7,
                'B8': QPrinter.B8,
                'B9': QPrinter.B9,
                'B10': QPrinter.B10,
                'C5E': QPrinter.C5E,
                'Comm10E': QPrinter.Comm10E,
                'DLE': QPrinter.DLE,
                'Executive': QPrinter.Executive,
                'Folio': QPrinter.Folio,
                'Ledger': QPrinter.Ledger,
                '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_webPage.mainFrame().print_(p)
        return True

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

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

    def userAgent(self):
        return self.m_webPage.m_userAgent

    ##
    # Properties and methods exposed to JavaScript
    ##

    @pyqtSlot(str)
    def _appendScriptElement(self, scriptUrl):
        self.m_mainFrame.evaluateJavaScript('''
            var el = document.createElement('script');
            el.onload = function() { alert('%(scriptUrl)s'); };
            el.src = '%(scriptUrl)s';
            document.body.appendChild(el);
        ''' % {'scriptUrl': scriptUrl})

    @pyqtProperty('QVariantMap')
    def clipRect(self):
        clipRect = self.m_clipRect
        result = {
            'width': clipRect.width(),
            'height': clipRect.height(),
            'top': clipRect.top(),
            'left': clipRect.left()
        }
        return result

    @clipRect.setter
    def clipRect(self, size):
        sizes = {'width': 0, 'height': 0, 'top': 0, 'left': 0}
        for item in sizes:
            try:
                sizes[item] = int(size[item])
                if sizes[item] < 0:
                    if item not in ('top', 'left'):
                        sizes[item] = 0
            except (KeyError, ValueError):
                sizes[item] = self.clipRect[item]

        self.m_clipRect = QRect(sizes['left'], sizes['top'], sizes['width'], sizes['height'])

    @pyqtProperty(str)
    def content(self):
        return self.m_mainFrame.toHtml()

    @content.setter
    def content(self, content):
        self.m_mainFrame.setHtml(content)

    @pyqtSlot(str, result='QVariant')
    def evaluate(self, code):
        function = '(%s)()' % code
        return self.m_mainFrame.evaluateJavaScript(function)

    @pyqtSlot(str, result=bool)
    def injectJs(self, filePath):
        return injectJsInFrame(filePath, self.parent().m_scriptEncoding.encoding, self.m_libraryPath, self.m_mainFrame)

    @pyqtSlot(str, str, 'QVariantMap')
    @pyqtSlot(str, 'QVariantMap', 'QVariantMap')
    def openUrl(self, address, op, settings):
        operation = op
        body = QByteArray()

        self.applySettings(settings)
        self.m_webPage.triggerAction(QWebPage.Stop)

        if type(op) is dict:
            operation = op.get('operation')
            body = QByteArray(op.get('data', ''))

        if operation == '':
            operation = 'get'

        networkOp = QNetworkAccessManager.CustomOperation
        operation = operation.lower()
        if operation == 'get':
            networkOp = QNetworkAccessManager.GetOperation
        elif operation == 'head':
            networkOp = QNetworkAccessManager.HeadOperation
        elif operation == 'put':
            networkOp = QNetworkAccessManager.PutOperation
        elif operation == 'post':
            networkOp = QNetworkAccessManager.PostOperation
        elif operation == 'delete':
            networkOp = QNetworkAccessManager.DeleteOperation

        if networkOp == QNetworkAccessManager.CustomOperation:
            self.m_mainFrame.evaluateJavaScript('console.error("Unknown network operation: %s");' % operation)
            return

        if address.lower() == 'about:blank':
            self.m_mainFrame.setHtml(self.blankHtml)
        else:
            self.m_mainFrame.load(QNetworkRequest(QUrl(address)), networkOp, body)

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

    @paperSize.setter
    def paperSize(self, size):
        self.m_paperSize = size

    @pyqtSlot()
    def release(self):
        self.parent().m_pages.remove(self)
        sip.delete(self)

    @pyqtSlot(str, result=bool)
    def render(self, fileName):
        if self.m_mainFrame.contentsSize() == '':
            return False

        fileInfo = QFileInfo(fileName)
        path = QDir()
        path.mkpath(fileInfo.absolutePath())

        if fileName.lower().endswith('.pdf'):
            return self.renderPdf(fileName)

        image = self.renderImage()

        return image.save(fileName)

    @pyqtProperty(str)
    def libraryPath(self):
        return self.m_libraryPath

    @libraryPath.setter
    def libraryPath(self, dirPath):
        self.m_libraryPath = dirPath

    @pyqtSlot(str, 'QVariant', 'QVariant')
    def sendEvent(self, type_, arg1, arg2):
        type_ = type_.lower()

        if type_ in ('mousedown', 'mouseup', 'mousemove'):
            eventType = QMouseEvent.Type(QEvent.None)
            button = Qt.MouseButton(Qt.LeftButton)
            buttons = Qt.MouseButtons(Qt.LeftButton)

            if type_ == 'mousedown':
                eventType = QEvent.MouseButtonPress
            elif type_ == 'mouseup':
                eventType = QEvent.MouseButtonRelease
            elif type_ == 'mousemove':
                eventType = QEvent.MouseMove
                button = buttons = Qt.NoButton

            assert eventType != QEvent.None

            event = QMouseEvent(eventType, QPoint(arg1, arg2), button, buttons, Qt.NoModifier)
            QApplication.postEvent(self.m_webPage, event)
            QApplication.processEvents()

            return

        if type_ == 'click':
            self.sendEvent('mousedown', arg1, arg2)
            self.sendEvent('mouseup', arg1, arg2)

    @pyqtProperty('QVariantMap')
    def scrollPosition(self):
        scroll = self.m_scrollPosition
        result = {
            'left': scroll.x(),
            'top': scroll.y()
        }
        return result

    @scrollPosition.setter
    def scrollPosition(self, size):
        positions = {'left': 0, 'top': 0}
        for item in positions:
            try:
                positions[item] = int(size[item])
                if positions[item] < 0:
                    positions[item] = 0
            except (KeyError, ValueError):
                positions[item] = self.scrollPosition[item]
        self.m_scrollPosition = QPoint(positions['left'], positions['top'])
        self.m_mainFrame.setScrollPosition(self.m_scrollPosition)

    @pyqtSlot(str, str)
    def uploadFile(self, selector, fileName):
        el = self.m_mainFrame.findFirstElement(selector)
        if el.isNull():
            return

        self.m_webPage.m_uploadFile = fileName
        el.evaluateJavaScript('''
            (function (el) {
                var ev = document.createEvent('MouseEvents');
                ev.initEvent('click', true, true);
                el.dispatchEvent(ev);
            })(this)
        ''')

    @pyqtProperty('QVariantMap')
    def viewportSize(self):
        size = self.m_webPage.viewportSize()
        result = {
            'width': size.width(),
            'height': size.height()
        }
        return result

    @viewportSize.setter
    def viewportSize(self, size):
        sizes = {'width': 0, 'height': 0}
        for item in sizes:
            try:
                sizes[item] = int(size[item])
                if sizes[item] < 0:
                    sizes[item] = 0
            except (KeyError, ValueError):
                sizes[item] = self.viewportSize[item]

        self.m_webPage.setViewportSize(QSize(sizes['width'], sizes['height']))

    do_action('WebPage')