示例#1
0
    def __init__(self, parent):
        super().__init__(parent)
        self.currentRow = None
        self.currentLayer = None
        self.parent = parent

        # Retrieve publishable layers once:
        # this is safe because the Bridge dialog is modal
        self.publishableLayers = getPublishableLayers()

        # Keep track of fields and metadata for each layer
        self.fieldsToPublish = {}
        self.metadata = {}

        # Keep track if metadata or geodata for a layer has been published
        self.isMetadataPublished = {}
        self.isDataPublished = {}

        # Default "not set" values for comboboxes
        self.COMBO_NOTSET_LANG = self.tr("Not specified")
        self.COMBO_NOTSET_DATA = self.tr("Do not publish data")
        self.COMBO_NOTSET_META = self.tr("Do not publish metadata")

        # Initialize the UI and populate with data on the GUI thread
        gui.execute(self._setupUi)
    def __init__(self, parent):
        super(PublishWidget, self).__init__()
        self.isMetadataPublished = {}
        self.isDataPublished = {}
        self.currentRow = None
        self.currentLayer = None
        self.parent = parent

        self.fieldsToPublish = {}
        self.metadata = {}
        execute(self._setupUi)
    def __init__(self, parent):
        super(PublishWidget, self).__init__()
        self.isMetadataPublished = {}
        self.isDataPublished = {}
        self.currentRow = None
        self.currentLayer = None
        self.parent = parent

        self.fieldsToPublish = {}
        self.metadata = {}
        execute(self._setupUi)

        for s in geodataServers().values():
            s.setupForProject()
 def publish(self):
     if self.validateBeforePublication():
         toPublish = self._toPublish()
         progressDialog = ProgressDialog(toPublish, self.parent)
         task = self.getPublishTask(self.parent)
         task.stepStarted.connect(progressDialog.setInProgress)
         task.stepSkipped.connect(progressDialog.setSkipped)
         task.stepFinished.connect(progressDialog.setFinished)
         progressDialog.show()
         #task.progressChanged.connect(progress.setValue)
         ret = execute(task.run)
         progressDialog.close()
         #self.bar.clearWidgets()
         task.finished(ret)
         if task.exception is not None:
             if task.exceptiontype == requests.exceptions.ConnectionError:
                 QMessageBox.warning(
                     self, self.tr("Error while publishing"),
                     self.
                     tr("Connection error. Server unavailable.\nSee QGIS log for details"
                        ))
             else:
                 self.bar.clearWidgets()
                 self.bar.pushMessage(self.tr("Error while publishing"),
                                      self.tr("See QGIS log for details"),
                                      level=Qgis.Warning,
                                      duration=5)
             QgsMessageLog.logMessage(task.exception,
                                      'GeoCat Bridge',
                                      level=Qgis.Critical)
         if isinstance(task, PublishTask):
             self.updateLayersPublicationStatus(
                 task.geodataServer is not None, task.metadataServer
                 is not None)
示例#5
0
    def publish(self):
        to_publish = self._toPublish()
        if not self.validateBeforePublication(to_publish):
            return

        progress_dialog = ProgressDialog(to_publish, self.parent)
        task = self.getPublishTask(self.parent)
        task.stepStarted.connect(progress_dialog.setInProgress)
        task.stepSkipped.connect(progress_dialog.setSkipped)
        task.stepFinished.connect(progress_dialog.setFinished)
        progress_dialog.show()
        ret = gui.execute(task.run)
        progress_dialog.close()
        task.finished(ret)
        if task.exception is not None:
            if task.exc_type == requests.exceptions.ConnectionError:
                self.showErrorBox(
                    "Error while publishing",
                    "Connection error. Server unavailable.\nSee QGIS log for details",
                    propagate=task.exception)
            else:
                self.showErrorBar("Error while publishing",
                                  "See QGIS log for details",
                                  propagate=task.exception)
        if isinstance(task, PublishTask):
            self.updateLayersPublicationStatus(
                task.geodata_server is not None, task.metadata_server
                is not None)
 def publish(self):
     progressMessageBar = self.bar.createMessage(
         self.tr("Publishing layers"))
     progress = QProgressBar()
     progress.setMaximum(100)
     progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
     progressMessageBar.layout().addWidget(progress)
     self.bar.pushWidget(progressMessageBar, Qgis.Info)
     QCoreApplication.processEvents()
     task = self.getPublishTask(self.parent)
     task.progressChanged.connect(progress.setValue)
     ret = execute(task.run)
     self.bar.clearWidgets()
     task.finished(ret)
     if task.exception is not None:
         self.bar.clearWidgets()
         self.bar.pushMessage(self.tr("Error while publishing"),
                              self.tr("See QGIS log for details"),
                              level=Qgis.Warning,
                              duration=5)
         QgsMessageLog.logMessage(task.exception,
                                  'GeoCat Bridge',
                                  level=Qgis.Critical)
     self.updateLayersPublicationStatus(task.geodataServer is not None,
                                        task.metadataServer is not None)
