Exemple #1
0
    def _editTemplate(self, templatePath, newName):
        """
        Updates the template document to use the new name.
        """
        templateFile = QFile(templatePath)

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

        templateDoc = QDomDocument()

        if templateDoc.setContent(templateFile):
            composerElement = templateDoc.documentElement()
            titleAttr = composerElement.attributeNode("_title")
            if not titleAttr.isNull():
                titleAttr.setValue(newName)

            # Try remove file
            status = templateFile.remove()

            if not status:
                return (False, "")

            # Create new file
            newTemplatePath = self._composerTemplatesPath(
            ) + "/" + newName + ".sdt"
            newTemplateFile = QFile(newTemplatePath)

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

            if newTemplateFile.write(templateDoc.toByteArray()) == -1:
                QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector", "Save Error"), \
                                     QApplication.translate("TemplateDocumentSelector",
                                                            "Could not save template file."))
                return (False, "")

            newTemplateFile.close()

            return (True, newTemplatePath)
Exemple #2
0
    def object_to_qlr(
            obj,
            input_file,
            output_path,
            context: Context,
            use_relative_paths: bool = False) -> Tuple[bool, Optional[str]]:
        """
        Converts an ESRI object to QLR
        """

        root_node, _ = LayerConverter.object_to_layers_and_tree(
            obj, input_file, context)

        output_path = QgsFileUtils.ensureFileNameHasExtension(
            output_path, ['qlr'])

        file = QFile(output_path)
        if not file.open(QFile.WriteOnly | QFile.Truncate):
            return False, file.errorString()

        rw_context = QgsReadWriteContext()
        if not use_relative_paths:
            rw_context.setPathResolver(QgsPathResolver())
        else:
            rw_context.setPathResolver(QgsPathResolver(output_path))

        doc = QDomDocument("qgis-layer-definition")
        res, error = QgsLayerDefinition.exportLayerDefinition(
            doc, root_node.children(), rw_context)
        if res:
            stream = QTextStream(file)
            doc.save(stream, 2)
            return True, None

        return res, error
    def saveProject(self, doc):
        f = QFile(self.projectFile)
        if not f.open(QIODevice.WriteOnly | QIODevice.Text):
            msg = self.tr("Cannot write file %s:\n%s.") % (self.projectFile,
                                                           f.errorString())
            raise IOError(msg)

        out = QTextStream(f)
        doc.save(out, 4)
        f.close()
    def loadProject(self):
        f = QFile(self.projectFile)
        if not f.open(QIODevice.ReadOnly | QIODevice.Text):
            msg = self.tr("Cannot read file %s:\n%s.") % (self.projectFile,
                                                          f.errorString())
            raise IOError(msg)

        doc = QDomDocument()
        setOk, errorString, errorLine, errorColumn = doc.setContent(f, True)
        if not setOk:
            msg = (self.tr("Parse error at line %d, column %d:\n%s") %
                   (errorLine, errorColumn, errorString))
            raise SyntaxError(msg)

        f.close()
        return doc
Exemple #5
0
    def __init__(self, qgis_utils):
        QDialog.__init__(self)
        self.setupUi(self)
        self.qgis_utils = qgis_utils
        self.check_local_help()

        self.tb_changelog.setOpenExternalLinks(True)

        if QGIS_LANG == 'en':
            file = QFile(":/Asistente-LADM_COL/resources/html/Changelog_en.html")
        else:
            file = QFile(":/Asistente-LADM_COL/resources/html/Changelog.html")

        if not file.open(QIODevice.ReadOnly | QIODevice.Text):
            raise Exception(file.errorString())

        stream = QTextStream(file)
        stream.setCodec("UTF-8")

        self.tb_changelog.setHtml(stream.readAll())
