Example #1
0
    def save_dependency_file(self, fetcher_task):
        if fetcher_task.reply() is not None:
            # Write response to tmp file
            tmp_file = tempfile.mktemp()
            out_file = QFile(tmp_file)
            out_file.open(QIODevice.WriteOnly)
            out_file.write(fetcher_task.reply().readAll())
            out_file.close()

            dependency_base_path = os.path.join(os.path.expanduser('~'), 'Asistente-LADM_COL')
            if not os.path.exists(dependency_base_path):
                os.makedirs(dependency_base_path)

            try:
                with zipfile.ZipFile(tmp_file, "r") as zip_ref:
                    zip_ref.extractall(dependency_base_path)
            except zipfile.BadZipFile as e:
                self.qgis_utils.message_with_duration_emitted.emit(
                    QCoreApplication.translate("ReportGenerator", "There was an error with the download. The downloaded file is invalid."),
                    Qgis.Warning,
                    0)
            except PermissionError as e:
                self.qgis_utils.message_with_duration_emitted.emit(
                    QCoreApplication.translate("ReportGenerator", "Dependencies to generate reports couldn't be installed. Check if it is possible to write into this folder: <a href='file:///{path}'>{path}</a>").format(path=normalize_local_url(os.path.join(dependency_base_path), 'impresion')),
                    Qgis.Warning,
                    0)
            else:
                self.qgis_utils.message_with_duration_emitted.emit(
                    QCoreApplication.translate("ReportGenerator", "The dependency to generate reports is properly installed! Select plots and click again the button in the toolbar to generate reports."),
                    Qgis.Info,
                    0)

            try:
                os.remove(tmp_file)
            except:
                pass

        self._downloading = False
Example #2
0
    def testQgsSimpleFillSymbolLayer(self):
        """Create a new style from a .sld file and match test.
        """
        mTestName = 'QgsSimpleFillSymbolLayer'
        mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.sld' % (unitTestDataPath(), mTestName))

        mDoc = QDomDocument(mTestName)
        mFile = QFile(mFilePath)
        mFile.open(QIODevice.ReadOnly)
        mDoc.setContent(mFile, True)
        mFile.close()
        mSymbolLayer = QgsSimpleFillSymbolLayer.createFromSld(
            mDoc.elementsByTagName('PolygonSymbolizer').item(0).toElement())

        mExpectedValue = type(QgsSimpleFillSymbolLayer())
        mValue = type(mSymbolLayer)
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage

        mExpectedValue = Qt.SolidPattern
        mValue = mSymbolLayer.brushStyle()
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage

        mExpectedValue = '#ffaa7f'
        mValue = mSymbolLayer.strokeColor().name()
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage

        mExpectedValue = Qt.DotLine
        mValue = mSymbolLayer.strokeStyle()
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage

        mExpectedValue = 0.26
        mValue = mSymbolLayer.strokeWidth()
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage
    def uploadImage(self, pathToImage):
        img = QFile(pathToImage)
        img.open(QIODevice.ReadOnly)
        imgPart = QHttpPart()
        txt = 'form-data; name="file"; filename="' + os.path.basename(
            pathToImage) + '"'
        imgPart.setHeader(QNetworkRequest.ContentDispositionHeader, txt)
        imgPart.setHeader(QNetworkRequest.ContentTypeHeader, 'image/zip')
        imgPart.setBodyDevice(img)

        multiPart = QHttpMultiPart(QHttpMultiPart.FormDataType)
        multiPart.append(imgPart)

        url = self.baseurl + 'projectimage/upload.action?'

        response = self.http.request(url, method='POST', body=multiPart)
        if response[0]['status'] > 199 and response[0]['status'] < 210:
            # if icon upload was successfull, server returns id of the new icon
            # in it's database
            id = json.loads(response[1])['data']['id']
            return id
        else:
            return False
Example #4
0
    def testQgsSvgMarkerSymbolLayer(self):
        """
        Create a new style from a .sld file and match test
        """
        mTestName = 'QgsSvgMarkerSymbolLayer'
        mFilePath = QDir.toNativeSeparators('%s/symbol_layer/%s.sld' %
                                            (unitTestDataPath(), mTestName))

        mDoc = QDomDocument(mTestName)
        mFile = QFile(mFilePath)
        mFile.open(QIODevice.ReadOnly)
        mDoc.setContent(mFile, True)
        mFile.close()
        mSymbolLayer = QgsSvgMarkerSymbolLayer.createFromSld(
            mDoc.elementsByTagName('PointSymbolizer').item(0).toElement())

        mExpectedValue = type(QgsSvgMarkerSymbolLayer())
        mValue = type(mSymbolLayer)
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage

        mExpectedValue = 'skull.svg'
        mValue = os.path.basename(mSymbolLayer.path())
        print(("VALUE", mSymbolLayer.path()))
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage

        mExpectedValue = 12
        mValue = mSymbolLayer.size()
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage

        mExpectedValue = 45
        mValue = mSymbolLayer.angle()
        mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
        assert mExpectedValue == mValue, mMessage
    def exportDocument(self, task, fileName, format):
        """

        :type task: QUrl
        :type fileName: str
        :type format: self.ExportFormat
        :return: bool
        """
        fileOut = QFile(fileName)

        if not fileOut.open(QIODevice.WriteOnly | QIODevice.Text):
            return False

        taskMap = self.__parseTask(task)

        text = self.__documentContent(taskMap, format)
        streamFileOut = QTextStream(fileOut)
        streamFileOut.setCodec("UTF-8")
        streamFileOut << text
        streamFileOut.flush()

        fileOut.close()

        return True
    def parse_xml(self):
        """Parse the xml file. Returns false if there is failure."""
        xml_file = QFile(self._xml_path)
        if not xml_file.open(QIODevice.ReadOnly):
            return False

        document = QDomDocument()
        if not document.setContent(xml_file):
            return False

        xml_file.close()

        document_element = document.documentElement()
        if document_element.tagName() != 'qgis_style':
            return False

        # Get all the symbols
        self._symbols = []
        symbols_element = document_element.firstChildElement('symbols')
        symbol_element = symbols_element.firstChildElement()
        context = QgsReadWriteContext()
        context.setPathResolver(QgsProject.instance().pathResolver())
        while not symbol_element.isNull():
            if symbol_element.tagName() == 'symbol':
                symbol = QgsSymbolLayerUtils.loadSymbol(
                    symbol_element, context)
                if symbol:
                    self._symbols.append({
                        'name':
                        symbol_element.attribute('name'),
                        'symbol':
                        symbol
                    })
            symbol_element = symbol_element.nextSiblingElement()

        return True
Example #7
0
    def load_aoi_from_file(self):
        path, _ = QFileDialog.getOpenFileName(self, "Open GeoJSON AOI file",
                                              QDir.homePath(),
                                              "JSON (*.json);;All Files (*)")
        file = QFile(path)
        if not file.open(QFile.ReadOnly | QFile.Text):
            return

        inf = QTextStream(file)
        json_txt = inf.readAll()

        try:
            json_obj = json.loads(json_txt)
        except ValueError:
            # noinspection PyUnresolvedReferences
            self._show_message('GeoJSON from file invalid',
                               level=Qgis.Warning,
                               duration=10)
            return

        json_geom = geometry_from_json(json_obj)

        if not json_geom:
            # noinspection PyUnresolvedReferences
            self._show_message('GeoJSON geometry from file invalid',
                               level=Qgis.Warning,
                               duration=10)
            return

        geom: QgsGeometry = qgsgeometry_from_geojson(json_geom)
        self._aoi_box.setToGeometry(geom,
                                    QgsCoordinateReferenceSystem("EPSG:4326"))

        self.leAOI.setText(json.dumps(json_geom))

        self.zoom_to_aoi()
