diff -r 90c57b50600f -r cbcca230679f WebBrowser/GreaseMonkey/GreaseMonkeyDownloader.py --- a/WebBrowser/GreaseMonkey/GreaseMonkeyDownloader.py Tue Apr 25 18:40:46 2017 +0200 +++ b/WebBrowser/GreaseMonkey/GreaseMonkeyDownloader.py Tue Apr 25 19:20:18 2017 +0200 @@ -11,22 +11,24 @@ import os -from PyQt5.QtCore import pyqtSignal, QObject, QSettings, QRegExp, QUrl -from PyQt5.QtWidgets import QDialog +from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QSettings, QFileInfo from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest -from E5Gui import E5MessageBox - from WebBrowser.WebBrowserWindow import WebBrowserWindow +# TODO: document signals class GreaseMonkeyDownloader(QObject): """ Class implementing the downloader for GreaseMonkey scripts. """ - finished = pyqtSignal() + finished = pyqtSignal(str) + error = pyqtSignal() - def __init__(self, url, manager): + DownloadMainScript = 1 + DownloadRequireScript = 2 + + def __init__(self, url, manager, mode): """ Constructor @@ -34,6 +36,8 @@ @type QUrl @param manager reference to the GreaseMonkey manager @type GreaseMonkeyManager + @param mode download mode + @type int (one of DownloadMainScript, DownloadRequireScript) """ super(GreaseMonkeyDownloader, self).__init__() @@ -41,139 +45,118 @@ self.__reply = WebBrowserWindow.networkManager().get( QNetworkRequest(url)) - self.__reply.finished.connect(self.__scriptDownloaded) + if mode == GreaseMonkeyDownloader.DownloadMainScript: + self.__reply.finished.connect(self.__scriptDownloaded) + else: + self.__reply.finished.connect(self.__requireDownloaded) self.__fileName = "" - self.__requireUrls = [] + def updateScript(self, fileName): + """ + Public method to set the file name for the script to be downloaded. + + @param fileName file name for the script + @type str + """ + self.__fileName = fileName + + @pyqtSlot() def __scriptDownloaded(self): """ Private slot to handle the finished download of a script. """ + self.deleteLater() + self.__reply.deleteLater() + if self.sender() != self.__reply: - self.finished.emit() + self.error.emit() + return + + if self.__reply.error() != QNetworkReply.NoError: + self.error.emit() return response = bytes(self.__reply.readAll()).decode() - if self.__reply.error() == QNetworkReply.NoError and \ - "// ==UserScript==" in response: + if "// ==UserScript==" not in response: + self.error.emit() + return + + if not self.__fileName: from WebBrowser.Tools import WebBrowserTools filePath = os.path.join( self.__manager.scriptsDirectory(), WebBrowserTools.getFileNameFromUrl(self.__reply.url())) self.__fileName = WebBrowserTools.ensureUniqueFilename(filePath) - - try: - f = open(self.__fileName, "w", encoding="utf-8") - except (IOError, OSError) as err: - E5MessageBox.critical( - None, - self.tr("GreaseMonkey Download"), - self.tr( - """<p>The file <b>{0}</b> could not be opened""" - """ for writing.<br/>Reason: {1}</p>""").format( - self.__fileName, str(err))) - self.finished.emit() - return - f.write(response) - f.close() - - settings = QSettings( - os.path.join(self.__manager.requireScriptsDirectory(), - "requires.ini"), - QSettings.IniFormat) - settings.beginGroup("Files") - - rx = QRegExp("@require(.*)\\n") - rx.setMinimal(True) - rx.indexIn(response) - - for i in range(1, rx.captureCount() + 1): - url = rx.cap(i).strip() - if url and not settings.contains(url): - self.__requireUrls.append(QUrl(url)) - self.__reply.deleteLater() - self.__reply = None + try: + f = open(self.__fileName, "w", encoding="utf-8") + except (IOError, OSError) as err: + self.error.emit() + return + f.write(response) + f.close() - self.__downloadRequires() + self.finished.emit(self.__fileName) + @pyqtSlot() def __requireDownloaded(self): """ Private slot to handle the finished download of a required script. """ + self.deleteLater() + self.__reply.deleteLater() + if self.sender() != self.__reply: - self.finished.emit() + self.error.emit() + return + + if self.__reply.error() != QNetworkReply.NoError: + self.error.emit() return response = bytes(self.__reply.readAll()).decode() - if self.__reply.error() == QNetworkReply.NoError and response: - from WebBrowser.Tools import WebBrowserTools - filePath = os.path.join(self.__manager.requireScriptsDirectory(), - "require.js") - fileName = WebBrowserTools.ensureUniqueFilename(filePath, "{0}") - - try: - f = open(fileName, "w", encoding="utf-8") - except (IOError, OSError) as err: - E5MessageBox.critical( - None, - self.tr("GreaseMonkey Download"), - self.tr( - """<p>The file <b>{0}</b> could not be opened""" - """ for writing.<br/>Reason: {1}</p>""").format( - fileName, str(err))) - self.finished.emit() - return - f.write(response) - f.close() - - settings = QSettings( - os.path.join(self.__manager.requireScriptsDirectory(), - "requires.ini"), - QSettings.IniFormat) - settings.beginGroup("Files") - settings.setValue(self.__reply.originalUrl().toString(), fileName) + if not response: + self.error.emit() + return - self.__reply.deleteLater() - self.__reply = None + settings = QSettings( + os.path.join(self.__manager.requireScriptsDirectory(), + "requires.ini"), + QSettings.IniFormat) + settings.beginGroup("Files") - self.__downloadRequires() - - def __downloadRequires(self): - """ - Private slot to initiate the download of required scripts. - """ - if self.__requireUrls: - self.__reply = WebBrowserWindow.networkManager().get( - QNetworkRequest(self.__requireUrls.pop(0))) - self.__reply.finished.connect(self.__requireDownloaded) - else: - from .GreaseMonkeyScript import GreaseMonkeyScript - deleteScript = True - script = GreaseMonkeyScript(self.__manager, self.__fileName) - - if script.isValid(): - if not self.__manager.containsScript(script.fullName()): - from .GreaseMonkeyAddScriptDialog import \ - GreaseMonkeyAddScriptDialog - dlg = GreaseMonkeyAddScriptDialog(self.__manager, script) - deleteScript = dlg.exec_() != QDialog.Accepted - else: - E5MessageBox.information( - None, - self.tr("GreaseMonkey Download"), - self.tr( - """<p><b>{0}</b> is already installed.</p>""") - .format(script.name())) - - if deleteScript: - try: - os.remove(self.__fileName) - except (IOError, OSError): - # ignore - pass - - self.finished.emit() + if not self.__fileName: + self.__fileName = settings.value( + self.__reply.request().url().toString()) + if not self.__fileName: + name = QFileInfo(self.__reply.request().url().path())\ + .fileName() + if not name: + name = "require.js" + elif not name.endswith(".js"): + name += ".js" + filePath = os.path.join( + self.__manager.requireScriptsDirectory(), name) + from WebBrowser.Tools import WebBrowserTools + self.__fileName = WebBrowserTools.ensureUniqueFilename( + filePath, "{0}") + if not QFileInfo(self.__fileName).isAbsolute(): + self.__fileName = os.path.join( + self.__manager.requireScriptsDirectory(), + self.__fileName) + + try: + f = open(self.__fileName, "w", encoding="utf-8") + except (IOError, OSError) as err: + self.error.emit() + return + f.write(response) + f.close() + + settings.setValue(self.__reply.request().url().toString(), + QFileInfo(self.__fileName).fileName()) + + self.finished.emit(self.__fileName)