示例#7
0
    def testConnection(self):
        """ Tests if the server instance can actually connect to it.

        .. note::   Not all servers might support this. Servers that don't support it,
                    should still implement :func:`testConnection`, but in that case,
                    the method should simply always return `True`.
        """
        server_widget = self.stackedWidget.currentWidget()
        if not server_widget or not hasattr(server_widget,
                                            'createServerInstance'):
            # No current server widget set or empty widget
            return

        server = server_widget.createServerInstance()
        if server is None:
            # Server is usually None when createServerInstance() call failed.
            self.showErrorBar(
                "Error",
                "Wrong value(s) in current server settings. Please check QGIS log."
            )
        else:
            errors = set()
            # Run the actual connection test method on the server instance.
            if gui.execute(server.testConnection, errors):
                self.showSuccessBar(
                    "Success", "Successfully established server connection")
                return
            for e in errors:
                self.showErrorBar("Error", e)
示例#8
0
 def _testConnection(self, server):
     if server is None:
         self.bar.pushMessage(self.tr("Error"), self.tr("Wrong values in current item"), level=Qgis.Warning, duration=5)
     else:
         if execute(server.testConnection):
             self.bar.pushMessage(self.tr("Success"), self.tr("Connection succesfully established with server"), level=Qgis.Success, duration=5)
         else:
             self.bar.pushMessage(self.tr("Error"), self.tr("Could not connect with server"), level=Qgis.Warning, duration=5)                    
    def updateDbServersCombo(self, managed_by_geoserver: bool, init_value=None):
        """ (Re)populate the combobox with database-driven datastores.

        :param managed_by_geoserver:    If True, GeoServer manages the DB connection. If False, Bridge manages it.
        :param init_value:              When the combobox shows for the first time and no databases have been loaded,
                                        this value can be set immediately as the only available and selected item.
                                        Doing so prevents a full refresh of GeoServer datastores.
        """
        if managed_by_geoserver and init_value:
            if self.comboGeoserverDatabase.count() == 0:
                # Only add the given init_value item to the empty combo (user should manually refresh)
                self.comboGeoserverDatabase.addItem(init_value)
                self.comboGeoserverDatabase.setCurrentText(init_value)
                return
            # If combo has values, try and find the init_value and set it to that (user should manually refresh)
            index = self.comboGeoserverDatabase.findText(init_value)
            if index >= 0:
                self.comboGeoserverDatabase.setCurrentIndex(index)
                return

        current_db = self.comboGeoserverDatabase.currentText() or init_value
        self.comboGeoserverDatabase.clear()

        if managed_by_geoserver:
            # Database is managed by GeoServer: instantiate server and retrieve datastores
            # TODO: only PostGIS datastores are supported for now
            server = self.createServerInstance()
            if not server:
                self.parent.showErrorBar("Error", "Bad values in server definition")
                return

            try:
                # Retrieve workspaces (single REST request)
                workspaces = gui.execute(server.getWorkspaces)
                if not workspaces:
                    return
                # Retrieve datastores for each workspace:
                # This is a potentially long-running operation and uses a separate QThread
                worker = gui.ItemProcessor(workspaces, server.getPostgisDatastores)
                self.showProgressDialog("Fetching PostGIS datastores...", len(workspaces), worker.stop)
                worker.progress.connect(self._pgdialog.setValue)
                worker.finished.connect(partial(self.addGeoserverPgDatastores, current_db))
                worker.run()
            except Exception as e:
                msg = f'Failed to retrieve datastores for {self.serverName}'
                if isinstance(e, HTTPError) and e.response.status_code == 401:
                    msg = f'{msg}: please check credentials'
                else:
                    msg = f'{msg}: {e}'
                self.parent.showErrorBar(msg)

        else:
            # Database is managed by Bridge: iterate over all user-defined database connections
            db_servers = self.parent.serverManager.getDbServerNames()
            self.comboGeoserverDatabase.addItems(db_servers)
            if current_db in db_servers:
                self.comboGeoserverDatabase.setCurrentText(current_db)