Example #8
0
    def installFromZipFile(self):
        settings = QSettings()
        lastDirectory = settings.value(
            '/Qgis/plugin-installer/lastZipDirectory', '.')
        filePath, _ = QFileDialog.getOpenFileName(
            iface.mainWindow(), self.tr('Open file'), lastDirectory,
            self.tr('Plugin packages (*.zip *.ZIP)'))
        if filePath == '':
            return

        settings.setValue('/Qgis/plugin-installer/lastZipDirectory',
                          QFileInfo(filePath).absoluteDir().absolutePath())

        error = False
        infoString = None

        with zipfile.ZipFile(filePath, 'r') as zf:
            pluginName = os.path.split(zf.namelist()[0])[0]

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

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

        # If the target directory already exists as a link,
        # remove the link without resolving
        QFile(os.path.join(pluginsDirectory, pluginFileName)).remove()

        try:
            # Test extraction. If fails, then exception will be raised
            # and no removing occurs
            unzip(str(filePath), str(pluginsDirectory))
            # Removing old plugin files if exist
            removeDir(
                QDir.cleanPath(os.path.join(pluginsDirectory, pluginFileName)))
            # Extract new files
            unzip(str(filePath), str(pluginsDirectory))
        except:
            error = True
            infoString = (
                self.tr("Plugin installation failed"),
                self.
                tr("Failed to unzip the plugin package\n{}.\nProbably it is broken"
                   .format(zipFilePath)))

        if infoString is None:
            updateAvailablePlugins()
            loadPlugin(pluginName)
            plugins.getAllInstalled(testLoad=True)
            plugins.rebuild()
            plugin = plugins.all()[pluginName]

            if settings.contains('/PythonPlugins/' + pluginName):
                if settings.value('/PythonPlugins/' + pluginName, False, bool):
                    startPlugin(pluginName)
                    reloadPlugin(pluginName)
                else:
                    unloadPlugin(pluginName)
                    loadPlugin(pluginName)
            else:
                if startPlugin(pluginName):
                    settings.setValue('/PythonPlugins/' + pluginName, True)
            infoString = (self.tr("Plugin installed successfully"), "")

        if infoString[0]:
            level = error and QgsMessageBar.CRITICAL or QgsMessageBar.INFO
            msg = "<b>%s:</b>%s" % (infoString[0], infoString[1])
            iface.messageBar().pushMessage(msg, level)
Example #9
0
    def upload_files(self, layer, field_index, features):
        """
        Upload given features' source files to remote server and return a dict
        formatted as changeAttributeValues expects to update 'datos' attribute
        to a remote location.
        """
        if not QSettings().value(
                'Asistente-LADM_COL/sources/document_repository', False, bool):
            self.message_with_duration_emitted.emit(
                QCoreApplication.translate(
                    "SourceHandler",
                    "The source files were not uploaded to the document repository because you have that option unchecked. You can still upload the source files later using the 'Upload Pending Source Files' menu."
                ), Qgis.Info, 10)
            return dict()

        # Test if we have Internet connection and a valid service
        dlg = self.qgis_utils.get_settings_dialog()
        res, msg = dlg.is_source_service_valid()

        if not res:
            msg['text'] = QCoreApplication.translate(
                "SourceHandler",
                "No file could be uploaded to the document repository. You can do it later from the 'Upload Pending Source Files' menu. Reason: {}"
            ).format(msg['text'])
            self.message_with_duration_emitted.emit(
                msg['text'], Qgis.Info,
                20)  # The data is still saved, so always show Info msg
            return dict()

        file_features = [
            feature for feature in features if not feature[field_index] == NULL
            and os.path.isfile(feature[field_index])
        ]
        total = len(features)
        not_found = total - len(file_features)

        upload_dialog = UploadProgressDialog(len(file_features), not_found)
        upload_dialog.show()
        count = 0
        upload_errors = 0
        new_values = dict()

        for feature in file_features:
            data_url = feature[field_index]
            file_name = os.path.basename(data_url)

            nam = QNetworkAccessManager()
            #reply.downloadProgress.connect(upload_dialog.update_current_progress)

            multiPart = QHttpMultiPart(QHttpMultiPart.FormDataType)
            textPart = QHttpPart()
            textPart.setHeader(QNetworkRequest.ContentDispositionHeader,
                               QVariant("form-data; name=\"driver\""))
            textPart.setBody(QByteArray().append('Local'))

            filePart = QHttpPart()
            filePart.setHeader(
                QNetworkRequest.ContentDispositionHeader,
                QVariant("form-data; name=\"file\"; filename=\"{}\"".format(
                    file_name)))
            file = QFile(data_url)
            file.open(QIODevice.ReadOnly)

            filePart.setBodyDevice(file)
            file.setParent(
                multiPart
            )  # we cannot delete the file now, so delete it with the multiPart

            multiPart.append(filePart)
            multiPart.append(textPart)

            service_url = '/'.join([
                QSettings().value(
                    'Asistente-LADM_COL/sources/service_endpoint',
                    DEFAULT_ENDPOINT_SOURCE_SERVICE),
                SOURCE_SERVICE_UPLOAD_SUFFIX
            ])
            request = QNetworkRequest(QUrl(service_url))
            reply = nam.post(request, multiPart)
            #reply.uploadProgress.connect(upload_dialog.update_current_progress)
            reply.error.connect(self.error_returned)
            multiPart.setParent(reply)

            # We'll block execution until we get response from the server
            loop = QEventLoop()
            reply.finished.connect(loop.quit)
            loop.exec_()

            response = reply.readAll()
            data = QTextStream(response, QIODevice.ReadOnly)
            content = data.readAll()

            if content is None:
                self.log.logMessage(
                    "There was an error uploading file '{}'".format(data_url),
                    PLUGIN_NAME, Qgis.Critical)
                upload_errors += 1
                continue

            try:
                response = json.loads(content)
            except json.decoder.JSONDecodeError:
                self.log.logMessage(
                    "Couldn't parse JSON response from server for file '{}'!!!"
                    .format(data_url), PLUGIN_NAME, Qgis.Critical)
                upload_errors += 1
                continue

            if 'error' in response:
                self.log.logMessage(
                    "STATUS: {}. ERROR: {} MESSAGE: {} FILE: {}".format(
                        response['status'], response['error'],
                        response['message'], data_url), PLUGIN_NAME,
                    Qgis.Critical)
                upload_errors += 1
                continue

            reply.deleteLater()

            if 'url' not in response:
                self.log.logMessage(
                    "'url' attribute not found in JSON response for file '{}'!"
                    .format(data_url), PLUGIN_NAME, Qgis.Critical)
                upload_errors += 1
                continue

            url = self.get_file_url(response['url'])
            new_values[feature.id()] = {field_index: url}

            count += 1
            upload_dialog.update_total_progress(count)

        if not_found > 0:
            self.message_with_duration_emitted.emit(
                QCoreApplication.translate(
                    "SourceHandler",
                    "{} out of {} records {} not uploaded to the document repository because {} file path is NULL or it couldn't be found in the local disk!"
                ).format(
                    not_found, total,
                    QCoreApplication.translate("SourceHandler", "was")
                    if not_found == 1 else QCoreApplication.translate(
                        "SourceHandler", "were"),
                    QCoreApplication.translate("SourceHandler", "its")
                    if not_found == 1 else QCoreApplication.translate(
                        "SourceHandler", "their")), Qgis.Info, 0)
        if len(new_values):
            self.message_with_duration_emitted.emit(
                QCoreApplication.translate(
                    "SourceHandler",
                    "{} out of {} files {} uploaded to the document repository and {} remote location stored in the database!"
                ).format(
                    len(new_values), total,
                    QCoreApplication.translate("SourceHandler", "was")
                    if len(new_values) == 1 else QCoreApplication.translate(
                        "SourceHandler", "were"),
                    QCoreApplication.translate("SourceHandler", "its")
                    if len(new_values) == 1 else QCoreApplication.translate(
                        "SourceHandler", "their")), Qgis.Info, 0)
        if upload_errors:
            self.message_with_duration_emitted.emit(
                QCoreApplication.translate(
                    "SourceHandler",
                    "{} out of {} files could not be uploaded to the document repository because of upload errors! See log for details."
                ).format(upload_errors, total), Qgis.Info, 0)

        return new_values