Exemple #6
0
    def load_template_into_layout(layout: QgsLayout, file_path: str):
        """
        Loads a document template into the view and updates the necessary STDM-related composer items.
        """
        copy_file = file_path.replace('sdt', 'cpy')

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

        orig_template_file = QFile(file_path)

        layout.setCustomProperty('variable_template_path', file_path)

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

        # work with copy
        template_file = QFile(copy_file)

        if not template_file.open(QIODevice.ReadOnly):
            raise IOError(template_file.errorString())

        template_doc = QDomDocument()
        if template_doc.setContent(template_file):
            # First load vector layers for the table definitions in the config
            # collection before loading the composition from file.

            #  table_config_collection = TableConfigurationCollection.create(template_doc)

            # Load items into the composition and configure STDM data controls
            context = QgsReadWriteContext()
            try:
                layout.loadFromTemplate(template_doc, context)
            except:
                pass

            LayoutUtils.sync_ids_with_uuids(layout)

        template_file.close()
Exemple #7
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()
Exemple #8
0
class MultipartFile(QFile):
    """Wrapper class to support reading a file in chunks and post each part separately."""
    def __init__(self, filename):
        super().__init__(filename)
        self._file = QFile(filename)
        self._bytes_left = 0
        self._file.readyRead.connect(self.on_readyRead)
        self._file.aboutToClose.connect(self.on_aboutToClose)
        self._file.bytesWritten.connect(self.on_bytesWritten)
        self._file.channelBytesWritten.connect(self.on_channelBytesWritten)
        self._file.channelReadyRead.connect(self.on_channelReadyRead)
        self._file.readChannelFinished.connect(self.on_readChannelFinished)

    def set_part_size(self, size):
        self._bytes_left = size
        self._original_size = size

    def commitTransaction(self):
        QgsMessageLog.logMessage('commitTransaction')
        return self._file.commitTransaction()

    def currentReadChannel(self):
        QgsMessageLog.logMessage('currentReadChannel')
        return self._file.currentReadChannel()

    def currentWriteChannel(self):
        QgsMessageLog.logMessage('currentWriteChannel')
        return self._file.currentWriteChannel()

    def errorString(self):
        QgsMessageLog.logMessage('errorString')
        return self._file.errorString()
    
    def getChar(self):
        if self._bytes_left > 0:
            QgsMessageLog.logMessage('getChar')
            self._bytes_left = self._bytes_left - 1
            return self._file.getChar()
        else:
            QgsMessageLog.logMessage('getChar(no bytes left)')
            return None

    def isOpen(self):
        QgsMessageLog.logMessage('isOpen')
        return self._file.isOpen()

    def isReadable(self):
        QgsMessageLog.logMessage('isReadable')
        return self._file.isReadable()

    def isTextModeEnabled(self):
        QgsMessageLog.logMessage('isTextModeEnabled')
        return self._file.isTextModeEnabled()

    def isTransactionStarted(self):
        QgsMessageLog.logMessage('isTransactionStarted')
        return self._file.isTransactionStarted()

    def isWritable(self):
        QgsMessageLog.logMessage('isWritable')
        return self._file.isWritable()

    def openMode(self):
        QgsMessageLog.logMessage('openMode')
        return self._file.openMode()

    def peek(self, maxlen):
        QgsMessageLog.logMessage('peek {0} {1}'.format(maxlen, self._bytes_left))
        if maxlen > self._bytes_left:
            maxlen = self._bytes_left
        return self._file.peek(maxlen)

    def read(self, max_size):
        QgsMessageLog.logMessage('read {0}'.format(max_size))
        return self._file.read(max_size)

    def readAll(self):
        QgsMessageLog.logMessage('readAll')
        data = self._file.read(self._bytes_left)
        self._bytes_left = self._bytes_left - len(data)
        return data

    def readChannelCount(self):
        QgsMessageLog.logMessage('readChannelCount')
        return self._file.readChannelCount()

    def readLine(self):
        QgsMessageLog.logMessage('readLine')
        return None

    def rollbackTransaction(self):
        QgsMessageLog.logMessage('rollbackTransaction')
        return self._file.rollbackTransaction()

    def setCurrentReadChannel(self, channel):
        QgsMessageLog.logMessage('setCurrentReadChannel {0}'.format(channel))
        return self._file.setCurrentReadChannel(channel)

    def setErrorString(self, errorString):
        QgsMessageLog.logMessage('setErrorString {0}'.format(errorString))
        return self._file.setErrorString(errorString)

    def setOpenMode(self, mode):
        QgsMessageLog.logMessage('setOpenMode {0}'.format(mode))
        return self._file.setOpenMode(mode)

    def setTextModeEnabled(self, enabled):
        QgsMessageLog.logMessage('setTextModeEnabled {0}'.format(enabled))
        return self._file.setTextModeenabled(enabled)

    def skip(self, maxSize):
        QgsMessageLog.logMessage('skip {0} {1}'.format(maxSize, self._bytes_left))
        if maxSize > self._bytes_left:
            maxSize = self._bytes_left
        return self._file.skip(maxSize)

    def startTransaction(self):
        QgsMessageLog.logMessage('startTransaction')
        return self._file.startTransaction()

    def ungetChar(self, c):
        QgsMessageLog.logMessage('ungetChar {0}'.format(c))
        return None

    def writeChannelCount(self):
        QgsMessageLog.logMessage('writeChannelCount')
        return self._file.writeChannelCount()

    def atEnd(self):
        QgsMessageLog.logMessage('atEnd')
        if self._bytes_left == 0:
            return True
        else:
            return self._file.atEnd()

    def bytesAvailable(self):
        QgsMessageLog.logMessage('bytesAvailable')
        real_bytes_available = self._file.bytesAvailable()
        if real_bytes_available > self._bytes_left:
            return self._bytes_left
        else:
            return real_bytes_available

    def bytesToWrite(self):
        QgsMessageLog.logMessage('bytesToWrite')
        return self._file.bytesToWrite()

    def canReadLine(self):
        QgsMessageLog.logMessage('canReadLine')
        return self._file.canReadLine()

    def close(self):
        QgsMessageLog.logMessage('close')
        return self._file.close()

    def isSequential(self):
        QgsMessageLog.logMessage('isSequential')
        return self._file.isSequential()

    def open(self, mode):
        QgsMessageLog.logMessage('open')
        return self._file.open(mode)

    def pos(self):
        QgsMessageLog.logMessage('pos')
        return self._original_size - self._bytes_left

    def readData(self, max_size):
        if max_size > self._bytes_left:
            max_size = self._bytes_left
        self._bytes_left = self._bytes_left - max_size
        if self._bytes_left == 0:
            self.readChannelFinished.emit()
        QgsMessageLog.logMessage('readData {0}'.format(max_size))
        return self._file.readData(max_size)

    def reset(self):
        QgsMessageLog.logMessage('readData')
        return True

    def seek(self, pos):
        QgsMessageLog.logMessage('seek {0}'.format(pos))
        return True

    def size(self):
        file_size = self._file.size()
        if file_size < self._bytes_left:
            QgsMessageLog.logMessage('size(file_size) {0}'.format(file_size))
            return file_size
        else:
            QgsMessageLog.logMessage('size(bytes_left) {0}'.format(self._bytes_left))
            return self._bytes_left
    
    def waitForReadyRead(self, msecs):
        QgsMessageLog.logMessage('waitForReadyRead {0}'.format(msecs))
        return self._file.waitForReadyRead(msecs)

    def on_aboutToClose(self):
        QgsMessageLog.logMessage('on_aboutToClose')
        self.aboutToClose.emit()
    
    def on_bytesWritten(self, bytes_written):
        QgsMessageLog.logMessage('on_bytesWritten {0}'.format(bytes_written))
        self.bytesWritten.emit(bytes_written)

    def on_channelBytesWritten(self, channel, bytes_written):
        QgsMessageLog.logMessage('on_channelBytesWritten {0} {1}'.format(channel, bytes_written))
        self.channelBytesWritten.emit(channel, bytes_written)
    
    def on_channelReadyRead(self, channel):
        QgsMessageLog.logMessage('on_channelReadyRead {0}'.format(channel))
        if self._bytes_left > 0:
            self.channelReadyRead.emit(channel)

    def on_readChannelFinished(self):
        QgsMessageLog.logMessage('on_readChannelFinished')
        self.readChannelFinished.emit()

    def on_readyRead(self):
        QgsMessageLog.logMessage('on_readyRead')
        if self._bytes_left > 0:
            self.readyRead.emit()

    def flush(self):
        QgsMessageLog.logMessage('flush')
        return self._file.flush()

    def fileName(self):
        QgsMessageLog.logMessage('filename')
        return self._file.fileName()

    def exists(self):
        QgsMessageLog.logMessage('exists')
        return self._file.exists()

    def decodeName(self, localFileName):
        QgsMessageLog.logMessage('decodeName {0}'.format(localFileName))
        return self._file.decodeName(localFileName)
