9 |
9 |
10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 |
11 |
12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl, QRegExp, \ |
12 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl, QRegExp, \ |
13 QByteArray, QCryptographicHash |
13 QByteArray, QCryptographicHash |
|
14 from PyQt5.QtGui import QIcon, QPixmap, QImage |
|
15 from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply |
14 from PyQt5.QtWebEngineWidgets import QWebEngineScript |
16 from PyQt5.QtWebEngineWidgets import QWebEngineScript |
15 |
17 |
16 from .GreaseMonkeyJavaScript import bootstrap_js, values_js |
18 from .GreaseMonkeyJavaScript import bootstrap_js, values_js |
17 from .GreaseMonkeyDownloader import GreaseMonkeyDownloader |
19 from .GreaseMonkeyDownloader import GreaseMonkeyDownloader |
18 |
20 |
19 from ..Tools.DelayedFileWatcher import DelayedFileWatcher |
21 from ..Tools.DelayedFileWatcher import DelayedFileWatcher |
20 from ..WebBrowserPage import WebBrowserPage |
22 from ..WebBrowserPage import WebBrowserPage |
|
23 from ..WebBrowserWindow import WebBrowserWindow |
21 |
24 |
22 from Globals import qVersionTuple |
25 from Globals import qVersionTuple |
23 |
26 |
24 |
27 |
25 class GreaseMonkeyScript(QObject): |
28 class GreaseMonkeyScript(QObject): |
69 self.__noFrames = False |
74 self.__noFrames = False |
70 |
75 |
71 self.__updating = False |
76 self.__updating = False |
72 |
77 |
73 self.__downloaders = [] |
78 self.__downloaders = [] |
|
79 self.__iconReplies = [] |
74 |
80 |
75 self.__parseScript() |
81 self.__parseScript() |
76 |
82 |
77 self.__fileWatcher.delayedFileChanged.connect( |
83 self.__fileWatcher.delayedFileChanged.connect( |
78 self.__watchedFileChanged) |
84 self.__watchedFileChanged) |
122 Public method to get the version of the script. |
128 Public method to get the version of the script. |
123 |
129 |
124 @return version of the script (string) |
130 @return version of the script (string) |
125 """ |
131 """ |
126 return self.__version |
132 return self.__version |
|
133 |
|
134 def icon(self): |
|
135 """ |
|
136 Public method to get the icon of the script. |
|
137 |
|
138 @return script icon |
|
139 @rtype QIcon |
|
140 """ |
|
141 return self.__icon |
|
142 |
|
143 def iconUrl(self): |
|
144 """ |
|
145 Public method to get the icon URL of the script. |
|
146 |
|
147 @return icon URL of the script (QUrl) |
|
148 """ |
|
149 return QUrl(self.__iconUrl) |
127 |
150 |
128 def downloadUrl(self): |
151 def downloadUrl(self): |
129 """ |
152 """ |
130 Public method to get the download URL of the script. |
153 Public method to get the download URL of the script. |
131 |
154 |
275 if not line.startswith("// @"): |
300 if not line.startswith("// @"): |
276 continue |
301 continue |
277 |
302 |
278 line = line[3:].replace("\t", " ") |
303 line = line[3:].replace("\t", " ") |
279 index = line.find(" ") |
304 index = line.find(" ") |
280 if index < 0: |
|
281 continue |
|
282 |
305 |
283 key = line[:index].strip() |
306 key = line[:index].strip() |
284 value = line[index + 1:].strip() |
307 if index > 0: |
285 |
308 value = line[index + 1:].strip() |
286 # Ignored values: @resource, @unwrap |
309 else: |
287 |
310 value = "" |
288 if not key or not value: |
311 |
|
312 if not key: |
289 continue |
313 continue |
290 |
314 |
291 if key == "@name": |
315 if key == "@name": |
292 self.__name = value |
316 self.__name = value |
293 |
317 |
320 elif key == "@downloadURL" and self.__downloadUrl.isEmpty(): |
344 elif key == "@downloadURL" and self.__downloadUrl.isEmpty(): |
321 self.__downloadUrl = QUrl(value) |
345 self.__downloadUrl = QUrl(value) |
322 |
346 |
323 elif key == "@updateURL" and self.__updateUrl.isEmpty(): |
347 elif key == "@updateURL" and self.__updateUrl.isEmpty(): |
324 self.__updateUrl = QUrl(value) |
348 self.__updateUrl = QUrl(value) |
|
349 |
|
350 elif key == "@icon": |
|
351 self.__iconUrl = QUrl(value) |
|
352 |
|
353 elif key == "@noframes": |
|
354 self.__noFrames = True |
|
355 |
|
356 self.__iconUrl = self.__downloadUrl.resolved(self.__iconUrl) |
325 |
357 |
326 if not self.__include: |
358 if not self.__include: |
327 self.__include.append("*") |
359 self.__include.append("*") |
328 |
360 |
329 nspace = bytes(QCryptographicHash.hash( |
361 nspace = bytes(QCryptographicHash.hash( |
361 self.__script = "(function(){{{0}\n{1}\n{2}\n}})();".format( |
393 self.__script = "(function(){{{0}\n{1}\n{2}\n}})();".format( |
362 valuesScript, self.__manager.requireScripts(self.__require), |
394 valuesScript, self.__manager.requireScripts(self.__require), |
363 fileData |
395 fileData |
364 ) |
396 ) |
365 self.__valid = True |
397 self.__valid = True |
|
398 |
|
399 self.__downloadIcon() |
|
400 self.__downloadRequires() |
366 |
401 |
367 def webScript(self): |
402 def webScript(self): |
368 """ |
403 """ |
369 Public method to create a script object. |
404 Public method to create a script object. |
370 |
405 |
512 @param downloader reference to the downloader object |
547 @param downloader reference to the downloader object |
513 @type GreaseMonkeyDownloader |
548 @type GreaseMonkeyDownloader |
514 """ |
549 """ |
515 if downloader in self.__downloaders: |
550 if downloader in self.__downloaders: |
516 self.__downloaders.remove(downloader) |
551 self.__downloaders.remove(downloader) |
|
552 |
|
553 def __downloadIcon(self): |
|
554 """ |
|
555 Private slot to download the script icon. |
|
556 """ |
|
557 if self.__iconUrl.isValid(): |
|
558 request = QNetworkRequest(self.__iconUrl) |
|
559 reply = WebBrowserWindow.networkManager().get(request) |
|
560 reply.finished.connect(lambda: self.__iconDownloaded(reply)) |
|
561 self.__iconReplies.append(reply) |
|
562 |
|
563 def __iconDownloaded(self, reply): |
|
564 """ |
|
565 Private slot to handle a finished download of a script icon. |
|
566 |
|
567 @param reply reference to the network reply |
|
568 @type QNetworkReply |
|
569 """ |
|
570 if reply in self.__iconReplies: |
|
571 self.__iconReplies.remove(reply) |
|
572 |
|
573 reply.deleteLater() |
|
574 if reply.error() == QNetworkReply.NoError: |
|
575 self.__icon = QPixmap.fromImage(QImage.fromData(reply.readAll())) |