Example #10
0
    def download(self):
        """Downloading the file.

        :returns: True if success, otherwise returns a tuple with format like
            this (QNetworkReply.NetworkError, error_message)

        :raises: IOError - when cannot create output_path
        """
        # Prepare output path
        self.output_file = QFile(self.output_path)
        if not self.output_file.open(QFile.WriteOnly):
            raise IOError(self.output_file.errorString())

        # Prepare downloaded buffer
        self.downloaded_file_buffer = QByteArray()

        # Request the url
        request = QNetworkRequest(self.url)
        self.reply = self.manager.get(request)
        self.reply.readyRead.connect(self.get_buffer)
        self.reply.finished.connect(self.write_data)
        self.manager.requestTimedOut.connect(self.request_timeout)

        if self.progress_dialog:
            # progress bar
            def progress_event(received, total):
                """Update progress.

                :param received: Data received so far.
                :type received: int

                :param total: Total expected data.
                :type total: int
                """
                # noinspection PyArgumentList
                QgsApplication.processEvents()

                self.progress_dialog.adjustSize()

                human_received = humanize_file_size(received)
                human_total = humanize_file_size(total)

                label_text = tr(
                    "%s : %s of %s" %
                    (self.prefix_text, human_received, human_total))

                self.progress_dialog.setLabelText(label_text)
                self.progress_dialog.setMaximum(total)
                self.progress_dialog.setValue(received)

            # cancel
            def cancel_action():
                """Cancel download."""
                self.reply.abort()
                self.reply.deleteLater()

            self.reply.downloadProgress.connect(progress_event)
            self.progress_dialog.canceled.connect(cancel_action)

        # Wait until finished
        # On Windows 32bit AND QGIS 2.2, self.reply.isFinished() always
        # returns False even after finished slot is called. So, that's why we
        # are adding self.finished_flag (see #864)
        while not self.reply.isFinished() and not self.finished_flag:
            # noinspection PyArgumentList
            QgsApplication.processEvents()

        result = self.reply.error()
        try:
            http_code = int(
                self.reply.attribute(QNetworkRequest.HttpStatusCodeAttribute))
        except TypeError:
            # If the user cancels the request, the HTTP response will be None.
            http_code = None

        self.reply.abort()
        self.reply.deleteLater()

        if result == QNetworkReply.NoError:
            return True, None

        elif result == QNetworkReply.UnknownNetworkError:
            return False, tr(
                'The network is unreachable. Please check your internet '
                'connection.')

        elif http_code == 408:
            msg = tr('Sorry, the server aborted your request. '
                     'Please try a smaller area.')
            LOGGER.debug(msg)
            return False, msg

        elif http_code == 509:
            msg = tr(
                'Sorry, the server is currently busy with another request. '
                'Please try again in a few minutes.')
            LOGGER.debug(msg)
            return False, msg

        elif result == QNetworkReply.ProtocolUnknownError or \
                result == QNetworkReply.HostNotFoundError:
            # See http://doc.qt.io/qt-5/qurl-obsolete.html#encodedHost
            encoded_host = self.url.toAce(self.url.host())
            LOGGER.exception('Host not found : %s' % encoded_host)
            return False, tr(
                'Sorry, the server is unreachable. Please try again later.')

        elif result == QNetworkReply.ContentNotFoundError:
            LOGGER.exception('Path not found : %s' % self.url.path())
            return False, tr('Sorry, the layer was not found on the server.')

        else:
            return result, self.reply.errorString()
Example #11
0
    def getInstalledPlugin(self, key, path, readOnly):
        """ get the metadata of an installed plugin """
        def metadataParser(fct):
            """ plugin metadata parser reimplemented from qgis.utils
                for better control on wchich module is examined
                in case there is an installed plugin masking a core one """
            global errorDetails
            cp = configparser.ConfigParser()
            try:
                with codecs.open(metadataFile, "r", "utf8") as f:
                    cp.read_file(f)
                return cp.get('general', fct)
            except Exception as e:
                if not errorDetails:
                    errorDetails = e.args[0]  # set to the first problem
                return ""

        def pluginMetadata(fct):
            """ calls metadataParser for current l10n.
                If failed, fallbacks to the standard metadata """
            locale = QLocale.system().name()
            if locale and fct in translatableAttributes:
                value = metadataParser("{}[{}]".format(fct, locale))
                if value:
                    return value
                value = metadataParser("{}[{}]".format(fct,
                                                       locale.split("_")[0]))
                if value:
                    return value
            return metadataParser(fct)

        if not QDir(path).exists():
            return

        global errorDetails  # to communicate with the metadataParser fn
        plugin = dict()
        error = ""
        errorDetails = ""
        version = None

        if not os.path.exists(os.path.join(path, '__init__.py')):
            error = "broken"
            errorDetails = QCoreApplication.translate("QgsPluginInstaller",
                                                      "Missing __init__.py")

        metadataFile = os.path.join(path, 'metadata.txt')
        if os.path.exists(metadataFile):
            version = normalizeVersion(pluginMetadata("version"))

        if version:
            qgisMinimumVersion = pluginMetadata("qgisMinimumVersion").strip()
            if not qgisMinimumVersion:
                qgisMinimumVersion = "0"
            qgisMaximumVersion = pluginMetadata("qgisMaximumVersion").strip()
            if not qgisMaximumVersion:
                qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
            # if compatible, add the plugin to the list
            if not isCompatible(pyQgisVersion(), qgisMinimumVersion,
                                qgisMaximumVersion):
                error = "incompatible"
                errorDetails = "{} - {}".format(qgisMinimumVersion,
                                                qgisMaximumVersion)
        elif not os.path.exists(metadataFile):
            error = "broken"
            errorDetails = QCoreApplication.translate("QgsPluginInstaller",
                                                      "Missing metadata file")
        else:
            error = "broken"
            e = errorDetails
            errorDetails = QCoreApplication.translate(
                "QgsPluginInstaller", u"Error reading metadata")
            if e:
                errorDetails += ": " + e

        if not version:
            version = "?"

        if error[:16] == "No module named ":
            mona = error.replace("No module named ", "")
            if mona != key:
                error = "dependent"
                errorDetails = mona

        icon = pluginMetadata("icon")
        if QFileInfo(icon).isRelative():
            icon = path + "/" + icon

        changelog = pluginMetadata("changelog")
        changelogFile = os.path.join(path, "CHANGELOG")
        if not changelog and QFile(changelogFile).exists():
            with open(changelogFile) as f:
                changelog = f.read()

        plugin = {
            "id":
            key,
            "plugin_id":
            None,
            "name":
            pluginMetadata("name") or key,
            "description":
            pluginMetadata("description"),
            "about":
            pluginMetadata("about"),
            "icon":
            icon,
            "category":
            pluginMetadata("category"),
            "tags":
            pluginMetadata("tags"),
            "changelog":
            changelog,
            "author_name":
            pluginMetadata("author_name") or pluginMetadata("author"),
            "author_email":
            pluginMetadata("email"),
            "homepage":
            pluginMetadata("homepage"),
            "tracker":
            pluginMetadata("tracker"),
            "code_repository":
            pluginMetadata("repository"),
            "version_installed":
            version,
            "library":
            path,
            "pythonic":
            True,
            "experimental":
            pluginMetadata("experimental").strip().upper() in ["TRUE", "YES"],
            "deprecated":
            pluginMetadata("deprecated").strip().upper() in ["TRUE", "YES"],
            "trusted":
            False,
            "version_available":
            "",
            "zip_repository":
            "",
            "download_url":
            path,  # warning: local path as url!
            "filename":
            "",
            "downloads":
            "",
            "average_vote":
            "",
            "rating_votes":
            "",
            "available":
            False,  # Will be overwritten, if any available version found.
            "installed":
            True,
            "status":
            "orphan",  # Will be overwritten, if any available version found.
            "error":
            error,
            "error_details":
            errorDetails,
            "readonly":
            readOnly
        }
        return plugin
