def _save_dependency_file(self, fetcher_task):
        self._downloading = False
        if fetcher_task.reply() is not None:
            try:
                if not os.path.exists(DEPENDENCY_CRYPTO_DIR):
                    os.makedirs(DEPENDENCY_CRYPTO_DIR)

                # Write response to tmp file
                out_file = QFile(CRYPTO_LIBRARY_PATH)
                out_file.open(QIODevice.WriteOnly)
                out_file.write(fetcher_task.reply().readAll())
                out_file.close()

            except PermissionError as e:
                self.logger.warning_msg(
                    __name__,
                    QCoreApplication.translate(
                        "EncrypterDecrypter",
                        "The dependency used to encrypt/decrypt 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(DEPENDENCY_CRYPTO_DIR)))
            else:
                self.logger.clear_message_bar()
                self.logger.info_msg(
                    __name__,
                    QCoreApplication.translate(
                        "EncrypterDecrypter",
                        "The dependency used to encrypt/decrypt is properly installed!"
                    ))
Exemple #2
0
    def save_file(self, fetcher_task):
        if fetcher_task.reply() is not None:
            tmpFile = tempfile.mktemp()
            tmpFold = tempfile.mktemp()
            outFile = QFile(tmpFile)
            outFile.open(QIODevice.WriteOnly)
            outFile.write(fetcher_task.reply().readAll())
            outFile.close()

            try:
                with zipfile.ZipFile(tmpFile, "r") as zip_ref:
                    zip_ref.extractall(tmpFold)
                    languages = glob.glob(os.path.join(tmpFold, 'asistente_ladm_col_docs/*'))

                    for language in languages:
                        shutil.move(language, os.path.join(PLUGIN_DIR, HELP_DIR_NAME, language[-2:]))

            except zipfile.BadZipFile as e:
                self.qgis_utils.message_emitted.emit(
                    QCoreApplication.translate("AboutDialog", "There was an error with the download. The downloaded file is invalid."),
                    Qgis.Warning)
            else:
                self.message_with_button_open_about_emitted.emit(
                    QCoreApplication.translate("AboutDialog", "Help files were successfully downloaded and can be accessed offline from the About dialog!"))

            try:
                os.remove(tmpFile)
                os.remove(tmpFold)
            except:
                pass

        self.check_local_help()
Exemple #3
0
    def save_file(self, fetcher_task):
        if fetcher_task.reply() is not None:
            tmpFile = tempfile.mktemp()
            tmpFold = tempfile.mktemp()
            outFile = QFile(tmpFile)
            outFile.open(QIODevice.WriteOnly)
            outFile.write(fetcher_task.reply().readAll())
            outFile.close()

            try:
                with zipfile.ZipFile(tmpFile, "r") as zip_ref:
                    zip_ref.extractall(tmpFold)
                    shutil.move(tmpFold, os.path.join(PLUGIN_DIR, HELP_DIR_NAME))

            except zipfile.BadZipFile as e:
                self.logger.warning_msg(__name__, QCoreApplication.translate("AboutDialog",
                    "There was an error with the download. The downloaded file is invalid."))
            else:
                self.message_with_button_open_about_emitted.emit(
                    QCoreApplication.translate("AboutDialog", "Help files were successfully downloaded and can be accessed offline from the About dialog!"))

            try:
                os.remove(tmpFile)
                os.remove(tmpFold)
            except:
                pass

        self.check_local_help()
    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()
Exemple #5
0
    def _save_dependency_file(self, fetcher_task):
        self._downloading = False
        if fetcher_task.reply() is not None:
            # Write response to tmp file
            out_file = QFile(self.tmp_file)
            out_file.open(QIODevice.WriteOnly)
            out_file.write(fetcher_task.reply().readAll())
            out_file.close()

            self.logger.status(QCoreApplication.translate("Dependency", "The plugin ZIP file was downloaded!"))
Exemple #6
0
    def finished():
        file = QFile(filename)
        file.open(QIODevice.WriteOnly)
        file.write(reply.readAll())
        file.close()
        if reply.error() and on_error:
            on_error(reply.error(), reply.errorString())
        elif not reply.error() and on_success:
            on_success()

        if on_finished:
            on_finished()
        reply.deleteLater()
Exemple #7
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()

            if not os.path.exists(DEPENDENCIES_BASE_PATH):
                os.makedirs(DEPENDENCIES_BASE_PATH)

            if md5sum(tmp_file) == DICT_JAVA_MD5SUM[KEY_JAVA_OS_VERSION]:

                try:
                    tar = tarfile.open(tmp_file)
                    tar.extractall(DEPENDENCIES_BASE_PATH)
                    tar.close()
                except tarfile.ReadError as e:
                    self.logger.warning_msg(
                        __name__,
                        QCoreApplication.translate(
                            "JavaDependency",
                            "There was an error with the download. The downloaded file is invalid."
                        ))
                except PermissionError as e:
                    self.logger.warning_msg(
                        __name__,
                        QCoreApplication.translate(
                            "JavaDependency",
                            "Java 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(
                                DEPENDENCIES_BASE_PATH,
                                DICT_JAVA_DIR_NAME[KEY_JAVA_OS_VERSION]))))

            else:
                self.logger.warning_msg(
                    __name__,
                    QCoreApplication.translate(
                        "JavaDependency",
                        "There was an error with the download. The downloaded file is invalid."
                    ))
            try:
                os.remove(tmp_file)
            except:
                pass

        self._downloading = False
    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()

            if not os.path.exists(DEPENDENCIES_BASE_PATH):
                os.makedirs(DEPENDENCIES_BASE_PATH)

            try:
                with zipfile.ZipFile(tmp_file, "r") as zip_ref:
                    zip_ref.extractall(DEPENDENCIES_BASE_PATH)
            except zipfile.BadZipFile as e:
                self.logger.warning_msg(
                    __name__,
                    QCoreApplication.translate(
                        "ReportGenerator",
                        "There was an error with the download. The downloaded file is invalid."
                    ))
            except PermissionError as e:
                self.logger.warning_msg(
                    __name__,
                    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(DEPENDENCIES_BASE_PATH),
                        DEPENDENCY_REPORTS_DIR_NAME)))
            else:
                self.logger.info_msg(
                    __name__,
                    QCoreApplication.translate(
                        "ReportGenerator",
                        "The dependency to generate reports is properly installed! Select plots and click again the button in the toolbar to generate reports."
                    ))

            try:
                os.remove(tmp_file)
            except:
                pass

        self._downloading = False
    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=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
