Exemplo n.º 1
0
    def executeSql(self):

        sql = self._getSqlQuery()
        if sql == "":
            return

        with OverrideCursor(Qt.WaitCursor):

            # delete the old model
            old_model = self.viewResult.model()
            self.viewResult.setModel(None)
            if old_model:
                old_model.deleteLater()

            cols = []
            quotedCols = []

            try:
                # set the new model
                model = self.db.sqlResultModel(sql, self)
                self.viewResult.setModel(model)
                self.lblResult.setText(
                    self.tr("{0} rows, {1:.1f} seconds").format(
                        model.affectedRows(), model.secs()))
                cols = self.viewResult.model().columnNames()
                for col in cols:
                    quotedCols.append(self.db.connector.quoteId(col))

            except BaseError as e:
                DlgDbError.showError(e, self)
                self.uniqueModel.clear()
                self.geomCombo.clear()
                return

            self.setColumnCombos(cols, quotedCols)

            self.update()
Exemplo n.º 2
0
    def executeSqlCompleted(self):
        self.updateUiWhileSqlExecution(False)

        with OverrideCursor(Qt.WaitCursor):
            if self.modelAsync.task.status() == QgsTask.Complete:
                model = self.modelAsync.model
                cols = []
                quotedCols = []

                self.viewResult.setModel(model)
                self.lblResult.setText(
                    self.tr("{0} rows, {1:.1f} seconds").format(
                        model.affectedRows(), model.secs()))
                cols = self.viewResult.model().columnNames()
                for col in cols:
                    quotedCols.append(self.db.connector.quoteId(col))

                self.setColumnCombos(cols, quotedCols)
                self.update()
            elif not self.modelAsync.canceled:
                DlgDbError.showError(self.modelAsync.error, self)
                self.uniqueModel.clear()
                self.geomCombo.clear()
                pass
Exemplo n.º 3
0
    def deleteConstraint(self):
        """ delete a constraint """

        index = self.currentConstraint()
        if index == -1:
            return

        m = self.viewConstraints.model()
        constr = m.getObject(index)

        res = QMessageBox.question(
            self, self.tr("Are you sure"),
            self.tr("Really delete constraint '{0}'?").format(constr.name),
            QMessageBox.Yes | QMessageBox.No)
        if res != QMessageBox.Yes:
            return

        with OverrideCursor(Qt.WaitCursor):
            self.aboutToChangeTable.emit()
            try:
                constr.delete()
                self.refresh()
            except BaseError as e:
                DlgDbError.showError(e, self)
    def editColumn(self):
        """ open dialog to change column info and alter table appropriately """
        index = self.currentColumn()
        if index == -1:
            return

        m = self.viewFields.model()
        # get column in table
        # (there can be missing number if someone deleted a column)
        fld = m.getObject(index)

        dlg = DlgFieldProperties(self, fld, self.table)
        if not dlg.exec_():
            return
        new_fld = dlg.getField(True)

        with OverrideCursor(Qt.WaitCursor):
            self.aboutToChangeTable.emit()
            try:
                fld.update(new_fld.name, new_fld.type2String(),
                           new_fld.notNull, new_fld.default2String())
                self.refresh()
            except BaseError as e:
                DlgDbError.showError(e, self)
Exemplo n.º 5
0
    def createGeomColumn(self):
        """ first check whether everything's fine """
        if self.editName.text() == "":
            QMessageBox.critical(self, self.tr("DB Manager"), self.tr("field name must not be empty"))
            return

        name = self.editName.text()
        geom_type = self.GEOM_TYPES[self.cboType.currentIndex()]
        dim = self.spinDim.value()
        try:
            srid = int(self.editSrid.text())
        except ValueError:
            srid = -1
        createSpatialIndex = False

        # now create the geometry column
        with OverrideCursor(Qt.WaitCursor):
            try:
                self.table.addGeometryColumn(name, geom_type, srid, dim, createSpatialIndex)
            except DbError as e:
                DlgDbError.showError(e, self)
                return

        self.accept()
Exemplo n.º 6
0
    def createSpatialIndex(self):
        """ create spatial index for the geometry column """
        if self.table.type != self.table.VectorType:
            QMessageBox.information(
                self, self.tr("DB Manager"),
                self.tr("The selected table has no geometry."))
            return

        res = QMessageBox.question(
            self, self.tr("Create Spatial Index"),
            self.tr("Create spatial index for field {0}?").format(
                self.table.geomColumn), QMessageBox.Yes | QMessageBox.No)
        if res != QMessageBox.Yes:
            return

        # TODO: first check whether the index doesn't exist already
        with OverrideCursor(Qt.WaitCursor):
            self.aboutToChangeTable.emit()

            try:
                self.table.createSpatialIndex()
                self.refresh()
            except BaseError as e:
                DlgDbError.showError(e, self)
