def _getInfoXmlContent(uuid, thumb_filename): root = Element("info", {"version": "1.1"}) general = _addSubElement(root, "general") d = datetime.now().isoformat() _addSubElement(general, "changeDate", d) _addSubElement(general, "createDate", d) _addSubElement(general, "schema", "iso19139") _addSubElement(general, "isTemplate", "n") _addSubElement(general, "format", "full") _addSubElement(general, "localId") _addSubElement(general, "uuid", uuid) _addSubElement(general, "siteId", meta.getAppName()) _addSubElement(general, "siteName", meta.getAppName()) _addSubElement(root, "categories") privs = _addSubElement(root, "privileges") grp = _addSubElement(privs, "group", attrib={"name": "all"}) _addSubElement(grp, "operation", attrib={"name": "dynamic"}) _addSubElement(grp, "operation", attrib={"name": "featured"}) _addSubElement(grp, "operation", attrib={"name": "view"}) _addSubElement(grp, "operation", attrib={"name": "download"}) public = _addSubElement(root, "public") _addSubElement(public, "file", attrib={"name": os.path.basename(thumb_filename), "changeDate": d}) _addSubElement(root, "private") xmlstring = ElementTree.tostring(root, encoding="UTF-8", method="xml").decode() dom = minidom.parseString(xmlstring) return dom.toprettyxml(indent=" ")
def importLayer(self, layer, fields): username, password = self.getCredentials() uri = "dbname='%s' key='id' host=%s port=%s user='******' password='******' table=\"%s\".\"%s\" (geom) sql=" % ( self.database, self.host, self.port, username, password, self.schema, layer.name()) qgsfields = QgsFields() for f in layer.fields(): if fields is None or f.name() in fields: qgsfields.append(f) exporter = QgsVectorLayerExporter(uri, "postgres", qgsfields, layer.wkbType(), layer.sourceCrs(), True, {}) if exporter.errorCode() != QgsVectorLayerExporter.NoError: raise Exception( self.translate( getAppName(), f'Error importing to PostGIS: {exporter.errorMessage()}')) features = layer.getFeatures() for f in features: if not exporter.addFeature(f, QgsFeatureSink.FastInsert): raise Exception( self.translate( getAppName(), f'Error importing to PostGIS: {exporter.errorMessage()}' )) exporter.flushBuffer() if exporter.errorCode() != QgsVectorLayerExporter.NoError: raise Exception( self.translate( getAppName(), f'Error importing to PostGIS: {exporter.errorMessage()}'))
def publishLayer(self, layer, fields=None): lyr_title, safe_name = lyr_utils.getLayerTitleAndName(layer) if layer.type() == layer.VectorLayer: if layer.featureCount() == 0: self.logError(f"Layer '{lyr_title}' contains zero features and cannot be published") return if layer.dataProvider().name() == "postgres" and self.useOriginalDataSource: try: from geocatbridge.servers.models.postgis import PostgisServer except (ImportError, ModuleNotFoundError): raise Exception(self.translate(getAppName(), "Cannot find or import PostgisServer class")) else: uri = QgsDataSourceUri(layer.source()) db = PostgisServer( "temp", uri.authConfigId(), uri.host(), uri.port(), uri.schema(), uri.database()) self._publishVectorLayerFromPostgis(layer, db) elif self.storage != GeoserverStorage.POSTGIS_BRIDGE: src_path, src_name, src_ext = lyr_utils.getLayerSourceInfo(layer) filename = self._exported_layers.get(src_path) if not filename: if self.storage == GeoserverStorage.POSTGIS_GEOSERVER: shp_name = exportLayer(layer, fields, to_shapefile=True, force=True, logger=self) basename = os.path.splitext(shp_name)[0] filename = basename + ".zip" with ZipFile(filename, 'w') as z: for ext in (".shp", ".shx", ".prj", ".dbf"): filetozip = basename + ext z.write(filetozip, arcname=os.path.basename(filetozip)) else: filename = exportLayer(layer, fields, logger=self) self._exported_layers[src_path] = filename if self.storage == GeoserverStorage.FILE_BASED: self._publishVectorLayerFromFile(layer, filename) else: self._publishVectorLayerFromFileToPostgis(layer, filename) elif self.storage == GeoserverStorage.POSTGIS_BRIDGE: db = manager.getServer(self.postgisdb) if not db: raise Exception(self.translate(getAppName(), "Cannot find the selected PostGIS database")) db.importLayer(layer, fields) self._publishVectorLayerFromPostgis(layer, db) elif layer.type() == layer.RasterLayer: if layer.source() not in self._exported_layers: path = exportLayer(layer, fields, logger=self) self._exported_layers[layer.source()] = path filename = self._exported_layers[layer.source()] self._publishRasterLayer(filename, safe_name) self._clearCache()
def unpublishAll(self): """ Removes all geodata from the current server workspace and clears all metadata (published layers only). """ if self.tabOnOffline.currentWidget() != self.tabOnline: return res = self.showQuestionBox(meta.getAppName(), "Are you sure you want to remove all geodata (clear workspace) " "and/or published metadata from the specified server(s)?", buttons=self.BUTTONS.YES | self.BUTTONS.NO) if res != self.BUTTONS.YES: return # Clear all geodata for the current workspace data_server = manager.getGeodataServer(self.comboGeodataServer.currentText()) if not data_server: return result = data_server.clearWorkspace(False) if result: for layer_id in self.isDataPublished.keys(): self.isDataPublished[layer_id] = False # Clear metadata (only what has been published) meta_server = manager.getMetadataServer(self.comboMetadataServer.currentText()) for layer_id, status in self.isMetadataPublished.items(): if status: self.isMetadataPublished[layer_id] = not self.unpublishMetadata(layer_id) if result: if meta_server: self.showSuccessBar("Success", "Removed geodata and/or metadata from the selected server(s)") else: self.showSuccessBar("Success", "Removed geodata from the selected server") # Update layer item widgets self.updateOnlineLayersPublicationStatus(data_server is not None, meta_server is not None)
def __init__(self, iface): self.iface = iface self._win = iface.mainWindow() self.action_publish = None self.action_help = None self.action_multistyler = None self.widget_multistyler = None readServers() self.name = meta.getAppName() self.provider = BridgeProvider() self.locale = QSettings().value("locale/userLocale")[0:2] locale_path = files.getLocalePath(f"bridge_{self.locale}") self.translator = QTranslator() if os.path.exists(locale_path): self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) self.qgis_hook = sys.excepthook def plugin_hook(t, value, tb): error_list = traceback.format_exception(t, value, tb) trace = "".join(error_list) if meta.PLUGIN_NAMESPACE in trace.lower(): try: handleError(error_list) except: pass # we swallow all exceptions here, to avoid entering an endless loop else: self.qgis_hook(t, value, tb) sys.excepthook = plugin_hook
def _log(self, message, level, context): if isinstance(message, Exception): message = str(message) text = self.translate(context, message) _LOGGER.logMessage(text, getAppName(), level) if level == Qgis.Warning: self._warnings.append(text) elif level == Qgis.Critical: self._errors.append(text)
def __init__(self, iface): self.iface = iface self._win = iface.mainWindow() self.main_dialog = None self.action_publish = None self.action_help = None self.action_styleviewer = None self.widget_styleviewer = StyleviewerWidget() self.widget_styleviewer.hideEvent = partial(self.styleviewerHidden) self.widget_styleviewer.showEvent = partial(self.styleviewerShown) self._layerSignals = LayerStyleEventManager() # Load server configuration from QSettings manager.loadConfiguredServers() self.name = meta.getAppName() self.provider = None self.locale = QSettings().value("locale/userLocale")[0:2] locale_path = files.getLocalePath(f"bridge_{self.locale}") self.translator = QTranslator() if os.path.exists(locale_path): self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) self.qgis_hook = sys.excepthook def plugin_hook(t, value, tb): """ Exception handling (catch all) """ error_list = traceback.format_exception(t, value, tb) trace = "".join(error_list) if meta.PLUGIN_NAMESPACE in trace.lower(): try: # Show error report dialog handleError(error_list) except Exception as err: # Swallow all exceptions here, to avoid entering an endless loop feedback.logWarning( f"A failure occurred while handling an exception: {err}" ) # TODO: Once Bridge is more mature, the code below should be uncommented # try: # # Close/disable the plugin to avoid messing up things # self.unload() # except Exception as err: # feedback.logWarning(f"A failure occurred while unloading the Bridge plugin: {err}") else: # Handle regular QGIS exception self.qgis_hook(t, value, tb) sys.excepthook = plugin_hook
def readServers(): global _servers value = QSettings().value(SERVERS_SETTING) if value is None: return stored_servers = json.loads(value) for serverDef in stored_servers: try: s = serverFromDefinition(serverDef) except KeyError: known_types = ','.join(c.__name__ for c in (GeonetworkServer, GeoserverServer, MapserverServer, PostgisServer)) QgsMessageLog().logMessage(f"Failed to load '{serverDef[0]}' type: expected one of ({known_types})", meta.getAppName(), Qgis.Critical) continue _servers[s.name] = s
def showProgressDialog(self, text, length, handler): self._pgdialog = QProgressDialog(text, "Cancel", 0, length, self) self._pgdialog.setWindowTitle(getAppName()) self._pgdialog.setWindowModality(QtCore.Qt.WindowModal) self._pgdialog.canceled.connect(handler, type=QtCore.Qt.DirectConnection) self._pgdialog.forceShow()
def tr(self, string, **kwargs): return QCoreApplication.translate(meta.getAppName(), string)
def name(self): return self.tr(meta.getAppName())
def _translate(message): """ Tries to translate the given message within the GeoCat Bridge context. """ return QCoreApplication.translate(getAppName(), str(message))
def _log(message, level): """ Simple log wrapper function. """ if isinstance(message, Exception): message = str(message) _LOGGER.logMessage(message, getAppName(), level)
def group(self): return self.tr(meta.getAppName())