WebBrowser/Network/QtHelpSchemeHandler.py

branch
QtWebEngine
changeset 4875
4ee26909ac0d
parent 4631
5c1a96925da4
child 4913
e16573640cb8
equal deleted inserted replaced
4870:72901685681d 4875:4ee26909ac0d
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a scheme access handler for QtHelp.
8 """
9
10 from __future__ import unicode_literals
11
12 import mimetypes
13 import os
14
15 from PyQt5.QtCore import pyqtSignal, QByteArray, QIODevice, QBuffer
16 from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler, \
17 QWebEngineUrlRequestJob
18
19 ##from .SchemeAccessHandler import SchemeAccessHandler
20 ##
21 ##from .NetworkReply import NetworkReply
22 ##
23 QtDocPath = "qthelp://org.qt-project."
24
25 ExtensionMap = {
26 ".bmp": "image/bmp",
27 ".css": "text/css",
28 ".gif": "image/gif",
29 ".html": "text/html",
30 ".htm": "text/html",
31 ".ico": "image/x-icon",
32 ".jpeg": "image/jpeg",
33 ".jpg": "image/jpeg",
34 ".js": "application/x-javascript",
35 ".mng": "video/x-mng",
36 ".pbm": "image/x-portable-bitmap",
37 ".pgm": "image/x-portable-graymap",
38 ".pdf": "application/pdf",
39 ".png": "image/png",
40 ".ppm": "image/x-portable-pixmap",
41 ".rss": "application/rss+xml",
42 ".svg": "image/svg+xml",
43 ".svgz": "image/svg+xml",
44 ".text": "text/plain",
45 ".tif": "image/tiff",
46 ".tiff": "image/tiff",
47 ".txt": "text/plain",
48 ".xbm": "image/x-xbitmap",
49 ".xml": "text/xml",
50 ".xpm": "image/x-xpm",
51 ".xsl": "text/xsl",
52 ".xhtml": "application/xhtml+xml",
53 ".wml": "text/vnd.wap.wml",
54 ".wmlc": "application/vnd.wap.wmlc",
55 }
56
57
58 class QtHelpSchemeHandler(QWebEngineUrlSchemeHandler):
59 """
60 Class implementing a scheme handler for the qthelp: scheme.
61 """
62 def __init__(self, engine, parent=None):
63 """
64 Constructor
65
66 @param engine reference to the help engine
67 @type QHelpEngine
68 @param parent reference to the parent object
69 @type QObject
70 """
71 super(QtHelpSchemeHandler, self).__init__(parent)
72
73 self.__engine = engine
74
75 self.__replies = []
76
77 def requestStarted(self, job):
78 """
79 Public method handling the URL request.
80
81 @param job URL request job
82 @type QWebEngineUrlRequestJob
83 """
84 if job.requestUrl().scheme() == "qthelp":
85 reply = QtHelpSchemeReply(job, self.__engine)
86 reply.closed.connect(self.__replyClosed)
87 self.__replies.append(reply)
88 job.reply(reply.mimeType(), reply)
89 else:
90 job.fail(QWebEngineUrlRequestJob.UrlInvalid)
91
92 def __replyClosed(self):
93 """
94 Private slot handling the closed signal of a reply.
95 """
96 object = self.sender()
97 if object and object in self.__replies:
98 self.__replies.remove(object)
99
100
101 class QtHelpSchemeReply(QIODevice):
102 """
103 Class implementing a reply for a requested qthelp: page.
104
105 @signal closed emitted to signal that the web engine has read
106 the data
107 """
108 closed = pyqtSignal()
109
110 def __init__(self, job, engine, parent=None):
111 """
112 Constructor
113
114 @param job reference to the URL request
115 @type QWebEngineUrlRequestJob
116 @param engine reference to the help engine
117 @type QHelpEngine
118 @param parent reference to the parent object
119 @type QObject
120 """
121 super(QtHelpSchemeReply, self).__init__(parent)
122
123 url = job.requestUrl()
124 strUrl = url.toString()
125
126 self.__buffer = QBuffer()
127
128 # For some reason the url to load maybe wrong (passed from web engine)
129 # though the css file and the references inside should work that way.
130 # One possible problem might be that the css is loaded at the same
131 # level as the html, thus a path inside the css like
132 # (../images/foo.png) might cd out of the virtual folder
133 if not engine.findFile(url).isValid():
134 if strUrl.startswith(QtDocPath):
135 newUrl = job.requestUrl()
136 if not newUrl.path().startswith("/qdoc/"):
137 newUrl.setPath("/qdoc" + newUrl.path())
138 url = newUrl
139 strUrl = url.toString()
140
141 self.__mimeType = mimetypes.guess_type(strUrl)[0]
142 if self.__mimeType is None:
143 # do our own (limited) guessing
144 self.__mimeType = self.__mimeFromUrl(url)
145
146 if engine.findFile(url).isValid():
147 data = engine.fileData(url)
148 else:
149 data = QByteArray(self.tr(
150 """<html>"""
151 """<head><title>Error 404...</title></head>"""
152 """<body><div align="center"><br><br>"""
153 """<h1>The page could not be found</h1><br>"""
154 """<h3>'{0}'</h3></div></body>"""
155 """</html>""").format(strUrl)
156 .encode("utf-8"))
157
158 self.__buffer.setData(data)
159 self.__buffer.open(QIODevice.ReadOnly)
160 self.open(QIODevice.ReadOnly)
161
162 def bytesAvailable(self):
163 """
164 Public method to get the number of available bytes.
165
166 @return number of available bytes
167 @rtype int
168 """
169 return self.__buffer.bytesAvailable()
170
171 def readData(self, maxlen):
172 """
173 Public method to retrieve data from the reply object.
174
175 @param maxlen maximum number of bytes to read (integer)
176 @return string containing the data (bytes)
177 """
178 return self.__buffer.read(maxlen)
179
180 def close(self):
181 """
182 Public method used to cloase the reply.
183 """
184 super(QtHelpSchemeReply, self).close()
185 self.closed.emit()
186
187 def __mimeFromUrl(self, url):
188 """
189 Private method to guess the mime type given an URL.
190
191 @param url URL to guess the mime type from (QUrl)
192 @return mime type for the given URL (string)
193 """
194 path = url.path()
195 ext = os.path.splitext(path)[1].lower()
196 if ext in ExtensionMap:
197 return ExtensionMap[ext]
198 else:
199 return "application/octet-stream"
200
201 def mimeType(self):
202 """
203 Public method to get the reply mime type.
204
205 @return mime type of the reply
206 @rtype bytes
207 """
208 return self.__mimeType.encode("utf-8")
209 ##
210 ##
211 ##
212 ##
213 ##
214 ##class QtHelpAccessHandler(SchemeAccessHandler):
215 ## """
216 ## Class implementing a scheme access handler for QtHelp.
217 ## """
218 ## def __init__(self, engine, parent=None):
219 ## """
220 ## Constructor
221 ##
222 ## @param engine reference to the help engine (QHelpEngine)
223 ## @param parent reference to the parent object (QObject)
224 ## """
225 ## SchemeAccessHandler.__init__(self, parent)
226 ##
227 ## self.__engine = engine
228 ##
229 ## def __mimeFromUrl(self, url):
230 ## """
231 ## Private method to guess the mime type given an URL.
232 ##
233 ## @param url URL to guess the mime type from (QUrl)
234 ## @return mime type for the given URL (string)
235 ## """
236 ## path = url.path()
237 ## ext = os.path.splitext(path)[1].lower()
238 ## if ext in ExtensionMap:
239 ## return ExtensionMap[ext]
240 ## else:
241 ## return "application/octet-stream"
242 ##
243 ## def createRequest(self, op, request, outgoingData=None):
244 ## """
245 ## Public method to create a request.
246 ##
247 ## @param op the operation to be performed
248 ## (QNetworkAccessManager.Operation)
249 ## @param request reference to the request object (QNetworkRequest)
250 ## @param outgoingData reference to an IODevice containing data to be sent
251 ## (QIODevice)
252 ## @return reference to the created reply object (QNetworkReply)
253 ## """
254 ## url = request.url()
255 ## strUrl = url.toString()
256 ##
257 ## # For some reason the url to load is already wrong (passed from webkit)
258 ## # though the css file and the references inside should work that way.
259 ## # One possible problem might be that the css is loaded at the same
260 ## # level as the html, thus a path inside the css like
261 ## # (../images/foo.png) might cd out of the virtual folder
262 ## if not self.__engine.findFile(url).isValid():
263 ## if strUrl.startswith(QtDocPath):
264 ## newUrl = request.url()
265 ## if not newUrl.path().startswith("/qdoc/"):
266 ## newUrl.setPath("qdoc" + newUrl.path())
267 ## url = newUrl
268 ## strUrl = url.toString()
269 ##
270 ## mimeType = mimetypes.guess_type(strUrl)[0]
271 ## if mimeType is None:
272 ## # do our own (limited) guessing
273 ## mimeType = self.__mimeFromUrl(url)
274 ##
275 ## if self.__engine.findFile(url).isValid():
276 ## data = self.__engine.fileData(url)
277 ## else:
278 ## data = QByteArray(self.tr(
279 ## """<title>Error 404...</title>"""
280 ## """<div align="center"><br><br>"""
281 ## """<h1>The page could not be found</h1><br>"""
282 ## """<h3>'{0}'</h3></div>""").format(strUrl).encode("utf-8"))
283 ## return NetworkReply(request, data, mimeType, self.parent())

eric ide

mercurial