Exemple #9
0
class FileDownloader():

    """The blueprint for downloading file from url."""

    def __init__(self, url, output_path, progress_dialog=None):
        """Constructor of the class.

        .. versionchanged:: 3.3 removed manager parameter.

        :param url: URL of file.
        :type url: str

        :param output_path: Output path.
        :type output_path: str

        :param progress_dialog: Progress dialog widget.
        :type progress_dialog: QWidget
        """
        # noinspection PyArgumentList
        self.manager = QgsNetworkAccessManager.instance()
        self.url = QUrl(url)
        self.output_path = output_path
        self.progress_dialog = progress_dialog
        if self.progress_dialog:
            self.prefix_text = self.progress_dialog.labelText()
        self.output_file = None
        self.reply = None
        self.downloaded_file_buffer = None
        self.finished_flag = False

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

    def get_buffer(self):
        """Get buffer from self.reply and store it to our buffer container."""
        buffer_size = self.reply.size()
        data = self.reply.read(buffer_size)
        self.downloaded_file_buffer.append(data)

    def write_data(self):
        """Write data to a file."""
        self.output_file.write(self.downloaded_file_buffer)
        self.output_file.close()
        self.finished_flag = True

    def request_timeout(self):
        """The request timed out."""
        if self.progress_dialog:
            self.progress_dialog.hide()