Exemplo n.º 7
0
    def accept(self):
        keepOpen = ProcessingConfig.getSetting(ProcessingConfig.KEEP_DIALOG_OPEN)
        parameters = self.getParamValues()
        if parameters:
            with OverrideCursor(Qt.WaitCursor):
                self.feedback = FieldCalculatorFeedback(self)
                self.feedback.progressChanged.connect(self.setPercentage)

                context = dataobjects.createContext()
                ProcessingLog.addToLog(self.alg.asPythonCommand(parameters, context))
                QgsGui.instance().processingRecentAlgorithmLog().push(self.alg.id())

                self.executed, results = execute(self.alg, parameters, context, self.feedback)
                self.setPercentage(0)

                if self.executed:
                    handleAlgorithmResults(self.alg,
                                           context,
                                           self.feedback,
                                           not keepOpen,
                                           parameters)
                self._wasExecuted = self.executed or self._wasExecuted
                if not keepOpen:
                    QDialog.reject(self)
Exemplo n.º 8
0
    def _get_catalog(self):
        """convenience function to init catalog wrapper"""

        auth = None

        if self.disable_ssl_verification:
            try:
                auth = Authentication(verify=False)
            except NameError:
                pass

        # connect to the server
        with OverrideCursor(Qt.WaitCursor):
            try:
                self.catalog = get_catalog_service(
                    self.catalog_url, catalog_type=self.catalog_type,
                    timeout=self.timeout, username=self.catalog_username,
                    password=self.catalog_password, auth=auth)
                return True
            except Exception as err:
                msg = self.tr('Error connecting to service: {0}').format(err)

        QMessageBox.warning(self, self.tr('CSW Connection error'), msg)
        return False
Exemplo n.º 9
0
    def runAlgorithm(self):
        alg_parameters = []

        feedback = self.createFeedback()

        load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
        project = QgsProject.instance() if load_layers else None

        for row in range(self.mainWidget().batchRowCount()):
            parameters = self.mainWidget().parametersForRow(
                row, destinationProject=project, warnOnInvalid=True)
            alg_parameters.append(parameters)

        task = QgsScopedProxyProgressTask(
            self.tr('Batch Processing - {0}').format(
                self.algorithm().displayName()))
        multi_feedback = QgsProcessingMultiStepFeedback(
            len(alg_parameters), feedback)
        feedback.progressChanged.connect(task.setProgress)

        with OverrideCursor(Qt.WaitCursor):

            self.mainWidget().setEnabled(False)
            self.cancelButton().setEnabled(True)

            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.showLog()
                self.repaint()
            except:
                pass

            start_time = time.time()

            algorithm_results = []
            for count, parameters in enumerate(alg_parameters):
                if feedback.isCanceled():
                    break
                self.setProgressText(
                    QCoreApplication.translate(
                        'BatchAlgorithmDialog',
                        '\nProcessing algorithm {0}/{1}…').format(
                            count + 1, len(alg_parameters)))
                self.setInfo(
                    self.tr('<b>Algorithm {0} starting&hellip;</b>').format(
                        self.algorithm().displayName()),
                    escapeHtml=False)
                multi_feedback.setCurrentStep(count)

                parameters = self.algorithm().preprocessParameters(parameters)

                feedback.pushInfo(self.tr('Input parameters:'))
                feedback.pushCommandInfo(pformat(parameters))
                feedback.pushInfo('')

                # important - we create a new context for each iteration
                # this avoids holding onto resources and layers from earlier iterations,
                # and allows batch processing of many more items then is possible
                # if we hold on to these layers
                context = dataobjects.createContext(feedback)

                alg_start_time = time.time()
                ret, results = execute(self.algorithm(), parameters, context,
                                       multi_feedback)
                if ret:
                    self.setInfo(QCoreApplication.translate(
                        'BatchAlgorithmDialog',
                        'Algorithm {0} correctly executed…').format(
                            self.algorithm().displayName()),
                                 escapeHtml=False)
                    feedback.pushInfo(
                        self.tr(
                            'Execution completed in {0:0.2f} seconds'.format(
                                time.time() - alg_start_time)))
                    feedback.pushInfo(self.tr('Results:'))
                    feedback.pushCommandInfo(pformat(results))
                    feedback.pushInfo('')
                    algorithm_results.append(results)
                else:
                    break

                handleAlgorithmResults(self.algorithm(), context,
                                       multi_feedback, False, parameters)

        feedback.pushInfo(
            self.tr('Batch execution completed in {0:0.2f} seconds'.format(
                time.time() - start_time)))
        task = None

        self.finish(algorithm_results)
        self.cancelButton().setEnabled(False)