示例#10
0
    def addPostgisDatastore(self):
        server = self.createServerInstance()
        if server is None:
            self.parent.showErrorBar("Error", "Wrong values in server definition")
            return
        dlg = GeoserverDatastoreDialog(self)
        dlg.exec_()
        name = dlg.name
        if name is None:
            return

        def _entry(k, v):
            return {"@key": k, "$": v}

        ds = {
            "dataStore": {
                "name": dlg.name,
                "type": "PostGIS",
                "enabled": True,
                "connectionParameters": {
                    "entry": [
                        _entry("schema", dlg.schema),
                        _entry("port", dlg.port),
                        _entry("database", dlg.database),
                        _entry("passwd", dlg.password),
                        _entry("user", dlg.username),
                        _entry("host", dlg.host),
                        _entry("dbtype", "postgis")
                    ]
                }
            }
        }
        try:
            gui.execute(partial(server.addPostgisDatastore, ds))
        except Exception as e:
            self.parent.showErrorBar("Error", "Could not create new PostGIS dataset", propagate=e)
        else:
            self.updateDbServersCombo(True)
示例#11
0
    def publish(self):
        """ Publish/export the selected layers. """

        online = self.tabOnOffline.currentWidget() == self.tabOnline
        action = 'publish' if online else 'export'
        to_publish = self.getCheckedLayers()
        if not to_publish:
            self.showWarningBar(f"Nothing to {action}", "Please select one or more layers.")
            return

        if not online and not self.checkOfflinePublicationStatus():
            # Offline tab active: check if required offline publish settings have been set
            return

        if online:
            # Online tab active
            if not self.checkOnlinePublicationStatus():
                # No server nor "only_symbology" has been selected
                return
            if not self.validateBeforePublication(to_publish, self.chkOnlySymbology.isChecked()):
                # No data is valid for online publishing
                return

        if self.chkBackground.isChecked():
            # User wants to publish in the background: close dialog
            return self.publishOnBackground(to_publish)

        progress_dialog = ProgressDialog(to_publish, self.parent)
        task = self.getPublishTask(self.parent, to_publish)
        task.stepStarted.connect(progress_dialog.setInProgress)
        task.stepSkipped.connect(progress_dialog.setSkipped)
        task.stepFinished.connect(progress_dialog.setFinished)
        progress_dialog.show()
        ret = gui.execute(task.run)
        progress_dialog.close()
        if task.exception is not None:
            if getattr(task, 'exc_type', None) == requests.exceptions.ConnectionError:
                self.showErrorBox(f"Error while {action}ing",
                                  "Connection error: server unavailable.\nPlease check QGIS log for details.",
                                  propagate=task.exception)
            else:
                self.showErrorBar(f"Error while {action}ing",
                                  "Please check QGIS log for details.", propagate=task.exception)
        elif isinstance(task, ExportTask):
            self.showSuccessBar(f"{action.capitalize()} completed", "No issues encountered.")

        if isinstance(task, PublishTask):
            # Show report dialog for publish tasks and update publication status
            task.finished(ret)
            self.updateOnlineLayersPublicationStatus(task.geodata_server is not None, task.metadata_server is not None)