Example #12
0
    def saveTemplate(self):
        """
        Creates and saves a new document template.
        """
        # Validate if the user has specified the data source

        if not LayoutUtils.get_stdm_data_source_for_layout(self.composition()):
            QMessageBox.critical(
                self.mainWindow(),
                QApplication.translate("ComposerWrapper", "Error"),
                QApplication.translate(
                    "ComposerWrapper", "Please specify the "
                    "data source name for the document composition."))
            return

        # Assert if the referenced table name has been set
        if not LayoutUtils.get_stdm_referenced_table_for_layout(
                self.composition()):
            QMessageBox.critical(
                self.mainWindow(),
                QApplication.translate("ComposerWrapper", "Error"),
                QApplication.translate(
                    "ComposerWrapper", "Please specify the "
                    "referenced table name for the selected data source."))
            return

        # If it is a new unsaved document template then prompt for the document name.
        #template_path = self.composition().customProperty('variable_template_path', None)
        template_path = self.variable_template_path

        if template_path is None:
            docName, ok = QInputDialog.getText(
                self.mainWindow(),
                QApplication.translate("ComposerWrapper", "Template Name"),
                QApplication.translate("ComposerWrapper",
                                       "Please enter the template name below"),
            )

            if not ok:
                return

            if ok and not docName:
                QMessageBox.critical(
                    self.mainWindow(),
                    QApplication.translate("ComposerWrapper", "Error"),
                    QApplication.translate("ComposerWrapper",
                                           "Please enter a template name!"))
                self.saveTemplate()

            if ok and docName:
                templateDir = self._composerTemplatesPath()

                if templateDir is None:
                    QMessageBox.critical(
                        self.mainWindow(),
                        QApplication.translate("ComposerWrapper", "Error"),
                        QApplication.translate(
                            "ComposerWrapper",
                            "Directory for document templates cannot not be found."
                        ))

                    return

                absPath = templateDir + "/" + docName + ".sdt"

                # Check if there is an existing document with the same name
                caseInsenDic = CaseInsensitiveDict(documentTemplates())
                if docName in caseInsenDic:
                    result = QMessageBox.warning(
                        self.mainWindow(),
                        QApplication.translate("ComposerWrapper",
                                               "Existing Template"),
                        "'{0}' {1}.\nDo you want to replace the "
                        "existing template?".format(
                            docName,
                            QApplication.translate("ComposerWrapper",
                                                   "already exists")),
                        QMessageBox.Yes | QMessageBox.No)

                    if result != QMessageBox.Yes:
                        return
                    else:
                        # Delete the existing template
                        delFile = QFile(absPath)
                        remove_status = delFile.remove()
                        if not remove_status:
                            QMessageBox.critical(
                                self.mainWindow(),
                                QApplication.translate("ComposerWrapper",
                                                       "Delete Error"),
                                "'{0}' {1}.".format(
                                    docName,
                                    QApplication.translate(
                                        "ComposerWrapper",
                                        "template could not be removed by the system,"
                                        " please remove it manually from the document templates directory."
                                    )))
                            return

                docFile = QFile(absPath)
                template_path = absPath
        else:
            docFile = QFile(template_path)

            # else:
            # return

        docFileInfo = QFileInfo(docFile)

        if not docFile.open(QIODevice.WriteOnly):
            QMessageBox.critical(
                self.mainWindow(),
                QApplication.translate("ComposerWrapper",
                                       "Save Operation Error"),
                "{0}\n{1}".format(
                    QApplication.translate("ComposerWrapper",
                                           "Could not save template file."),
                    docFile.errorString()))

            return

        templateDoc = QDomDocument()
        template_name = docFileInfo.completeBaseName()

        # Catch exception raised when writing items' elements
        try:
            self._writeXML(templateDoc, template_name)
        except DummyException as exc:
            msg = str(exc)
            QMessageBox.critical(
                self.mainWindow(),
                QApplication.translate("ComposerWrapper", "Save Error"), msg)
            docFile.close()
            docFile.remove()

            return

        if docFile.write(templateDoc.toByteArray()) == -1:
            QMessageBox.critical(
                self.mainWindow(),
                QApplication.translate("ComposerWrapper", "Save Error"),
                QApplication.translate("ComposerWrapper",
                                       "Could not save template file."))

            return

        else:
            self.mainWindow().setWindowTitle(template_name)

        self.composition().setCustomProperty('variable_template_path',
                                             template_path)

        docFile.close()
Example #13
0
 def read_cached_dfd_qlr(self):
     #return file(unicode(self.cached_kf_qlr_filename)).read()
     f = QFile(self.cached_dfd_qlr_filename)
     f.open(QIODevice.ReadOnly)
     return f.readAll()
Example #14
0
    def parse_xml(self):
        """Parse the xml file. Returns false if there is failure."""
        xml_file = QFile(self._xml_path)
        if not xml_file.open(QIODevice.ReadOnly):
            return False

        document = QDomDocument()
        if not document.setContent(xml_file):
            return False

        xml_file.close()

        document_element = document.documentElement()
        if document_element.tagName() != "qgis_style":
            return False

        # Get all the symbols
        self._symbols = []
        symbols_element = document_element.firstChildElement("symbols")
        symbol_element = symbols_element.firstChildElement()
        context = QgsReadWriteContext()
        context.setPathResolver(QgsProject.instance().pathResolver())
        while not symbol_element.isNull():
            if symbol_element.tagName() == "symbol":
                symbol = QgsSymbolLayerUtils.loadSymbol(
                    symbol_element, context)
                if symbol:
                    self._symbols.append({
                        "name":
                        symbol_element.attribute("name"),
                        "symbol":
                        symbol
                    })
            symbol_element = symbol_element.nextSiblingElement()

        # Get all the colorramps
        self._colorramps = []
        ramps_element = document_element.firstChildElement("colorramps")
        ramp_element = ramps_element.firstChildElement()
        while not ramp_element.isNull():
            if ramp_element.tagName() == "colorramp":
                colorramp = QgsSymbolLayerUtils.loadColorRamp(ramp_element)
                if colorramp:
                    self._colorramps.append({
                        "name":
                        ramp_element.attribute("name"),
                        "colorramp":
                        colorramp
                    })

            ramp_element = ramp_element.nextSiblingElement()

        # Get all the TextFormats - textformats - textformat
        self._textformats = []
        textformats_element = document_element.firstChildElement("textformats")
        textformat_element = textformats_element.firstChildElement()
        while not textformat_element.isNull():
            if textformat_element.tagName() == "textformat":
                textformat = QgsTextFormat()
                textformat.readXml(textformat_element, QgsReadWriteContext())
                if textformat:
                    self._textformats.append({
                        "name":
                        textformat_element.attribute("name"),
                        "textformat":
                        textformat,
                    })
            textformat_element = textformat_element.nextSiblingElement()

        # Get all the LabelSettings - labelsettings - labelsetting -
        #  QgsPalLayerSettings.readXML?
        self._labelsettings = []
        labels_element = document_element.firstChildElement("labelsettings")
        label_element = labels_element.firstChildElement()

        while not label_element.isNull():
            if label_element.tagName() == "labelsetting":
                labelsettings = QgsPalLayerSettings()
                labelsettings.readXml(label_element, QgsReadWriteContext())
                if labelsettings:
                    self._labelsettings.append({
                        "name":
                        label_element.attribute("name"),
                        "labelsettings":
                        labelsettings,
                    })
            label_element = label_element.nextSiblingElement()
        return True
 def _download_file(self, url, out_path):
     reply = self.__sync_request(url)
     local_file = QFile(out_path)
     local_file.open(QIODevice.WriteOnly)
     local_file.write(reply)
     local_file.close()
    def sendOutputFile(self, handler):
        format_dict = WFSFormats[self.format]

        # read the GML
        gml_path = join(self.tempdir, '{}.gml'.format(self.filename))
        output_layer = QgsVectorLayer(gml_path, 'qgis_server_wfs_features',
                                      'ogr')

        # Temporary file where to write the output
        temporary = QTemporaryFile(
            join(QDir.tempPath(),
                 'request-WFS-XXXXXX.{}'.format(format_dict['filenameExt'])))
        temporary.open()
        output_file = temporary.fileName()
        temporary.close()

        if output_layer.isValid():
            try:
                # create save options
                options = QgsVectorFileWriter.SaveVectorOptions()
                # driver name
                options.driverName = format_dict['ogrProvider']
                # file encoding
                options.fileEncoding = 'utf-8'

                # coordinate transformation
                if format_dict['forceCRS']:
                    options.ct = QgsCoordinateTransform(
                        output_layer.crs(),
                        QgsCoordinateReferenceSystem(format_dict['forceCRS']),
                        QgsProject.instance())

                # datasource options
                if format_dict['ogrDatasourceOptions']:
                    options.datasourceOptions = format_dict[
                        'ogrDatasourceOptions']

                # write file
                if Qgis.QGIS_VERSION_INT >= 31003:
                    write_result, error_message = QgsVectorFileWriter.writeAsVectorFormatV2(
                        output_layer, output_file,
                        QgsProject.instance().transformContext(), options)
                else:
                    write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
                        output_layer, output_file, options)

                if write_result != QgsVectorFileWriter.NoError:
                    handler.appendBody(b'')
                    self.logger.critical(error_message)
                    return False

            except Exception as e:
                handler.appendBody(b'')
                self.logger.critical(str(e))
                return False

            if format_dict['zip']:
                # compress files
                import zipfile
                # noinspection PyBroadException
                try:
                    import zlib  # NOQA
                    compression = zipfile.ZIP_DEFLATED
                except Exception:
                    compression = zipfile.ZIP_STORED

                # create the zip file
                zip_file_path = join(self.tempdir, '%s.zip' % self.filename)
                with zipfile.ZipFile(zip_file_path, 'w') as zf:
                    # add all files
                    zf.write(join(
                        self.tempdir,
                        '%s.%s' % (self.filename, format_dict['filenameExt'])),
                             compress_type=compression,
                             arcname='%s.%s' %
                             (self.typename, format_dict['filenameExt']))

                    for e in format_dict['extToZip']:
                        file_path = join(self.tempdir,
                                         '%s.%s' % (self.filename, e))
                        if exists(file_path):
                            zf.write(file_path,
                                     compress_type=compression,
                                     arcname='%s.%s' % (self.typename, e))

                    zf.close()

                f = QFile(zip_file_path)
                if f.open(QFile.ReadOnly):
                    ba = f.readAll()
                    handler.appendBody(ba)
                    return True

            else:
                # return the file created without zip
                f = QFile(output_file)
                if f.open(QFile.ReadOnly):
                    ba = f.readAll()
                    handler.appendBody(ba)
                    return True

        handler.appendBody(b'')
        self.logger.critical('Error no output file')
        return False
    def requestFinished(self):
        reply = self.sender()
        self.buttonBox.setEnabled(False)
        if reply.error() != QNetworkReply.NoError:
            self.mResult = reply.errorString()
            if reply.error() == QNetworkReply.OperationCanceledError:
                self.mResult += "<br/><br/>" + QCoreApplication.translate(
                    "QgsPluginInstaller",
                    "If you haven't canceled the download manually, it might be caused by a timeout. In this case consider increasing the connection timeout value in QGIS options."
                )
            self.reject()
            reply.deleteLater()
            return
        elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 301:
            redirectionUrl = reply.attribute(
                QNetworkRequest.RedirectionTargetAttribute)
            self.redirectionCounter += 1
            if self.redirectionCounter > 4:
                self.mResult = QCoreApplication.translate(
                    "QgsPluginInstaller", "Too many redirections")
                self.reject()
                reply.deleteLater()
                return
            else:
                if redirectionUrl.isRelative():
                    redirectionUrl = reply.url().resolved(redirectionUrl)
                # Fire a new request and exit immediately in order to quietly destroy the old one
                self.url = redirectionUrl
                self.requestDownloading()
                reply.deleteLater()
                return

        self.file.open(QFile.WriteOnly)
        self.file.write(reply.readAll())
        self.file.close()
        self.stateChanged(0)
        reply.deleteLater()
        pluginDir = qgis.utils.home_plugin_path
        tmpPath = self.file.fileName()
        # make sure that the parent directory exists
        if not QDir(pluginDir).exists():
            QDir().mkpath(pluginDir)
        # if the target directory already exists as a link, remove the link without resolving:
        QFile(pluginDir + str(QDir.separator()) + self.plugin["id"]).remove()
        try:
            unzip(
                str(tmpPath), str(pluginDir)
            )  # test extract. If fails, then exception will be raised and no removing occurs
            # removing old plugin files if exist
            removeDir(QDir.cleanPath(
                pluginDir + "/" +
                self.plugin["id"]))  # remove old plugin if exists
            unzip(str(tmpPath), str(pluginDir))  # final extract.
        except:
            self.mResult = self.tr(
                "Failed to unzip the plugin package. Probably it's broken or missing from the repository. You may also want to make sure that you have write permission to the plugin directory:"
            ) + "\n" + pluginDir
            self.reject()
            return
        try:
            # cleaning: removing the temporary zip file
            QFile(tmpPath).remove()
        except:
            pass
        self.close()