Exemplo n.º 10
0
    def search(self):
        """execute search"""

        self.catalog = None
        self.constraints = []

        # clear all fields and disable buttons
        self.lblResults.clear()
        self.treeRecords.clear()

        self.reset_buttons()

        # save some settings
        self.settings.setValue('/MetaSearch/returnRecords',
                               self.spnRecords.cleanText())

        # set current catalog
        current_text = self.cmbConnectionsSearch.currentText()
        key = '/MetaSearch/%s' % current_text
        self.catalog_url = self.settings.value('%s/url' % key)
        self.catalog_username = self.settings.value('%s/username' % key)
        self.catalog_password = self.settings.value('%s/password' % key)

        # start position and number of records to return
        self.startfrom = 0
        self.maxrecords = self.spnRecords.value()

        # set timeout
        self.timeout = self.spnTimeout.value()

        # bbox
        # CRS is WGS84 with axis order longitude, latitude
        # defined by 'urn:ogc:def:crs:OGC:1.3:CRS84'
        minx = self.leWest.text()
        miny = self.leSouth.text()
        maxx = self.leEast.text()
        maxy = self.leNorth.text()
        bbox = [minx, miny, maxx, maxy]

        # only apply spatial filter if bbox is not global
        # even for a global bbox, if a spatial filter is applied, then
        # the CSW server will skip records without a bbox
        if bbox != ['-180', '-90', '180', '90']:
            self.constraints.append(
                BBox(bbox, crs='urn:ogc:def:crs:OGC:1.3:CRS84'))

        # keywords
        if self.leKeywords.text():
            # TODO: handle multiple word searches
            keywords = self.leKeywords.text()
            self.constraints.append(PropertyIsLike('csw:AnyText', keywords))

        if len(self.constraints) > 1:  # exclusive search (a && b)
            self.constraints = [self.constraints]

        # build request
        if not self._get_csw():
            return

        # TODO: allow users to select resources types
        # to find ('service', 'dataset', etc.)
        try:
            with OverrideCursor(Qt.WaitCursor):
                self.catalog.getrecords2(constraints=self.constraints,
                                         maxrecords=self.maxrecords,
                                         esn='full')
        except ExceptionReport as err:
            QMessageBox.warning(self, self.tr('Search error'),
                                self.tr('Search error: {0}').format(err))
            return
        except Exception as err:
            QMessageBox.warning(self, self.tr('Connection error'),
                                self.tr('Connection error: {0}').format(err))
            return

        if self.catalog.results['matches'] == 0:
            self.lblResults.setText(self.tr('0 results'))
            return

        self.display_results()
Exemplo n.º 11
0
 def tabChanged(self, index):
     with OverrideCursor(Qt.WaitCursor):
         try:
             self.refreshTabs()
         except BaseError as e:
             DlgDbError.showError(e, self)
Exemplo n.º 12
0
    def createTable(self):
        """Creates table with chosen fields, optionally add a geometry column """
        if not self.hasSchemas:
            schema = None
        else:
            schema = str(self.cboSchema.currentText())
            if len(schema) == 0:
                QMessageBox.information(
                    self, self.tr("DB Manager"),
                    self.tr("A valid schema must be selected first."))
                return

        table = str(self.editName.text())
        if len(table) == 0:
            QMessageBox.information(self, self.tr("DB Manager"),
                                    self.tr("A valid table name is required."))
            return

        m = self.fields.model()
        if m.rowCount() == 0:
            QMessageBox.information(self, self.tr("DB Manager"),
                                    self.tr("At least one field is required."))
            return

        useGeomColumn = self.chkGeomColumn.isChecked()
        if useGeomColumn:
            geomColumn = str(self.editGeomColumn.text())
            if len(geomColumn) == 0:
                QMessageBox.information(
                    self, self.tr("DB Manager"),
                    self.tr("A name is required for the geometry column."))
                return

            geomType = self.GEOM_TYPES[self.cboGeomType.currentIndex()]
            geomDim = self.spinGeomDim.value()
            try:
                geomSrid = int(self.editGeomSrid.text())
            except ValueError:
                geomSrid = 0
            useSpatialIndex = self.chkSpatialIndex.isChecked()

        flds = m.getFields()
        pk_index = self.cboPrimaryKey.currentIndex()
        if pk_index >= 0:
            flds[pk_index].primaryKey = True

        # commit to DB
        with OverrideCursor(Qt.WaitCursor):
            try:
                if not useGeomColumn:
                    self.db.createTable(table, flds, schema)
                else:
                    geom = geomColumn, geomType, geomSrid, geomDim, useSpatialIndex
                    self.db.createVectorTable(table, flds, geom, schema)

            except (ConnectionError, DbError) as e:
                DlgDbError.showError(e, self)

        # clear UI
        self.editName.clear()
        self.fields.model().removeRows(0, self.fields.model().rowCount())
        self.cboPrimaryKey.clear()
        self.chkGeomColumn.setChecked(False)
        self.chkSpatialIndex.setChecked(False)
        self.editGeomSrid.clear()

        self.cboGeomType.setEnabled(False)
        self.editGeomColumn.setEnabled(False)
        self.spinGeomDim.setEnabled(False)
        self.editGeomSrid.setEnabled(False)
        self.chkSpatialIndex.setEnabled(False)

        QMessageBox.information(self, self.tr("DB Manager"),
                                self.tr("Table created successfully."))