class CloudqubeFileReply(CloudqubeReply):
    """Class that handles file downloads."""
    def __init__(self, reply, callback, finished, error):
        super().__init__(reply, error)
        reply.readyRead.connect(self.read)
        reply.finished.connect(self.finished)
        self._callback = callback
        self._finished = finished

        # Figure out extension from content-type
        try:
            extension = '.{0}'.format(
                reply.header(QNetworkRequest.ContentTypeHeader).split('/')[1])
        except:
            extension = ''
        _, filename = tempfile.mkstemp(suffix=extension)

        self._filename = filename
        self._file = QFile(filename)
        self._file.open(QIODevice.WriteOnly)

    def read(self):
        """Handles read signal."""
        self._file.write(self._reply.readAll())

    def finished(self):
        """Handles finished signal."""
        if (self._reply.error() == QNetworkReply.NoError):
            # Write last remaining bytes if there are any
            self._file.write(self._reply.readAll())
            self._file.close()
            self._callback(self._filename)
        else:
            self._file.close()
        # Call finished callback to remove this reply
        # which will remove all handling objects
        # and close all streams
        self._finished(self)

    def filename(self):
        """Returns the name of the file that was downloaded."""
        return self._filename
Exemple #11
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)
    def requestFinished(self):
        if self.reply.error() != QNetworkReply.NoError:
            QApplication.restoreOverrideCursor()
            iface.messageBar().pushMessage(
                "Lessons could not be installed:\n",
                self.reply.errorString(),
                QgsMessageBar.WARNING)
            self.reply.deleteLater()
            return

        f = QFile(tempFilenameInTempFolder(os.path.basename(self.url).split(".")[0]))
        f.open(QFile.WriteOnly)
        f.write(self.reply.readAll())
        f.close()
        self.reply.deleteLater()

        from lessons import installLessonsFromZipFile
        installLessonsFromZipFile(f.fileName())
        QApplication.restoreOverrideCursor()

        iface.messageBar().pushMessage(
            "Completed",
            "Lessons were correctly installed",
            QgsMessageBar.INFO)