Example #18
0
                    cfg["Value"] = "value_fr"
                    layer.editFormConfig().setWidgetConfig(idx, cfg)
            # value maps
            if layer.editFormConfig().widgetType(idx) == 'ValueMap':
                cfg = layer.editFormConfig().widgetConfig(idx)
                for key in cfg.keys():
                    trans = get_table_translation(cur, cfg[key])
                    if trans:
                        cfg[trans] = cfg[key]
                        del cfg[key]
                layer.editFormConfig().setWidgetConfig(idx, cfg)

# update styles from other project
if 'style_file' in config_data:
    errMsg = ''
    file = QFile(config_data['style_file'])
    file.open(QFile.ReadOnly | QFile.Text)
    doc = QDomDocument()
    doc.setContent(file)
    root = doc.elementsByTagName('qgis.custom.style')
    nodes = root.at(0).childNodes()
    for i in range(0, nodes.count()):
        elem = nodes.at(i).toElement()
        if elem.tagName() != 'layer' or not elem.hasAttribute('id'):
            continue
        layer_id = elem.attribute('id')
        if layer_id not in style_layer_ids:
            print('skipping ', layer_id)
        layer = QgsProject.instance().mapLayer(layer_id)
        if not layer:
            print('layer not found', layer_id)
Example #19
0
def foreign_key_parent_tables(table_name, search_parent=True, filter_exp=None):
    """
    Function that searches for foreign key references in the specified table.
    :param table_name: Name of the database table.
    :type table_name: str
    :param search_parent: Select True if table_name is the child and
    parent tables are to be retrieved, else child tables will be
    returned.
    :type search_parent: bool
    :param filter_exp: A regex expression to filter related table names.
    :type filter_exp: QRegExp
    :return: A list of tuples containing the local column name, foreign table
    name, corresponding foreign column name and constraint name.
    :rtype: list
    """
    # Check if the view for listing foreign key references exists
    fk_ref_view = pg_table_exists("foreign_key_references")

    # Create if it does not exist
    if not fk_ref_view:
        script_path = PLUGIN_DIR + "/scripts/foreign_key_references.sql"

        script_file = QFile(script_path)
        if script_file.exists():
            if not script_file.open(QIODevice.ReadOnly):
                return None

            reader = QTextStream(script_file)
            sql = reader.readAll()
            if sql:
                t = text(sql)
                _execute(t)

        else:
            return None

    if search_parent:
        ref_table = "foreign_table_name"
        search_table = "table_name"
    else:
        ref_table = "table_name"
        search_table = "foreign_table_name"

    # Fetch foreign key references
    sql = "SELECT column_name,{0},foreign_column_name, constraint_name FROM " \
          "foreign_key_references where {1} =:tb_name".format(ref_table,
                                                               search_table)

    t = text(sql)
    result = _execute(t, tb_name=table_name)

    fk_refs = []

    for r in result:
        rel_table = r[ref_table]

        fk_ref = r["column_name"], rel_table, \
                 r["foreign_column_name"], r["constraint_name"]

        if not filter_exp is None:
            if filter_exp.indexIn(rel_table) >= 0:
                fk_refs.append(fk_ref)

                continue

        fk_refs.append(fk_ref)

    return fk_refs
