WebBrowser/Network/QtHelpSchemeHandler.py

Sat, 19 Mar 2016 16:05:11 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 19 Mar 2016 16:05:11 +0100
branch
QtWebEngine
changeset 4875
4ee26909ac0d
parent 4631
Helpviewer/Network/QtHelpAccessHandler.py@5c1a96925da4
child 4913
e16573640cb8
permissions
-rw-r--r--

Continued porting the web browser.

- ported the QtHelp support

# -*- coding: utf-8 -*-

# Copyright (c) 2009 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a scheme access handler for QtHelp.
"""

from __future__ import unicode_literals

import mimetypes
import os

from PyQt5.QtCore import pyqtSignal, QByteArray, QIODevice, QBuffer
from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler, \
    QWebEngineUrlRequestJob

##from .SchemeAccessHandler import SchemeAccessHandler
##
##from .NetworkReply import NetworkReply
##
QtDocPath = "qthelp://org.qt-project."

ExtensionMap = {
    ".bmp": "image/bmp",
    ".css": "text/css",
    ".gif": "image/gif",
    ".html": "text/html",
    ".htm": "text/html",
    ".ico": "image/x-icon",
    ".jpeg": "image/jpeg",
    ".jpg": "image/jpeg",
    ".js": "application/x-javascript",
    ".mng": "video/x-mng",
    ".pbm": "image/x-portable-bitmap",
    ".pgm": "image/x-portable-graymap",
    ".pdf": "application/pdf",
    ".png": "image/png",
    ".ppm": "image/x-portable-pixmap",
    ".rss": "application/rss+xml",
    ".svg": "image/svg+xml",
    ".svgz": "image/svg+xml",
    ".text": "text/plain",
    ".tif": "image/tiff",
    ".tiff": "image/tiff",
    ".txt": "text/plain",
    ".xbm": "image/x-xbitmap",
    ".xml": "text/xml",
    ".xpm": "image/x-xpm",
    ".xsl": "text/xsl",
    ".xhtml": "application/xhtml+xml",
    ".wml": "text/vnd.wap.wml",
    ".wmlc": "application/vnd.wap.wmlc",
}


class QtHelpSchemeHandler(QWebEngineUrlSchemeHandler):
    """
    Class implementing a scheme handler for the qthelp: scheme.
    """
    def __init__(self, engine, parent=None):
        """
        Constructor
        
        @param engine reference to the help engine
        @type QHelpEngine
        @param parent reference to the parent object
        @type QObject
        """
        super(QtHelpSchemeHandler, self).__init__(parent)
        
        self.__engine = engine
        
        self.__replies = []
    
    def requestStarted(self, job):
        """
        Public method handling the URL request.
        
        @param job URL request job
        @type QWebEngineUrlRequestJob
        """
        if job.requestUrl().scheme() == "qthelp":
            reply = QtHelpSchemeReply(job, self.__engine)
            reply.closed.connect(self.__replyClosed)
            self.__replies.append(reply)
            job.reply(reply.mimeType(), reply)
        else:
            job.fail(QWebEngineUrlRequestJob.UrlInvalid)
    
    def __replyClosed(self):
        """
        Private slot handling the closed signal of a reply.
        """
        object = self.sender()
        if object and object in self.__replies:
            self.__replies.remove(object)


class QtHelpSchemeReply(QIODevice):
    """
    Class implementing a reply for a requested qthelp: page.
    
    @signal closed emitted to signal that the web engine has read
        the data
    """
    closed = pyqtSignal()
    
    def __init__(self, job, engine, parent=None):
        """
        Constructor
        
        @param job reference to the URL request
        @type QWebEngineUrlRequestJob
        @param engine reference to the help engine
        @type QHelpEngine
        @param parent reference to the parent object
        @type QObject
        """
        super(QtHelpSchemeReply, self).__init__(parent)
        
        url = job.requestUrl()
        strUrl = url.toString()
        
        self.__buffer = QBuffer()
        
        # For some reason the url to load maybe wrong (passed from web engine)
        # though the css file and the references inside should work that way.
        # One possible problem might be that the css is loaded at the same
        # level as the html, thus a path inside the css like
        # (../images/foo.png) might cd out of the virtual folder
        if not engine.findFile(url).isValid():
            if strUrl.startswith(QtDocPath):
                newUrl = job.requestUrl()
                if not newUrl.path().startswith("/qdoc/"):
                    newUrl.setPath("/qdoc" + newUrl.path())
                    url = newUrl
                    strUrl = url.toString()
        
        self.__mimeType = mimetypes.guess_type(strUrl)[0]
        if self.__mimeType is None:
            # do our own (limited) guessing
            self.__mimeType = self.__mimeFromUrl(url)
        
        if engine.findFile(url).isValid():
            data = engine.fileData(url)
        else:
            data = QByteArray(self.tr(
                """<html>"""
                """<head><title>Error 404...</title></head>"""
                """<body><div align="center"><br><br>"""
                """<h1>The page could not be found</h1><br>"""
                """<h3>'{0}'</h3></div></body>"""
                """</html>""").format(strUrl)
                .encode("utf-8"))
        
        self.__buffer.setData(data)
        self.__buffer.open(QIODevice.ReadOnly)
        self.open(QIODevice.ReadOnly)
    
    def bytesAvailable(self):
        """
        Public method to get the number of available bytes.
        
        @return number of available bytes
        @rtype int
        """
        return self.__buffer.bytesAvailable()
    
    def readData(self, maxlen):
        """
        Public method to retrieve data from the reply object.
        
        @param maxlen maximum number of bytes to read (integer)
        @return string containing the data (bytes)
        """
        return self.__buffer.read(maxlen)
    
    def close(self):
        """
        Public method used to cloase the reply.
        """
        super(QtHelpSchemeReply, self).close()
        self.closed.emit()
    
    def __mimeFromUrl(self, url):
        """
        Private method to guess the mime type given an URL.
        
        @param url URL to guess the mime type from (QUrl)
        @return mime type for the given URL (string)
        """
        path = url.path()
        ext = os.path.splitext(path)[1].lower()
        if ext in ExtensionMap:
            return ExtensionMap[ext]
        else:
            return "application/octet-stream"
    
    def mimeType(self):
        """
        Public method to get the reply mime type.
        
        @return mime type of the reply
        @rtype bytes
        """
        return self.__mimeType.encode("utf-8")
##
##
##
##
##
##class QtHelpAccessHandler(SchemeAccessHandler):
##    """
##    Class implementing a scheme access handler for QtHelp.
##    """
##    def __init__(self, engine, parent=None):
##        """
##        Constructor
##        
##        @param engine reference to the help engine (QHelpEngine)
##        @param parent reference to the parent object (QObject)
##        """
##        SchemeAccessHandler.__init__(self, parent)
##        
##        self.__engine = engine
##    
##    def __mimeFromUrl(self, url):
##        """
##        Private method to guess the mime type given an URL.
##        
##        @param url URL to guess the mime type from (QUrl)
##        @return mime type for the given URL (string)
##        """
##        path = url.path()
##        ext = os.path.splitext(path)[1].lower()
##        if ext in ExtensionMap:
##            return ExtensionMap[ext]
##        else:
##            return "application/octet-stream"
##    
##    def createRequest(self, op, request, outgoingData=None):
##        """
##        Public method to create a request.
##        
##        @param op the operation to be performed
##            (QNetworkAccessManager.Operation)
##        @param request reference to the request object (QNetworkRequest)
##        @param outgoingData reference to an IODevice containing data to be sent
##            (QIODevice)
##        @return reference to the created reply object (QNetworkReply)
##        """
##        url = request.url()
##        strUrl = url.toString()
##        
##        # For some reason the url to load is already wrong (passed from webkit)
##        # though the css file and the references inside should work that way.
##        # One possible problem might be that the css is loaded at the same
##        # level as the html, thus a path inside the css like
##        # (../images/foo.png) might cd out of the virtual folder
##        if not self.__engine.findFile(url).isValid():
##            if strUrl.startswith(QtDocPath):
##                newUrl = request.url()
##                if not newUrl.path().startswith("/qdoc/"):
##                    newUrl.setPath("qdoc" + newUrl.path())
##                    url = newUrl
##                    strUrl = url.toString()
##        
##        mimeType = mimetypes.guess_type(strUrl)[0]
##        if mimeType is None:
##            # do our own (limited) guessing
##            mimeType = self.__mimeFromUrl(url)
##        
##        if self.__engine.findFile(url).isValid():
##            data = self.__engine.fileData(url)
##        else:
##            data = QByteArray(self.tr(
##                """<title>Error 404...</title>"""
##                """<div align="center"><br><br>"""
##                """<h1>The page could not be found</h1><br>"""
##                """<h3>'{0}'</h3></div>""").format(strUrl).encode("utf-8"))
##        return NetworkReply(request, data, mimeType, self.parent())

eric ide

mercurial