Exemple #13
0
class XFORMDocument:
    """
    class to generate an Xml file that is needed for data collection
    using mobile device. The class creates the file and QDOM sections
    for holding data once the file is called
    """
    def __init__(self, fname):
        """
        Initalize the class so that we have a new file
        everytime document generation method is called
        """
        self.dt_text = QDate()
        self.file_handler = FilePaths()
        self.doc = QDomDocument()
        self.form = None
        self.fname = fname
        self.doc_with_entities = []
        self.supports_doc = self.document()

    def document(self):
        """
        use the globally defined Document name for supporting document
        :return:
        """
        global DOCUMENT
        return DOCUMENT

    def form_name(self):
        """
        Format the name for the new file to be created. We need to ensure it is
        .xml file.
        :return:
        """
        if len(self.fname.split(".")) > 1:
            return self.fname
        else:
            return self.fname + "{}".format(DOCEXTENSION)

    def set_form_name(self, local_name):
        """
        Allow the user to update the name of the file. This method
        will be called to return a new file with the local_name given
        :param local_name: string
        :return: QFile
        """
        self.fname = local_name + "{}".format(DOCEXTENSION)
        self.form.setFileName(self.fname)
        self.create_form()

        return self.fname

    def create_form(self):
        """
        Create an XML file that will be our XFORM Document for reading and writing
        We want a new file when everytime we are creating XForm
        type: file
        :return: file
        """
        self.form = QFile(os.path.join(FORM_HOME, self.form_name()))
        if not QFileInfo(self.form).suffix() == DOCEXTENSION:
            self.form_name()

        if not self.form.open(QIODevice.ReadWrite | QIODevice.Truncate
                              | QIODevice.Text):
            return self.form.OpenError

    def create_node(self, name):
        """
        Create a XML element node
        :param name:
        :return: node
        :rtype: QelementNode
        """
        return self.doc.createElement(name)

    def create_text_node(self, text):
        """
        Create an XML text node
        :param text:
        :return:
        """
        return self.doc.createTextNode(text)

    def create_node_attribute(self, node, key, value):
        """
        Create an attribute and attach it to the node
        :param node: Qnode
        :param key: Qnode name
        :param value: Qnode value
        :return: QNode
        """
        return node.setAttribute(key, value)

    def xform_document(self):
        """
        :return: QDomDocument
        """
        return self.doc

    def write_to_form(self):
        """
        Write data to xml file from the base calling class to an output file created earlier
        :return:
        """
        if isinstance(self.form, QFile):
            self.form.write(self.doc.toByteArray())
            self.form.close()
            self.doc.clear()
        else:
            return None

    def update_form_data(self):
        """
        Update the xml file with changes that the user has made.
        Particular section of the document will be deleted or added
        :return:
        """
        pass
