src/eric7/WebBrowser/Tools/WebBrowserTools.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 9167
2d2b9a26e904
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2016 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing tool functions for the web browser.
8 """
9
10 import os
11 import re
12 import mimetypes
13
14 from PyQt6.QtCore import (
15 QByteArray, QUrl, QCoreApplication, QBuffer, QIODevice
16 )
17 from PyQt6.QtGui import QPixmap
18
19
20 WebBrowserDataDirectory = {
21 "html": os.path.join(os.path.dirname(__file__), "..", "data", "html"),
22 "icons": os.path.join(os.path.dirname(__file__), "..", "data", "icons"),
23 "js": os.path.join(os.path.dirname(__file__), "..", "data", "javascript"),
24 }
25
26
27 def readAllFileContents(filename):
28 """
29 Function to read the string contents of the given file.
30
31 @param filename name of the file
32 @type str
33 @return contents of the file
34 @rtype str
35 """
36 try:
37 with open(filename, "r", encoding="utf-8") as f:
38 return f.read()
39 except OSError:
40 return ""
41
42
43 def containsSpace(string):
44 """
45 Function to check, if a string contains whitespace characters.
46
47 @param string string to be checked
48 @type str
49 @return flag indicating the presence of at least one whitespace character
50 @rtype bool
51 """
52 return any(ch.isspace() for ch in string)
53
54
55 def ensureUniqueFilename(name, appendFormat="({0})"):
56 """
57 Module function to generate an unique file name based on a pattern.
58
59 @param name desired file name (string)
60 @param appendFormat format pattern to be used to make the unique name
61 (string)
62 @return unique file name
63 """
64 if not os.path.exists(name):
65 return name
66
67 tmpFileName = name
68 i = 1
69 while os.path.exists(tmpFileName):
70 tmpFileName = name
71 index = tmpFileName.rfind(".")
72
73 appendString = appendFormat.format(i)
74 if index == -1:
75 tmpFileName += appendString
76 else:
77 tmpFileName = (
78 tmpFileName[:index] + appendString + tmpFileName[index:]
79 )
80 i += 1
81
82 return tmpFileName
83
84
85 def getFileNameFromUrl(url):
86 """
87 Module function to generate a file name based on the given URL.
88
89 @param url URL (QUrl)
90 @return file name (string)
91 """
92 fileName = url.toString(
93 QUrl.UrlFormattingOption.RemoveFragment |
94 QUrl.UrlFormattingOption.RemoveQuery |
95 QUrl.UrlFormattingOption.RemoveScheme |
96 QUrl.UrlFormattingOption.RemovePort
97 )
98 if fileName.find("/") != -1:
99 pos = fileName.rfind("/")
100 fileName = fileName[pos:]
101 fileName = fileName.replace("/", "")
102
103 fileName = filterCharsFromFilename(fileName)
104
105 if not fileName:
106 fileName = filterCharsFromFilename(url.host().replace(".", "_"))
107
108 return fileName
109
110
111 def filterCharsFromFilename(name):
112 """
113 Module function to filter illegal characters.
114
115 @param name name to be sanitized (string)
116 @return sanitized name (string)
117 """
118 return (
119 name
120 .replace("/", "_")
121 .replace("\\", "")
122 .replace(":", "")
123 .replace("*", "")
124 .replace("?", "")
125 .replace('"', "")
126 .replace("<", "")
127 .replace(">", "")
128 .replace("|", "")
129 )
130
131
132 def pixmapFromByteArray(data):
133 """
134 Module function to convert a byte array to a pixmap.
135
136 @param data data for the pixmap
137 @type bytes or QByteArray
138 @return extracted pixmap
139 @rtype QPixmap
140 """
141 pixmap = QPixmap()
142 barray = QByteArray.fromBase64(data)
143 pixmap.loadFromData(barray)
144
145 return pixmap
146
147
148 def pixmapToByteArray(pixmap):
149 """
150 Module function to convert a pixmap to a byte array containing the pixmap
151 as a PNG encoded as base64.
152
153 @param pixmap pixmap to be converted
154 @type QPixmap
155 @return byte array containing the pixmap
156 @rtype QByteArray
157 """
158 byteArray = QByteArray()
159 buffer = QBuffer(byteArray)
160 buffer.open(QIODevice.OpenModeFlag.WriteOnly)
161 if pixmap.save(buffer, "PNG"):
162 return buffer.buffer().toBase64()
163
164 return QByteArray()
165
166
167 def pixmapToDataUrl(pixmap, mimetype="image/png"):
168 """
169 Module function to convert a pixmap to a data: URL.
170
171 @param pixmap pixmap to be converted
172 @type QPixmap
173 @param mimetype MIME type to be used
174 @type str
175 @return data: URL
176 @rtype QUrl
177 """
178 data = bytes(pixmapToByteArray(pixmap)).decode()
179 if data:
180 return QUrl("data:{0};base64,{1}".format(mimetype, data))
181 else:
182 return QUrl()
183
184
185 def pixmapFileToDataUrl(pixmapFile, asString=False):
186 """
187 Module function to load a pixmap file and convert the pixmap to a
188 data: URL.
189
190 Note: If the given pixmap file path is not absolute, it is assumed to
191 denote a pixmap file in the icons data directory.
192
193 @param pixmapFile file name of the pixmap file
194 @type str
195 @param asString flag indicating a string representation is requested
196 @type bool
197 @return data: URL
198 @rtype QUrl or str
199 """
200 if not os.path.isabs(pixmapFile):
201 pixmapFile = os.path.join(WebBrowserDataDirectory["icons"], pixmapFile)
202
203 mime = mimetypes.guess_type(pixmapFile, strict=False)[0]
204 if mime is None:
205 # assume PNG file
206 mime = "image/png"
207 url = pixmapToDataUrl(QPixmap(pixmapFile), mimetype=mime)
208
209 if asString:
210 return url.toString()
211 else:
212 return url
213
214
215 def getWebEngineVersions():
216 """
217 Module function to extract the web engine related versions from the default
218 user agent string.
219
220 Note: For PyQt 6.3.1 or newer the data is extracted via some Qt functions.
221
222 @return tuple containing the Chromium version, the Chromium security patch
223 version and the QtWebEngine version
224 @rtype tuple of (str, str, str)
225 """
226 try:
227 from PyQt6.QtWebEngineCore import (
228 qWebEngineVersion, qWebEngineChromiumVersion,
229 qWebEngineChromiumSecurityPatchVersion
230 )
231 chromiumVersion = qWebEngineChromiumVersion()
232 chromiumSecurityVersion = qWebEngineChromiumSecurityPatchVersion()
233 webengineVersion = qWebEngineVersion()
234 except ImportError:
235 # backwards compatibility for PyQt < 6.3.1
236 from PyQt6.QtWebEngineCore import QWebEngineProfile
237
238 useragent = QWebEngineProfile.defaultProfile().httpUserAgent()
239 match = re.search(r"""Chrome/([\d.]+)""", useragent)
240 chromiumVersion = (
241 match.group(1)
242 if match else
243 QCoreApplication.translate("WebBrowserTools", "<unknown>")
244 )
245 match = re.search(r"""QtWebEngine/([\d.]+)""", useragent)
246 webengineVersion = (
247 match.group(1)
248 if match else
249 QCoreApplication.translate("WebBrowserTools", "<unknown>")
250 )
251 chromiumSecurityVersion = ""
252 # not available via the user agent string
253
254 return (chromiumVersion, chromiumSecurityVersion, webengineVersion)
255
256
257 def getHtmlPage(pageFileName):
258 """
259 Module function to load a HTML page.
260
261 Note: If the given HTML file path is not absolute, it is assumed to
262 denote a HTML file in the html data directory.
263
264 @param pageFileName file name of the HTML file
265 @type str
266 @return HTML page
267 @rtype str
268 """
269 if not os.path.isabs(pageFileName):
270 pageFileName = os.path.join(
271 WebBrowserDataDirectory["html"], pageFileName)
272
273 return readAllFileContents(pageFileName)
274
275
276 def getJavascript(jsFileName):
277 """
278 Module function to load a JavaScript source file.
279
280 Note: If the given JavaScript source file path is not absolute, it is
281 assumed to denote a JavaScript source file in the javascript data
282 directory.
283
284 @param jsFileName file name of the JavaScript source file
285 @type str
286 @return JavaScript source
287 @rtype str
288 """
289 if not os.path.isabs(jsFileName):
290 jsFileName = os.path.join(
291 WebBrowserDataDirectory["js"], jsFileName)
292
293 return readAllFileContents(jsFileName)

eric ide

mercurial