WebBrowser/GreaseMonkey/GreaseMonkeyManager.py

branch
QtWebEngine
changeset 4763
8ad353f31184
parent 4631
5c1a96925da4
child 4766
5f8d08aa2217
equal deleted inserted replaced
4762:ea40955a0937 4763:8ad353f31184
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2012 - 2016 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, QObject, QTimer, QFile, QDir, QSettings, \
15 QUrl, QByteArray
16 from PyQt5.QtNetwork import QNetworkAccessManager
17
18 import Utilities
19 import Preferences
20
21
22 class GreaseMonkeyManager(QObject):
23 """
24 Class implementing the manager for GreaseMonkey scripts.
25 """
26 scriptsChanged = pyqtSignal()
27
28 def __init__(self, parent=None):
29 """
30 Constructor
31
32 @param parent reference to the parent object (QObject)
33 """
34 super(GreaseMonkeyManager, self).__init__(parent)
35
36 self.__disabledScripts = []
37 self.__endScripts = []
38 self.__startScripts = []
39 self.__downloaders = []
40
41 QTimer.singleShot(0, self.__load)
42 ## , m_interceptor(new GM_UrlInterceptor(this))
43 ##{
44 ## mApp->networkManager()->installUrlInterceptor(m_interceptor);
45 ##
46 ## QTimer::singleShot(0, this, SLOT(load()));
47 ##}
48 ##
49 ##GM_Manager::~GM_Manager()
50 ##{
51 ## mApp->networkManager()->removeUrlInterceptor(m_interceptor);
52 ##}
53
54 def showConfigurationDialog(self, parent=None):
55 """
56 Public method to show the configuration dialog.
57
58 @param parent reference to the parent widget (QWidget)
59 """
60 from .GreaseMonkeyConfiguration.GreaseMonkeyConfigurationDialog \
61 import GreaseMonkeyConfigurationDialog
62 self.__configDiaolg = GreaseMonkeyConfigurationDialog(self, parent)
63 self.__configDiaolg.show()
64
65 def downloadScript(self, request):
66 """
67 Public method to download a GreaseMonkey script.
68
69 @param request reference to the request (QNetworkRequest)
70 """
71 from .GreaseMonkeyDownloader import GreaseMonkeyDownloader
72 downloader = GreaseMonkeyDownloader(request, self)
73 downloader.finished.connect(self.__downloaderFinished)
74 self.__downloaders.append(downloader)
75
76 def __downloaderFinished(self):
77 """
78 Private slot to handle the completion of a script download.
79 """
80 downloader = self.sender()
81 if downloader is None or downloader not in self.__downloaders:
82 return
83
84 self.__downloaders.remove(downloader)
85
86 def scriptsDirectory(self):
87 """
88 Public method to get the path of the scripts directory.
89
90 @return path of the scripts directory (string)
91 """
92 return os.path.join(
93 Utilities.getConfigDir(), "web_browser", "greasemonkey")
94
95 def requireScriptsDirectory(self):
96 """
97 Public method to get the path of the scripts directory.
98
99 @return path of the scripts directory (string)
100 """
101 return os.path.join(self.scriptsDirectory(), "requires")
102
103 def requireScripts(self, urlList):
104 """
105 Public method to get the sources of all required scripts.
106
107 @param urlList list of URLs (list of string)
108 @return sources of all required scripts (string)
109 """
110 requiresDir = QDir(self.requireScriptsDirectory())
111 if not requiresDir.exists() or len(urlList) == 0:
112 return ""
113
114 script = ""
115
116 settings = QSettings(
117 os.path.join(self.requireScriptsDirectory(), "requires.ini"),
118 QSettings.IniFormat)
119 settings.beginGroup("Files")
120 for url in urlList:
121 if settings.contains(url):
122 fileName = settings.value(url)
123 try:
124 f = open(fileName, "r", encoding="utf-8")
125 source = f.read()
126 f.close()
127 except (IOError, OSError):
128 source = ""
129 script += source.strip() + "\n"
130
131 return script
132
133 def saveConfiguration(self):
134 """
135 Public method to save the configuration.
136 """
137 Preferences.setWebBrowser("GreaseMonkeyDisabledScripts",
138 self.__disabledScripts)
139
140 def allScripts(self):
141 """
142 Public method to get a list of all scripts.
143
144 @return list of all scripts (list of GreaseMonkeyScript)
145 """
146 return self.__startScripts[:] + self.__endScripts[:]
147
148 def containsScript(self, fullName):
149 """
150 Public method to check, if the given script exists.
151
152 @param fullName full name of the script (string)
153 @return flag indicating the existence (boolean)
154 """
155 for script in self.__startScripts:
156 if script.fullName() == fullName:
157 return True
158 for script in self.__endScripts:
159 if script.fullName() == fullName:
160 return True
161 return False
162
163 def enableScript(self, script):
164 """
165 Public method to enable the given script.
166
167 @param script script to be enabled (GreaseMonkeyScript)
168 """
169 script.setEnabled(True)
170 fullName = script.fullName()
171 if fullName in self.__disabledScripts:
172 self.__disabledScripts.remove(fullName)
173 ##void GM_Manager::enableScript(GM_Script* script)
174 ##{
175 ## script->setEnabled(true);
176 ## m_disabledScripts.removeOne(script->fullName());
177 ##
178 ## QWebEngineScriptCollection *collection = mApp->webProfile()->scripts();
179 ## collection->insert(script->webScript());
180 ##}
181
182 def disableScript(self, script):
183 """
184 Public method to disable the given script.
185
186 @param script script to be disabled (GreaseMonkeyScript)
187 """
188 script.setEnabled(False)
189 fullName = script.fullName()
190 if fullName not in self.__disabledScripts:
191 self.__disabledScripts.append(fullName)
192 ##void GM_Manager::disableScript(GM_Script* script)
193 ##{
194 ## script->setEnabled(false);
195 ## m_disabledScripts.append(script->fullName());
196 ##
197 ## QWebEngineScriptCollection *collection = mApp->webProfile()->scripts();
198 ## collection->remove(collection->findScript(script->fullName()));
199
200 def addScript(self, script):
201 """
202 Public method to add a script.
203
204 @param script script to be added (GreaseMonkeyScript)
205 @return flag indicating success (boolean)
206 """
207 if not script:
208 return False
209
210 from .GreaseMonkeyScript import GreaseMonkeyScript
211 if script.startAt() == GreaseMonkeyScript.DocumentStart:
212 self.__startScripts.append(script)
213 else:
214 self.__endScripts.append(script)
215
216 self.scriptsChanged.emit()
217 return True
218 ##bool GM_Manager::addScript(GM_Script* script)
219 ##{
220 ## if (!script || !script->isValid()) {
221 ## return false;
222 ## }
223 ##
224 ## m_scripts.append(script);
225 ## connect(script, &GM_Script::scriptChanged, this, &GM_Manager::scriptChanged);
226 ##
227 ## QWebEngineScriptCollection *collection = mApp->webProfile()->scripts();
228 ## collection->insert(script->webScript());
229 ##
230 ## emit scriptsChanged();
231 ## return true;
232 ##}
233
234 def removeScript(self, script):
235 """
236 Public method to remove a script.
237
238 @param script script to be removed (GreaseMonkeyScript)
239 @return flag indicating success (boolean)
240 """
241 if not script:
242 return False
243
244 from .GreaseMonkeyScript import GreaseMonkeyScript
245 if script.startAt() == GreaseMonkeyScript.DocumentStart:
246 try:
247 self.__startScripts.remove(script)
248 except ValueError:
249 pass
250 else:
251 try:
252 self.__endScripts.remove(script)
253 except ValueError:
254 pass
255
256 fullName = script.fullName()
257 if fullName in self.__disabledScripts:
258 self.__disabledScripts.remove(fullName)
259 QFile.remove(script.fileName())
260
261 self.scriptsChanged.emit()
262 return True
263 ##bool GM_Manager::removeScript(GM_Script* script, bool removeFile)
264 ##{
265 ## if (!script) {
266 ## return false;
267 ## }
268 ##
269 ## m_scripts.removeOne(script);
270 ##
271 ## QWebEngineScriptCollection *collection = mApp->webProfile()->scripts();
272 ## collection->remove(collection->findScript(script->fullName()));
273 ##
274 ## m_disabledScripts.removeOne(script->fullName());
275 ##
276 ## if (removeFile) {
277 ## QFile::remove(script->fileName());
278 ## delete script;
279 ## }
280 ##
281 ## emit scriptsChanged();
282 ## return true;
283 ##}
284
285 def canRunOnScheme(self, scheme):
286 """
287 Public method to check, if scripts can be run on a scheme.
288
289 @param scheme scheme to check (string)
290 @return flag indicating, that scripts can be run (boolean)
291 """
292 return scheme in ["http", "https", "data", "ftp"]
293
294 ## def pageLoadStarted(self):
295 ## """
296 ## Public slot to handle the start of loading a page.
297 ## """
298 ## frame = self.sender()
299 ## if not frame:
300 ## return
301 ##
302 ## urlScheme = frame.url().scheme()
303 ## urlString = bytes(frame.url().toEncoded()).decode()
304 ##
305 ## if not self.canRunOnScheme(urlScheme):
306 ## return
307 ##
308 ## from .GreaseMonkeyJavaScript import bootstrap_js
309 ## for script in self.__startScripts:
310 ## if script.match(urlString):
311 ## frame.evaluateJavaScript(bootstrap_js + script.script())
312 ##
313 ## for script in self.__endScripts:
314 ## if script.match(urlString):
315 ## javascript = 'window.addEventListener("DOMContentLoaded",' \
316 ## 'function(e) {{ {0} }}, false);'.format(
317 ## bootstrap_js + script.script())
318 ## frame.evaluateJavaScript(javascript)
319
320 def __load(self):
321 """
322 Private slot to load the available scripts into the manager.
323 """
324 scriptsDir = QDir(self.scriptsDirectory())
325 if not scriptsDir.exists():
326 scriptsDir.mkpath(self.scriptsDirectory())
327
328 if not scriptsDir.exists("requires"):
329 scriptsDir.mkdir("requires")
330
331 self.__disabledScripts = \
332 Preferences.getHelp("GreaseMonkeyDisabledScripts")
333
334 from .GreaseMonkeyScript import GreaseMonkeyScript
335 for fileName in scriptsDir.entryList(["*.js"], QDir.Files):
336 absolutePath = scriptsDir.absoluteFilePath(fileName)
337 script = GreaseMonkeyScript(self, absolutePath)
338
339 if script.fullName() in self.__disabledScripts:
340 script.setEnabled(False)
341
342 if script.startAt() == GreaseMonkeyScript.DocumentStart:
343 self.__startScripts.append(script)
344 else:
345 self.__endScripts.append(script)
346 ##void GM_Manager::load()
347 ##{
348 ## QDir gmDir(m_settingsPath + QL1S("/greasemonkey"));
349 ## if (!gmDir.exists()) {
350 ## gmDir.mkdir(m_settingsPath + QL1S("/greasemonkey"));
351 ## }
352 ##
353 ## if (!gmDir.exists("requires")) {
354 ## gmDir.mkdir("requires");
355 ## }
356 ##
357 ## m_bootstrapScript = QzTools::readAllFileContents(":gm/data/bootstrap.min.js");
358 ## m_valuesScript = QzTools::readAllFileContents(":gm/data/values.min.js");
359 ##
360 ## QSettings settings(m_settingsPath + QL1S("/extensions.ini"), QSettings::IniFormat);
361 ## settings.beginGroup("GreaseMonkey");
362 ## m_disabledScripts = settings.value("disabledScripts", QStringList()).toStringList();
363 ##
364 ## foreach (const QString &fileName, gmDir.entryList(QStringList("*.js"), QDir::Files)) {
365 ## const QString absolutePath = gmDir.absoluteFilePath(fileName);
366 ## GM_Script* script = new GM_Script(this, absolutePath);
367 ##
368 ## if (!script->isValid()) {
369 ## delete script;
370 ## continue;
371 ## }
372 ##
373 ## m_scripts.append(script);
374 ##
375 ## if (m_disabledScripts.contains(script->fullName())) {
376 ## script->setEnabled(false);
377 ## }
378 ## else {
379 ## mApp->webProfile()->scripts()->insert(script->webScript());
380 ## }
381 ## }
382 ##}
383
384 def __scriptChanged(self):
385 """
386 Private slot handling a changed script.
387 """
388 ##void GM_Manager::scriptChanged()
389 ##{
390 ## GM_Script *script = qobject_cast<GM_Script*>(sender());
391 ## if (!script)
392 ## return;
393 ##
394 ## QWebEngineScriptCollection *collection = mApp->webProfile()->scripts();
395 ## collection->remove(collection->findScript(script->fullName()));
396 ## collection->insert(script->webScript());
397 ##}
398
399 ## def connectPage(self, page):
400 ## """
401 ## Public method to allow the GreaseMonkey manager to connect to the page.
402 ##
403 ## @param page reference to the web page (HelpWebPage)
404 ## """
405 ## page.mainFrame().javaScriptWindowObjectCleared.connect(
406 ## self.pageLoadStarted)
407 ##
408 ## def createRequest(self, op, request, outgoingData=None):
409 ## """
410 ## Public method to create a request.
411 ##
412 ## @param op the operation to be performed
413 ## (QNetworkAccessManager.Operation)
414 ## @param request reference to the request object (QNetworkRequest)
415 ## @param outgoingData reference to an IODevice containing data to be sent
416 ## (QIODevice)
417 ## @return reference to the created reply object (QNetworkReply)
418 ## """
419 ## if op == QNetworkAccessManager.GetOperation and \
420 ## request.rawHeader(b"X-Eric6-UserLoadAction") == QByteArray(b"1"):
421 ## urlString = request.url().toString(
422 ## QUrl.RemoveFragment | QUrl.RemoveQuery)
423 ## if urlString.endswith(".user.js"):
424 ## self.downloadScript(request)
425 ## from Helpviewer.Network.EmptyNetworkReply import \
426 ## EmptyNetworkReply
427 ## return EmptyNetworkReply(self)
428 ##
429 ## return None

eric ide

mercurial