def SaveTools(self):
        try:
            if os.path.isfile(self.filepath):
                QFile.remove(self.file)

            self.file.open(QIODevice.WriteOnly)
            datastream = QDataStream(self.file)
            count = self.MyToolsBars.topLevelItemCount()
            datastream.writeUInt32(count)

            for i in range(0, count):
                item = self.MyToolsBars.topLevelItem(i)
                item.write(datastream)
                self.bar = None
                self.CreateToolBar(item)
                self.save_item(item, datastream)

            self.hasChanged = False
            self.file.close()
            # We restore the list of Qgis tools.
            state = self.saveWidgetState(self.ToolBars) 
            self.PopulateQgisTools()
            self.loadWidgetState(self.ToolBars, state)

            self.iface.messageBar().pushMessage("Info: ", "Save correctly.", level=QGis.Info, duration=3)
            self.rename_btn.setEnabled(False)
            self.delete_btn.setEnabled(False)
            self.restore = {}

        except Exception:
            self.iface.messageBar().pushMessage("Error: ", "Error save tools ", level=QGis.Critical, duration=3)
        return
Esempio n. 2
0
 def removeScript(self, script):
     """
     Public method to remove a script.
     
     @param script script to be removed (GreaseMonkeyScript)
     @return flag indicating success (boolean)
     """
     if not script:
         return False
     
     from .GreaseMonkeyScript import GreaseMonkeyScript
     if script.startAt() == GreaseMonkeyScript.DocumentStart:
         try:
             self.__startScripts.remove(script)
         except ValueError:
             pass
     else:
         try:
             self.__endScripts.remove(script)
         except ValueError:
             pass
     
     fullName = script.fullName()
     if fullName in self.__disabledScripts:
         self.__disabledScripts.remove(fullName)
     QFile.remove(script.fileName())
     
     self.scriptsChanged.emit()
     return True
Esempio n. 3
0
    def _copy_lib_file(cls, file_name, dir_name, dst_file_name=None):
        """ Copy a library file to a directory and return the full pathname of
        the copy.
        """

        # Note that we use the Qt file operations to support the possibility
        # that pyqtdeploy itself has been deployed as a single executable.

        if dst_file_name is None:
            dst_file_name = file_name
            s_file_name = cls._get_lib_file_name(file_name)
        else:
            s_file_name = file_name

        d_file_name = dir_name + '/' + dst_file_name

        # Make sure the destination doesn't exist.
        QFile.remove(d_file_name)

        if not QFile.copy(s_file_name, d_file_name):
            raise UserException("Unable to copy file {0}".format(file_name))

        # The file will be read-only if it was embedded.
        QFile.setPermissions(d_file_name,
                             QFileDevice.ReadOwner | QFileDevice.WriteOwner)

        return d_file_name
Esempio n. 4
0
    def removeEngine(self, name):
        """
        Public method to remove an engine.
        
        @param name name of the engine (string)
        """
        if len(self.__engines) <= 1:
            return

        if name not in self.__engines:
            return

        engine = self.__engines[name]
        for keyword in [
                k for k in self.__keywords if self.__keywords[k] == engine
        ]:
            del self.__keywords[keyword]
        del self.__engines[name]

        file_ = QDir(self.enginesDirectory()).filePath(
            self.generateEngineFileName(name))
        QFile.remove(file_)

        if name == self.__current:
            self.setCurrentEngineName(list(self.__engines.keys())[0])

        self.changed.emit()
Esempio n. 5
0
 def __finished(self):
     """
     Private slot to handle the download finished.
     """
     self.__finishedDownloading = True
     if not self.__startedSaving:
         return
     
     noError = self.__reply.error() == QNetworkReply.NoError
     
     self.progressBar.setVisible(False)
     if not self.__isFtpDownload:
         self.stopButton.setEnabled(False)
         self.stopButton.setVisible(False)
         self.pauseButton.setEnabled(False)
         self.pauseButton.setVisible(False)
     self.openButton.setEnabled(noError)
     self.openButton.setVisible(noError)
     self.__output.close()
     if QFile.exists(self.__fileName):
         QFile.remove(self.__fileName)
     self.__output.rename(self.__fileName)
     self.__updateInfoLabel()
     self.__state = DownloadItem.DownloadSuccessful
     self.statusChanged.emit()
     self.downloadFinished.emit()
     
     if self.__autoOpen:
         self.__open()
Esempio n. 6
0
    def removeItem(self, deleteFile: bool):
        """ Remove a char item from the presentation

            Args:
                deleteFile (bool) : whether to delete the file of the char item
        """

        # find the selected item
        charItem = self.selectedItem()

        # remove the item from the presentation
        charItem.setParentItem(None)

        # rearrange the items
        self.insertionIndex = -1
        for charItem in self.childItems():
            self.insertionIndex += 1
            self.positionChar(charItem)

        # reset the selected index
        self.selectedItemIndex = -1

        # delete the character file if requested
        if deleteFile == QMessageBox.Yes:
            fh = QFile(charItem.filename)
            fh.remove()
    def removeScript(self, script):
        """
        Public method to remove a script.
        
        @param script script to be removed (GreaseMonkeyScript)
        @return flag indicating success (boolean)
        """
        if not script:
            return False

        from .GreaseMonkeyScript import GreaseMonkeyScript
        if script.startAt() == GreaseMonkeyScript.DocumentStart:
            try:
                self.__startScripts.remove(script)
            except ValueError:
                pass
        else:
            try:
                self.__endScripts.remove(script)
            except ValueError:
                pass

        fullName = script.fullName()
        if fullName in self.__disabledScripts:
            self.__disabledScripts.remove(fullName)
        QFile.remove(script.fileName())

        self.scriptsChanged.emit()
        return True
