eric6/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7229
53054eb5b15a
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2012 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the manager for GreaseMonkey scripts.
8 """
9
10 from __future__ import unicode_literals
11
12 import os
13
14 from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QObject, QTimer, QFile, \
15 QFileInfo, QDir, QSettings, QMetaObject, QUrl, Q_ARG, QCoreApplication
16 from PyQt5.QtWidgets import QDialog
17
18 from E5Gui import E5MessageBox
19
20 import Utilities
21 import Preferences
22
23 from WebBrowser.WebBrowserWindow import WebBrowserWindow
24 from WebBrowser.JavaScript.ExternalJsObject import ExternalJsObject
25
26 from .GreaseMonkeyJsObject import GreaseMonkeyJsObject
27
28
29 class GreaseMonkeyManager(QObject):
30 """
31 Class implementing the manager for GreaseMonkey scripts.
32
33 @signal scriptsChanged() emitted to indicate a change of scripts
34 """
35 scriptsChanged = pyqtSignal()
36
37 def __init__(self, parent=None):
38 """
39 Constructor
40
41 @param parent reference to the parent object (QObject)
42 """
43 super(GreaseMonkeyManager, self).__init__(parent)
44
45 self.__disabledScripts = []
46 self.__scripts = []
47 self.__downloaders = []
48
49 self.__jsObject = GreaseMonkeyJsObject(self)
50
51 QTimer.singleShot(0, self.__load)
52
53 def showConfigurationDialog(self, parent=None):
54 """
55 Public method to show the configuration dialog.
56
57 @param parent reference to the parent widget (QWidget)
58 """
59 from .GreaseMonkeyConfiguration.GreaseMonkeyConfigurationDialog \
60 import GreaseMonkeyConfigurationDialog
61 self.__configDiaolg = GreaseMonkeyConfigurationDialog(self, parent)
62 self.__configDiaolg.show()
63
64 def downloadScript(self, url):
65 """
66 Public method to download a GreaseMonkey script.
67
68 @param url URL to download script from
69 @type QUrl
70 """
71 QMetaObject.invokeMethod(
72 self, "doDownloadScript", Qt.QueuedConnection,
73 Q_ARG(QUrl, url))
74
75 @pyqtSlot(QUrl)
76 def doDownloadScript(self, url):
77 """
78 Public slot to download a GreaseMonkey script.
79
80 Note: The download needed to be separated in the invoking part
81 (s.a.) and the one doing the real download because the invoking
82 part runs in a different thread (i.e. the web engine thread).
83
84 @param url URL to download script from
85 @type QUrl
86 """
87 from .GreaseMonkeyDownloader import GreaseMonkeyDownloader
88 downloader = GreaseMonkeyDownloader(
89 url, self, GreaseMonkeyDownloader.DownloadMainScript)
90 downloader.finished.connect(
91 lambda f: self.__downloaderFinished(f, downloader))
92 self.__downloaders.append(downloader)
93
94 def __downloaderFinished(self, fileName, downloader):
95 """
96 Private slot to handle the completion of a script download.
97
98 @param fileName name of the downloaded script
99 @type str
100 @param downloader reference to the downloader object
101 @type GreaseMonkeyDownloader
102 """
103 if downloader in self.__downloaders:
104 self.__downloaders.remove(downloader)
105
106 deleteScript = True
107 from .GreaseMonkeyScript import GreaseMonkeyScript
108 script = GreaseMonkeyScript(self, fileName)
109 if script.isValid():
110 if not self.containsScript(script.fullName()):
111 from .GreaseMonkeyAddScriptDialog import \
112 GreaseMonkeyAddScriptDialog
113 dlg = GreaseMonkeyAddScriptDialog(self, script)
114 deleteScript = dlg.exec_() != QDialog.Accepted
115 else:
116 E5MessageBox.information(
117 None,
118 QCoreApplication.translate(
119 "GreaseMonkeyManager",
120 "Install GreaseMonkey Script"),
121 QCoreApplication.translate(
122 "GreaseMonkeyManager",
123 """'{0}' is already installed.""").format(
124 script.fullName())
125 )
126
127 if deleteScript:
128 try:
129 os.remove(fileName)
130 except (IOError, OSError):
131 # ignore
132 pass
133
134 def scriptsDirectory(self):
135 """
136 Public method to get the path of the scripts directory.
137
138 @return path of the scripts directory (string)
139 """
140 return os.path.join(
141 Utilities.getConfigDir(), "web_browser", "greasemonkey")
142
143 def requireScriptsDirectory(self):
144 """
145 Public method to get the path of the scripts directory.
146
147 @return path of the scripts directory (string)
148 """
149 return os.path.join(self.scriptsDirectory(), "requires")
150
151 def requireScripts(self, urlList):
152 """
153 Public method to get the sources of all required scripts.
154
155 @param urlList list of URLs (list of string)
156 @return sources of all required scripts (string)
157 """
158 requiresDir = QDir(self.requireScriptsDirectory())
159 if not requiresDir.exists() or len(urlList) == 0:
160 return ""
161
162 script = ""
163
164 settings = QSettings(
165 os.path.join(self.requireScriptsDirectory(), "requires.ini"),
166 QSettings.IniFormat)
167 settings.beginGroup("Files")
168 for url in urlList:
169 if settings.contains(url):
170 fileName = settings.value(url)
171 if not QFileInfo(fileName).isAbsolute():
172 fileName = os.path.join(self.requireScriptsDirectory(),
173 fileName)
174 try:
175 f = open(fileName, "r", encoding="utf-8")
176 source = f.read().strip()
177 f.close()
178 except (IOError, OSError):
179 source = ""
180 if source:
181 script += source + "\n"
182
183 return script
184
185 def saveConfiguration(self):
186 """
187 Public method to save the configuration.
188 """
189 Preferences.setWebBrowser("GreaseMonkeyDisabledScripts",
190 self.__disabledScripts)
191
192 def allScripts(self):
193 """
194 Public method to get a list of all scripts.
195
196 @return list of all scripts (list of GreaseMonkeyScript)
197 """
198 return self.__scripts[:]
199
200 def containsScript(self, fullName):
201 """
202 Public method to check, if the given script exists.
203
204 @param fullName full name of the script (string)
205 @return flag indicating the existence (boolean)
206 """
207 for script in self.__scripts:
208 if script.fullName() == fullName:
209 return True
210
211 return False
212
213 def enableScript(self, script):
214 """
215 Public method to enable the given script.
216
217 @param script script to be enabled (GreaseMonkeyScript)
218 """
219 script.setEnabled(True)
220 fullName = script.fullName()
221 if fullName in self.__disabledScripts:
222 self.__disabledScripts.remove(fullName)
223
224 collection = WebBrowserWindow.webProfile().scripts()
225 collection.insert(script.webScript())
226
227 def disableScript(self, script):
228 """
229 Public method to disable the given script.
230
231 @param script script to be disabled (GreaseMonkeyScript)
232 """
233 script.setEnabled(False)
234 fullName = script.fullName()
235 if fullName not in self.__disabledScripts:
236 self.__disabledScripts.append(fullName)
237
238 collection = WebBrowserWindow.webProfile().scripts()
239 collection.remove(collection.findScript(fullName))
240
241 def addScript(self, script):
242 """
243 Public method to add a script.
244
245 @param script script to be added (GreaseMonkeyScript)
246 @return flag indicating success (boolean)
247 """
248 if not script or not script.isValid():
249 return False
250
251 self.__scripts.append(script)
252 script.scriptChanged.connect(lambda: self.__scriptChanged(script))
253
254 collection = WebBrowserWindow.webProfile().scripts()
255 collection.insert(script.webScript())
256
257 self.scriptsChanged.emit()
258 return True
259
260 def removeScript(self, script, removeFile=True):
261 """
262 Public method to remove a script.
263
264 @param script script to be removed (GreaseMonkeyScript)
265 @param removeFile flag indicating to remove the script file as well
266 (bool)
267 @return flag indicating success (boolean)
268 """
269 if not script:
270 return False
271
272 try:
273 self.__scripts.remove(script)
274 except ValueError:
275 pass
276
277 fullName = script.fullName()
278 collection = WebBrowserWindow.webProfile().scripts()
279 collection.remove(collection.findScript(fullName))
280
281 if fullName in self.__disabledScripts:
282 self.__disabledScripts.remove(fullName)
283
284 if removeFile:
285 QFile.remove(script.fileName())
286 del script
287
288 self.scriptsChanged.emit()
289 return True
290
291 def canRunOnScheme(self, scheme):
292 """
293 Public method to check, if scripts can be run on a scheme.
294
295 @param scheme scheme to check (string)
296 @return flag indicating, that scripts can be run (boolean)
297 """
298 return scheme in ["http", "https", "data", "ftp"]
299
300 def __load(self):
301 """
302 Private slot to load the available scripts into the manager.
303 """
304 scriptsDir = QDir(self.scriptsDirectory())
305 if not scriptsDir.exists():
306 scriptsDir.mkpath(self.scriptsDirectory())
307
308 if not scriptsDir.exists("requires"):
309 scriptsDir.mkdir("requires")
310
311 self.__disabledScripts = \
312 Preferences.getWebBrowser("GreaseMonkeyDisabledScripts")
313
314 from .GreaseMonkeyScript import GreaseMonkeyScript
315 for fileName in scriptsDir.entryList(["*.js"], QDir.Files):
316 absolutePath = scriptsDir.absoluteFilePath(fileName)
317 script = GreaseMonkeyScript(self, absolutePath)
318
319 if not script.isValid():
320 del script
321 continue
322
323 self.__scripts.append(script)
324
325 if script.fullName() in self.__disabledScripts:
326 script.setEnabled(False)
327 else:
328 collection = WebBrowserWindow.webProfile().scripts()
329 collection.insert(script.webScript())
330
331 self.__jsObject.setSettingsFile(os.path.join(
332 Utilities.getConfigDir(), "web_browser",
333 "greasemonkey_values.ini"))
334 ExternalJsObject.registerExtraObject("GreaseMonkey", self.__jsObject)
335
336 def __scriptChanged(self, script):
337 """
338 Private slot handling a changed script.
339
340 @param script reference to the changed script
341 @type GreaseMonkeyScript
342 """
343 fullName = script.fullName()
344 collection = WebBrowserWindow.webProfile().scripts()
345 collection.remove(collection.findScript(fullName))
346 collection.insert(script.webScript())

eric ide

mercurial