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()
Exemple #4
0
    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)
Exemple #5
0
    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)
Exemple #7
0
    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
Exemple #8
0
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()
Exemple #10
0
 def tr(self, string, **kwargs):
     return QCoreApplication.translate(meta.getAppName(), string)
Exemple #11
0
 def name(self):
     return self.tr(meta.getAppName())
Exemple #12
0
def _translate(message):
    """ Tries to translate the given message within the GeoCat Bridge context. """
    return QCoreApplication.translate(getAppName(), str(message))
Exemple #13
0
def _log(message, level):
    """ Simple log wrapper function. """
    if isinstance(message, Exception):
        message = str(message)
    _LOGGER.logMessage(message, getAppName(), level)
Exemple #14
0
 def group(self):
     return self.tr(meta.getAppName())