Esempio n. 8
0
    def downloadFile(self):
        self.url = QUrl(self.urlLineEdit.text())
        fileInfo = QFileInfo(self.url.path())
        fileName = fileInfo.fileName()

        if not fileName:
            fileName = 'index.html'

        if QFile.exists(fileName):
            ret = QMessageBox.question(self, "HTTP",
                    "There already exists a file called %s in the current "
                    "directory. Overwrite?" % fileName,
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

            if ret == QMessageBox.No:
                return

            QFile.remove(fileName)

        self.outFile = QFile(fileName)
        if not self.outFile.open(QIODevice.WriteOnly):
            QMessageBox.information(self, "HTTP",
                    "Unable to save the file %s: %s." % (fileName, self.outFile.errorString()))
            self.outFile = None
            return

        self.progressDialog.setWindowTitle("HTTP")
        self.progressDialog.setLabelText("Downloading %s." % fileName)
        self.downloadButton.setEnabled(False)

        self.httpRequestAborted = False
        self.startRequest(self.url)
Esempio n. 9
0
 def removeSubscription(self, subscription, emitSignal=True):
     """
     Public method to remove an AdBlock subscription.
     
     @param subscription AdBlock subscription to be removed
         (AdBlockSubscription)
     @param emitSignal flag indicating to send a signal (boolean)
     """
     if subscription is None:
         return
     
     if subscription.url().toString().startswith(
         (self.__defaultSubscriptionUrlString,
          self.__customSubscriptionUrlString)):
         return
     
     try:
         self.__subscriptions.remove(subscription)
         rulesFileName = subscription.rulesFileName()
         QFile.remove(rulesFileName)
         requiresSubscriptions = self.getRequiresSubscriptions(subscription)
         for requiresSubscription in requiresSubscriptions:
             self.removeSubscription(requiresSubscription, False)
         if emitSignal:
             self.rulesChanged.emit()
     except ValueError:
         pass
Esempio n. 10
0
    def __loadRules(self):
        """
        Private method to load the rules of the subscription.
        """
        fileName = self.rulesFileName()
        f = QFile(fileName)
        if f.exists():
            if not f.open(QIODevice.ReadOnly):
                E5MessageBox.warning(
                    None, self.tr("Load subscription rules"),
                    self.tr(
                        """Unable to open adblock file '{0}' for reading.""").
                    format(fileName))
            else:
                textStream = QTextStream(f)
                header = textStream.readLine(1024)
                if not header.startswith("[Adblock"):
                    E5MessageBox.warning(
                        None, self.tr("Load subscription rules"),
                        self.tr("""AdBlock file '{0}' does not start"""
                                """ with [Adblock.""").format(fileName))
                    f.close()
                    f.remove()
                    self.__lastUpdate = QDateTime()
                else:
                    from .AdBlockRule import AdBlockRule

                    self.__updatePeriod = 0
                    self.__remoteModified = QDateTime()
                    self.__rules = []
                    self.__rules.append(AdBlockRule(header, self))
                    while not textStream.atEnd():
                        line = textStream.readLine()
                        self.__rules.append(AdBlockRule(line, self))
                        expires = self.__expiresRe.search(line)
                        if expires:
                            period, kind = expires.groups()
                            if kind:
                                # hours
                                self.__updatePeriod = int(period)
                            else:
                                # days
                                self.__updatePeriod = int(period) * 24
                        remoteModified = self.__remoteModifiedRe.search(line)
                        if remoteModified:
                            day, month, year, time, hour, minute = \
                                remoteModified.groups()
                            self.__remoteModified.setDate(
                                QDate(int(year),
                                      self.__monthNameToNumber[month],
                                      int(day)))
                            if time:
                                self.__remoteModified.setTime(
                                    QTime(int(hour), int(minute)))
                    self.__populateCache()
                    self.changed.emit()
        elif not fileName.endswith("_custom"):
            self.__lastUpdate = QDateTime()

        self.checkForUpdate()
Esempio n. 11
0
 def removeEngine(self, name):
     """
     Public method to remove an engine.
     
     @param name name of the engine (string)
     """
     if len(self.__engines) <= 1:
         return
     
     if name not in self.__engines:
         return
     
     engine = self.__engines[name]
     for keyword in [k for k in self.__keywords
                     if self.__keywords[k] == engine]:
         del self.__keywords[keyword]
     del self.__engines[name]
     
     file_ = QDir(self.enginesDirectory()).filePath(
         self.generateEngineFileName(name))
     QFile.remove(file_)
     
     if name == self.__current:
         self.setCurrentEngineName(list(self.__engines.keys())[0])
     
     self.changed.emit()
Esempio n. 12
0
    def __finished(self):
        """
        Private slot to handle the download finished.
        """
        self.__finishedDownloading = True
        if not self.__startedSaving:
            return

        noError = self.__reply.error() == QNetworkReply.NoError

        self.progressBar.setVisible(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        self.openButton.setEnabled(noError)
        self.openButton.setVisible(noError)
        self.__output.close()
        if QFile.exists(self.__fileName):
            QFile.remove(self.__fileName)
        self.__output.rename(self.__fileName)
        self.__updateInfoLabel()
        self.__state = DownloadItem.DownloadSuccessful
        self.statusChanged.emit()
        self.downloadFinished.emit()

        if self.__autoOpen:
            self.__open()
Esempio n. 13
0
    def removeSubscription(self, subscription, emitSignal=True):
        """
        Public method to remove an AdBlock subscription.
        
        @param subscription AdBlock subscription to be removed
            (AdBlockSubscription)
        @param emitSignal flag indicating to send a signal (boolean)
        """
        if subscription is None:
            return

        if subscription.url().toString().startswith(
            (self.__defaultSubscriptionUrlString,
             self.__customSubscriptionUrlString)):
            return

        try:
            self.__subscriptions.remove(subscription)
            rulesFileName = subscription.rulesFileName()
            QFile.remove(rulesFileName)
            requiresSubscriptions = self.getRequiresSubscriptions(subscription)
            for requiresSubscription in requiresSubscriptions:
                self.removeSubscription(requiresSubscription, False)
            if emitSignal:
                self.rulesChanged.emit()
        except ValueError:
            pass
Esempio n. 14
0
    def downloadV2raycore(self, url=False):
        if (url):
            self.downloadURL = url
        fileInfo = QFileInfo(self.downloadURL.path())
        self.fileName = fileName = fileInfo.fileName()

        if not fileName:
            fileName = "v2ray.zip"

        if QFile.exists(fileName):
            QFile.remove(fileName)

        self.outFile = QFile(fileName)

        if not self.outFile.open(QIODevice.WriteOnly):
            if (self.silentInstall == False):
                self.msgBox.information(
                    QDialog().move(self.fly),
                    self.translate("updateV2ray",
                                   "Download {}").format(fileName),
                    self.translate("updateV2ray",
                                   "Unable to save the file {}: {}.").format(
                                       fileName, self.outFile.errorString()))
            self.outFile = None
            return

        self.httpRequestAborted = False

        if (self.silentInstall == False):
            self.progressDialog = QProgressDialog()
            self.progressDialog.setLabelText(
                self.translate("updateV2ray", "v2ray-core is downloading..."))
            self.progressDialog.canceled.connect(self.cancelDownload)

        self.startRequest(self.downloadURL)
Esempio n. 15
0
    async def setupQrCodesFolder(self, ipfsop, profile, model, files):
        """
        Import the sample QR codes to the corresponding folder
        Needs rewrite ..
        """
        for name, qrFile in sampleQrCodes():
            await ipfsop.sleep()

            if qrFile.exists():
                path = self.app.tempDir.filePath(name)
                if qrFile.copy(path):
                    tmpFile = QFile(path)
                    entry = await ipfsop.addPath(path)
                    await ipfsop.sleep()

                    if not entry:
                        tmpFile.remove()
                        continue

                    exists = await ipfsop.filesLookupHash(
                        model.itemQrCodes.path, entry['Hash'])

                    await ipfsop.sleep()

                    if not exists:
                        await files.linkEntryNoMetadata(
                            entry, model.itemQrCodes.path, entry['Name'])

                    tmpFile.remove()

        self.qrInitialized = True
Esempio n. 16
0
    def saveTextdata(self, filePath, data):
        outFile = QFileInfo(filePath)

        fileName = outFile.fileName()
        if QFile.exists(fileName):
            QFile.remove(fileName)

        outFile = QFile(outFile.absoluteFilePath())

        outFile.open(QIODevice.WriteOnly | QIODevice.Text)
        if outFile.error() != outFile.NoError:
            self.msgBox.information(
                QDialog().move(self.fly), "{}".format(fileName),
                self.translate("openV2rayJSONFile",
                               "Unable to open the file {}:  {}.").format(
                                   fileName, outFile.errorString()))
            outFile = None
            return False

        outFile.write(codecs.encode(data, "utf-8"))

        if outFile.error() != outFile.NoError:
            self.msgBox.information(
                QDialog().move(self.fly), "{}".format(fileName),
                self.translate("openV2rayJSONFile",
                               "Unable to save the file {}:  {}.").format(
                                   fileName, outFile.errorString()))
            outFile = None
            return False

        outFile.close()
Esempio n. 17
0
    def removeItem(self, deleteFile: bool):
        """ Remove a char item from the presentation

            Args:
                deleteFile (bool) : whether to delete the file of the char item
        """

        # find the selected item
        charItem = self.selectedItem()

        # remove the item from the presentation
        charItem.setParentItem(None)

        # rearrange the items
        self.insertionIndex = -1
        for charItem in self.childItems():
            self.insertionIndex += 1
            self.positionChar(charItem)

        # reset the selected index
        self.selectedItemIndex = -1

        # delete the character file if requested
        if deleteFile == QMessageBox.Yes:
            fh = QFile(charItem.filename)
            fh.remove()
Esempio n. 18
0
 def saveV2raycoreJSONFile(self):
     JSONData = {}
     JSONData["preferences"] = copy.deepcopy(self.preferences)
     JSONData["update"]      = copy.deepcopy(self.update)
     JSONData["configFiles"] = copy.deepcopy(self.configFiles)
     
     outFile = QFileInfo(self.v2rayshellConfigFileName)
     
     fileName = outFile.fileName()
     if QFile.exists(fileName):
         QFile.remove(fileName)
         
     outFile = QFile(fileName)
     
     outFile.open(QIODevice.WriteOnly | QIODevice.Text)
     if outFile.error() != outFile.NoError:
         self.msgBox.information(QDialog().move(self.fly), 
                            "{}".format(fileName), 
                            self.translate("bridgetreasureChest", "Unable to open the file {}:  {}.").format(fileName, 
                                                                      outFile.errorString()))
         outFile = None
         return False
     
     outFile.write(codecs.encode(json.dumps(JSONData, indent = 4, sort_keys = False), "utf-8"))
     
     if outFile.error() != outFile.NoError:
         self.msgBox.information(QDialog().move(self.fly), 
                            "{}".format(fileName), 
                            self.translate("bridgetreasureChest", "Unable to save the file {}:  {}.").format(fileName, 
                                                                      outFile.errorString()))
         outFile = None
         return False
     
     outFile.close()
Esempio n. 19
0
    def removeScript(self, script, removeFile=True):
        """
        Public method to remove a script.
        
        @param script script to be removed (GreaseMonkeyScript)
        @param removeFile flag indicating to remove the script file as well
            (bool)
        @return flag indicating success (boolean)
        """
        if not script:
            return False

        try:
            self.__scripts.remove(script)
        except ValueError:
            pass

        fullName = script.fullName()
        collection = WebBrowserWindow.webProfile().scripts()
        collection.remove(collection.findScript(fullName))

        if fullName in self.__disabledScripts:
            self.__disabledScripts.remove(fullName)

        if removeFile:
            QFile.remove(script.fileName())
            del script

        self.scriptsChanged.emit()
        return True
Esempio n. 20
0
    def _copy_lib_file(cls, file_name, dir_name, dst_file_name=None):
        """ Copy a library file to a directory and return the full pathname of
        the copy.
        """

        # Note that we use the Qt file operations to support the possibility
        # that pyqtdeploy itself has been deployed as a single executable.

        if dst_file_name is None:
            dst_file_name = file_name
            s_file_name = cls._get_lib_file_name(file_name)
        else:
            s_file_name = file_name

        d_file_name = dir_name + '/' +  dst_file_name

        # Make sure the destination doesn't exist.
        QFile.remove(d_file_name)

        if not QFile.copy(s_file_name, d_file_name):
            raise UserException("Unable to copy file {0}".format(file_name))

        # The file will be read-only if it was embedded.
        QFile.setPermissions(d_file_name,
                QFileDevice.ReadOwner|QFileDevice.WriteOwner)

        return d_file_name
Esempio n. 21
0
    def _copy_file(self, uid: str = "", source_path: str = "", dest_path: str = ""):
        self._current_uid = uid

        source_file = QFile(source_path)
        dest_file = QFile(dest_path)

        if not source_file.open(QFile.ReadOnly):
            self.copy_error.emit(uid, FileCopier.CannotOpenSourceFile)
            return

        dest_file_info = QFileInfo(dest_file)
        dest_dir = dest_file_info.absoluteDir()
        if not dest_dir.exists():
            if not dest_dir.mkpath(dest_dir.absolutePath()):
                self.copy_error.emit(uid, FileCopier.CannotCreateDestinationDirectory)
                return

        if not dest_file.open(QFile.WriteOnly):
            ic(dest_path, dest_file.errorString())
            self.copy_error.emit(uid, FileCopier.CannotOpenDestinationFile)
            return

        progress: int = 0
        total: int = source_file.size()
        error: int = FileCopier.NoError
        while True:
            if self._cancel_current:
                self._cancel_current = False
                self.copy_cancelled.emit(uid)
                break

            data: Union[bytes, int] = source_file.read(_COPY_BLOCK_SIZE)
            if isinstance(data, int):
                assert data == -1
                error = FileCopier.CannotReadSourceFile
                break

            data_len = len(data)
            if data_len == 0:
                self.copy_progress.emit(uid, progress, total)
                break

            if data_len != dest_file.write(data):
                error = FileCopier.CannotWriteDestinationFile
                break

            progress += data_len
            self.copy_progress.emit(uid, progress, total)

            qApp.processEvents()

        source_file.close()
        dest_file.close()
        if error != FileCopier.NoError:
            dest_file.remove()
            self.copy_error.emit(uid, error)
        else:
            dest_file.setPermissions(source_file.permissions())
            self.copy_complete.emit(uid)
Esempio n. 22
0
 def checkdownloadFileExists(self, downloadPath):
     if (not downloadPath or not downloadPath): return False
     filePath = QUrl(downloadPath)
     fileInfo = QFileInfo(filePath.path())
     fileName = fileInfo.fileName()
     if QFile.exists(fileName):
         QFile.remove(fileName)
         return True
Esempio n. 23
0
    def savebugReportText(self, save=False):
        if save:
            outFile = QFileInfo(self.translate("bugReport", "bugReport.txt"))
            fileName = outFile.fileName()
            if QFile.exists(fileName):
                QFile.remove(fileName)

            outFile = QFile(fileName)
            outFile.open(QIODevice.WriteOnly | QIODevice.Text)
            outFile.write(codecs.encode(save, "utf-8"))
Esempio n. 24
0
 def __downloadRepositoryFileDone(self):
     """
     Private method called after the repository file was downloaded.
     """
     reply = self.sender()
     if reply in self.__replies:
         self.__replies.remove(reply)
     if reply.error() != QNetworkReply.NoError:
         E5MessageBox.warning(
             None,
             self.tr("Error downloading file"),
             self.tr(
                 """<p>Could not download the requested file"""
                 """ from {0}.</p><p>Error: {1}</p>"""
             ).format(Preferences.getUI("PluginRepositoryUrl6"),
                      reply.errorString())
         )
         return
     
     ioDevice = QFile(self.pluginRepositoryFile + ".tmp")
     ioDevice.open(QIODevice.WriteOnly)
     ioDevice.write(reply.readAll())
     ioDevice.close()
     if QFile.exists(self.pluginRepositoryFile):
         QFile.remove(self.pluginRepositoryFile)
     ioDevice.rename(self.pluginRepositoryFile)
     
     if os.path.exists(self.pluginRepositoryFile):
         f = QFile(self.pluginRepositoryFile)
         if f.open(QIODevice.ReadOnly):
             # save current URL
             url = Preferences.getUI("PluginRepositoryUrl6")
             
             # read the repository file
             from E5XML.PluginRepositoryReader import PluginRepositoryReader
             reader = PluginRepositoryReader(f, self.checkPluginEntry)
             reader.readXML()
             if url != Preferences.getUI("PluginRepositoryUrl6"):
                 # redo if it is a redirect
                 self.checkPluginUpdatesAvailable()
                 return
             
             if self.__updateAvailable:
                 res = E5MessageBox.information(
                     None,
                     self.tr("New plugin versions available"),
                     self.tr("<p>There are new plug-ins or plug-in"
                             " updates available. Use the plug-in"
                             " repository dialog to get them.</p>"),
                     E5MessageBox.StandardButtons(
                         E5MessageBox.Ignore |
                         E5MessageBox.Open),
                     E5MessageBox.Open)
                 if res == E5MessageBox.Open:
                     self.__ui.showPluginsAvailable()
Esempio n. 25
0
    def delete_csl_style(self, style_identifier: str) -> None:
        """Deletes a csl style"""
        # Remove style path
        styles = self.get_setting_value("Render/Csl_styles")
        style_path = styles[style_identifier]["path"]

        QFile.remove(style_path)

        # Remove style from Settings manager
        styles.pop(style_identifier)
        self.set_setting_value("Render/Csl_styles", styles)
Esempio n. 26
0
 def joinVideos(self, joinlist: list, filename: str) -> None:
     listfile = os.path.normpath(
         os.path.join(os.path.dirname(joinlist[0]), '.vidcutter.list'))
     fobj = open(listfile, 'w')
     for file in joinlist:
         fobj.write('file \'%s\'\n' % file.replace("'", "\\'"))
     fobj.close()
     self.videoService.join(listfile, filename)
     QFile.remove(listfile)
     for file in joinlist:
         if os.path.isfile(file):
             QFile.remove(file)
 def __downloadFileDone(self):
     """
     Private method called, after the file has been downloaded
     from the internet.
     """
     self.__updateButton.setEnabled(True)
     self.__downloadCancelButton.setEnabled(False)
     self.__onlineStateChanged(
         self.__networkConfigurationManager.isOnline())
     
     ok = True
     reply = self.sender()
     if reply in self.__replies:
         self.__replies.remove(reply)
     if reply.error() != QNetworkReply.NoError:
         ok = False
         if not self.__downloadCancelled:
             E5MessageBox.warning(
                 self,
                 self.tr("Error downloading file"),
                 self.tr(
                     """<p>Could not download the requested file"""
                     """ from {0}.</p><p>Error: {1}</p>"""
                 ).format(self.__downloadURL, reply.errorString())
             )
         self.downloadProgress.setValue(0)
         self.__downloadURL = None
         self.__downloadIODevice.remove()
         self.__downloadIODevice = None
         if self.repositoryList.topLevelItemCount():
             if self.repositoryList.currentItem() is None:
                 self.repositoryList.setCurrentItem(
                     self.repositoryList.topLevelItem(0))
             else:
                 self.__downloadButton.setEnabled(
                     len(self.__selectedItems()))
                 self.__downloadInstallButton.setEnabled(
                     len(self.__selectedItems()))
         reply.deleteLater()
         return
     
     self.__downloadIODevice.open(QIODevice.WriteOnly)
     self.__downloadIODevice.write(reply.readAll())
     self.__downloadIODevice.close()
     if QFile.exists(self.__downloadFileName):
         QFile.remove(self.__downloadFileName)
     self.__downloadIODevice.rename(self.__downloadFileName)
     self.__downloadIODevice = None
     self.__downloadURL = None
     reply.deleteLater()
     
     if self.__doneMethod is not None:
         self.__doneMethod(ok, self.__downloadFileName)
 def redo(self):
     redo = QFile(self.redoFilename)
     if redo.exists():
         dest = QFile(self.filename)
         if dest.exists():
             dest.remove()
         QFile.copy(self.redoFilename, self.filename)
         self.editor.load()
     else:
         QFile.copy(self.filename, self.undoFilename)
         self.editor.save()
         QFile.copy(self.filename, self.redoFilename)
Esempio n. 29
0
 def __rulesDownloaded(self):
     """
     Private slot to deal with the downloaded rules.
     """
     reply = self.sender()
     
     response = reply.readAll()
     reply.close()
     self.__downloading = None
     
     if reply.error() != QNetworkReply.NoError:
         if not self.__defaultSubscription:
             # don't show error if we try to load the default
             E5MessageBox.warning(
                 None,
                 self.tr("Downloading subscription rules"),
                 self.tr(
                     """<p>Subscription rules could not be"""
                     """ downloaded.</p><p>Error: {0}</p>""")
                 .format(reply.errorString()))
         else:
             # reset after first download attempt
             self.__defaultSubscription = False
         return
     
     if response.isEmpty():
         E5MessageBox.warning(
             None,
             self.tr("Downloading subscription rules"),
             self.tr("""Got empty subscription rules."""))
         return
     
     fileName = self.rulesFileName()
     QFile.remove(fileName)
     f = QFile(fileName)
     if not f.open(QIODevice.ReadWrite):
         E5MessageBox.warning(
             None,
             self.tr("Downloading subscription rules"),
             self.tr(
                 """Unable to open adblock file '{0}' for writing.""")
             .file(fileName))
         return
     f.write(response)
     f.close()
     self.__lastUpdate = QDateTime.currentDateTime()
     if self.__validateCheckSum(fileName):
         self.__loadRules()
     else:
         QFile.remove(fileName)
     self.__downloading = None
     reply.deleteLater()
 def exportHistory(self):
     result = QFileDialog.getSaveFileName(
         parent=None,
         caption="Экспорт истории",
         directory='../ExportedHistories/',
         filter='Файлы настроек (*.conf)\nВсе файлы (*)',
         options=QFileDialog.DontUseNativeDialog)[0]
     if QFile.exists(result):
         QFile.remove(result)
     self.dataHistory = QSettings(result, QSettings.IniFormat)
     for i in self.history:
         self.dataHistory.setValue(str(i), self.history[i])
     self.dataHistory = QSettings(self.pathDataHistory, QSettings.IniFormat)
Esempio n. 31
0
 def mpegtsJoin(self, inputs: list, output: str) -> bool:
     result = False
     try:
         self.checkDiskSpace(output)
         outfiles = list()
         video_bsf, audio_bsf = self.getBSF(inputs[0])
         # 1. transcode to mpeg transport streams
         for file in inputs:
             name, _ = os.path.splitext(file)
             outfile = '%s.ts' % name
             outfiles.append(outfile)
             if os.path.isfile(outfile):
                 os.remove(outfile)
             args = '-i "%s" -c copy -map 0 %s -f mpegts -v 16 "%s"' % (
                 file, video_bsf, outfile)
             if not self.cmdExec(self.backend, args):
                 return result
         # 2. losslessly concatenate at the file level
         if len(outfiles):
             if os.path.isfile(output):
                 os.remove(output)
             args = '-i "concat:%s" -c copy %s -v 16 "%s"' % (
                 '|'.join(map(str, outfiles)), audio_bsf,
                 QDir.fromNativeSeparators(output))
             result = self.cmdExec(self.backend, args)
             # 3. cleanup mpegts files
             [QFile.remove(file) for file in outfiles]
     except:
         self.logger.exception('Exception in VideoService.mpegtsJoin()',
                               exc_info=True)
         result = False
     return result
Esempio n. 32
0
    def configure(self):
        data = "database_name: " + self.dbName.text()
        data += "\ndatabase_username: "******"\ndatabase_password: "******"\ndatabase_hostname: " + self.hostname.text()
        data += "\ndatabase_port: " + self.port.text()

        f = QFile("config/database.config")
        f.remove("config/database.config")

        if f.open(QIODevice.ReadWrite | QIODevice.Text):
            stream = QTextStream(f)
            stream << data
            f.close()

        self.close()
Esempio n. 33
0
def copy_dir_recursive(from_dir, to_dir, replace_on_conflict=False):
    dir = QDir()
    dir.setPath(from_dir)

    from_dir += QDir.separator()
    to_dir += QDir.separator()

    if not os.path.exists(to_dir):
        os.makedirs(to_dir)

    for file_ in dir.entryList(QDir.Files):
        from_ = from_dir + file_
        to_ = to_dir + file_

        if os.path.exists(to_):
            if replace_on_conflict:
                if not QFile.remove(to):
                    return False
            else:
                continue

        if not QFile.copy(from_, to_):
            return False

    for dir_ in dir.entryList(QDir.Dirs | QDir.NoDotAndDotDot):
        from_ = from_dir + dir_
        to_ = to_dir + dir_

        if not os.path.exists(to_):
            os.makedirs(to_)

        if not copy_dir_recursive(from_, to_, replace_on_conflict):
            return False

    return True
Esempio n. 34
0
    def __rulesDownloaded(self):
        """
        Private slot to deal with the downloaded rules.
        """
        reply = self.sender()

        response = reply.readAll()
        reply.close()
        self.__downloading = None

        if reply.error() != QNetworkReply.NoError:
            if not self.__defaultSubscription:
                # don't show error if we try to load the default
                E5MessageBox.warning(
                    None, self.tr("Downloading subscription rules"),
                    self.tr("""<p>Subscription rules could not be"""
                            """ downloaded.</p><p>Error: {0}</p>""").format(
                                reply.errorString()))
            else:
                # reset after first download attempt
                self.__defaultSubscription = False
            return

        if response.isEmpty():
            E5MessageBox.warning(None,
                                 self.tr("Downloading subscription rules"),
                                 self.tr("""Got empty subscription rules."""))
            return

        fileName = self.rulesFileName()
        QFile.remove(fileName)
        f = QFile(fileName)
        if not f.open(QIODevice.ReadWrite):
            E5MessageBox.warning(
                None, self.tr("Downloading subscription rules"),
                self.tr("""Unable to open adblock file '{0}' for writing.""").
                file(fileName))
            return
        f.write(response)
        f.close()
        self.__lastUpdate = QDateTime.currentDateTime()
        if self.__validateCheckSum(fileName):
            self.__loadRules()
        else:
            QFile.remove(fileName)
        self.__downloading = None
        reply.deleteLater()
Esempio n. 35
0
 def removeFromDriveByUrl(self, url, actionType="removeSongByUrl"):
     '''
         remove song from Drive by url
     '''
     df = QFile(url)
     flag = df.remove()
     if flag:
         self.removeFromDatabaseByUrl(url, actionType)
Esempio n. 36
0
 def removeFromDriveByUrl(self, url, actionType="removeSongByUrl"):
     '''
         remove song from Drive by url
     '''
     df = QFile(url)
     flag = df.remove()
     if flag:
         self.removeFromDatabaseByUrl(url, actionType)
Esempio n. 37
0
 def cutVideo(self) -> bool:
     self.setCursor(Qt.BusyCursor)
     clips = len(self.clipTimes)
     filename, filelist = '', []
     source = self.mediaPlayer.currentMedia().canonicalUrl().toLocalFile()
     _, sourceext = os.path.splitext(source)
     if clips > 0:
         self.finalFilename, _ = QFileDialog.getSaveFileName(
             self.parent, 'Save video', source,
             'Video files (*%s)' % sourceext)
         if self.finalFilename != '':
             self.saveAction.setDisabled(True)
             self.showProgress(clips)
             file, ext = os.path.splitext(self.finalFilename)
             index = 1
             self.progress.setLabelText('Cutting video clips...')
             qApp.processEvents()
             for clip in self.clipTimes:
                 duration = self.deltaToQTime(clip[0].msecsTo(
                     clip[1])).toString(self.timeformat)
                 filename = '%s_%s%s' % (file, '{0:0>2}'.format(index), ext)
                 filelist.append(filename)
                 self.videoService.cut(source, filename,
                                       clip[0].toString(self.timeformat),
                                       duration)
                 index += 1
             if len(filelist) > 1:
                 self.joinVideos(filelist, self.finalFilename)
             else:
                 QFile.remove(self.finalFilename)
                 QFile.rename(filename, self.finalFilename)
             self.unsetCursor()
             self.progress.setLabelText('Complete...')
             qApp.processEvents()
             self.saveAction.setEnabled(True)
             self.progress.close()
             self.progress.deleteLater()
             self.complete()
             self.saveAction.setEnabled(True)
         self.unsetCursor()
         self.saveAction.setDisabled(True)
         return True
     self.unsetCursor()
     self.saveAction.setDisabled(True)
     return False
Esempio n. 38
0
    def deleteFile(self):
        index = self.selectionModel().currentIndex()
        path = self.model.filePath(index)
        if path:
            fileInfo = QFileInfo(path)
            if fileInfo.isFile():
                if not self.ask_dialog(
                        "Do you wan't to delete the selected file?"):
                    return
                file = QFile(path)
                file.remove()

            elif fileInfo.isDir():
                if not self.ask_dialog(
                        "Do you wan't to delete the selected directory?"):
                    return
                directory = QDir(path)
                directory.removeRecursively()
Esempio n. 39
0
def copyFile(source, dest, overwrite=False):
    if os.path.exists(dest):
        if overwrite or abs(QFileInfo(source).lastModified().secsTo(QFileInfo(dest).lastModified())) > 5:   # use secsTo for different file systems
            if DEBUG_MODE:
                qDebug("Existing file removed: %s (%s, %s)" % (dest, str(QFileInfo(source).lastModified()), str(QFileInfo(dest).lastModified())))
            QFile.remove(dest)
        else:
            if DEBUG_MODE:
                qDebug("File already exists: %s" % dest)
            return False

    ret = QFile.copy(source, dest)
    if DEBUG_MODE:
        if ret:
            qDebug("File copied: %s to %s" % (source, dest))
        else:
            qDebug("Failed to copy file: %s to %s" % (source, dest))
    return ret
Esempio n. 40
0
def copy_dir_recursive(from_dir, to_dir, replace_on_conflict=False):
    dir = QDir()
    dir.setPath(from_dir)

    from_dir += QDir.separator()
    to_dir += QDir.separator()

    if not os.path.exists(to_dir):
        os.makedirs(to_dir)

    for file_ in dir.entryList(QDir.Files):
        from_ = from_dir + file_
        to_ = to_dir + file_
        if str(to_).endswith(".src"):
            to_ = str(to_).replace(".src", "")

        if os.path.exists(to_):
            if replace_on_conflict:
                if not QFile.remove(to_):
                    return False
            else:
                continue

        if not QFile.copy(from_, to_):
            return False

    for dir_ in dir.entryList(QDir.Dirs | QDir.NoDotAndDotDot):
        from_ = from_dir + dir_
        to_ = to_dir + dir_

        if not os.path.exists(to_):
            os.makedirs(to_)

        if not copy_dir_recursive(from_, to_, replace_on_conflict):
            return False

    return True
Esempio n. 41
0
class HttpWindow(QDialog):
    def __init__(self, parent=None):
        super(HttpWindow, self).__init__(parent)

        self.url = QUrl()
        self.qnam = QNetworkAccessManager()
        self.reply = None
        self.outFile = None
        self.httpGetId = 0
        self.httpRequestAborted = False

        self.urlLineEdit = QLineEdit('https://www.qt.io')

        urlLabel = QLabel("&URL:")
        urlLabel.setBuddy(self.urlLineEdit)
        self.statusLabel = QLabel(
                "Please enter the URL of a file you want to download.")
        self.statusLabel.setWordWrap(True)

        self.downloadButton = QPushButton("Download")
        self.downloadButton.setDefault(True)
        self.quitButton = QPushButton("Quit")
        self.quitButton.setAutoDefault(False)

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.downloadButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(self.quitButton, QDialogButtonBox.RejectRole)

        self.progressDialog = QProgressDialog(self)

        self.urlLineEdit.textChanged.connect(self.enableDownloadButton)
        self.qnam.authenticationRequired.connect(
                self.slotAuthenticationRequired)
        self.qnam.sslErrors.connect(self.sslErrors)
        self.progressDialog.canceled.connect(self.cancelDownload)
        self.downloadButton.clicked.connect(self.downloadFile)
        self.quitButton.clicked.connect(self.close)

        topLayout = QHBoxLayout()
        topLayout.addWidget(urlLabel)
        topLayout.addWidget(self.urlLineEdit)

        mainLayout = QVBoxLayout()
        mainLayout.addLayout(topLayout)
        mainLayout.addWidget(self.statusLabel)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle("HTTP")
        self.urlLineEdit.setFocus()

    def startRequest(self, url):
        self.reply = self.qnam.get(QNetworkRequest(url))
        self.reply.finished.connect(self.httpFinished)
        self.reply.readyRead.connect(self.httpReadyRead)
        self.reply.downloadProgress.connect(self.updateDataReadProgress)

    def downloadFile(self):
        self.url = QUrl(self.urlLineEdit.text())
        fileInfo = QFileInfo(self.url.path())
        fileName = fileInfo.fileName()

        if not fileName:
            fileName = 'index.html'

        if QFile.exists(fileName):
            ret = QMessageBox.question(self, "HTTP",
                    "There already exists a file called %s in the current "
                    "directory. Overwrite?" % fileName,
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

            if ret == QMessageBox.No:
                return

            QFile.remove(fileName)

        self.outFile = QFile(fileName)
        if not self.outFile.open(QIODevice.WriteOnly):
            QMessageBox.information(self, "HTTP",
                    "Unable to save the file %s: %s." % (fileName, self.outFile.errorString()))
            self.outFile = None
            return

        self.progressDialog.setWindowTitle("HTTP")
        self.progressDialog.setLabelText("Downloading %s." % fileName)
        self.downloadButton.setEnabled(False)

        self.httpRequestAborted = False
        self.startRequest(self.url)

    def cancelDownload(self):
        self.statusLabel.setText("Download canceled.")
        self.httpRequestAborted = True
        if self.reply is not None:
            self.reply.abort()
        self.downloadButton.setEnabled(True)

    def httpFinished(self):
        if self.httpRequestAborted:
            if self.outFile is not None:
                self.outFile.close()
                self.outFile.remove()
                self.outFile = None

            self.reply.deleteLater()
            self.reply = None
            self.progressDialog.hide()
            return

        self.progressDialog.hide()
        self.outFile.flush()
        self.outFile.close()

        redirectionTarget = self.reply.attribute(QNetworkRequest.RedirectionTargetAttribute)

        if self.reply.error():
            self.outFile.remove()
            QMessageBox.information(self, "HTTP",
                    "Download failed: %s." % self.reply.errorString())
            self.downloadButton.setEnabled(True)
        elif redirectionTarget is not None:
            newUrl = self.url.resolved(redirectionTarget)

            ret = QMessageBox.question(self, "HTTP",
                    "Redirect to %s?" % newUrl.toString(),
                    QMessageBox.Yes | QMessageBox.No)

            if ret == QMessageBox.Yes:
                self.url = newUrl
                self.reply.deleteLater()
                self.reply = None
                self.outFile.open(QIODevice.WriteOnly)
                self.outFile.resize(0)
                self.startRequest(self.url)
                return
        else:
            fileName = QFileInfo(QUrl(self.urlLineEdit.text()).path()).fileName()
            self.statusLabel.setText("Downloaded %s to %s." % (fileName, QDir.currentPath()))

            self.downloadButton.setEnabled(True)

        self.reply.deleteLater()
        self.reply = None
        self.outFile = None

    def httpReadyRead(self):
        if self.outFile is not None:
            self.outFile.write(self.reply.readAll())

    def updateDataReadProgress(self, bytesRead, totalBytes):
        if self.httpRequestAborted:
            return

        self.progressDialog.setMaximum(totalBytes)
        self.progressDialog.setValue(bytesRead)

    def enableDownloadButton(self):
        self.downloadButton.setEnabled(self.urlLineEdit.text() != '')

    def slotAuthenticationRequired(self, authenticator):
        import os
        from PyQt5 import uic

        ui = os.path.join(os.path.dirname(__file__), 'authenticationdialog.ui')
        dlg = uic.loadUi(ui)
        dlg.adjustSize()
        dlg.siteDescription.setText("%s at %s" % (authenticator.realm(), self.url.host()))

        dlg.userEdit.setText(self.url.userName())
        dlg.passwordEdit.setText(self.url.password())

        if dlg.exec_() == QDialog.Accepted:
            authenticator.setUser(dlg.userEdit.text())
            authenticator.setPassword(dlg.passwordEdit.text())

    def sslErrors(self, reply, errors):
        errorString = ", ".join([str(error.errorString()) for error in errors])

        ret = QMessageBox.warning(self, "HTTP Example",
                "One or more SSL errors has occurred: %s" % errorString,
                QMessageBox.Ignore | QMessageBox.Abort)

        if ret == QMessageBox.Ignore:
            self.reply.ignoreSslErrors()
Esempio n. 42
0
    def build(self, opt, nr_resources, build_dir=None, clean=False):
        """ Build the project in a given directory.  Raise a UserException if
        there is an error.
        """

        project = self._project

        # Create a temporary directory which will be removed automatically when
        # this function's objects are garbage collected.
        temp_dir = QTemporaryDir()
        if not temp_dir.isValid():
            raise UserException(
                    "There was an error creating a temporary directory")

        # Get the names of the required Python modules, extension modules and
        # libraries.
        metadata = get_python_metadata(project.python_target_version)
        required_modules, required_libraries = project.get_stdlib_requirements(
                include_hidden=True)

        required_py = {}
        required_ext = {}
        for name in required_modules.keys():
            module = metadata[name]

            if module.source is None:
                required_py[name] = module
            elif not module.core:
                required_ext[name] = module

        # Initialise and check we have the information we need.
        if len(required_py) != 0 or len(required_ext) != 0:
            if project.python_source_dir == '':
                raise UserException(
                        "The name of the Python source directory has not been "
                        "specified")

        if project.get_executable_basename() == '':
            raise UserException("The name of the application has not been "
                    "specified and cannot be inferred")

        if project.application_script == '':
            if project.application_entry_point == '':
                raise UserException("Either the application script name or "
                        "the entry point must be specified")
            elif len(project.application_entry_point.split(':')) != 2:
                raise UserException("An entry point must be a module name and "
                        "a callable separated by a colon.")
        elif project.application_entry_point != '':
            raise UserException("Either the application script name or the "
                    "entry point must be specified but not both")

        # Get the name of the build directory.
        if build_dir is None:
            build_dir = project.build_dir
            if build_dir == '':
                build_dir = '.'

            build_dir = project.path_from_user(build_dir)

        # Remove any build directory if required.
        if clean:
            native_build_dir = QDir.toNativeSeparators(build_dir)
            self._message_handler.progress_message(
                    "Cleaning {0}".format(native_build_dir))
            shutil.rmtree(native_build_dir, ignore_errors=True)

        # Now start the build.
        self._create_directory(build_dir)

        # Create the job file and writer.
        job_filename = QDir.toNativeSeparators(temp_dir.path() + '/jobs.csv')
        job_file = open(job_filename, 'w', newline='')
        job_writer = csv.writer(job_file)

        # Freeze the bootstrap.
        py_major, py_minor, py_patch = project.python_target_version
        py_version = (py_major << 16) + (py_minor << 8) + py_patch

        bootstrap_src = get_embedded_file_for_version(py_version, __file__,
                'lib', 'bootstrap')
        bootstrap = self._copy_lib_file(bootstrap_src, temp_dir.path(),
                dst_file_name='bootstrap.py')
        self._freeze(job_writer, build_dir + '/frozen_bootstrap.h', bootstrap,
                'pyqtdeploy_bootstrap', as_c=True)

        # Freeze any main application script.
        if project.application_script != '':
            self._freeze(job_writer, build_dir + '/frozen_main.h',
                    project.path_from_user(project.application_script),
                    'pyqtdeploy_main', as_c=True)

        # Create the pyqtdeploy module version file.
        version_f = self._create_file(build_dir + '/pyqtdeploy_version.h')
        version_f.write(
                '#define PYQTDEPLOY_HEXVERSION %s\n' % hex(
                        PYQTDEPLOY_HEXVERSION))
        version_f.close()

        # Generate the application resource.
        resource_names = self._generate_resource(build_dir + '/resources',
                required_py, job_writer, nr_resources)

        # Write the .pro file.
        self._write_qmake(build_dir, required_ext, required_libraries,
                job_writer, opt, resource_names)

        # Run the freeze jobs.
        job_file.close()

        # The odd naming of Python source files is to prevent them from being
        # frozen if we deploy ourself.
        freeze = self._copy_lib_file(self._get_lib_file_name('freeze.python'),
                temp_dir.path(), dst_file_name='freeze.py')

        self._run_freeze(freeze, job_filename, opt)

        # Remove the contents of the temporary directory.
        QFile.remove(freeze)
        QFile.remove(bootstrap)
        QFile.remove(job_filename)
Esempio n. 43
0
 def deleteStamp(self, stamp):
     self.mStampsByName.remove(stamp.name())
     QFile.remove(stampFilePath(stamp.fileName()))
Esempio n. 44
0
class PluginRepositoryWidget(QWidget, Ui_PluginRepositoryDialog):
    """
    Class implementing a dialog showing the available plugins.
    
    @signal closeAndInstall() emitted when the Close & Install button is
        pressed
    """
    closeAndInstall = pyqtSignal()
    
    DescrRole = Qt.UserRole
    UrlRole = Qt.UserRole + 1
    FilenameRole = Qt.UserRole + 2
    AuthorRole = Qt.UserRole + 3

    PluginStatusUpToDate = 0
    PluginStatusNew = 1
    PluginStatusLocalUpdate = 2
    PluginStatusRemoteUpdate = 3
    
    def __init__(self, parent=None, external=False):
        """
        Constructor
        
        @param parent parent of this dialog (QWidget)
        @param external flag indicating an instatiation as a main
            window (boolean)
        """
        super(PluginRepositoryWidget, self).__init__(parent)
        self.setupUi(self)
        
        self.__updateButton = self.buttonBox.addButton(
            self.tr("Update"), QDialogButtonBox.ActionRole)
        self.__downloadButton = self.buttonBox.addButton(
            self.tr("Download"), QDialogButtonBox.ActionRole)
        self.__downloadButton.setEnabled(False)
        self.__downloadInstallButton = self.buttonBox.addButton(
            self.tr("Download && Install"),
            QDialogButtonBox.ActionRole)
        self.__downloadInstallButton.setEnabled(False)
        self.__downloadCancelButton = self.buttonBox.addButton(
            self.tr("Cancel"), QDialogButtonBox.ActionRole)
        self.__installButton = \
            self.buttonBox.addButton(self.tr("Close && Install"),
                                     QDialogButtonBox.ActionRole)
        self.__downloadCancelButton.setEnabled(False)
        self.__installButton.setEnabled(False)
        
        self.repositoryUrlEdit.setText(
            Preferences.getUI("PluginRepositoryUrl6"))
        
        self.repositoryList.headerItem().setText(
            self.repositoryList.columnCount(), "")
        self.repositoryList.header().setSortIndicator(0, Qt.AscendingOrder)
        
        self.__pluginContextMenu = QMenu(self)
        self.__hideAct = self.__pluginContextMenu.addAction(
            self.tr("Hide"), self.__hidePlugin)
        self.__hideSelectedAct = self.__pluginContextMenu.addAction(
            self.tr("Hide Selected"), self.__hideSelectedPlugins)
        self.__pluginContextMenu.addSeparator()
        self.__showAllAct = self.__pluginContextMenu.addAction(
            self.tr("Show All"), self.__showAllPlugins)
        self.__pluginContextMenu.addSeparator()
        self.__pluginContextMenu.addAction(
            self.tr("Cleanup Downloads"), self.__cleanupDownloads)
        
        self.pluginRepositoryFile = \
            os.path.join(Utilities.getConfigDir(), "PluginRepository")
        
        self.__external = external
        
        # attributes for the network objects
        self.__networkManager = QNetworkAccessManager(self)
        self.__networkManager.proxyAuthenticationRequired.connect(
            proxyAuthenticationRequired)
        if SSL_AVAILABLE:
            self.__sslErrorHandler = E5SslErrorHandler(self)
            self.__networkManager.sslErrors.connect(self.__sslErrors)
        self.__replies = []
        
        self.__networkConfigurationManager = QNetworkConfigurationManager(self)
        self.__onlineStateChanged(
            self.__networkConfigurationManager.isOnline())
        
        self.__networkConfigurationManager.onlineStateChanged.connect(
            self.__onlineStateChanged)
        
        self.__doneMethod = None
        self.__inDownload = False
        self.__pluginsToDownload = []
        self.__pluginsDownloaded = []
        self.__isDownloadInstall = False
        self.__allDownloadedOk = False
        
        self.__hiddenPlugins = Preferences.getPluginManager("HiddenPlugins")
        
        self.__populateList()
    
    @pyqtSlot(bool)
    def __onlineStateChanged(self, online):
        """
        Private slot handling online state changes.
        
        @param online flag indicating the online status
        @type bool
        """
        self.__updateButton.setEnabled(online)
        self.on_repositoryList_itemSelectionChanged()
        if online:
            msg = self.tr("Network Status: online")
        else:
            msg = self.tr("Network Status: offline")
        self.statusLabel.setText(msg)
    
    @pyqtSlot(QAbstractButton)
    def on_buttonBox_clicked(self, button):
        """
        Private slot to handle the click of a button of the button box.
        
        @param button reference to the button pressed (QAbstractButton)
        """
        if button == self.__updateButton:
            self.__updateList()
        elif button == self.__downloadButton:
            self.__isDownloadInstall = False
            self.__downloadPlugins()
        elif button == self.__downloadInstallButton:
            self.__isDownloadInstall = True
            self.__allDownloadedOk = True
            self.__downloadPlugins()
        elif button == self.__downloadCancelButton:
            self.__downloadCancel()
        elif button == self.__installButton:
            self.__closeAndInstall()
    
    def __formatDescription(self, lines):
        """
        Private method to format the description.
        
        @param lines lines of the description (list of strings)
        @return formatted description (string)
        """
        # remove empty line at start and end
        newlines = lines[:]
        if len(newlines) and newlines[0] == '':
            del newlines[0]
        if len(newlines) and newlines[-1] == '':
            del newlines[-1]
        
        # replace empty lines by newline character
        index = 0
        while index < len(newlines):
            if newlines[index] == '':
                newlines[index] = '\n'
            index += 1
        
        # join lines by a blank
        return ' '.join(newlines)
    
    @pyqtSlot(QPoint)
    def on_repositoryList_customContextMenuRequested(self, pos):
        """
        Private slot to show the context menu.
        
        @param pos position to show the menu (QPoint)
        """
        self.__hideAct.setEnabled(
            self.repositoryList.currentItem() is not None and
            len(self.__selectedItems()) == 1)
        self.__hideSelectedAct.setEnabled(
            len(self.__selectedItems()) > 1)
        self.__showAllAct.setEnabled(bool(self.__hasHiddenPlugins()))
        self.__pluginContextMenu.popup(self.repositoryList.mapToGlobal(pos))
    
    @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
    def on_repositoryList_currentItemChanged(self, current, previous):
        """
        Private slot to handle the change of the current item.
        
        @param current reference to the new current item (QTreeWidgetItem)
        @param previous reference to the old current item (QTreeWidgetItem)
        """
        if self.__repositoryMissing or current is None:
            return
        
        self.urlEdit.setText(
            current.data(0, PluginRepositoryWidget.UrlRole) or "")
        self.descriptionEdit.setPlainText(
            current.data(0, PluginRepositoryWidget.DescrRole) and
            self.__formatDescription(
                current.data(0, PluginRepositoryWidget.DescrRole)) or "")
        self.authorEdit.setText(
            current.data(0, PluginRepositoryWidget.AuthorRole) or "")
    
    def __selectedItems(self):
        """
        Private method to get all selected items without the toplevel ones.
        
        @return list of selected items (list)
        """
        ql = self.repositoryList.selectedItems()
        for index in range(self.repositoryList.topLevelItemCount()):
            ti = self.repositoryList.topLevelItem(index)
            if ti in ql:
                ql.remove(ti)
        return ql
    
    @pyqtSlot()
    def on_repositoryList_itemSelectionChanged(self):
        """
        Private slot to handle a change of the selection.
        """
        self.__downloadButton.setEnabled(
            len(self.__selectedItems()) and
            self.__networkConfigurationManager.isOnline())
        self.__downloadInstallButton.setEnabled(
            len(self.__selectedItems()) and
            self.__networkConfigurationManager.isOnline())
        self.__installButton.setEnabled(len(self.__selectedItems()))
    
    def __updateList(self):
        """
        Private slot to download a new list and display the contents.
        """
        url = self.repositoryUrlEdit.text()
        self.__downloadFile(url,
                            self.pluginRepositoryFile,
                            self.__downloadRepositoryFileDone)
    
    def __downloadRepositoryFileDone(self, status, filename):
        """
        Private method called after the repository file was downloaded.
        
        @param status flaging indicating a successful download (boolean)
        @param filename full path of the downloaded file (string)
        """
        self.__populateList()
    
    def __downloadPluginDone(self, status, filename):
        """
        Private method called, when the download of a plugin is finished.
        
        @param status flag indicating a successful download (boolean)
        @param filename full path of the downloaded file (string)
        """
        if status:
            self.__pluginsDownloaded.append(filename)
        if self.__isDownloadInstall:
            self.__allDownloadedOk &= status
        
        del self.__pluginsToDownload[0]
        if len(self.__pluginsToDownload):
            self.__downloadPlugin()
        else:
            self.__downloadPluginsDone()
    
    def __downloadPlugin(self):
        """
        Private method to download the next plugin.
        """
        self.__downloadFile(self.__pluginsToDownload[0][0],
                            self.__pluginsToDownload[0][1],
                            self.__downloadPluginDone)
    
    def __downloadPlugins(self):
        """
        Private slot to download the selected plugins.
        """
        self.__pluginsDownloaded = []
        self.__pluginsToDownload = []
        self.__downloadButton.setEnabled(False)
        self.__downloadInstallButton.setEnabled(False)
        self.__installButton.setEnabled(False)
        for itm in self.repositoryList.selectedItems():
            if itm not in [self.__stableItem, self.__unstableItem,
                           self.__unknownItem]:
                url = itm.data(0, PluginRepositoryWidget.UrlRole)
                filename = os.path.join(
                    Preferences.getPluginManager("DownloadPath"),
                    itm.data(0, PluginRepositoryWidget.FilenameRole))
                self.__pluginsToDownload.append((url, filename))
        self.__downloadPlugin()
    
    def __downloadPluginsDone(self):
        """
        Private method called, when the download of the plugins is finished.
        """
        self.__downloadButton.setEnabled(len(self.__selectedItems()))
        self.__downloadInstallButton.setEnabled(len(self.__selectedItems()))
        self.__installButton.setEnabled(True)
        self.__doneMethod = None
        if not self.__external:
            ui = e5App().getObject("UserInterface")
        else:
            ui = None
        if ui and ui.notificationsEnabled():
            ui.showNotification(
                UI.PixmapCache.getPixmap("plugin48.png"),
                self.tr("Download Plugin Files"),
                self.tr("""The requested plugins were downloaded."""))
        
        if self.__isDownloadInstall:
            self.closeAndInstall.emit()
        else:
            if ui is None or not ui.notificationsEnabled():
                E5MessageBox.information(
                    self,
                    self.tr("Download Plugin Files"),
                    self.tr("""The requested plugins were downloaded."""))
            self.downloadProgress.setValue(0)
            
            # repopulate the list to update the refresh icons
            self.__populateList()
    
    def __resortRepositoryList(self):
        """
        Private method to resort the tree.
        """
        self.repositoryList.sortItems(
            self.repositoryList.sortColumn(),
            self.repositoryList.header().sortIndicatorOrder())
    
    def __populateList(self):
        """
        Private method to populate the list of available plugins.
        """
        self.repositoryList.clear()
        self.__stableItem = None
        self.__unstableItem = None
        self.__unknownItem = None
        
        self.downloadProgress.setValue(0)
        self.__doneMethod = None
        
        if os.path.exists(self.pluginRepositoryFile):
            self.__repositoryMissing = False
            f = QFile(self.pluginRepositoryFile)
            if f.open(QIODevice.ReadOnly):
                from E5XML.PluginRepositoryReader import PluginRepositoryReader
                reader = PluginRepositoryReader(f, self.addEntry)
                reader.readXML()
                self.repositoryList.resizeColumnToContents(0)
                self.repositoryList.resizeColumnToContents(1)
                self.repositoryList.resizeColumnToContents(2)
                self.__resortRepositoryList()
                url = Preferences.getUI("PluginRepositoryUrl6")
                if url != self.repositoryUrlEdit.text():
                    self.repositoryUrlEdit.setText(url)
                    E5MessageBox.warning(
                        self,
                        self.tr("Plugins Repository URL Changed"),
                        self.tr(
                            """The URL of the Plugins Repository has"""
                            """ changed. Select the "Update" button to get"""
                            """ the new repository file."""))
            else:
                E5MessageBox.critical(
                    self,
                    self.tr("Read plugins repository file"),
                    self.tr("<p>The plugins repository file <b>{0}</b> "
                            "could not be read. Select Update</p>")
                    .format(self.pluginRepositoryFile))
        else:
            self.__repositoryMissing = True
            QTreeWidgetItem(
                self.repositoryList,
                ["", self.tr(
                    "No plugin repository file available.\nSelect Update.")
                 ])
            self.repositoryList.resizeColumnToContents(1)
    
    def __downloadFile(self, url, filename, doneMethod=None):
        """
        Private slot to download the given file.
        
        @param url URL for the download (string)
        @param filename local name of the file (string)
        @param doneMethod method to be called when done
        """
        if self.__networkConfigurationManager.isOnline():
            self.__updateButton.setEnabled(False)
            self.__downloadButton.setEnabled(False)
            self.__downloadInstallButton.setEnabled(False)
            self.__downloadCancelButton.setEnabled(True)
            
            self.statusLabel.setText(url)
            
            self.__doneMethod = doneMethod
            self.__downloadURL = url
            self.__downloadFileName = filename
            self.__downloadIODevice = QFile(self.__downloadFileName + ".tmp")
            self.__downloadCancelled = False
            
            request = QNetworkRequest(QUrl(url))
            request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
                                 QNetworkRequest.AlwaysNetwork)
            reply = self.__networkManager.get(request)
            reply.finished.connect(self.__downloadFileDone)
            reply.downloadProgress.connect(self.__downloadProgress)
            self.__replies.append(reply)
        else:
            E5MessageBox.warning(
                self,
                self.tr("Error downloading file"),
                self.tr(
                    """<p>Could not download the requested file"""
                    """ from {0}.</p><p>Error: {1}</p>"""
                ).format(url, self.tr("Computer is offline.")))
    
    def __downloadFileDone(self):
        """
        Private method called, after the file has been downloaded
        from the internet.
        """
        self.__updateButton.setEnabled(True)
        self.__downloadCancelButton.setEnabled(False)
        self.__onlineStateChanged(
            self.__networkConfigurationManager.isOnline())
        
        ok = True
        reply = self.sender()
        if reply in self.__replies:
            self.__replies.remove(reply)
        if reply.error() != QNetworkReply.NoError:
            ok = False
            if not self.__downloadCancelled:
                E5MessageBox.warning(
                    self,
                    self.tr("Error downloading file"),
                    self.tr(
                        """<p>Could not download the requested file"""
                        """ from {0}.</p><p>Error: {1}</p>"""
                    ).format(self.__downloadURL, reply.errorString())
                )
            self.downloadProgress.setValue(0)
            self.__downloadURL = None
            self.__downloadIODevice.remove()
            self.__downloadIODevice = None
            if self.repositoryList.topLevelItemCount():
                if self.repositoryList.currentItem() is None:
                    self.repositoryList.setCurrentItem(
                        self.repositoryList.topLevelItem(0))
                else:
                    self.__downloadButton.setEnabled(
                        len(self.__selectedItems()))
                    self.__downloadInstallButton.setEnabled(
                        len(self.__selectedItems()))
            reply.deleteLater()
            return
        
        self.__downloadIODevice.open(QIODevice.WriteOnly)
        self.__downloadIODevice.write(reply.readAll())
        self.__downloadIODevice.close()
        if QFile.exists(self.__downloadFileName):
            QFile.remove(self.__downloadFileName)
        self.__downloadIODevice.rename(self.__downloadFileName)
        self.__downloadIODevice = None
        self.__downloadURL = None
        reply.deleteLater()
        
        if self.__doneMethod is not None:
            self.__doneMethod(ok, self.__downloadFileName)
    
    def __downloadCancel(self):
        """
        Private slot to cancel the current download.
        """
        if self.__replies:
            reply = self.__replies[0]
            self.__downloadCancelled = True
            self.__pluginsToDownload = []
            reply.abort()
    
    def __downloadProgress(self, done, total):
        """
        Private slot to show the download progress.
        
        @param done number of bytes downloaded so far (integer)
        @param total total bytes to be downloaded (integer)
        """
        if total:
            self.downloadProgress.setMaximum(total)
            self.downloadProgress.setValue(done)
    
    def addEntry(self, name, short, description, url, author, version,
                 filename, status):
        """
        Public method to add an entry to the list.
        
        @param name data for the name field (string)
        @param short data for the short field (string)
        @param description data for the description field (list of strings)
        @param url data for the url field (string)
        @param author data for the author field (string)
        @param version data for the version field (string)
        @param filename data for the filename field (string)
        @param status status of the plugin (string [stable, unstable, unknown])
        """
        pluginName = filename.rsplit("-", 1)[0]
        if pluginName in self.__hiddenPlugins:
            return
        
        if status == "stable":
            if self.__stableItem is None:
                self.__stableItem = \
                    QTreeWidgetItem(self.repositoryList,
                                    [self.tr("Stable")])
                self.__stableItem.setExpanded(True)
            parent = self.__stableItem
        elif status == "unstable":
            if self.__unstableItem is None:
                self.__unstableItem = \
                    QTreeWidgetItem(self.repositoryList,
                                    [self.tr("Unstable")])
                self.__unstableItem.setExpanded(True)
            parent = self.__unstableItem
        else:
            if self.__unknownItem is None:
                self.__unknownItem = \
                    QTreeWidgetItem(self.repositoryList,
                                    [self.tr("Unknown")])
                self.__unknownItem.setExpanded(True)
            parent = self.__unknownItem
        itm = QTreeWidgetItem(parent, [name, version, short])
        
        itm.setData(0, PluginRepositoryWidget.UrlRole, url)
        itm.setData(0, PluginRepositoryWidget.FilenameRole, filename)
        itm.setData(0, PluginRepositoryWidget.AuthorRole, author)
        itm.setData(0, PluginRepositoryWidget.DescrRole, description)
        
        updateStatus = self.__updateStatus(filename, version)
        if updateStatus == PluginRepositoryWidget.PluginStatusUpToDate:
            itm.setIcon(1, UI.PixmapCache.getIcon("empty.png"))
            itm.setToolTip(1, self.tr("up-to-date"))
        elif updateStatus == PluginRepositoryWidget.PluginStatusNew:
            itm.setIcon(1, UI.PixmapCache.getIcon("download.png"))
            itm.setToolTip(1, self.tr("new download available"))
        elif updateStatus == PluginRepositoryWidget.PluginStatusLocalUpdate:
            itm.setIcon(1, UI.PixmapCache.getIcon("updateLocal.png"))
            itm.setToolTip(1, self.tr("update installable"))
        elif updateStatus == PluginRepositoryWidget.PluginStatusRemoteUpdate:
            itm.setIcon(1, UI.PixmapCache.getIcon("updateRemote.png"))
            itm.setToolTip(1, self.tr("updated download available"))
    
    def __updateStatus(self, filename, version):
        """
        Private method to check, if the given archive update status.
        
        @param filename data for the filename field (string)
        @param version data for the version field (string)
        @return plug-in update status (integer, one of PluginStatusNew,
            PluginStatusUpToDate, PluginStatusLocalUpdate,
            PluginStatusRemoteUpdate)
        """
        archive = os.path.join(Preferences.getPluginManager("DownloadPath"),
                               filename)
        
        # check, if it is an update (i.e. we already have archives
        # with the same pattern)
        archivesPattern = archive.rsplit('-', 1)[0] + "-*.zip"
        if len(glob.glob(archivesPattern)) == 0:
            return PluginRepositoryWidget.PluginStatusNew
        
        # check, if the archive exists
        if not os.path.exists(archive):
            return PluginRepositoryWidget.PluginStatusRemoteUpdate
        
        # check, if the archive is a valid zip file
        if not zipfile.is_zipfile(archive):
            return PluginRepositoryWidget.PluginStatusRemoteUpdate
        
        zip = zipfile.ZipFile(archive, "r")
        try:
            aversion = zip.read("VERSION").decode("utf-8")
        except KeyError:
            aversion = ""
        zip.close()
        
        if aversion == version:
            if not self.__external:
                # Check against installed/loaded plug-ins
                pluginManager = e5App().getObject("PluginManager")
                pluginName = filename.rsplit('-', 1)[0]
                pluginDetails = pluginManager.getPluginDetails(pluginName)
                if pluginDetails is None or pluginDetails["version"] < version:
                    return PluginRepositoryWidget.PluginStatusLocalUpdate
            
            return PluginRepositoryWidget.PluginStatusUpToDate
        else:
            return PluginRepositoryWidget.PluginStatusRemoteUpdate
    
    def __sslErrors(self, reply, errors):
        """
        Private slot to handle SSL errors.
        
        @param reply reference to the reply object (QNetworkReply)
        @param errors list of SSL errors (list of QSslError)
        """
        ignored = self.__sslErrorHandler.sslErrorsReply(reply, errors)[0]
        if ignored == E5SslErrorHandler.NotIgnored:
            self.__downloadCancelled = True
    
    def getDownloadedPlugins(self):
        """
        Public method to get the list of recently downloaded plugin files.
        
        @return list of plugin filenames (list of strings)
        """
        return self.__pluginsDownloaded
    
    @pyqtSlot(bool)
    def on_repositoryUrlEditButton_toggled(self, checked):
        """
        Private slot to set the read only status of the repository URL line
        edit.
        
        @param checked state of the push button (boolean)
        """
        self.repositoryUrlEdit.setReadOnly(not checked)
    
    def __closeAndInstall(self):
        """
        Private method to close the dialog and invoke the install dialog.
        """
        if not self.__pluginsDownloaded and self.__selectedItems():
            for itm in self.__selectedItems():
                filename = os.path.join(
                    Preferences.getPluginManager("DownloadPath"),
                    itm.data(0, PluginRepositoryWidget.FilenameRole))
                self.__pluginsDownloaded.append(filename)
        self.closeAndInstall.emit()
    
    def __hidePlugin(self):
        """
        Private slot to hide the current plug-in.
        """
        itm = self.__selectedItems()[0]
        pluginName = (itm.data(0, PluginRepositoryWidget.FilenameRole)
                      .rsplit("-", 1)[0])
        self.__updateHiddenPluginsList([pluginName])
    
    def __hideSelectedPlugins(self):
        """
        Private slot to hide all selected plug-ins.
        """
        hideList = []
        for itm in self.__selectedItems():
            pluginName = (itm.data(0, PluginRepositoryWidget.FilenameRole)
                          .rsplit("-", 1)[0])
            hideList.append(pluginName)
        self.__updateHiddenPluginsList(hideList)
    
    def __showAllPlugins(self):
        """
        Private slot to show all plug-ins.
        """
        self.__hiddenPlugins = []
        self.__updateHiddenPluginsList([])
    
    def __hasHiddenPlugins(self):
        """
        Private method to check, if there are any hidden plug-ins.
        
        @return flag indicating the presence of hidden plug-ins (boolean)
        """
        return bool(self.__hiddenPlugins)
    
    def __updateHiddenPluginsList(self, hideList):
        """
        Private method to store the list of hidden plug-ins to the settings.
        
        @param hideList list of plug-ins to add to the list of hidden ones
            (list of string)
        """
        if hideList:
            self.__hiddenPlugins.extend(
                [p for p in hideList if p not in self.__hiddenPlugins])
        Preferences.setPluginManager("HiddenPlugins", self.__hiddenPlugins)
        self.__populateList()
    
    def __cleanupDownloads(self):
        """
        Private slot to cleanup the plug-in downloads area.
        """
        downloadPath = Preferences.getPluginManager("DownloadPath")
        downloads = {}  # plug-in name as key, file name as value
        
        # step 1: extract plug-ins and downloaded files
        for pluginFile in os.listdir(downloadPath):
            if not os.path.isfile(os.path.join(downloadPath, pluginFile)):
                continue
            
            pluginName = pluginFile.rsplit("-", 1)[0]
            if pluginName not in downloads:
                downloads[pluginName] = []
            downloads[pluginName].append(pluginFile)
        
        # step 2: delete old entries
        for pluginName in downloads:
            downloads[pluginName].sort()
        
            if pluginName in self.__hiddenPlugins and \
                    not Preferences.getPluginManager("KeepHidden"):
                removeFiles = downloads[pluginName]
            else:
                removeFiles = downloads[pluginName][
                    :-Preferences.getPluginManager("KeepGenerations")]
            for removeFile in removeFiles:
                try:
                    os.remove(os.path.join(downloadPath, removeFile))
                except (IOError, OSError) as err:
                    E5MessageBox.critical(
                        self,
                        self.tr("Cleanup of Plugin Downloads"),
                        self.tr("""<p>The plugin download <b>{0}</b> could"""
                                """ not be deleted.</p><p>Reason: {1}</p>""")
                        .format(removeFile, str(err)))
Esempio n. 45
0
    def save(self):
        """
        Public slot to save the history entries to disk.
        """
        historyFile = QFile(self.getFileName())
        if not historyFile.exists():
            self.__lastSavedUrl = ""

        saveAll = self.__lastSavedUrl == ""
        first = len(self.__history) - 1
        if not saveAll:
            # find the first one to save
            for index in range(len(self.__history)):
                if self.__history[index].url == self.__lastSavedUrl:
                    first = index - 1
                    break
        if first == len(self.__history) - 1:
            saveAll = True

        if saveAll:
            # use a temporary file when saving everything
            f = QTemporaryFile()
            f.setAutoRemove(False)
            opened = f.open()
        else:
            f = historyFile
            opened = f.open(QIODevice.Append)

        if not opened:
            E5MessageBox.warning(
                None,
                self.tr("Saving History"),
                self.tr("""<p>Unable to open history file <b>{0}</b>.<br/>""" """Reason: {1}</p>""").format(
                    f.fileName(), f.errorString()
                ),
            )
            return

        for index in range(first, -1, -1):
            data = QByteArray()
            stream = QDataStream(data, QIODevice.WriteOnly)
            stream.setVersion(QDataStream.Qt_4_6)
            itm = self.__history[index]
            stream.writeUInt32(HISTORY_VERSION)
            stream.writeString(itm.url.encode("utf-8"))
            stream << itm.dateTime
            stream.writeString(itm.title.encode("utf-8"))
            f.write(data)

        f.close()
        if saveAll:
            if historyFile.exists() and not historyFile.remove():
                E5MessageBox.warning(
                    None,
                    self.tr("Saving History"),
                    self.tr("""<p>Error removing old history file <b>{0}</b>.""" """<br/>Reason: {1}</p>""").format(
                        historyFile.fileName(), historyFile.errorString()
                    ),
                )
            if not f.copy(historyFile.fileName()):
                E5MessageBox.warning(
                    None,
                    self.tr("Saving History"),
                    self.tr(
                        """<p>Error moving new history file over old one """ """(<b>{0}</b>).<br/>Reason: {1}</p>"""
                    ).format(historyFile.fileName(), f.errorString()),
                )
        self.historySaved.emit()
        try:
            self.__lastSavedUrl = self.__history[0].url
        except IndexError:
            self.__lastSavedUrl = ""
Esempio n. 46
0
 def __loadRules(self):
     """
     Private method to load the rules of the subscription.
     """
     fileName = self.rulesFileName()
     f = QFile(fileName)
     if f.exists():
         if not f.open(QIODevice.ReadOnly):
             E5MessageBox.warning(
                 None,
                 self.tr("Load subscription rules"),
                 self.tr(
                     """Unable to open adblock file '{0}' for reading.""")
                 .format(fileName))
         else:
             textStream = QTextStream(f)
             header = textStream.readLine(1024)
             if not header.startswith("[Adblock"):
                 E5MessageBox.warning(
                     None,
                     self.tr("Load subscription rules"),
                     self.tr("""AdBlock file '{0}' does not start"""
                             """ with [Adblock.""")
                     .format(fileName))
                 f.close()
                 f.remove()
                 self.__lastUpdate = QDateTime()
             else:
                 from .AdBlockRule import AdBlockRule
                 
                 self.__updatePeriod = 0
                 self.__remoteModified = QDateTime()
                 self.__rules = []
                 self.__rules.append(AdBlockRule(header, self))
                 while not textStream.atEnd():
                     line = textStream.readLine()
                     self.__rules.append(AdBlockRule(line, self))
                     expires = self.__expiresRe.search(line)
                     if expires:
                         period, kind = expires.groups()
                         if kind:
                             # hours
                             self.__updatePeriod = int(period)
                         else:
                             # days
                             self.__updatePeriod = int(period) * 24
                     remoteModified = self.__remoteModifiedRe.search(line)
                     if remoteModified:
                         day, month, year, time, hour, minute = \
                             remoteModified.groups()
                         self.__remoteModified.setDate(
                             QDate(int(year),
                                   self.__monthNameToNumber[month],
                                   int(day))
                         )
                         if time:
                             self.__remoteModified.setTime(
                                 QTime(int(hour), int(minute)))
                 self.__populateCache()
                 self.changed.emit()
     elif not fileName.endswith("_custom"):
         self.__lastUpdate = QDateTime()
     
     self.checkForUpdate()
Esempio n. 47
0
class DownloadItem(QWidget, Ui_DownloadItem):
    """
    Class implementing a widget controlling a download.
    
    @signal statusChanged() emitted upon a status change of a download
    @signal downloadFinished() emitted when a download finished
    @signal progress(int, int) emitted to signal the download progress
    """
    statusChanged = pyqtSignal()
    downloadFinished = pyqtSignal()
    progress = pyqtSignal(int, int)
    
    Downloading = 0
    DownloadSuccessful = 1
    DownloadCancelled = 2
    
    def __init__(self, reply=None, requestFilename=False, webPage=None,
                 download=False, parent=None, mainWindow=None):
        """
        Constructor
        
        @keyparam reply reference to the network reply object (QNetworkReply)
        @keyparam requestFilename flag indicating to ask the user for a
            filename (boolean)
        @keyparam webPage reference to the web page object the download
            originated from (QWebPage)
        @keyparam download flag indicating a download operation (boolean)
        @keyparam parent reference to the parent widget (QWidget)
        @keyparam mainWindow reference to the main window (HelpWindow)
        """
        super(DownloadItem, self).__init__(parent)
        self.setupUi(self)
        
        p = self.infoLabel.palette()
        p.setColor(QPalette.Text, Qt.darkGray)
        self.infoLabel.setPalette(p)
        
        self.progressBar.setMaximum(0)
        
        self.__isFtpDownload = reply is not None and \
            reply.url().scheme() == "ftp"
        
        self.tryAgainButton.setIcon(UI.PixmapCache.getIcon("restart.png"))
        self.tryAgainButton.setEnabled(False)
        self.tryAgainButton.setVisible(False)
        self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading.png"))
        self.pauseButton.setIcon(UI.PixmapCache.getIcon("pause.png"))
        self.openButton.setIcon(UI.PixmapCache.getIcon("open.png"))
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        if self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        
        self.__state = DownloadItem.Downloading
        
        icon = self.style().standardIcon(QStyle.SP_FileIcon)
        self.fileIcon.setPixmap(icon.pixmap(48, 48))
        
        self.__mainWindow = mainWindow
        self.__reply = reply
        self.__requestFilename = requestFilename
        self.__page = webPage
        self.__pageUrl = webPage and webPage.mainFrame().url() or QUrl()
        self.__toDownload = download
        self.__bytesReceived = 0
        self.__bytesTotal = -1
        self.__downloadTime = QTime()
        self.__output = QFile()
        self.__fileName = ""
        self.__originalFileName = ""
        self.__startedSaving = False
        self.__finishedDownloading = False
        self.__gettingFileName = False
        self.__canceledFileSelect = False
        self.__autoOpen = False
        
        self.__sha1Hash = QCryptographicHash(QCryptographicHash.Sha1)
        self.__md5Hash = QCryptographicHash(QCryptographicHash.Md5)
        
        if not requestFilename:
            self.__requestFilename = \
                Preferences.getUI("RequestDownloadFilename")
        
        self.__initialize()
    
    def __initialize(self, tryAgain=False):
        """
        Private method to (re)initialize the widget.
        
        @param tryAgain flag indicating a retry (boolean)
        """
        if self.__reply is None:
            return
        
        self.__startedSaving = False
        self.__finishedDownloading = False
        self.__bytesReceived = 0
        self.__bytesTotal = -1
        
        self.__sha1Hash.reset()
        self.__md5Hash.reset()
        
        # start timer for the download estimation
        self.__downloadTime.start()
        
        # attach to the reply object
        self.__url = self.__reply.url()
        self.__reply.setParent(self)
        self.__reply.setReadBufferSize(16 * 1024 * 1024)
        self.__reply.readyRead.connect(self.__readyRead)
        self.__reply.error.connect(self.__networkError)
        self.__reply.downloadProgress.connect(self.__downloadProgress)
        self.__reply.metaDataChanged.connect(self.__metaDataChanged)
        self.__reply.finished.connect(self.__finished)
        
        # reset info
        self.infoLabel.clear()
        self.progressBar.setValue(0)
        self.__getFileName()
        
        if self.__reply.error() != QNetworkReply.NoError:
            self.__networkError()
            self.__finished()
    
    def __getFileName(self):
        """
        Private method to get the file name to save to from the user.
        """
        if self.__gettingFileName:
            return
        
        import Helpviewer.HelpWindow
        downloadDirectory = Helpviewer.HelpWindow.HelpWindow\
            .downloadManager().downloadDirectory()
        
        if self.__fileName:
            fileName = self.__fileName
            originalFileName = self.__originalFileName
            self.__toDownload = True
            ask = False
        else:
            defaultFileName, originalFileName = \
                self.__saveFileName(downloadDirectory)
            fileName = defaultFileName
            self.__originalFileName = originalFileName
            ask = True
        self.__autoOpen = False
        if not self.__toDownload:
            from .DownloadAskActionDialog import DownloadAskActionDialog
            url = self.__reply.url()
            dlg = DownloadAskActionDialog(
                QFileInfo(originalFileName).fileName(),
                self.__reply.header(QNetworkRequest.ContentTypeHeader),
                "{0}://{1}".format(url.scheme(), url.authority()),
                self)
            if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel":
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("Download canceled: {0}").format(
                        QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return
            
            if dlg.getAction() == "scan":
                self.__mainWindow.requestVirusTotalScan(url)
                
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("VirusTotal scan scheduled: {0}").format(
                        QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return
            
            self.__autoOpen = dlg.getAction() == "open"
            if PYQT_VERSION_STR >= "5.0.0":
                from PyQt5.QtCore import QStandardPaths
                tempLocation = QStandardPaths.standardLocations(
                    QStandardPaths.TempLocation)[0]
            else:
                from PyQt5.QtGui import QDesktopServices
                tempLocation = QDesktopServices.storageLocation(
                    QDesktopServices.TempLocation)
            fileName = tempLocation + '/' + \
                QFileInfo(fileName).completeBaseName()
        
        if ask and not self.__autoOpen and self.__requestFilename:
            self.__gettingFileName = True
            fileName = E5FileDialog.getSaveFileName(
                None,
                self.tr("Save File"),
                defaultFileName,
                "")
            self.__gettingFileName = False
            if not fileName:
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("Download canceled: {0}")
                        .format(QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return
        
        fileInfo = QFileInfo(fileName)
        Helpviewer.HelpWindow.HelpWindow.downloadManager()\
            .setDownloadDirectory(fileInfo.absoluteDir().absolutePath())
        self.filenameLabel.setText(fileInfo.fileName())
        
        self.__output.setFileName(fileName + ".part")
        self.__fileName = fileName
        
        # check file path for saving
        saveDirPath = QFileInfo(self.__fileName).dir()
        if not saveDirPath.exists():
            if not saveDirPath.mkpath(saveDirPath.absolutePath()):
                self.progressBar.setVisible(False)
                self.on_stopButton_clicked()
                self.infoLabel.setText(self.tr(
                    "Download directory ({0}) couldn't be created.")
                    .format(saveDirPath.absolutePath()))
                return
        
        self.filenameLabel.setText(QFileInfo(self.__fileName).fileName())
        if self.__requestFilename:
            self.__readyRead()
    
    def __saveFileName(self, directory):
        """
        Private method to calculate a name for the file to download.
        
        @param directory name of the directory to store the file into (string)
        @return proposed filename and original filename (string, string)
        """
        path = parseContentDisposition(self.__reply)
        info = QFileInfo(path)
        baseName = info.completeBaseName()
        endName = info.suffix()
        
        origName = baseName
        if endName:
            origName += '.' + endName
        
        name = directory + baseName
        if endName:
            name += '.' + endName
            if not self.__requestFilename:
                # do not overwrite, if the user is not being asked
                i = 1
                while QFile.exists(name):
                    # file exists already, don't overwrite
                    name = directory + baseName + ('-{0:d}'.format(i))
                    if endName:
                        name += '.' + endName
                    i += 1
        return name, origName
    
    def __open(self):
        """
        Private slot to open the downloaded file.
        """
        info = QFileInfo(self.__output)
        url = QUrl.fromLocalFile(info.absoluteFilePath())
        QDesktopServices.openUrl(url)
    
    @pyqtSlot()
    def on_tryAgainButton_clicked(self):
        """
        Private slot to retry the download.
        """
        self.retry()
    
    def retry(self):
        """
        Public slot to retry the download.
        """
        if not self.tryAgainButton.isEnabled():
            return
        
        self.tryAgainButton.setEnabled(False)
        self.tryAgainButton.setVisible(False)
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(True)
            self.stopButton.setVisible(True)
            self.pauseButton.setEnabled(True)
            self.pauseButton.setVisible(True)
        self.progressBar.setVisible(True)
        
        if self.__page:
            nam = self.__page.networkAccessManager()
        else:
            import Helpviewer.HelpWindow
            nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
        reply = nam.get(QNetworkRequest(self.__url))
        if self.__output.exists():
            self.__output.remove()
        self.__output = QFile()
        self.__reply = reply
        self.__initialize(tryAgain=True)
        self.__state = DownloadItem.Downloading
        self.statusChanged.emit()
    
    @pyqtSlot(bool)
    def on_pauseButton_clicked(self, checked):
        """
        Private slot to pause the download.
        
        @param checked flag indicating the state of the button (boolean)
        """
        if checked:
            self.__reply.readyRead.disconnect(self.__readyRead)
            self.__reply.setReadBufferSize(16 * 1024)
        else:
            self.__reply.readyRead.connect(self.__readyRead)
            self.__reply.setReadBufferSize(16 * 1024 * 1024)
            self.__readyRead()
    
    @pyqtSlot()
    def on_stopButton_clicked(self):
        """
        Private slot to stop the download.
        """
        self.cancelDownload()
    
    def cancelDownload(self):
        """
        Public slot to stop the download.
        """
        self.setUpdatesEnabled(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        self.tryAgainButton.setEnabled(True)
        self.tryAgainButton.setVisible(True)
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        self.setUpdatesEnabled(True)
        self.__state = DownloadItem.DownloadCancelled
        self.__reply.abort()
        self.downloadFinished.emit()
    
    @pyqtSlot()
    def on_openButton_clicked(self):
        """
        Private slot to open the downloaded file.
        """
        self.openFile()
    
    def openFile(self):
        """
        Public slot to open the downloaded file.
        """
        info = QFileInfo(self.__fileName)
        url = QUrl.fromLocalFile(info.absoluteFilePath())
        QDesktopServices.openUrl(url)
    
    def openFolder(self):
        """
        Public slot to open the folder containing the downloaded file.
        """
        info = QFileInfo(self.__fileName)
        url = QUrl.fromLocalFile(info.absolutePath())
        QDesktopServices.openUrl(url)
    
    def __readyRead(self):
        """
        Private slot to read the available data.
        """
        if self.__requestFilename and not self.__output.fileName():
            return
        
        if not self.__output.isOpen():
            # in case someone else has already put a file there
            if not self.__requestFilename:
                self.__getFileName()
            if not self.__output.open(QIODevice.WriteOnly):
                self.infoLabel.setText(
                    self.tr("Error opening save file: {0}")
                    .format(self.__output.errorString()))
                self.on_stopButton_clicked()
                self.statusChanged.emit()
                return
            self.statusChanged.emit()
        
        buffer = self.__reply.readAll()
        self.__sha1Hash.addData(buffer)
        self.__md5Hash.addData(buffer)
        bytesWritten = self.__output.write(buffer)
        if bytesWritten == -1:
            self.infoLabel.setText(
                self.tr("Error saving: {0}")
                    .format(self.__output.errorString()))
            self.on_stopButton_clicked()
        else:
            self.__startedSaving = True
            if self.__finishedDownloading:
                self.__finished()
    
    def __networkError(self):
        """
        Private slot to handle a network error.
        """
        self.infoLabel.setText(
            self.tr("Network Error: {0}")
                .format(self.__reply.errorString()))
        self.tryAgainButton.setEnabled(True)
        self.tryAgainButton.setVisible(True)
        self.downloadFinished.emit()
    
    def __metaDataChanged(self):
        """
        Private slot to handle a change of the meta data.
        """
        locationHeader = self.__reply.header(QNetworkRequest.LocationHeader)
        if locationHeader and locationHeader.isValid():
            self.__url = QUrl(locationHeader)
            import Helpviewer.HelpWindow
            self.__reply = Helpviewer.HelpWindow.HelpWindow\
                .networkAccessManager().get(QNetworkRequest(self.__url))
            self.__initialize()
    
    def __downloadProgress(self, bytesReceived, bytesTotal):
        """
        Private method to show the download progress.
        
        @param bytesReceived number of bytes received (integer)
        @param bytesTotal number of total bytes (integer)
        """
        self.__bytesReceived = bytesReceived
        self.__bytesTotal = bytesTotal
        currentValue = 0
        totalValue = 0
        if bytesTotal > 0:
            currentValue = bytesReceived * 100 / bytesTotal
            totalValue = 100
        self.progressBar.setValue(currentValue)
        self.progressBar.setMaximum(totalValue)
        
        self.progress.emit(currentValue, totalValue)
        self.__updateInfoLabel()
    
    def bytesTotal(self):
        """
        Public method to get the total number of bytes of the download.
        
        @return total number of bytes (integer)
        """
        if self.__bytesTotal == -1:
            self.__bytesTotal = self.__reply.header(
                QNetworkRequest.ContentLengthHeader)
            if self.__bytesTotal is None:
                self.__bytesTotal = -1
        return self.__bytesTotal
    
    def bytesReceived(self):
        """
        Public method to get the number of bytes received.
        
        @return number of bytes received (integer)
        """
        return self.__bytesReceived
    
    def remainingTime(self):
        """
        Public method to get an estimation for the remaining time.
        
        @return estimation for the remaining time (float)
        """
        if not self.downloading():
            return -1.0
        
        if self.bytesTotal() == -1:
            return -1.0
        
        cSpeed = self.currentSpeed()
        if cSpeed != 0:
            timeRemaining = (self.bytesTotal() - self.bytesReceived()) / cSpeed
        else:
            timeRemaining = 1
        
        # ETA should never be 0
        if timeRemaining == 0:
            timeRemaining = 1
        
        return timeRemaining
    
    def currentSpeed(self):
        """
        Public method to get an estimation for the download speed.
        
        @return estimation for the download speed (float)
        """
        if not self.downloading():
            return -1.0
        
        return self.__bytesReceived * 1000.0 / self.__downloadTime.elapsed()
    
    def __updateInfoLabel(self):
        """
        Private method to update the info label.
        """
        if self.__reply.error() != QNetworkReply.NoError:
            return
        
        bytesTotal = self.bytesTotal()
        running = not self.downloadedSuccessfully()
        
        speed = self.currentSpeed()
        timeRemaining = self.remainingTime()
        
        info = ""
        if running:
            remaining = ""
            
            if bytesTotal > 0:
                remaining = timeString(timeRemaining)
            
            info = self.tr("{0} of {1} ({2}/sec)\n{3}")\
                .format(
                    dataString(self.__bytesReceived),
                    bytesTotal == -1 and self.tr("?")
                    or dataString(bytesTotal),
                    dataString(int(speed)),
                    remaining)
        else:
            if self.__bytesReceived == bytesTotal or bytesTotal == -1:
                info = self.tr("{0} downloaded\nSHA1: {1}\nMD5: {2}")\
                    .format(dataString(self.__output.size()),
                            str(self.__sha1Hash.result().toHex(),
                                encoding="ascii"),
                            str(self.__md5Hash.result().toHex(),
                                encoding="ascii")
                            )
            else:
                info = self.tr("{0} of {1} - Stopped")\
                    .format(dataString(self.__bytesReceived),
                            dataString(bytesTotal))
        self.infoLabel.setText(info)
    
    def downloading(self):
        """
        Public method to determine, if a download is in progress.
        
        @return flag indicating a download is in progress (boolean)
        """
        return self.__state == DownloadItem.Downloading
    
    def downloadedSuccessfully(self):
        """
        Public method to check for a successful download.
        
        @return flag indicating a successful download (boolean)
        """
        return self.__state == DownloadItem.DownloadSuccessful
    
    def downloadCanceled(self):
        """
        Public method to check, if the download was cancelled.
        
        @return flag indicating a canceled download (boolean)
        """
        return self.__state == DownloadItem.DownloadCancelled
    
    def __finished(self):
        """
        Private slot to handle the download finished.
        """
        self.__finishedDownloading = True
        if not self.__startedSaving:
            return
        
        noError = self.__reply.error() == QNetworkReply.NoError
        
        self.progressBar.setVisible(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        self.openButton.setEnabled(noError)
        self.openButton.setVisible(noError)
        self.__output.close()
        if QFile.exists(self.__fileName):
            QFile.remove(self.__fileName)
        self.__output.rename(self.__fileName)
        self.__updateInfoLabel()
        self.__state = DownloadItem.DownloadSuccessful
        self.statusChanged.emit()
        self.downloadFinished.emit()
        
        if self.__autoOpen:
            self.__open()
    
    def canceledFileSelect(self):
        """
        Public method to check, if the user canceled the file selection.
        
        @return flag indicating cancellation (boolean)
        """
        return self.__canceledFileSelect
    
    def setIcon(self, icon):
        """
        Public method to set the download icon.
        
        @param icon reference to the icon to be set (QIcon)
        """
        self.fileIcon.setPixmap(icon.pixmap(48, 48))
    
    def fileName(self):
        """
        Public method to get the name of the output file.
        
        @return name of the output file (string)
        """
        return self.__fileName
    
    def absoluteFilePath(self):
        """
        Public method to get the absolute path of the output file.
        
        @return absolute path of the output file (string)
        """
        return QFileInfo(self.__fileName).absoluteFilePath()
    
    def getData(self):
        """
        Public method to get the relevant download data.
        
        @return tuple of URL, save location, flag and the
            URL of the related web page (QUrl, string, boolean,QUrl)
        """
        return (self.__url, QFileInfo(self.__fileName).filePath(),
                self.downloadedSuccessfully(), self.__pageUrl)
    
    def setData(self, data):
        """
        Public method to set the relevant download data.
        
        @param data tuple of URL, save location, flag and the
            URL of the related web page (QUrl, string, boolean, QUrl)
        """
        self.__url = data[0]
        self.__fileName = data[1]
        self.__pageUrl = data[3]
        self.__isFtpDownload = self.__url.scheme() == "ftp"
        
        self.filenameLabel.setText(QFileInfo(self.__fileName).fileName())
        self.infoLabel.setText(self.__fileName)
        
        self.stopButton.setEnabled(False)
        self.stopButton.setVisible(False)
        self.pauseButton.setEnabled(False)
        self.pauseButton.setVisible(False)
        self.openButton.setEnabled(data[2])
        self.openButton.setVisible(data[2])
        self.tryAgainButton.setEnabled(not data[2])
        self.tryAgainButton.setVisible(not data[2])
        if data[2]:
            self.__state = DownloadItem.DownloadSuccessful
        else:
            self.__state = DownloadItem.DownloadCancelled
        self.progressBar.setVisible(False)
    
    def getInfoData(self):
        """
        Public method to get the text of the info label.
        
        @return text of the info label (string)
        """
        return self.infoLabel.text()
    
    def getPageUrl(self):
        """
        Public method to get the URL of the download page.
        
        @return URL of the download page (QUrl)
        """
        return self.__pageUrl