eric7/WebBrowser/QtHelp/HelpDocsInstaller.py

branch
eric7
changeset 8312
800c432b34c8
parent 8218
7c09585bd960
child 8314
e3642a6a1e71
equal deleted inserted replaced
8311:4e8b98454baa 8312:800c432b34c8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a thread class populating and updating the QtHelp
8 documentation database.
9 """
10
11 import os
12
13 from PyQt5.QtCore import (
14 pyqtSignal, QThread, Qt, QMutex, QDateTime, QDir, QLibraryInfo, QFileInfo
15 )
16 from PyQt5.QtHelp import QHelpEngineCore
17
18 from eric6config import getConfig
19
20 from Globals import qVersionTuple
21
22
23 class HelpDocsInstaller(QThread):
24 """
25 Class implementing the worker thread populating and updating the QtHelp
26 documentation database.
27
28 @signal errorMessage(str) emitted, if an error occurred during
29 the installation of the documentation
30 @signal docsInstalled(bool) emitted after the installation has finished
31 """
32 errorMessage = pyqtSignal(str)
33 docsInstalled = pyqtSignal(bool)
34
35 def __init__(self, collection):
36 """
37 Constructor
38
39 @param collection full pathname of the collection file (string)
40 """
41 super().__init__()
42
43 self.__abort = False
44 self.__collection = collection
45 self.__mutex = QMutex()
46
47 def stop(self):
48 """
49 Public slot to stop the installation procedure.
50 """
51 if not self.isRunning():
52 return
53
54 self.__mutex.lock()
55 self.__abort = True
56 self.__mutex.unlock()
57 self.wait()
58
59 def installDocs(self):
60 """
61 Public method to start the installation procedure.
62 """
63 self.start(QThread.Priority.LowPriority)
64
65 def run(self):
66 """
67 Public method executed by the thread.
68 """
69 engine = QHelpEngineCore(self.__collection)
70 changes = False
71
72 qt5Docs = [
73 "activeqt", "qdoc", "qmake", "qt3d", "qt3drenderer",
74 "qtandroidextras", "qtassistant", "qtbluetooth", "qtcanvas3d",
75 "qtcharts", "qtconcurrent", "qtcore", "qtdatavisualization",
76 "qtdbus", "qtdesigner", "qtdistancefieldgenerator", "qtdoc",
77 "qtenginio", "qtenginiooverview", "qtenginoqml", "qtgamepad",
78 "qtgraphicaleffects", "qtgui", "qthelp", "qtimageformats",
79 "qtlabscalendar", "qtlabsplatform", "qtlabscontrols", "qtlinguist",
80 "qtlocation", "qtlottieanimation", "qtmaxextras", "qtmultimedia",
81 "qtmultimediawidgets", "qtnetwork", "qtnetworkauth", "qtnfc",
82 "qtopengl", "qtplatformheaders", "qtpositioning", "qtprintsupport",
83 "qtpurchasing", "qtqml", "qtqmltest", "qtquick", "qtquickcontrols",
84 "qtquickcontrols1", "qtquickdialogs", "qtquickextras",
85 "qtquicklayouts", "qtremoteobjects", "qtscript", "qtscripttools",
86 "qtscxml", "qtsensors", "qtserialbus", "qtserialport", "qtspeech",
87 "qtsql", "qtsvg", "qttest", "qttestlib", "qtuitools",
88 "qtvirtualkeyboard", "qtwaylandcompositor", "qtwebchannel",
89 "qtwebengine", "qtwebenginewidgets", "qtwebkit",
90 "qtwebkitexamples", "qtwebsockets", "qtwebview", "qtwidgets",
91 "qtwinextras", "qtx11extras", "qtxml", "qtxmlpatterns"]
92 for qtDocs, version in [(qt5Docs, 5)]:
93 for doc in qtDocs:
94 changes |= self.__installQtDoc(doc, version, engine)
95 self.__mutex.lock()
96 if self.__abort:
97 engine = None
98 self.__mutex.unlock()
99 return
100 self.__mutex.unlock()
101
102 changes |= self.__installEric6Doc(engine)
103 engine = None
104 del engine
105 self.docsInstalled.emit(changes)
106
107 def __installQtDoc(self, name, version, engine):
108 """
109 Private method to install/update a Qt help document.
110
111 @param name name of the Qt help document (string)
112 @param version Qt version of the help documens (integer)
113 @param engine reference to the help engine (QHelpEngineCore)
114 @return flag indicating success (boolean)
115 """
116 versionKey = "qt_version_{0}@@{1}".format(version, name)
117 info = engine.customValue(versionKey, "")
118 lst = info.split('|')
119
120 dt = QDateTime()
121 if len(lst) and lst[0]:
122 dt = QDateTime.fromString(lst[0], Qt.DateFormat.ISODate)
123
124 qchFile = ""
125 if len(lst) == 2:
126 qchFile = lst[1]
127
128 if version == 4:
129 docsPath = QDir(
130 QLibraryInfo.location(
131 QLibraryInfo.LibraryLocation.DocumentationPath) +
132 QDir.separator() + "qch")
133 elif version == 5:
134 docsPath = QLibraryInfo.location(
135 QLibraryInfo.LibraryLocation.DocumentationPath)
136 if (
137 not os.path.isdir(docsPath) or
138 len(QDir(docsPath).entryList(["*.qch"])) == 0
139 ):
140 docsPathList = QDir.fromNativeSeparators(docsPath).split("/")
141 docsPath = os.sep.join(
142 docsPathList[:-3] +
143 ["Docs", "Qt-{0}.{1}".format(*qVersionTuple())])
144 docsPath = QDir(docsPath)
145 else:
146 # unsupported Qt version
147 return False
148
149 files = docsPath.entryList(["*.qch"])
150 if not files:
151 engine.setCustomValue(
152 versionKey,
153 QDateTime().toString(Qt.DateFormat.ISODate) + '|')
154 return False
155
156 for f in files:
157 if f.startswith(name + "."):
158 fi = QFileInfo(docsPath.absolutePath() + QDir.separator() + f)
159 namespace = QHelpEngineCore.namespaceName(
160 fi.absoluteFilePath())
161 if not namespace:
162 continue
163
164 if (
165 dt.isValid() and
166 namespace in engine.registeredDocumentations() and
167 (fi.lastModified().toString(Qt.DateFormat.ISODate) ==
168 dt.toString(Qt.DateFormat.ISODate)) and
169 qchFile == fi.absoluteFilePath()
170 ):
171 return False
172
173 if namespace in engine.registeredDocumentations():
174 engine.unregisterDocumentation(namespace)
175
176 if not engine.registerDocumentation(fi.absoluteFilePath()):
177 self.errorMessage.emit(
178 self.tr(
179 """<p>The file <b>{0}</b> could not be"""
180 """ registered. <br/>Reason: {1}</p>""")
181 .format(fi.absoluteFilePath, engine.error())
182 )
183 return False
184
185 engine.setCustomValue(
186 versionKey,
187 fi.lastModified().toString(Qt.DateFormat.ISODate) + '|' +
188 fi.absoluteFilePath())
189 return True
190
191 return False
192
193 def __installEric6Doc(self, engine):
194 """
195 Private method to install/update the eric help documentation.
196
197 @param engine reference to the help engine (QHelpEngineCore)
198 @return flag indicating success (boolean)
199 """
200 versionKey = "eric6_ide"
201 info = engine.customValue(versionKey, "")
202 lst = info.split('|')
203
204 dt = QDateTime()
205 if len(lst) and lst[0]:
206 dt = QDateTime.fromString(lst[0], Qt.DateFormat.ISODate)
207
208 qchFile = ""
209 if len(lst) == 2:
210 qchFile = lst[1]
211
212 docsPath = QDir(getConfig("ericDocDir") + QDir.separator() + "Help")
213
214 files = docsPath.entryList(["*.qch"])
215 if not files:
216 engine.setCustomValue(
217 versionKey, QDateTime().toString(Qt.DateFormat.ISODate) + '|')
218 return False
219
220 for f in files:
221 if f == "source.qch":
222 fi = QFileInfo(docsPath.absolutePath() + QDir.separator() + f)
223 namespace = QHelpEngineCore.namespaceName(
224 fi.absoluteFilePath())
225 if not namespace:
226 continue
227
228 if (
229 dt.isValid() and
230 namespace in engine.registeredDocumentations() and
231 (fi.lastModified().toString(Qt.DateFormat.ISODate) ==
232 dt.toString(Qt.DateFormat.ISODate)) and
233 qchFile == fi.absoluteFilePath()
234 ):
235 return False
236
237 if namespace in engine.registeredDocumentations():
238 engine.unregisterDocumentation(namespace)
239
240 if not engine.registerDocumentation(fi.absoluteFilePath()):
241 self.errorMessage.emit(
242 self.tr(
243 """<p>The file <b>{0}</b> could not be"""
244 """ registered. <br/>Reason: {1}</p>""")
245 .format(fi.absoluteFilePath, engine.error())
246 )
247 return False
248
249 engine.setCustomValue(
250 versionKey,
251 fi.lastModified().toString(Qt.DateFormat.ISODate) + '|' +
252 fi.absoluteFilePath())
253 return True
254
255 return False

eric ide

mercurial