src/eric7/WebBrowser/QtHelp/HelpDocsInstaller.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9286
f6f950e4c8f0
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
21 21
22 class HelpDocsInstaller(QThread): 22 class HelpDocsInstaller(QThread):
23 """ 23 """
24 Class implementing the worker thread populating and updating the QtHelp 24 Class implementing the worker thread populating and updating the QtHelp
25 documentation database. 25 documentation database.
26 26
27 @signal errorMessage(str) emitted, if an error occurred during 27 @signal errorMessage(str) emitted, if an error occurred during
28 the installation of the documentation 28 the installation of the documentation
29 @signal docsInstalled(bool) emitted after the installation has finished 29 @signal docsInstalled(bool) emitted after the installation has finished
30 """ 30 """
31
31 errorMessage = pyqtSignal(str) 32 errorMessage = pyqtSignal(str)
32 docsInstalled = pyqtSignal(bool) 33 docsInstalled = pyqtSignal(bool)
33 34
34 def __init__(self, collection): 35 def __init__(self, collection):
35 """ 36 """
36 Constructor 37 Constructor
37 38
38 @param collection full pathname of the collection file 39 @param collection full pathname of the collection file
39 @type str 40 @type str
40 """ 41 """
41 super().__init__() 42 super().__init__()
42 43
43 self.__abort = False 44 self.__abort = False
44 self.__collection = collection 45 self.__collection = collection
45 self.__mutex = QMutex() 46 self.__mutex = QMutex()
46 47
47 def stop(self): 48 def stop(self):
48 """ 49 """
49 Public slot to stop the installation procedure. 50 Public slot to stop the installation procedure.
50 """ 51 """
51 if not self.isRunning(): 52 if not self.isRunning():
52 return 53 return
53 54
54 self.__mutex.lock() 55 self.__mutex.lock()
55 self.__abort = True 56 self.__abort = True
56 self.__mutex.unlock() 57 self.__mutex.unlock()
57 self.wait() 58 self.wait()
58 59
59 def installDocs(self): 60 def installDocs(self):
60 """ 61 """
61 Public method to start the installation procedure. 62 Public method to start the installation procedure.
62 """ 63 """
63 self.start(QThread.Priority.LowPriority) 64 self.start(QThread.Priority.LowPriority)
64 65
65 def run(self): 66 def run(self):
66 """ 67 """
67 Public method executed by the thread. 68 Public method executed by the thread.
68 """ 69 """
69 engine = QHelpEngineCore(self.__collection) 70 engine = QHelpEngineCore(self.__collection)
70 changes = False 71 changes = False
71 72
72 qt5Docs = [ 73 qt5Docs = [
73 "activeqt", "qdoc", "qmake", "qt3d", "qt3drenderer", 74 "activeqt",
74 "qtandroidextras", "qtassistant", "qtbluetooth", "qtcanvas3d", 75 "qdoc",
75 "qtcharts", "qtcmake", "qtconcurrent", "qtcore", "qtdatavis3d", 76 "qmake",
76 "qtdatavisualization", "qtdbus", "qtdesigner", 77 "qt3d",
77 "qtdistancefieldgenerator", "qtdoc", "qtenginio", 78 "qt3drenderer",
78 "qtenginiooverview", "qtenginoqml", "qtgamepad", 79 "qtandroidextras",
79 "qtgraphicaleffects", "qtgui", "qthelp", "qtimageformats", 80 "qtassistant",
80 "qtlabscalendar", "qtlabsplatform", "qtlabscontrols", "qtlinguist", 81 "qtbluetooth",
81 "qtlocation", "qtlottieanimation", "qtmaxextras", "qtmultimedia", 82 "qtcanvas3d",
82 "qtmultimediawidgets", "qtnetwork", "qtnetworkauth", "qtnfc", 83 "qtcharts",
83 "qtopengl", "qtplatformheaders", "qtpositioning", "qtprintsupport", 84 "qtcmake",
84 "qtpurchasing", "qtqml", "qtqmlmodels", "qtqmltest", "qtquick", 85 "qtconcurrent",
85 "qtquick3d", "qtquickcontrols", "qtquickcontrols1", 86 "qtcore",
86 "qtquickdialogs", "qtquickextras", "qtquicklayouts", 87 "qtdatavis3d",
87 "qtquicktimeline", "qtremoteobjects", "qtscript", "qtscripttools", 88 "qtdatavisualization",
88 "qtscxml", "qtsensors", "qtserialbus", "qtserialport", 89 "qtdbus",
89 "qtshadertools", "qtspeech", "qtsql", "qtsvg", "qttest", 90 "qtdesigner",
90 "qttestlib", "qtuitools", "qtvirtualkeyboard", 91 "qtdistancefieldgenerator",
91 "qtwaylandcompositor", "qtwebchannel", "qtwebengine", 92 "qtdoc",
92 "qtwebenginewidgets", "qtwebkit", "qtwebkitexamples", 93 "qtenginio",
93 "qtwebsockets", "qtwebview", "qtwidgets", "qtwinextras", 94 "qtenginiooverview",
94 "qtx11extras", "qtxml", "qtxmlpatterns"] 95 "qtenginoqml",
96 "qtgamepad",
97 "qtgraphicaleffects",
98 "qtgui",
99 "qthelp",
100 "qtimageformats",
101 "qtlabscalendar",
102 "qtlabsplatform",
103 "qtlabscontrols",
104 "qtlinguist",
105 "qtlocation",
106 "qtlottieanimation",
107 "qtmaxextras",
108 "qtmultimedia",
109 "qtmultimediawidgets",
110 "qtnetwork",
111 "qtnetworkauth",
112 "qtnfc",
113 "qtopengl",
114 "qtplatformheaders",
115 "qtpositioning",
116 "qtprintsupport",
117 "qtpurchasing",
118 "qtqml",
119 "qtqmlmodels",
120 "qtqmltest",
121 "qtquick",
122 "qtquick3d",
123 "qtquickcontrols",
124 "qtquickcontrols1",
125 "qtquickdialogs",
126 "qtquickextras",
127 "qtquicklayouts",
128 "qtquicktimeline",
129 "qtremoteobjects",
130 "qtscript",
131 "qtscripttools",
132 "qtscxml",
133 "qtsensors",
134 "qtserialbus",
135 "qtserialport",
136 "qtshadertools",
137 "qtspeech",
138 "qtsql",
139 "qtsvg",
140 "qttest",
141 "qttestlib",
142 "qtuitools",
143 "qtvirtualkeyboard",
144 "qtwaylandcompositor",
145 "qtwebchannel",
146 "qtwebengine",
147 "qtwebenginewidgets",
148 "qtwebkit",
149 "qtwebkitexamples",
150 "qtwebsockets",
151 "qtwebview",
152 "qtwidgets",
153 "qtwinextras",
154 "qtx11extras",
155 "qtxml",
156 "qtxmlpatterns",
157 ]
95 for qtDocs, version in [(qt5Docs, 5)]: 158 for qtDocs, version in [(qt5Docs, 5)]:
96 for doc in qtDocs: 159 for doc in qtDocs:
97 changes |= self.__installQtDoc(doc, version, engine) 160 changes |= self.__installQtDoc(doc, version, engine)
98 self.__mutex.lock() 161 self.__mutex.lock()
99 if self.__abort: 162 if self.__abort:
100 engine = None 163 engine = None
101 self.__mutex.unlock() 164 self.__mutex.unlock()
102 return 165 return
103 self.__mutex.unlock() 166 self.__mutex.unlock()
104 167
105 changes |= self.__installEric7Doc(engine) 168 changes |= self.__installEric7Doc(engine)
106 engine = None 169 engine = None
107 del engine 170 del engine
108 self.docsInstalled.emit(changes) 171 self.docsInstalled.emit(changes)
109 172
110 def __installQtDoc(self, name, version, engine): 173 def __installQtDoc(self, name, version, engine):
111 """ 174 """
112 Private method to install/update a Qt help document. 175 Private method to install/update a Qt help document.
113 176
114 @param name name of the Qt help document 177 @param name name of the Qt help document
115 @type str 178 @type str
116 @param version Qt version of the help documents 179 @param version Qt version of the help documents
117 @type int 180 @type int
118 @param engine reference to the help engine 181 @param engine reference to the help engine
120 @return flag indicating success 183 @return flag indicating success
121 @rtype bool 184 @rtype bool
122 """ 185 """
123 versionKey = "qt_version_{0}@@{1}".format(version, name) 186 versionKey = "qt_version_{0}@@{1}".format(version, name)
124 info = engine.customValue(versionKey, "") 187 info = engine.customValue(versionKey, "")
125 lst = info.split('|') 188 lst = info.split("|")
126 189
127 dt = None 190 dt = None
128 if len(lst) and lst[0]: 191 if len(lst) and lst[0]:
129 dt = datetime.datetime.fromisoformat(lst[0]) 192 dt = datetime.datetime.fromisoformat(lst[0])
130 193
131 qchFile = "" 194 qchFile = ""
132 if len(lst) == 2: 195 if len(lst) == 2:
133 qchFile = lst[1] 196 qchFile = lst[1]
134 197
135 if version == 5: 198 if version == 5:
136 docsPath = pathlib.Path(QLibraryInfo.path( 199 docsPath = pathlib.Path(
137 QLibraryInfo.LibraryPath.DocumentationPath)) 200 QLibraryInfo.path(QLibraryInfo.LibraryPath.DocumentationPath)
138 if ( 201 )
139 not docsPath.is_dir() or 202 if not docsPath.is_dir() or len(docsPath.glob("*.qch")) == 0:
140 len(docsPath.glob("*.qch")) == 0
141 ):
142 docsPath = ( 203 docsPath = (
143 docsPath.parents[2] / "Docs" / 204 docsPath.parents[2] / "Docs" / "Qt-{0}.{1}".format(*qVersionTuple())
144 "Qt-{0}.{1}".format(*qVersionTuple())
145 ) 205 )
146 else: 206 else:
147 # unsupported Qt version 207 # unsupported Qt version
148 return False 208 return False
149 209
150 files = docsPath.glob("*.qch") 210 files = docsPath.glob("*.qch")
151 if not files: 211 if not files:
152 engine.setCustomValue(versionKey, '|') 212 engine.setCustomValue(versionKey, "|")
153 return False 213 return False
154 214
155 for f in files: 215 for f in files:
156 if f.stem == name: 216 if f.stem == name:
157 namespace = QHelpEngineCore.namespaceName(str(f.resolve())) 217 namespace = QHelpEngineCore.namespaceName(str(f.resolve()))
158 if not namespace: 218 if not namespace:
159 continue 219 continue
160 220
161 if ( 221 if (
162 dt is not None and 222 dt is not None
163 namespace in engine.registeredDocumentations() and 223 and namespace in engine.registeredDocumentations()
164 (datetime.datetime.fromtimestamp(f.stat().st_mtime) == 224 and (datetime.datetime.fromtimestamp(f.stat().st_mtime) == dt)
165 dt) and 225 and qchFile == str(f.resolve())
166 qchFile == str(f.resolve())
167 ): 226 ):
168 return False 227 return False
169 228
170 if namespace in engine.registeredDocumentations(): 229 if namespace in engine.registeredDocumentations():
171 engine.unregisterDocumentation(namespace) 230 engine.unregisterDocumentation(namespace)
172 231
173 if not engine.registerDocumentation(str(f.resolve())): 232 if not engine.registerDocumentation(str(f.resolve())):
174 self.errorMessage.emit( 233 self.errorMessage.emit(
175 self.tr( 234 self.tr(
176 """<p>The file <b>{0}</b> could not be""" 235 """<p>The file <b>{0}</b> could not be"""
177 """ registered. <br/>Reason: {1}</p>""") 236 """ registered. <br/>Reason: {1}</p>"""
178 .format(f, engine.error()) 237 ).format(f, engine.error())
179 ) 238 )
180 return False 239 return False
181 240
182 engine.setCustomValue( 241 engine.setCustomValue(
183 versionKey, 242 versionKey,
184 datetime.datetime.fromtimestamp(f.stat().st_mtime) 243 datetime.datetime.fromtimestamp(f.stat().st_mtime).isoformat()
185 .isoformat() + '|' + str(f.resolve())) 244 + "|"
245 + str(f.resolve()),
246 )
186 return True 247 return True
187 248
188 return False 249 return False
189 250
190 def __installEric7Doc(self, engine): 251 def __installEric7Doc(self, engine):
191 """ 252 """
192 Private method to install/update the eric help documentation. 253 Private method to install/update the eric help documentation.
193 254
194 @param engine reference to the help engine 255 @param engine reference to the help engine
195 @type QHelpEngineCore 256 @type QHelpEngineCore
196 @return flag indicating success 257 @return flag indicating success
197 @rtype bool 258 @rtype bool
198 """ 259 """
199 versionKey = "eric7_ide" 260 versionKey = "eric7_ide"
200 info = engine.customValue(versionKey, "") 261 info = engine.customValue(versionKey, "")
201 lst = info.split('|') 262 lst = info.split("|")
202 263
203 dt = None 264 dt = None
204 if len(lst) and lst[0]: 265 if len(lst) and lst[0]:
205 dt = datetime.datetime.fromisoformat(lst[0]) 266 dt = datetime.datetime.fromisoformat(lst[0])
206 267
207 qchFile = "" 268 qchFile = ""
208 if len(lst) == 2: 269 if len(lst) == 2:
209 qchFile = lst[1] 270 qchFile = lst[1]
210 271
211 docsPath = pathlib.Path(getConfig("ericDocDir")) / "Help" 272 docsPath = pathlib.Path(getConfig("ericDocDir")) / "Help"
212 273
213 files = docsPath.glob("*.qch") 274 files = docsPath.glob("*.qch")
214 if not files: 275 if not files:
215 engine.setCustomValue(versionKey, '|') 276 engine.setCustomValue(versionKey, "|")
216 return False 277 return False
217 278
218 for f in files: 279 for f in files:
219 if f.name == "source.qch": 280 if f.name == "source.qch":
220 namespace = QHelpEngineCore.namespaceName(str(f.resolve())) 281 namespace = QHelpEngineCore.namespaceName(str(f.resolve()))
221 if not namespace: 282 if not namespace:
222 continue 283 continue
223 284
224 if ( 285 if (
225 dt is not None and 286 dt is not None
226 namespace in engine.registeredDocumentations() and 287 and namespace in engine.registeredDocumentations()
227 (datetime.datetime.fromtimestamp(f.stat().st_mtime) == 288 and (datetime.datetime.fromtimestamp(f.stat().st_mtime) == dt)
228 dt) and 289 and qchFile == str(f.resolve())
229 qchFile == str(f.resolve())
230 ): 290 ):
231 return False 291 return False
232 292
233 if namespace in engine.registeredDocumentations(): 293 if namespace in engine.registeredDocumentations():
234 engine.unregisterDocumentation(namespace) 294 engine.unregisterDocumentation(namespace)
235 295
236 if not engine.registerDocumentation(str(f.resolve())): 296 if not engine.registerDocumentation(str(f.resolve())):
237 self.errorMessage.emit( 297 self.errorMessage.emit(
238 self.tr( 298 self.tr(
239 """<p>The file <b>{0}</b> could not be""" 299 """<p>The file <b>{0}</b> could not be"""
240 """ registered. <br/>Reason: {1}</p>""") 300 """ registered. <br/>Reason: {1}</p>"""
241 .format(f, engine.error()) 301 ).format(f, engine.error())
242 ) 302 )
243 return False 303 return False
244 304
245 engine.setCustomValue( 305 engine.setCustomValue(
246 versionKey, 306 versionKey,
247 datetime.datetime.fromtimestamp(f.stat().st_mtime) 307 datetime.datetime.fromtimestamp(f.stat().st_mtime).isoformat()
248 .isoformat() + '|' + str(f.resolve())) 308 + "|"
309 + str(f.resolve()),
310 )
249 return True 311 return True
250 312
251 return False 313 return False

eric ide

mercurial