Exemplo n.º 13
0
    def accept(self):
        if self.mode == self.ASK_FOR_INPUT_MODE:
            # create the input layer (if not already done) and
            # update available options
            self.reloadInputLayer()

        # sanity checks
        if self.inLayer is None:
            QMessageBox.critical(self, self.tr("Import to Database"),
                                 self.tr("Input layer missing or not valid."))
            return

        if self.cboTable.currentText() == "":
            QMessageBox.critical(self, self.tr("Import to Database"),
                                 self.tr("Output table name is required."))
            return

        if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
            if not self.widgetSourceSrid.crs().isValid():
                QMessageBox.critical(
                    self, self.tr("Import to Database"),
                    self.tr("Invalid source srid: must be a valid crs."))
                return

        if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
            if not self.widgetTargetSrid.crs().isValid():
                QMessageBox.critical(
                    self, self.tr("Import to Database"),
                    self.tr("Invalid target srid: must be a valid crs."))
                return

        with OverrideCursor(Qt.WaitCursor):
            # store current input layer crs and encoding, so I can restore it
            prevInCrs = self.inLayer.crs()
            prevInEncoding = self.inLayer.dataProvider().encoding()

            try:
                schema = self.outUri.schema() if not self.cboSchema.isEnabled(
                ) else self.cboSchema.currentText()
                table = self.cboTable.currentText()

                # get pk and geom field names from the source layer or use the
                # ones defined by the user
                srcUri = QgsDataSourceUri(self.inLayer.source())

                pk = srcUri.keyColumn() if not self.chkPrimaryKey.isChecked(
                ) else self.editPrimaryKey.text()
                if not pk:
                    pk = self.default_pk

                if self.inLayer.isSpatial() and self.chkGeomColumn.isEnabled():
                    geom = srcUri.geometryColumn(
                    ) if not self.chkGeomColumn.isChecked(
                    ) else self.editGeomColumn.text()
                    if not geom:
                        geom = self.default_geom
                else:
                    geom = None

                options = {}
                if self.chkLowercaseFieldNames.isEnabled(
                ) and self.chkLowercaseFieldNames.isChecked():
                    pk = pk.lower()
                    if geom:
                        geom = geom.lower()
                    options['lowercaseFieldNames'] = True

                # get output params, update output URI
                self.outUri.setDataSource(schema, table, geom, "", pk)
                typeName = self.db.dbplugin().typeName()
                providerName = self.db.dbplugin().providerName()
                if typeName == 'gpkg':
                    uri = self.outUri.database()
                    options['update'] = True
                    options['driverName'] = 'GPKG'
                    options['layerName'] = table
                else:
                    uri = self.outUri.uri(False)

                if self.chkDropTable.isChecked():
                    options['overwrite'] = True

                if self.chkSinglePart.isEnabled(
                ) and self.chkSinglePart.isChecked():
                    options['forceSinglePartGeometryType'] = True

                outCrs = QgsCoordinateReferenceSystem()
                if self.chkTargetSrid.isEnabled(
                ) and self.chkTargetSrid.isChecked():
                    outCrs = self.widgetTargetSrid.crs()

                # update input layer crs and encoding
                if self.chkSourceSrid.isEnabled(
                ) and self.chkSourceSrid.isChecked():
                    inCrs = self.widgetSourceSrid.crs()
                    self.inLayer.setCrs(inCrs)

                if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked(
                ):
                    enc = self.cboEncoding.currentText()
                    self.inLayer.setProviderEncoding(enc)

                onlySelected = self.chkSelectedFeatures.isChecked()

                # do the import!
                ret, errMsg = QgsVectorLayerExporter.exportLayer(
                    self.inLayer, uri, providerName, outCrs, onlySelected,
                    options)
            except Exception as e:
                ret = -1
                errMsg = str(e)

            finally:
                # restore input layer crs and encoding
                self.inLayer.setCrs(prevInCrs)
                self.inLayer.setProviderEncoding(prevInEncoding)

        if ret != 0:
            output = QgsMessageViewer()
            output.setTitle(self.tr("Import to Database"))
            output.setMessageAsPlainText(
                self.tr("Error {0}\n{1}").format(ret, errMsg))
            output.showMessage()
            return

        # create spatial index
        if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked(
        ):
            self.db.connector.createSpatialIndex((schema, table), geom)

        # add comment on table
        supportCom = self.db.supportsComment()
        if self.chkCom.isEnabled() and self.chkCom.isChecked() and supportCom:
            # using connector executing COMMENT ON TABLE query (with editCome.text() value)
            com = self.editCom.text()
            self.db.connector.commentTable(schema, table, com)

        self.db.connection().reconnect()
        self.db.refresh()
        QMessageBox.information(self, self.tr("Import to Database"),
                                self.tr("Import was successful."))
        return QDialog.accept(self)