示例#12
0
 def populatePostgisComboWithGeoserverPostgisServers(self):
     url = self.txtGeoserverUrl.text().strip()
     self.comboGeoserverDatabase.clear()
     server = self.createGeoserverServer()
     if server is None:
         self.bar.pushMessage(self.tr("Wrong values in server definition"), level=Qgis.Warning, duration=5)
         return
     try:
         datastores = execute(server.postgisDatastores)
     except:
         datastores = []
     if datastores:
         self.comboGeoserverDatabase.addItems(datastores)
     else:
         self.bar.pushMessage(self.tr("No PostGIS datastores in server or could not retrieve them"), level=Qgis.Warning, duration=5)
示例#13
0
 def login(self, user):
     try:
         self.user = user
         self.server = GeocatLiveServer("GeoCat Live - " + self.user,
                                        self.user, "", "")
         url = "%s/%s" % (GeocatLiveServer.BASE_URL, self.user)
         response = execute(lambda: requests.get(url))
         responsejson = response.json()
         for serv in responsejson["services"]:
             if serv["application"] == "geoserver":
                 self.geoserverUrl = serv["url"] + "/rest"
                 self.geoserverStatus = serv["status"]
             if serv["application"] == "geonetwork":
                 self.geonetworkUrl = serv["url"]
                 self.geonetworkStatus = serv["status"]
     except:
         self.logout()
         raise Exception("Could not log in to GeoCat Live")
    def addPostgisDatastore(self):
        url = self.txtGeoserverUrl.text().strip()
        server = self.createGeoserverServer()
        if server is None:
            self.bar.pushMessage(self.tr("Wrong values in server definition"),
                                 level=Qgis.Warning,
                                 duration=5)
            return
        dlg = NewDatasetDialog(self)
        dlg.exec_()
        name = dlg.name
        if name is None:
            return

        def _entry(k, v):
            return {"@key": k, "$": v}

        ds = {
            "dataStore": {
                "name": dlg.name,
                "type": "PostGIS",
                "enabled": True,
                "connectionParameters": {
                    "entry": [
                        _entry("schema", dlg.schema),
                        _entry("port", dlg.port),
                        _entry("database", dlg.database),
                        _entry("passwd", dlg.password),
                        _entry("user", dlg.username),
                        _entry("host", dlg.host),
                        _entry("dbtype", "postgis")
                    ]
                }
            }
        }
        try:
            datastores = execute(lambda: server.addPostgisDatastore(ds))
            self.populatePostgisComboWithGeoserverPostgisServers()
        except:
            self.bar.pushMessage(
                self.tr("Could not create new PostGIS dataset"),
                level=Qgis.Warning,
                duration=5)
 def publish(self):
     if self.validateBeforePublication():
         '''
         progressMessageBar = self.bar.createMessage(self.tr("Publishing layers"))
         progress = QProgressBar()
         progress.setMaximum(100) 
         progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
         progressMessageBar.layout().addWidget(progress)            
         self.bar.pushWidget(progressMessageBar, Qgis.Info)
         QCoreApplication.processEvents()
         '''
         toPublish = self._toPublish()
         progressDialog = ProgressDialog(toPublish, self.parent)
         task = self.getPublishTask(self.parent)
         task.stepStarted.connect(progressDialog.setInProgress)
         task.stepSkipped.connect(progressDialog.setSkipped)
         task.stepFinished.connect(progressDialog.setFinished)
         progressDialog.show()
         #task.progressChanged.connect(progress.setValue)
         ret = execute(task.run)
         progressDialog.close()
         #self.bar.clearWidgets()
         task.finished(ret)
         if task.exception is not None:
             self.bar.clearWidgets()
             self.bar.pushMessage(self.tr("Error while publishing"),
                                  self.tr("See QGIS log for details"),
                                  level=Qgis.Warning,
                                  duration=5)
             QgsMessageLog.logMessage(task.exception,
                                      'GeoCat Bridge',
                                      level=Qgis.Critical)
         if isinstance(task, PublishTask):
             self.updateLayersPublicationStatus(
                 task.geodataServer is not None, task.metadataServer
                 is not None)