Example #20
0
    def installFromZipFile(self, filePath):
        if not os.path.isfile(filePath):
            return

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

        error = False
        infoString = None

        with zipfile.ZipFile(filePath, 'r') as zf:
            pluginName = os.path.split(zf.namelist()[0])[0]

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

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

        # If the target directory already exists as a link,
        # remove the link without resolving
        QFile(os.path.join(pluginsDirectory, pluginFileName)).remove()

        try:
            # Test extraction. If fails, then exception will be raised
            # and no removing occurs
            unzip(str(filePath), str(pluginsDirectory))
            # Removing old plugin files if exist
            removeDir(
                QDir.cleanPath(os.path.join(pluginsDirectory, pluginFileName)))
            # Extract new files
            unzip(str(filePath), str(pluginsDirectory))
        except:
            error = True
            infoString = (
                self.tr("Plugin installation failed"),
                self.
                tr("Failed to unzip the plugin package\n{}.\nProbably it is broken"
                   .format(filePath)))

        if infoString is None:
            updateAvailablePlugins()
            loadPlugin(pluginName)
            plugins.getAllInstalled()
            plugins.rebuild()
            self.exportPluginsToManager()

            if settings.contains('/PythonPlugins/' + pluginName):
                if settings.value('/PythonPlugins/' + pluginName, False, bool):
                    startPlugin(pluginName)
                    reloadPlugin(pluginName)
                else:
                    unloadPlugin(pluginName)
                    loadPlugin(pluginName)
            else:
                if startPlugin(pluginName):
                    settings.setValue('/PythonPlugins/' + pluginName, True)
            infoString = (self.tr("Plugin installed successfully"), "")

        if infoString[0]:
            level = error and QgsMessageBar.CRITICAL or QgsMessageBar.INFO
            msg = "<b>%s</b>" % infoString[0]
            if infoString[1]:
                msg += "<b>:</b> %s" % infoString[1]
            iface.pluginManagerInterface().pushMessage(msg, level)
    def installFromZipFile(self, filePath):
        if not os.path.isfile(filePath):
            return

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

        with zipfile.ZipFile(filePath, 'r') as zf:
            pluginName = os.path.split(zf.namelist()[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:
            updateAvailablePlugins()
            self.processDependencies(pluginName)
            loadPlugin(pluginName)
            plugins.getAllInstalled()
            plugins.rebuild()

            if settings.contains('/PythonPlugins/' + pluginName):
                if settings.value('/PythonPlugins/' + pluginName, False, bool):
                    startPlugin(pluginName)
                    reloadPlugin(pluginName)
                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)
Example #22
0
    def sendOutputFile(self, handler):
        formatDict = WFSFormats[self.format]
        # read the GML
        outputLayer = QgsVectorLayer(
            os.path.join(self.tempdir, '%s.gml' % self.filename),
            'qgis_server_wfs_features', 'ogr')
        if outputLayer.isValid():
            try:
                # create save options
                options = QgsVectorFileWriter.SaveVectorOptions()
                # driver name
                options.driverName = formatDict['ogrProvider']
                # file encoding
                options.fileEncoding = 'utf-8'
                # coordinate transformation
                if formatDict['forceCRS']:
                    options.ct = QgsCoordinateTransform(
                        outputLayer.crs(),
                        QgsCoordinateReferenceSystem(formatDict['forceCRS']),
                        QgsProject.instance())
                # datasource options
                if formatDict['ogrDatasourceOptions']:
                    options.datasourceOptions = formatDict[
                        'ogrDatasourceOptions']

                # write file
                write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
                    outputLayer,
                    os.path.join(
                        self.tempdir,
                        '%s.%s' % (self.filename, formatDict['filenameExt'])),
                    options)
                if write_result != QgsVectorFileWriter.NoError:
                    handler.appendBody(b'')
                    QgsMessageLog.logMessage(error_message,
                                             "wfsOutputExtension",
                                             Qgis.Critical)
                    return False
            except Exception as e:
                handler.appendBody(b'')
                QgsMessageLog.logMessage(str(e), "wfsOutputExtension",
                                         Qgis.Critical)
                return False

            if formatDict['zip']:
                # compress files
                import zipfile
                try:
                    import zlib
                    compression = zipfile.ZIP_DEFLATED
                except:
                    compression = zipfile.ZIP_STORED
                # create the zip file
                with zipfile.ZipFile(
                        os.path.join(self.tempdir, '%s.zip' % self.filename),
                        'w') as zf:
                    # add all files
                    zf.write(os.path.join(
                        self.tempdir,
                        '%s.%s' % (self.filename, formatDict['filenameExt'])),
                             compress_type=compression,
                             arcname='%s.%s' %
                             (self.typename, formatDict['filenameExt']))
                    for e in formatDict['extToZip']:
                        if os.path.exists(
                                os.path.join(self.tempdir,
                                             '%s.%s' % (self.filename, e))):
                            zf.write(os.path.join(self.tempdir, '%s.%s' %
                                                  (self.filename, e)),
                                     compress_type=compression,
                                     arcname='%s.%s' % (self.typename, e))
                    zf.close()
                f = QFile(os.path.join(self.tempdir, '%s.zip' % self.filename))
                if (f.open(QFile.ReadOnly)):
                    ba = f.readAll()
                    handler.appendBody(ba)
                    return True
            else:
                # return the file created without zip
                f = QFile(
                    os.path.join(
                        self.tempdir,
                        '%s.%s' % (self.filename, formatDict['filenameExt'])))
                if (f.open(QFile.ReadOnly)):
                    ba = f.readAll()
                    handler.appendBody(ba)
                    return True

        handler.appendBody(b'')
        QgsMessageLog.logMessage('Error no output file', "wfsOutputExtension",
                                 Qgis.Critical)
        return False
 def cleanTempPki():
     pkies = glob.glob(os.path.join(tempfile.gettempdir(), 'tmp*_{*}.pem'))
     for fn in pkies:
         f = QFile(fn)
         f.setPermissions(QFile.WriteOwner)
         f.remove()
Example #24
0
    def loadTemplate(self, filePath):
        """
        Loads a document template into the view and updates the necessary STDM-related composer items.
        """
        if not QFile.exists(filePath):
            QMessageBox.critical(
                self.mainWindow(),
                QApplication.translate("OpenTemplateConfig",
                                       "Open Template Error"),
                QApplication.translate(
                    "OpenTemplateConfig",
                    "The specified template does not exist."))
            return

        copy_file = filePath.replace('sdt', 'cpy')

        # remove existing copy file
        if QFile.exists(copy_file):
            copy_template = QFile(copy_file)
            copy_template.remove()

        orig_template_file = QFile(filePath)

        self.setDocumentFile(orig_template_file)

        # make a copy of the original
        result = orig_template_file.copy(copy_file)

        #templateFile = QFile(filePath)

        # work with copy
        templateFile = QFile(copy_file)

        self.copy_template_file = templateFile

        if not templateFile.open(QIODevice.ReadOnly):
            QMessageBox.critical(
                self.mainWindow(),
                QApplication.translate("ComposerWrapper",
                                       "Open Operation Error"),
                "{0}\n{1}".format(
                    QApplication.translate("ComposerWrapper",
                                           "Cannot read template file."),
                    templateFile.errorString()))
            return

        templateDoc = QDomDocument()

        if templateDoc.setContent(templateFile):
            table_config_collection = TableConfigurationCollection.create(
                templateDoc)
            '''
            First load vector layers for the table definitions in the config
            collection before loading the composition from file.
            '''
            load_table_layers(table_config_collection)

            self.clearWidgetMappings()

            #Load items into the composition and configure STDM data controls
            self.composition().loadFromTemplate(templateDoc)

            #Load data controls
            composerDS = ComposerDataSource.create(templateDoc)

            #Set title by appending template name
            title = QApplication.translate("STDMPlugin",
                                           "STDM Document Designer")

            composer_el = templateDoc.documentElement()
            if not composer_el is None:
                template_name = ""
                if composer_el.hasAttribute("title"):
                    template_name = composer_el.attribute("title", "")
                elif composer_el.hasAttribute("_title"):
                    template_name = composer_el.attribute("_title", "")

                if template_name:
                    win_title = "{0} - {1}".format(title, template_name)
                    self.mainWindow().setWindowTitle(template_name)

            self._configure_data_controls(composerDS)

            #Load symbol editors
            spatialFieldsConfig = SpatialFieldsConfiguration.create(
                templateDoc)
            self._configureSpatialSymbolEditor(spatialFieldsConfig)

            #Load photo editors
            photo_config_collection = PhotoConfigurationCollection.create(
                templateDoc)
            self._configure_photo_editors(photo_config_collection)

            # Load table editors
            self._configure_table_editors(table_config_collection)

            #Load chart property editors
            chart_config_collection = ChartConfigurationCollection.create(
                templateDoc)
            self._configure_chart_editors(chart_config_collection)

            # Load QR code property editors
            qrc_config_collection = QRCodeConfigurationCollection.create(
                templateDoc)
            self._configure_qr_code_editors(qrc_config_collection)

            self._sync_ids_with_uuids()