Exemplo n.º 14
0
    def accept(self):
        # sanity checks
        if self.editOutputFile.text() == "":
            QMessageBox.information(self, self.tr("Export to file"),
                                    self.tr("Output file name is required"))
            return

        if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
            try:
                sourceSrid = int(self.editSourceSrid.text())
            except ValueError:
                QMessageBox.information(
                    self, self.tr("Export to file"),
                    self.tr("Invalid source srid: must be an integer"))
                return

        if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
            try:
                targetSrid = int(self.editTargetSrid.text())
            except ValueError:
                QMessageBox.information(
                    self, self.tr("Export to file"),
                    self.tr("Invalid target srid: must be an integer"))
                return

        with OverrideCursor(Qt.WaitCursor):
            # store current input layer crs, so I can restore it later
            prevInCrs = self.inLayer.crs()
            try:
                uri = self.editOutputFile.text()
                providerName = "ogr"

                options = {}

                # set the OGR driver will be used
                driverName = self.cboFileFormat.currentData()
                options['driverName'] = driverName

                # set the output file encoding
                if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked(
                ):
                    enc = self.cboEncoding.currentText()
                    options['fileEncoding'] = enc

                if self.chkDropTable.isChecked():
                    options['overwrite'] = True

                outCrs = QgsCoordinateReferenceSystem()
                if self.chkTargetSrid.isEnabled(
                ) and self.chkTargetSrid.isChecked():
                    targetSrid = int(self.editTargetSrid.text())
                    outCrs = QgsCoordinateReferenceSystem(targetSrid)

                # update input layer crs
                if self.chkSourceSrid.isEnabled(
                ) and self.chkSourceSrid.isChecked():
                    sourceSrid = int(self.editSourceSrid.text())
                    inCrs = QgsCoordinateReferenceSystem(sourceSrid)
                    self.inLayer.setCrs(inCrs)

                # do the export!
                ret, errMsg = QgsVectorLayerExporter.exportLayer(
                    self.inLayer, uri, providerName, outCrs, False, options)
            except Exception as e:
                ret = -1
                errMsg = str(e)

            finally:
                # restore input layer crs and encoding
                self.inLayer.setCrs(prevInCrs)

        if ret != 0:
            QMessageBox.warning(self, self.tr("Export to file"),
                                self.tr("Error {0}\n{1}").format(ret, errMsg))
            return

        # create spatial index
        # if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked():
        #       self.db.connector.createSpatialIndex( (schema, table), geom )

        QMessageBox.information(self, self.tr("Export to file"),
                                self.tr("Export finished."))
        return QDialog.accept(self)