Exemple #10
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()
Exemple #11
0
class FileDownloader():
    """The blueprint for downloading file from url."""
    def __init__(self, url, output_path, progress_dialog=None):
        """Constructor of the class.

        .. versionchanged:: 3.3 removed manager parameter.

        :param url: URL of file.
        :type url: str

        :param output_path: Output path.
        :type output_path: str

        :param progress_dialog: Progress dialog widget.
        :type progress_dialog: QWidget
        """
        # noinspection PyArgumentList
        self.manager = QgsNetworkAccessManager.instance()
        self.url = QUrl(url)
        self.output_path = output_path
        self.progress_dialog = progress_dialog
        if self.progress_dialog:
            self.prefix_text = self.progress_dialog.labelText()
        self.output_file = None
        self.reply = None
        self.downloaded_file_buffer = None
        self.finished_flag = False

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

    def get_buffer(self):
        """Get buffer from self.reply and store it to our buffer container."""
        buffer_size = self.reply.size()
        data = self.reply.read(buffer_size)
        self.downloaded_file_buffer.append(data)

    def write_data(self):
        """Write data to a file."""
        self.output_file.write(self.downloaded_file_buffer)
        self.output_file.close()
        self.finished_flag = True

    def request_timeout(self):
        """The request timed out."""
        if self.progress_dialog:
            self.progress_dialog.hide()