Example #25
0
    def accept(self):
        project_name = self.project_name_le.text()
        if project_name.endswith('.qgs'):
            project_name = project_name[:-4]
        if not project_name:
            QMessageBox.critical(self, self.tr("OQ-Consolidate: Error"),
                                 self.tr("Please specify the project name"))
            return

        outputDir = self.leOutputDir.text()
        if not outputDir:
            QMessageBox.critical(
                self, self.tr("OQ-Consolidate: Error"),
                self.tr("Please specify the output directory."))
            return
        outputDir = os.path.join(outputDir, get_valid_filename(project_name))

        # create main directory if not exists
        d = QDir(outputDir)
        if not d.exists():
            if not d.mkpath("."):
                QMessageBox.critical(
                    self, self.tr("OQ-Consolidate: Error"),
                    self.tr("Can't create directory to store the project."))
                return

        # create directory for layers if not exists
        if d.exists("layers"):
            res = QMessageBox.question(
                self, self.tr("Directory exists"),
                self.tr("Output directory already contains 'layers'"
                        " subdirectory. Maybe this directory was used to"
                        " consolidate another project. Continue?"),
                QMessageBox.Yes | QMessageBox.No)
            if res == QMessageBox.No:
                return
        else:
            if not d.mkdir("layers"):
                QMessageBox.critical(
                    self, self.tr("OQ-Consolidate: Error"),
                    self.tr("Can't create directory for layers."))
                return

        # copy project file
        projectFile = QgsProject.instance().fileName()
        if projectFile:
            f = QFile(projectFile)
            newProjectFile = os.path.join(outputDir, '%s.qgs' % project_name)
            f.copy(newProjectFile)
        else:
            newProjectFile = os.path.join(outputDir, '%s.qgs' % project_name)
            f = QFileInfo(newProjectFile)
            p = QgsProject.instance()
            p.write(f)

        # start consolidate thread that does all real work
        self.workThread = consolidatethread.ConsolidateThread(
            self.iface, outputDir, newProjectFile,
            self.checkBoxZip.isChecked())
        self.workThread.rangeChanged.connect(self.setProgressRange)
        self.workThread.updateProgress.connect(self.updateProgress)
        self.workThread.processFinished.connect(self.processFinished)
        self.workThread.processInterrupted.connect(self.processInterrupted)
        self.workThread.processError.connect(self.processError)
        self.workThread.exceptionOccurred.connect(self.exceptionOccurred)

        self.btnClose.setText(self.tr("Cancel"))
        self.btnOk.setEnabled(False)
        self.buttonBox.rejected.disconnect(self.reject)
        self.btnClose.clicked.connect(self.stopProcessing)

        self.workThread.start()
Example #26
0
 def read_local_qlr(self):
     f = QFile(self.local_qlr_filename)
     f.open(QIODevice.ReadOnly)
     return f.readAll()
Example #27
0
 def test_default_north_arrow_path(self):
     """Verify the call to default north arrow path works."""
     # Check if it exists
     path = QFile(default_north_arrow_path())
     self.assertTrue(QFile.exists(path))
Example #28
0
    def imprimirPlanol(self, x, y, escala, rotacion, midaPagina, templateFile,
                       fitxerSortida, tipusSortida):
        tInicial = time.time()

        template = QFile(templateFile)
        doc = QDomDocument()
        doc.setContent(template, False)

        layout = QgsLayout(self.project)
        # page=QgsLayoutItemPage(layout)
        # page.setPageSize(midaPagina)
        # layout.pageCollection().addPage(page)

        # layout.initializeDefaults()
        # p=layout.pageCollection().pages()[0]
        # p.setPageSize(midaPagina)

        context = QgsReadWriteContext()
        [items, ok] = layout.loadFromTemplate(doc, context)
        # p=layout.pageCollection().pages()[0]
        # p.setPageSize(midaPagina)

        if ok:
            refMap = layout.referenceMap()

            titol = layout.itemById('idNomMapa')
            dataMapa = layout.itemById('idData')
            if self.leTitol.text() != '':
                titol.setText(self.leTitol.text())  #comentat pk peta
            else:
                titol.setText('')
            try:
                t = time.localtime()
                dataMapa.setText(strftime('%b-%d-%Y %H:%M', t))
            except:
                pass

            rect = refMap.extent()
            vector = QgsVector(x - rect.center().x(), y - rect.center().y())
            rect += vector
            refMap.setExtent(rect)
            refMap.setScale(escala)
            refMap.setMapRotation(rotacion)
            #Depenent del tipus de sortida...

            exporter = QgsLayoutExporter(layout)
            # image_settings = exporter.ImageExportSettings()
            # image_settings.dpi = 30

            # result = exporter.exportToImage('d:/dropbox/qpic/preview.png',  image_settings)
            # imatge = QPixmap('d:/dropbox/qpic/preview.png')
            # self.ui.lblImatgeResultat.setPixmap(imatge)

            if tipusSortida == 'PDF':
                settings = QgsLayoutExporter.PdfExportSettings()
                settings.dpi = 300
                settings.exportMetadata = False

                # fitxerSortida='d:/sortida_'+timestamp+'.PDF'
                fitxerSortida += '.PDF'
                result = exporter.exportToPdf(
                    fitxerSortida, settings)  #Cal desar el resultat (???)

                print(fitxerSortida)

            if tipusSortida == 'PNG':
                settings = QgsLayoutExporter.ImageExportSettings()
                settings.dpi = 300

                # fitxerSortida='d:/sortida_'+timestamp+'.PNG'
                fitxerSortida += '.PNG'
                result = exporter.exportToImage(
                    fitxerSortida, settings)  #Cal desar el resultat (???)

            #Obra el document si està marcat checkObrirResultat
            QDesktopServices().openUrl(QUrl(fitxerSortida))

            segonsEmprats = round(time.time() - tInicial, 1)  #???
            layersTemporals = self.project.mapLayersByName(
                "Capa temporal d'impressió")

            estatDirtybit = self.parent.canvisPendents
            for layer in layersTemporals:
                self.project.removeMapLayer(layer.id())
            self.parent.setDirtyBit(estatDirtybit)
Example #29
0
    def createSimpleMemorial(self):
        tempDoc = QDomDocument()
        simple = QFile(self.simpleMemorial)
        simple.open(QIODevice.ReadOnly)
        loaded = tempDoc.setContent(simple)
        simple.close()

        element = tempDoc.documentElement()

        nodes = element.elementsByTagName("table")

        table = nodes.item(0).toElement()

        tr = tempDoc.createElement("tr")
        tr.appendChild(
            self.createCellElement(tempDoc, u"MEMORIAL DESCRITIVO SINTÉTICO",
                                   7, 0))
        table.appendChild(tr)

        tr = tempDoc.createElement("tr")
        tr.appendChild(self.createCellElement(tempDoc, u"VÉRTICE", 0, 2))
        tr.appendChild(self.createCellElement(tempDoc, "COORDENADAS", 2, 0))
        tr.appendChild(self.createCellElement(tempDoc, "LADO", 0, 2))
        tr.appendChild(self.createCellElement(tempDoc, "AZIMUTES", 2, 0))
        tr.appendChild(self.createCellElement(tempDoc, u"DISTÂNCIA", 0, 0))
        table.appendChild(tr)

        tr = tempDoc.createElement("tr")
        tr.appendChild(self.createCellElement(tempDoc, "E", 0, 0))
        tr.appendChild(self.createCellElement(tempDoc, "N", 0, 0))
        tr.appendChild(self.createCellElement(tempDoc, "PLANO", 0, 0))
        tr.appendChild(self.createCellElement(tempDoc, "REAL", 0, 0))
        tr.appendChild(self.createCellElement(tempDoc, "(m)", 0, 0))
        table.appendChild(tr)

        convergence = float(self.convergenciaEdit.text())

        rowCount = self.tableWidget.rowCount()

        for i in range(0, rowCount):
            lineElement = tempDoc.createElement("tr")

            lineElement.appendChild(
                self.createCellElement(tempDoc,
                                       self.tableWidget.item(i, 0).text(), 0,
                                       0))

            lineElement.appendChild(
                self.createCellElement(tempDoc,
                                       self.tableWidget.item(i, 1).text(), 0,
                                       0))
            lineElement.appendChild(
                self.createCellElement(tempDoc,
                                       self.tableWidget.item(i, 2).text(), 0,
                                       0))

            lineElement.appendChild(
                self.createCellElement(tempDoc,
                                       self.tableWidget.item(i, 3).text(), 0,
                                       0))

            lineElement.appendChild(
                self.createCellElement(tempDoc,
                                       self.tableWidget.item(i, 4).text(), 0,
                                       0))
            lineElement.appendChild(
                self.createCellElement(tempDoc,
                                       self.tableWidget.item(i, 5).text(), 0,
                                       0))
            lineElement.appendChild(
                self.createCellElement(tempDoc,
                                       self.tableWidget.item(i, 6).text(), 0,
                                       0))

            table.appendChild(lineElement)

        simple = open(self.simpleMemorial, "w", encoding='utf-8')
        simple.write(tempDoc.toString())
        simple.close()
