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)
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)
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)
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)
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)
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)
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)
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)