Exemplo n.º 15
0
    def installPlugin(self, key, quiet=False, stable=True):
        """ Install given plugin """
        error = False
        status_key = 'status' if stable else 'status_exp'
        infoString = ('', '')
        plugin = plugins.all()[key]
        previousStatus = plugin[status_key]
        if not plugin:
            return
        if plugin[status_key] == "newer" and not plugin[
                "error"]:  # ask for confirmation if user downgrades an usable plugin
            if QMessageBox.warning(
                    iface.mainWindow(),
                    self.tr("QGIS Python Plugin Installer"),
                    self.
                    tr("Are you sure you want to downgrade the plugin to the latest available version? The installed one is newer!"
                       ), QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
                return

        dlg = QgsPluginInstallerInstallingDialog(iface.mainWindow(),
                                                 plugin,
                                                 stable=stable)
        dlg.exec_()

        plugin_path = qgis.utils.home_plugin_path + "/" + key
        if dlg.result():
            error = True
            infoString = (self.tr("Plugin installation failed"), dlg.result())
        elif not QDir(plugin_path).exists():
            error = True
            infoString = (
                self.tr("Plugin has disappeared"),
                self.
                tr("The plugin seems to have been installed but it's not possible to know where. The directory \"{}\" "
                   "has not been found. Probably the plugin package contained a wrong named directory.\nPlease search "
                   "the list of installed plugins. You should find the plugin there, but it's not possible to "
                   "determine which of them it is and it's also not possible to inform you about available updates. "
                   "Please contact the plugin author and submit this issue."
                   ).format(plugin_path))
            with OverrideCursor(Qt.WaitCursor):
                plugins.getAllInstalled()
                plugins.rebuild()
                self.exportPluginsToManager()
        else:
            QApplication.setOverrideCursor(Qt.WaitCursor)
            # update the list of plugins in plugin handling routines
            updateAvailablePlugins()
            self.processDependencies(plugin["id"])
            # try to load the plugin
            loadPlugin(plugin["id"])
            plugins.getAllInstalled()
            plugins.rebuild()
            plugin = plugins.all()[key]
            if not plugin["error"]:
                if previousStatus in ["not installed", "new"]:
                    infoString = (self.tr("Plugin installed successfully"), "")
                    if startPlugin(plugin["id"]):
                        settings = QgsSettings()
                        settings.setValue("/PythonPlugins/" + plugin["id"],
                                          True)
                else:
                    settings = QgsSettings()
                    if settings.value(
                            "/PythonPlugins/" + key, False, type=bool
                    ):  # plugin will be reloaded on the fly only if currently loaded
                        reloadPlugin(
                            key)  # unloadPlugin + loadPlugin + startPlugin
                        infoString = (
                            self.tr("Plugin reinstalled successfully"), "")
                    else:
                        unloadPlugin(
                            key
                        )  # Just for a case. Will exit quietly if really not loaded
                        loadPlugin(key)
                        infoString = (
                            self.tr("Plugin reinstalled successfully"),
                            self.
                            tr("Python plugin reinstalled.\nYou need to restart QGIS in order to reload it."
                               ))
                if quiet:
                    infoString = (None, None)
                QApplication.restoreOverrideCursor()
            else:
                QApplication.restoreOverrideCursor()
                if plugin["error"] == "incompatible":
                    message = self.tr(
                        "The plugin is not compatible with this version of QGIS. It's designed for QGIS versions:"
                    )
                    message += " <b>" + plugin["error_details"] + "</b>"
                elif plugin["error"] == "dependent":
                    message = self.tr(
                        "The plugin depends on some components missing on your system. You need to install the following Python module in order to enable it:"
                    )
                    message += "<b> " + plugin["error_details"] + "</b>"
                else:
                    message = self.tr("The plugin is broken. Python said:")
                    message += "<br><b>" + plugin["error_details"] + "</b>"
                dlg = QgsPluginInstallerPluginErrorDialog(
                    iface.mainWindow(), message)
                dlg.exec_()
                if dlg.result():
                    # revert installation
                    pluginDir = qgis.utils.home_plugin_path + "/" + plugin["id"]
                    result = removeDir(pluginDir)
                    if QDir(pluginDir).exists():
                        error = True
                        infoString = (self.tr("Plugin uninstall failed"),
                                      result)
                        try:
                            exec("sys.path_importer_cache.clear()")
                            exec("import %s" % plugin["id"])
                            exec("reload (%s)" % plugin["id"])
                        except:
                            pass
                    else:
                        try:
                            exec("del sys.modules[%s]" % plugin["id"])
                        except:
                            pass
                    plugins.getAllInstalled()
                    plugins.rebuild()

            self.exportPluginsToManager()

        if infoString[0]:
            level = error and Qgis.Critical or Qgis.Info
            msg = "<b>%s</b>" % infoString[0]
            if infoString[1]:
                msg += "<b>:</b> %s" % infoString[1]
            iface.pluginManagerInterface().pushMessage(msg, level)
Exemplo n.º 16
0
    def show_metadata(self):
        """show record metadata"""

        if not self.treeRecords.selectedItems():
            return

        item = self.treeRecords.currentItem()
        if not item:
            return

        identifier = get_item_data(item, 'identifier')

        self.disable_ssl_verification = self.disableSSLVerification.isChecked()
        auth = None

        if self.disable_ssl_verification:
            try:
                auth = Authentication(verify=False)
            except NameError:
                pass

        try:
            with OverrideCursor(Qt.WaitCursor):
                if auth is not None:
                    cat = CatalogueServiceWeb(
                        self.catalog_url,
                        timeout=self.timeout,  # spellok
                        username=self.catalog_username,
                        password=self.catalog_password,
                        auth=auth)
                else:
                    # older owslib version without the auth keyword
                    cat = CatalogueServiceWeb(
                        self.catalog_url,
                        timeout=self.timeout,  # spellok
                        username=self.catalog_username,
                        password=self.catalog_password)

                cat.getrecordbyid(
                    [self.catalog.records[identifier].identifier])
        except ExceptionReport as err:
            QMessageBox.warning(
                self, self.tr('GetRecords error'),
                self.tr('Error getting response: {0}').format(err))
            return
        except KeyError as err:
            QMessageBox.warning(self, self.tr('Record parsing error'),
                                self.tr('Unable to locate record identifier'))
            return

        record = cat.records[identifier]
        record.xml_url = cat.request

        crd = RecordDialog()
        metadata = render_template('en', self.context, record,
                                   'record_metadata_dc.html')

        style = QgsApplication.reportStyleSheet()
        crd.textMetadata.document().setDefaultStyleSheet(style)
        crd.textMetadata.setHtml(metadata)
        crd.exec_()
Exemplo n.º 17
0
    def installFromZipFile(self, filePath):
        if not os.path.isfile(filePath):
            return

        settings = QgsSettings()
        settings.setValue(settingsGroup + '/lastZipDirectory',
                          QFileInfo(filePath).absoluteDir().absolutePath())

        pluginName = None
        with zipfile.ZipFile(filePath, 'r') as zf:
            # search for metadata.txt. In case of multiple files, we can assume that
            # the shortest path relates <pluginname>/metadata.txt
            metadatafiles = sorted(f for f in zf.namelist()
                                   if f.endswith('metadata.txt'))
            if len(metadatafiles) > 0:
                pluginName = os.path.split(metadatafiles[0])[0]

        pluginFileName = os.path.splitext(os.path.basename(filePath))[0]

        if not pluginName:
            msg_box = QMessageBox()
            msg_box.setIcon(QMessageBox.Warning)
            msg_box.setWindowTitle(
                self.tr("QGIS Python Install from ZIP Plugin Installer"))
            msg_box.setText(
                self.
                tr("The Zip file is not a valid QGIS python plugin. No root folder was found inside."
                   ))
            msg_box.setStandardButtons(QMessageBox.Ok)
            more_info_btn = msg_box.addButton(self.tr("More Information"),
                                              QMessageBox.HelpRole)
            msg_box.exec()
            if msg_box.clickedButton() == more_info_btn:
                QgsHelp.openHelp(
                    "plugins/plugins.html#the-install-from-zip-tab")
            return

        pluginsDirectory = qgis.utils.home_plugin_path
        if not QDir(pluginsDirectory).exists():
            QDir().mkpath(pluginsDirectory)

        pluginDirectory = QDir.cleanPath(
            os.path.join(pluginsDirectory, pluginName))

        # If the target directory already exists as a link,
        # remove the link without resolving
        QFile(pluginDirectory).remove()

        password = None
        infoString = None
        success = False
        keepTrying = True

        while keepTrying:
            try:
                # Test extraction. If fails, then exception will be raised and no removing occurs
                unzip(filePath, pluginsDirectory, password)
                # Removing old plugin files if exist
                removeDir(pluginDirectory)
                # Extract new files
                unzip(filePath, pluginsDirectory, password)
                keepTrying = False
                success = True
            except Exception as e:
                success = False
                if 'password' in str(e):
                    infoString = self.tr('Aborted by user')
                    if 'Bad password' in str(e):
                        msg = self.tr(
                            'Wrong password. Please enter a correct password to the zip file.'
                        )
                    else:
                        msg = self.tr(
                            'The zip file is encrypted. Please enter password.'
                        )
                    # Display a password dialog with QgsPasswordLineEdit
                    dlg = QDialog()
                    dlg.setWindowTitle(self.tr('Enter password'))
                    buttonBox = QDialogButtonBox(
                        QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
                        Qt.Horizontal)
                    buttonBox.rejected.connect(dlg.reject)
                    buttonBox.accepted.connect(dlg.accept)
                    lePass = QgsPasswordLineEdit()
                    layout = QVBoxLayout()
                    layout.addWidget(QLabel(msg))
                    layout.addWidget(lePass)
                    layout.addWidget(buttonBox)
                    dlg.setLayout(layout)
                    keepTrying = dlg.exec_()
                    password = lePass.text()
                else:
                    infoString = self.tr(
                        "Failed to unzip the plugin package\n{}.\nProbably it is broken"
                        .format(filePath))
                    keepTrying = False

        if success:
            with OverrideCursor(Qt.WaitCursor):
                updateAvailablePlugins()
                self.processDependencies(pluginName)
                loadPlugin(pluginName)
                plugins.getAllInstalled()
                plugins.rebuild()

                if settings.contains('/PythonPlugins/' +
                                     pluginName):  # Plugin was available?
                    if settings.value('/PythonPlugins/' + pluginName, False,
                                      bool):  # Plugin was also active?
                        reloadPlugin(
                            pluginName
                        )  # unloadPlugin + loadPlugin + startPlugin
                    else:
                        unloadPlugin(pluginName)
                        loadPlugin(pluginName)
                else:
                    if startPlugin(pluginName):
                        settings.setValue('/PythonPlugins/' + pluginName, True)

            self.exportPluginsToManager()
            msg = "<b>%s</b>" % self.tr("Plugin installed successfully")
        else:
            msg = "<b>%s:</b> %s" % (self.tr("Plugin installation failed"),
                                     infoString)

        level = Qgis.Info if success else Qgis.Critical
        iface.pluginManagerInterface().pushMessage(msg, level)
Exemplo n.º 18
0
    def accept(self):
        alg_parameters = []

        feedback = self.createFeedback()

        load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
        project = QgsProject.instance() if load_layers else None

        for row in range(self.mainWidget().tblParameters.rowCount()):
            col = 0
            parameters = {}
            for param in self.algorithm().parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
                    continue
                wrapper = self.mainWidget().wrappers[row][col]
                parameters[param.name()] = wrapper.value()
                if not param.checkValueIsAcceptable(wrapper.value()):
                    self.messageBar().pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
                        param.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return
                col += 1
            count_visible_outputs = 0
            for out in self.algorithm().destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue

                count_visible_outputs += 1
                widget = self.mainWidget().tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if out.checkValueIsAcceptable(text):
                    if isinstance(out, (QgsProcessingParameterRasterDestination,
                                        QgsProcessingParameterFeatureSink)):
                        # load rasters and sinks on completion
                        parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, project)
                    else:
                        parameters[out.name()] = text
                    col += 1
                else:
                    self.messageBar().pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
                        out.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return

            alg_parameters.append(parameters)

        with OverrideCursor(Qt.WaitCursor):

            self.mainWidget().setEnabled(False)
            self.cancelButton().setEnabled(True)

            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.showLog()
                self.repaint()
            except:
                pass

            start_time = time.time()

            algorithm_results = []
            for count, parameters in enumerate(alg_parameters):
                if feedback.isCanceled():
                    break
                self.setProgressText(QCoreApplication.translate('BatchAlgorithmDialog', '\nProcessing algorithm {0}/{1}…').format(count + 1, len(alg_parameters)))
                self.setInfo(self.tr('<b>Algorithm {0} starting&hellip;</b>').format(self.algorithm().displayName()), escapeHtml=False)

                feedback.pushInfo(self.tr('Input parameters:'))
                feedback.pushCommandInfo(pformat(parameters))
                feedback.pushInfo('')

                # important - we create a new context for each iteration
                # this avoids holding onto resources and layers from earlier iterations,
                # and allows batch processing of many more items then is possible
                # if we hold on to these layers
                context = dataobjects.createContext(feedback)

                alg_start_time = time.time()
                ret, results = execute(self.algorithm(), parameters, context, feedback)
                if ret:
                    self.setInfo(QCoreApplication.translate('BatchAlgorithmDialog', 'Algorithm {0} correctly executed…').format(self.algorithm().displayName()), escapeHtml=False)
                    feedback.setProgress(100)
                    feedback.pushInfo(
                        self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
                    feedback.pushInfo(self.tr('Results:'))
                    feedback.pushCommandInfo(pformat(results))
                    feedback.pushInfo('')
                    algorithm_results.append(results)
                else:
                    break

                handleAlgorithmResults(self.algorithm(), context, feedback, False)

        feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))

        self.finish(algorithm_results)
        self.cancelButton().setEnabled(False)