Exemple #14
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 #15
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 #16
0
class QgsPluginInstallerInstallingDialog(
        QDialog, Ui_QgsPluginInstallerInstallingDialogBase):
    # ----------------------------------------- #

    def __init__(self, parent, plugin):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.plugin = plugin
        self.mResult = ""
        self.progressBar.setRange(0, 0)
        self.progressBar.setFormat("%p%")
        self.labelName.setText(plugin["name"])
        self.buttonBox.clicked.connect(self.abort)

        url = QUrl(plugin["download_url"])

        fileName = plugin["filename"]
        tmpDir = QDir.tempPath()
        tmpPath = QDir.cleanPath(tmpDir + "/" + fileName)
        self.file = QFile(tmpPath)

        self.request = QNetworkRequest(url)
        authcfg = repositories.all()[plugin["zip_repository"]]["authcfg"]
        if authcfg and isinstance(authcfg, basestring):
            if not QgsAuthManager.instance().updateNetworkRequest(
                    self.request, authcfg.strip()):
                self.mResult = self.tr(
                    "Update of network request with authentication "
                    "credentials FAILED for configuration '{0}'").format(
                        authcfg)
                self.request = None

        if self.request is not None:
            self.reply = QgsNetworkAccessManager.instance().get(self.request)
            self.reply.downloadProgress.connect(self.readProgress)
            self.reply.finished.connect(self.requestFinished)

            self.stateChanged(4)

    def exec_(self):
        if self.request is None:
            return QDialog.Rejected

        QDialog.exec_(self)

    # ----------------------------------------- #
    def result(self):
        return self.mResult

    # ----------------------------------------- #
    def stateChanged(self, state):
        messages = [
            self.tr("Installing..."),
            self.tr("Resolving host name..."),
            self.tr("Connecting..."),
            self.tr("Host connected. Sending request..."),
            self.tr("Downloading data..."),
            self.tr("Idle"),
            self.tr("Closing connection..."),
            self.tr("Error")
        ]
        self.labelState.setText(messages[state])

    # ----------------------------------------- #
    def readProgress(self, done, total):
        if total > 0:
            self.progressBar.setMaximum(total)
            self.progressBar.setValue(done)

    # ----------------------------------------- #
    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 cancelled 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
        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 + unicode(QDir.separator()) +
              self.plugin["id"]).remove()
        try:
            unzip(
                unicode(tmpPath), unicode(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(unicode(tmpPath), unicode(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()

    # ----------------------------------------- #
    def abort(self):
        if self.reply.isRunning():
            self.reply.finished.disconnect()
            self.reply.abort()
            del self.reply
        self.mResult = self.tr("Aborted by user")
        self.reject()
class QgsPluginInstallerInstallingDialog(QDialog, Ui_QgsPluginInstallerInstallingDialogBase):
    # ----------------------------------------- #

    def __init__(self, parent, plugin):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.plugin = plugin
        self.mResult = ""
        self.progressBar.setRange(0, 0)
        self.progressBar.setFormat("%p%")
        self.labelName.setText(plugin["name"])
        self.buttonBox.clicked.connect(self.abort)

        self.url = QUrl(plugin["download_url"])
        self.redirectionCounter = 0

        fileName = plugin["filename"]
        tmpDir = QDir.tempPath()
        tmpPath = QDir.cleanPath(tmpDir + "/" + fileName)
        self.file = QFile(tmpPath)

        self.requestDownloading()

    def requestDownloading(self):
        self.request = QNetworkRequest(self.url)
        self.request.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorClass), "QgsPluginInstallerInstallingDialog")
        authcfg = repositories.all()[self.plugin["zip_repository"]]["authcfg"]
        if authcfg and isinstance(authcfg, str):
            if not QgsApplication.authManager().updateNetworkRequest(
                    self.request, authcfg.strip()):
                self.mResult = self.tr(
                    "Update of network request with authentication "
                    "credentials FAILED for configuration '{0}'").format(authcfg)
                self.request = None

        if self.request is not None:
            self.reply = QgsNetworkAccessManager.instance().get(self.request)
            self.reply.downloadProgress.connect(self.readProgress)
            self.reply.finished.connect(self.requestFinished)

            self.stateChanged(4)

    def exec_(self):
        if self.request is None:
            return QDialog.Rejected

        QDialog.exec_(self)

    # ----------------------------------------- #
    def result(self):
        return self.mResult

    # ----------------------------------------- #
    def stateChanged(self, state):
        messages = [
            QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Installing…"),
            QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Resolving host name…"),
            QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Connecting…"),
            QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Host connected. Sending request…"),
            QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Downloading data…"),
            self.tr("Idle"),
            QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Closing connection…"),
            self.tr("Error")
        ]
        self.labelState.setText(messages[state])

    # ----------------------------------------- #
    def readProgress(self, done, total):
        if total > 0:
            self.progressBar.setMaximum(total)
            self.progressBar.setValue(done)

    # ----------------------------------------- #
    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) in (301, 302):
            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()

    # ----------------------------------------- #
    def abort(self):
        if self.reply.isRunning():
            self.reply.finished.disconnect()
            self.reply.abort()
            del self.reply
        self.mResult = self.tr("Aborted by user")
        self.reject()
Exemple #18
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()
Exemple #19
0
    def adjust(self):
        """ Export data to GNU Gama xml, adjust the network and read result

            :returns: result list of adjusment from GNU Gama
        """
        # fix = 0 free network
        fix = 0
        adj = 0
        for p, s in self.points:
            if s == 'FIX':
                fix += 1
            else:
                adj += 1
        if adj == 0 or len(self.observations) == 0:
            # no unknowns or observations
            return None

        doc = QDomDocument()
        doc.appendChild(
            doc.createComment(
                'Gama XML created by SurveyingCalculation plugin for QGIS'))
        gama_local = doc.createElement('gama-local')
        gama_local.setAttribute('version', '2.0')
        doc.appendChild(gama_local)
        network = doc.createElement('network')
        network.setAttribute('axes-xy', 'ne')
        network.setAttribute('angles', 'left-handed')
        gama_local.appendChild(network)
        description = doc.createElement('description')
        if self.dimension == 1:
            description.appendChild(doc.createTextNode('GNU Gama 1D network'))
        elif self.dimension == 2:
            description.appendChild(doc.createTextNode('GNU Gama 2D network'))
        elif self.dimension == 3:
            description.appendChild(doc.createTextNode('GNU Gama 3D network'))
        network.appendChild(description)
        parameters = doc.createElement('parameters')
        parameters.setAttribute('sigma-apr', '1')
        parameters.setAttribute('conf-pr', str(self.probability))
        parameters.setAttribute('tol-abs', '1000')
        parameters.setAttribute('sigma-act', 'aposteriori')
        parameters.setAttribute('update-constrained-coordinates', 'yes')
        network.appendChild(parameters)
        points_observations = doc.createElement('points-observations')
        points_observations.setAttribute(
            'distance-stdev',
            str(self.stdev_dist) + ' ' + str(self.stdev_dist1))
        points_observations.setAttribute('direction-stdev',
                                         str(self.stdev_angle))
        points_observations.setAttribute('angle-stdev',
                                         str(math.sqrt(self.stdev_angle * 2)))
        points_observations.setAttribute('zenith-angle-stdev',
                                         str(self.stdev_angle))
        network.appendChild(points_observations)
        for p, s in self.points:
            if self.dimension == 1:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.z is not None:
                    tmp.setAttribute('z', str(p.z))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'z')
                else:
                    if fix == 0:
                        tmp.setAttribute('adj', 'Z')
                    else:
                        tmp.setAttribute('adj', 'z')
                points_observations.appendChild(tmp)
            elif self.dimension == 2:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.e is not None and p.n is not None:
                    tmp.setAttribute('y', str(p.e))
                    tmp.setAttribute('x', str(p.n))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'xy')
                else:
                    if fix == 0:
                        # free network
                        tmp.setAttribute('adj', 'XY')
                    else:
                        tmp.setAttribute('adj', 'xy')
                points_observations.appendChild(tmp)
            elif self.dimension == 3:
                tmp = doc.createElement('point')
                tmp.setAttribute('id', p.id)
                if p.e is not None and p.n is not None:
                    tmp.setAttribute('y', str(p.e))
                    tmp.setAttribute('x', str(p.n))
                if p.z is not None:
                    tmp.setAttribute('z', str(p.z))
                if s == 'FIX':
                    tmp.setAttribute('fix', 'xyz')
                else:
                    if fix == 0:
                        tmp.setAttribute('adj', 'XYZ')
                    else:
                        tmp.setAttribute('adj', 'xyz')
                points_observations.appendChild(tmp)
        if self.dimension == 1:
            hd = doc.createElement('height-differences')
            points_observations.appendChild(hd)
        for o in self.observations:
            if o.station == 'station':
                # station record
                st_id = o.point_id
                if o.th is None:
                    ih = 0
                else:
                    ih = o.th
                if self.dimension in [2, 3]:
                    sta = doc.createElement('obs')
                    sta.setAttribute('from', o.point_id)
                    points_observations.appendChild(sta)
            else:
                # observation
                if self.dimension == 2:
                    # horizontal network
                    if o.hz is not None:
                        tmp = doc.createElement('direction')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.hz.get_angle('GON')))
                        sta.appendChild(tmp)
                    if o.d is not None:
                        # horizontal distance
                        hd = o.horiz_dist()
                        if hd is not None:
                            tmp = doc.createElement('distance')
                            tmp.setAttribute('to', o.point_id)
                            tmp.setAttribute('val', str(hd))
                            sta.appendChild(tmp)
                elif self.dimension == 1:
                    # elevations only 1d
                    if o.th is None:
                        th = 0
                    else:
                        th = o.th
                    if o.d is not None and o.v is not None:
                        tmp = doc.createElement('dh')
                        tmp.setAttribute('from', st_id)
                        tmp.setAttribute('to', o.point_id)
                        # TODO hibaterjedes
                        tmp.setAttribute('stdev', '1')
                        sz = math.sin(o.v.get_angle())
                        w = self.stdev_dist + self.stdev_dist1 * o.d.d / 1000
                        ro_cc = 200 * 100 * 100 / math.pi
                        if o.d.mode == 'SD':
                            cz = math.cos(o.v.get_angle())
                            tmp.setAttribute('val', str(o.d.d * cz + ih - th))
                            tmp.setAttribute(
                                'stdev',
                                str(
                                    math.sqrt(cz**2 * w**2 +
                                              (o.d.d * 1000)**2 * sz**2 *
                                              (self.stdev_angle / RO_CC)**2)))
                        else:
                            tz = math.tan(o.v.get_angle())
                            tmp.setAttribute(
                                'val',
                                str(o.d.d / math.tan(o.v.get_angle()) + ih -
                                    th))
                            tmp.setAttribute(
                                'stdev',
                                str(
                                    math.sqrt((1 / tz)**2 * w**2 +
                                              (o.d.d * 1000)**2 *
                                              (o.d.d * 1000)**2 *
                                              (1 / sz**2)**2 *
                                              (self.stdev_angle / RO_CC)**2)))
                        hd.appendChild(tmp)
                elif self.dimension == 3:
                    # 3d
                    if o.th is None:
                        th = 0
                    else:
                        th = o.th
                    if o.hz is not None:
                        tmp = doc.createElement('direction')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.hz.get_angle('GON')))
                        sta.appendChild(tmp)
                    if o.d is not None:
                        if o.d.mode == 'SD':
                            tmp = doc.createElement('s-distance')
                            tmp.setAttribute('val', str(o.d.d))
                            tmp.setAttribute('from_dh', str(ih))
                            tmp.setAttribute('to_dh', str(th))
                        else:
                            tmp = doc.createElement('distance')
                            tmp.setAttribute('val', str(o.d.d))
                        tmp.setAttribute('to', o.point_id)
                        sta.appendChild(tmp)
                    if o.v is not None:
                        tmp = doc.createElement('z-angle')
                        tmp.setAttribute('to', o.point_id)
                        tmp.setAttribute('val', str(o.v.get_angle('GON')))
                        tmp.setAttribute('from_dh', str(ih))
                        tmp.setAttribute('to_dh', str(th))
                        sta.appendChild(tmp)
                else:
                    # unknown dimension
                    return None
        # generate temp file name
        tmpf = QTemporaryFile(QDir.temp().absoluteFilePath('w'))
        tmpf.open(QIODevice.WriteOnly)
        tmpf.close()
        tmp_name = tmpf.fileName()
        f = QFile(tmp_name + '.xml')
        if f.open(QIODevice.WriteOnly):
            f.write(doc.toByteArray())
            f.close()

        # run gama-local
        if self.gama_prog is None:
            return None
        status = QProcess.execute(self.gama_prog, [
            tmp_name + '.xml', '--angles', '360', '--text', tmp_name + '.txt',
            '--xml', tmp_name + 'out.xml'
        ])
        if status != 0:
            return None

        xmlParser = QXmlSimpleReader()
        xmlFile = QFile(tmp_name + 'out.xml')
        xmlInputSource = QXmlInputSource(xmlFile)
        doc.setContent(xmlInputSource, xmlParser)

        f_txt = QFile(tmp_name + '.txt')
        f_txt.open(QIODevice.ReadOnly)
        res = f_txt.readAll().data()
        f_txt.close()

        # store coordinates
        adj_nodes = doc.elementsByTagName('adjusted')
        if adj_nodes.count() < 1:
            return res
        adj_node = adj_nodes.at(0)
        for i in range(len(adj_node.childNodes())):
            pp = adj_node.childNodes().at(i)
            if pp.nodeName() == 'point':
                for ii in range(len(pp.childNodes())):
                    ppp = pp.childNodes().at(ii)
                    if ppp.nodeName() == 'id':
                        p = Point(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'Y' or ppp.nodeName() == 'y':
                        p.e = float(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'X' or ppp.nodeName() == 'x':
                        p.n = float(ppp.firstChild().nodeValue())
                    elif ppp.nodeName() == 'Z' or ppp.nodeName() == 'z':
                        p.z = float(ppp.firstChild().nodeValue())
                ScPoint(p).store_coord(self.dimension)
        # remove input xml and output xml
        tmpf.remove()
        f_txt.remove()
        f.remove()
        xmlFile.remove()

        return res
 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 _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()
Exemple #22
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()