Example #30
0
    def run(self, *args, **kwargs):
        """
        :param templatePath: The file path to the user-defined template.
        :param entityFieldName: The name of the column for the specified entity which
        must exist in the data source view or table.
        :param entityFieldValue: The value for filtering the records in the data source
        view or table.
        :param outputMode: Whether the output composition should be an image or PDF.
        :param filePath: The output file where the composition will be written to. Applies
        to single mode output generation.
        :param dataFields: List containing the field names whose values will be used to name the files.
        This is used in multiple mode configuration.
        :param fileExtension: The output file format. Used in multiple mode configuration.
        :param data_source: Name of the data source table or view whose
        row values will be used to name output files if the options has been
        specified by the user.
        """
        templatePath = args[0]
        entityFieldName = args[1]
        entityFieldValue = args[2]
        outputMode = args[3]
        filePath = kwargs.get("filePath", None)
        dataFields = kwargs.get("dataFields", [])
        fileExtension = kwargs.get("fileExtension", "")
        data_source = kwargs.get("data_source", "")

        templateFile = QFile(templatePath)

        if not templateFile.open(QIODevice.ReadOnly):
            return False, QApplication.translate("DocumentGenerator",
                                            "Cannot read template file.")

        templateDoc = QDomDocument()

        if templateDoc.setContent(templateFile):
            composerDS = ComposerDataSource.create(templateDoc)
            spatialFieldsConfig = SpatialFieldsConfiguration.create(templateDoc)
            composerDS.setSpatialFieldsConfig(spatialFieldsConfig)

            #Check if data source exists and return if it doesn't
            if not self.data_source_exists(composerDS):
                msg = QApplication.translate("DocumentGenerator",
                                             "'{0}' data source does not exist in the database."
                                             "\nPlease contact your database "
                                             "administrator.".format(composerDS.name()))
                return False, msg

            #Set file name value formatter
            self._file_name_value_formatter = EntityValueFormatter(
                name=data_source
            )

            #Register field names to be used for file naming
            self._file_name_value_formatter.register_columns(dataFields)

            #TODO: Need to automatically register custom configuration collections
            #Photo config collection
            ph_config_collection = PhotoConfigurationCollection.create(templateDoc)

            #Table configuration collection
            table_config_collection = TableConfigurationCollection.create(templateDoc)

            #Create chart configuration collection object
            chart_config_collection = ChartConfigurationCollection.create(templateDoc)

            # Create QR code configuration collection object
            qrc_config_collection = QRCodeConfigurationCollection.create(templateDoc)

            #Load the layers required by the table composer items
            self._table_mem_layers = load_table_layers(table_config_collection)

            entityFieldName = self.format_entity_field_name(composerDS.name(), data_source)

            #Execute query
            dsTable,records = self._exec_query(composerDS.name(), entityFieldName, entityFieldValue)

            if records is None or len(records) == 0:
                return False, QApplication.translate("DocumentGenerator",
                                                    "No matching records in the database")

            """
            Iterate through records where a single file output will be generated for each matching record.
            """

            for rec in records:
                composition = QgsPrintLayout(self._map_settings)
                composition.loadFromTemplate(templateDoc)
                ref_layer = None
                #Set value of composer items based on the corresponding db values
                for composerId in composerDS.dataFieldMappings().reverse:
                    #Use composer item id since the uuid is stripped off
                    composerItem = composition.getComposerItemById(composerId)
                    if not composerItem is None:
                        fieldName = composerDS.dataFieldName(composerId)
                        fieldValue = getattr(rec,fieldName)
                        self._composeritem_value_handler(composerItem, fieldValue)

                # Extract photo information
                self._extract_photo_info(composition, ph_config_collection, rec)

                # Set table item values based on configuration information
                self._set_table_data(composition, table_config_collection, rec)

                # Refresh non-custom map composer items
                self._refresh_composer_maps(composition,
                                            list(spatialFieldsConfig.spatialFieldsMapping().keys()))

                # Set use fixed scale to false i.e. relative zoom
                use_fixed_scale = False

                # Create memory layers for spatial features and add them to the map
                for mapId,spfmList in spatialFieldsConfig.spatialFieldsMapping().items():

                    map_item = composition.getComposerItemById(mapId)

                    if not map_item is None:
                        # Clear any previous map memory layer
                        # self.clear_temporary_map_layers()
                        for spfm in spfmList:
                            #Use the value of the label field to name the layer
                            lbl_field = spfm.labelField()
                            spatial_field = spfm.spatialField()

                            if not spatial_field:
                                continue

                            if lbl_field:
                                if hasattr(rec, spfm.labelField()):
                                    layerName = getattr(rec, spfm.labelField())
                                else:
                                    layerName = self._random_feature_layer_name(spatial_field)
                            else:
                                layerName = self._random_feature_layer_name(spatial_field)

                            #Extract the geometry using geoalchemy spatial capabilities
                            geom_value = getattr(rec, spatial_field)
                            if geom_value is None:
                                continue

                            geom_func = geom_value.ST_AsText()
                            geomWKT = self._dbSession.scalar(geom_func)

                            #Get geometry type
                            geom_type, srid = geometryType(composerDS.name(),
                                                          spatial_field)

                            #Create reference layer with feature
                            ref_layer = self._build_vector_layer(layerName, geom_type, srid)

                            if ref_layer is None or not ref_layer.isValid():
                                continue
                            # Add feature
                            bbox = self._add_feature_to_layer(ref_layer, geomWKT)

                            zoom_type = spfm.zoom_type
                            # Only scale the extents if zoom type is relative
                            if zoom_type == 'RELATIVE':
                                bbox.scale(spfm.zoomLevel())

                            #Workaround for zooming to single point extent
                            if ref_layer.wkbType() == QgsWkbTypes.Point:
                                canvas_extent = self._iface.mapCanvas().fullExtent()
                                cnt_pnt = bbox.center()
                                canvas_extent.scale(1.0/32, cnt_pnt)
                                bbox = canvas_extent

                            #Style layer based on the spatial field mapping symbol layer
                            symbol_layer = spfm.symbolLayer()
                            if not symbol_layer is None:
                                ref_layer.rendererV2().symbols()[0].changeSymbolLayer(0,spfm.symbolLayer())
                            '''
                            Add layer to map and ensure its always added at the top
                            '''
                            self.map_registry.addMapLayer(ref_layer)
                            self._iface.mapCanvas().setExtent(bbox)

                            # Set scale if type is FIXED
                            if zoom_type == 'FIXED':
                                self._iface.mapCanvas().zoomScale(spfm.zoomLevel())
                                use_fixed_scale = True

                            self._iface.mapCanvas().refresh()
                            # Add layer to map memory layer list
                            self._map_memory_layers.append(ref_layer.id())
                            self._hide_layer(ref_layer)
                        '''
                        Use root layer tree to get the correct ordering of layers
                        in the legend
                        '''
                        self._refresh_map_item(map_item, use_fixed_scale)

                # Extract chart information and generate chart
                self._generate_charts(composition, chart_config_collection, rec)

                # Extract QR code information in order to generate QR codes
                self._generate_qr_codes(composition, qrc_config_collection,rec)

                #Build output path and generate composition
                if not filePath is None and len(dataFields) == 0:
                    self._write_output(composition, outputMode, filePath)

                elif filePath is None and len(dataFields) > 0:
                    entityFieldName = 'id'
                    docFileName = self._build_file_name(data_source, entityFieldName,
                                                      entityFieldValue, dataFields, fileExtension)

                    # Replace unsupported characters in Windows file naming
                    docFileName = docFileName.replace('/', '_').replace \
                        ('\\', '_').replace(':', '_').strip('*?"<>|')


                    if not docFileName:
                        return (False, QApplication.translate("DocumentGenerator",
                                    "File name could not be generated from the data fields."))

                    outputDir = self._composer_output_path()
                    if outputDir is None:
                        return (False, QApplication.translate("DocumentGenerator",
                            "System could not read the location of the output directory in the registry."))

                    qDir = QDir()
                    if not qDir.exists(outputDir):
                        return (False, QApplication.translate("DocumentGenerator",
                                "Output directory does not exist"))

                    absDocPath = "{0}/{1}".format(outputDir, docFileName)
                    self._write_output(composition, outputMode, absDocPath)

            return True, "Success"

        return False, "Document composition could not be generated"