Exemplo n.º 19
0
 def runNextStep(self):
     self.stopBlinking()
     test = self.tests[self.currentTest]
     step = test.steps[self.currentTestStep]
     self.btnSkip.setEnabled(True)
     self.btnCancel.setEnabled(True)
     if os.path.exists(step.description):
         with open(step.description) as f:
             html = ''.join(f.readlines())
         self.webView.setHtml(html)
     else:
         if step.function is not None:
             self.webView.setHtml(
                 step.description +
                 '<p><b>[This is an automated step. Please, wait until it has been completed]</b></p>'
             )
         else:
             self.webView.setHtml(
                 step.description +
                 '<p><b>[Click on the right-hand side buttons once you have performed this step]</b></p>'
             )
     QCoreApplication.processEvents()
     if self.currentTestStep == len(test.steps) - 1:
         if step.function is not None:
             self.btnTestOk.setEnabled(False)
             self.btnTestFailed.setEnabled(False)
             self.btnNextStep.setEnabled(False)
             self.btnSkip.setEnabled(False)
             self.btnCancel.setEnabled(False)
             self.webView.setEnabled(False)
             QCoreApplication.processEvents()
             try:
                 if step.busyCursor:
                     with OverrideCursor(Qt.WaitCursor):
                         step.function()
                 else:
                     step.function()
                 QCoreApplication.processEvents()
                 self.testPasses()
             except Exception as e:
                 if isinstance(e, AssertionError):
                     self.testFails('{}\n{}'.format(str(e),
                                                    traceback.format_exc()))
                 else:
                     self.testContainsError('{}\n{}'.format(
                         str(e), traceback.format_exc()))
         else:
             self.btnTestOk.setEnabled(True)
             self.btnTestOk.setText('Test Passes')
             self.btnTestFailed.setEnabled(True)
             self.btnTestFailed.setText('Test Fails')
             self.webView.setEnabled(True)
             self.btnNextStep.setEnabled(False)
             if step.prestep:
                 try:
                     if step.busyCursor:
                         with OverrideCursor(Qt.WaitCursor):
                             step.prestep()
                     else:
                         step.prestep()
                     QCoreApplication.processEvents()
                 except Exception as e:
                     if isinstance(e, AssertionError):
                         self.testFailsAtSetup('{}\n{}'.format(
                             str(e), traceback.format_exc()))
                     else:
                         self.testContainsError('{}\n{}'.format(
                             str(e), traceback.format_exc()))
     else:
         if step.function is not None:
             self.btnTestOk.setEnabled(False)
             self.btnTestFailed.setEnabled(False)
             self.btnNextStep.setEnabled(False)
             self.btnSkip.setEnabled(False)
             self.btnCancel.setEnabled(False)
             self.webView.setEnabled(False)
             QCoreApplication.processEvents()
             try:
                 if step.busyCursor:
                     with OverrideCursor(Qt.WaitCursor):
                         step.function()
                 else:
                     step.function()
                 QCoreApplication.processEvents()
                 self.currentTestStep += 1
                 self.runNextStep()
             except Exception as e:
                 if isinstance(e, AssertionError):
                     self.testFails('{}\n{}'.format(str(e),
                                                    traceback.format_exc()))
                 else:
                     self.testContainsError('{}\n{}'.format(
                         str(e), traceback.format_exc()))
         else:
             self.currentTestStep += 1
             self.webView.setEnabled(True)
             self.btnNextStep.setEnabled(not step.isVerifyStep)
             if step.isVerifyStep:
                 self.btnTestOk.setEnabled(True)
                 self.btnTestOk.setText('Step Passes')
                 self.btnTestFailed.setEnabled(True)
                 self.btnTestFailed.setText('Step Fails')
             else:
                 self.btnTestOk.setEnabled(False)
                 self.btnTestFailed.setEnabled(False)
             if step.prestep:
                 try:
                     if step.busyCursor:
                         with OverrideCursor(Qt.WaitCursor):
                             step.prestep()
                     else:
                         step.prestep()
                     QCoreApplication.processEvents()
                 except Exception as e:
                     if isinstance(e, AssertionError):
                         self.testFailsAtSetup('{}\n{}'.format(
                             str(e), traceback.format_exc()))
                     else:
                         self.testContainsError('{}\n{}'.format(
                             str(e), traceback.format_exc()))
     if step.function is None:
         self.startBlinking()