Ejemplo n.º 1
0
    def sendVote(self, plugin_id, vote):
        """ send vote via the RPC """

        if not plugin_id or not vote:
            return False
        url = "http://plugins.qgis.org/plugins/RPC2/"
        params = {"id": "djangorpc", "method": "plugin.vote", "params": [str(plugin_id), str(vote)]}
        req = QNetworkRequest(QUrl(url))
        req.setRawHeader(b"Content-Type", b"application/json")
        QgsNetworkAccessManager.instance().post(req, bytes(json.dumps(params), "utf-8"))
        return True
Ejemplo n.º 2
0
    def sendVote(self, plugin_id, vote):
        """ send vote via the RPC """

        if not plugin_id or not vote:
            return False
        url = "http://plugins.qgis.org/plugins/RPC2/"
        params = "{\"id\":\"djangorpc\",\"method\":\"plugin.vote\",\"params\":[%s,%s]}" % (str(plugin_id), str(vote))
        req = QNetworkRequest(QUrl(url))
        req.setRawHeader("Content-Type", "application/json")
        QgsNetworkAccessManager.instance().post(req, params)
        return True
Ejemplo n.º 3
0
    def sendVote(self, plugin_id, vote):
        """ send vote via the RPC """

        if not plugin_id or not vote:
            return False
        url = "http://plugins.qgis.org/plugins/RPC2/"
        params = "{\"id\":\"djangorpc\",\"method\":\"plugin.vote\",\"params\":[%s,%s]}" % (
            str(plugin_id), str(vote))
        req = QNetworkRequest(QUrl(url))
        req.setRawHeader("Content-Type", "application/json")
        QgsNetworkAccessManager.instance().post(req, params)
        return True
    def sendVote(self, plugin_id, vote):
        """ send vote via the RPC """

        if not plugin_id or not vote:
            return False
        url = "http://plugins.qgis.org/plugins/RPC2/"
        params = {"id": "djangorpc", "method": "plugin.vote", "params": [str(plugin_id), str(vote)]}
        req = QNetworkRequest(QUrl(url))
        req.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorClass), "QgsPluginInstaller")
        req.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorRequestId), "sendVote")
        req.setRawHeader(b"Content-Type", b"application/json")
        QgsNetworkAccessManager.instance().post(req, bytes(json.dumps(params), "utf-8"))
        return True
    def fetchNext(self):
        if len(self.queue) == 0:
            return
        url = self.queue.pop(0)
        self.log("fetchNext: %s" % url)

        request = QNetworkRequest(QUrl(url))
        request.setRawHeader("User-Agent", self.userAgent)
        reply = QgsNetworkAccessManager.instance().get(request)
        reply.finished.connect(self.replyFinishedSlot)
        self.requestingUrls.append(url)
        self.replies.append(reply)
        return reply
Ejemplo n.º 6
0
    def create_request(self, request_type: str):
        """Creates a QNetworkRequest() with appropriate headers and URL according to the
        'request_type' parameter.

        :param str request_type: type of request to create. Options:
            - 'token'
            - 'search'
            - 'details'
            - 'shares'

        :returns: the QNetworkRequest to send to the Isogeo's API

        :rtype: QNetworkRequest
        """
        # creating headers (same steps wathever request_type value)
        header_value = QByteArray()
        header_name = QByteArray()
        header_name.append("Authorization")
        # for token request
        if request_type == "token":
            # filling request header with credentials
            header_value.append("Basic ")
            header_value.append(
                base64.b64encode("{}:{}".format(self.app_id,
                                                self.app_secret).encode()))
            # creating the QNetworkRequest from oAuth2 authentication URL
            request = QNetworkRequest(QUrl(self.api_url_token))
            # creating and setting the 'Content-type header'
            ct_header_value = QByteArray()
            ct_header_value.append("application/json")
            request.setHeader(request.ContentTypeHeader, ct_header_value)
        # for other request_type, setting appropriate url
        else:
            if request_type == "shares":
                url = QUrl("{}/shares".format(self.api_url_base))
            elif request_type == "search" or request_type == "details":
                url = QUrl(self.currentUrl)
            else:
                logger.debug(
                    "Unkown request type asked : {}".format(request_type))
                raise ValueError
                return 0
            # filling request header with token
            header_value.append(self.token)
            request = QNetworkRequest(url)
        # creating QNetworkRequest from appropriate url
        request.setRawHeader(header_name, header_value)
        return request
Ejemplo n.º 7
0
    def send_request_to_isogeo_api(self, token, limit=10):
        """Send a content url to the Isogeo API.

        This takes the currentUrl variable and send a request to this url,
        using the token variable.
        """
        myurl = QUrl(self.currentUrl)
        request = QNetworkRequest(myurl)
        request.setRawHeader("Authorization", token)
        if self.requestStatusClear is True:
            self.requestStatusClear = False
            api_reply = self.manager.get(request)
            api_reply.finished.connect(
                partial(self.handle_api_reply, answer=api_reply))
        else:
            pass
Ejemplo n.º 8
0
    def api_get_request(self):
        logger.debug("\n----------------- Sending request -----------------")

        # creating credentials header
        crd_header_value = QByteArray()
        crd_header_value.append(self.token)
        crd_header_name = QByteArray()
        crd_header_name.append("Authorization")

        # creating request
        rqst = QNetworkRequest(QUrl(self.request_url))

        # setting credentials header
        rqst.setRawHeader(crd_header_name, crd_header_value)  # sending request

        rqst_reply = self.naMngr.get(rqst)
        rqst_reply.finished.connect(partial(self.api_handle_request, reply=rqst_reply))
Ejemplo n.º 9
0
 def delegate_download(self, action_url, method, headers, data, js_cb_func,
                       js_cb_object_id):
     """
     :param action_url: url to call on ipt api
     :param method: string like 'POST'
     :param headers: list of strings
     :param data: list of dictionaries {name (string) value(string)}
     :param delegate_download_js_cb: javascript callback
     :param js_cb_object_id: id of the javascript object to be called back
     """
     # TODO: Accept also methods other than POST
     if method != 'POST':
         self.call_js_cb(js_cb_func, js_cb_object_id, None, 1,
                         'Method %s not allowed' % method)
         return False
     if ':' in action_url:
         qurl = QUrl(action_url)
     elif action_url.startswith('/'):
         qurl = QUrl("%s%s" % (self.parent().host, action_url))
     else:
         url = "%s/%s" % ('/'.join([
             str(x) for x in self.parent().web_view.url().toEncoded().split(
                 '/')[:-1]
         ]), action_url)
         qurl = QUrl(url)
     manager = self.parent().web_view.page().networkAccessManager()
     request = QNetworkRequest(qurl)
     request.setAttribute(REQUEST_ATTRS['instance_finished_cb'],
                          self.manager_finished_cb)
     request.setAttribute(REQUEST_ATTRS['js_cb_object_id'], js_cb_object_id)
     request.setAttribute(REQUEST_ATTRS['js_cb_func'], js_cb_func)
     for header in headers:
         request.setRawHeader(header['name'], header['value'])
     multipart = QHttpMultiPart(QHttpMultiPart.FormDataType)
     for d in data:
         part = QHttpPart()
         part.setHeader(QNetworkRequest.ContentDispositionHeader,
                        "form-data; name=\"%s\"" % d['name'])
         part.setBody(d['value'])
         multipart.append(part)
     reply = manager.post(request, multipart)
     # NOTE: needed to avoid segfault!
     multipart.setParent(reply)  # delete the multiPart with the reply
     return True
Ejemplo n.º 10
0
    def api_authentification(self):
        logger.debug("\n------------------ Authentication ------------------")

        # creating credentials header
        logger.debug("Creating credentials header")

        crd_header_value = QByteArray()
        crd_header_value.append("Basic ")
        crd_header_value.append(
            base64.b64encode("{}:{}".format(self.app_id,
                                            self.app_secrets).encode()))

        crd_header_name = QByteArray()
        crd_header_name.append("Authorization")

        # creating Content-Type header
        logger.debug("Creating 'Content-Type' header")

        ct_header_value = QByteArray()
        ct_header_value.append("application/json")

        # creating request
        token_rqst = QNetworkRequest(QUrl(self.token_url))
        logger.debug("Creating token request : {}".format(token_rqst.url()))

        # setting headers
        token_rqst.setRawHeader(crd_header_name, crd_header_value)
        logger.debug("Setting credentials header : {}".format(
            token_rqst.rawHeader(crd_header_name)))

        token_rqst.setHeader(token_rqst.ContentTypeHeader, ct_header_value)
        logger.debug("Setting 'Content-Type' header : {}".format(
            token_rqst.header(token_rqst.ContentTypeHeader)))

        # creating data
        data = QByteArray()
        data.append(urlencode({"grant_type": "client_credentials"}))
        logger.debug("Creating data : {}".format(data))

        # requesting and handle reply
        logger.debug("Asking for token")
        token_reply = self.naMngr.post(token_rqst, data)
        token_reply.finished.connect(
            partial(self.api_handle_token, reply=token_reply))
Ejemplo n.º 11
0
def get_reply(url):
    qgs_request = QgsBlockingNetworkRequest()
    request = QNetworkRequest(QUrl(url))
    request.setRawHeader(b"User-Agent", b"qgis-pdokservices-plugin")
    err = qgs_request.get(request, True)

    if err is QgsBlockingNetworkRequest.NoError:
        # TODO: add proper error handling
        QgsMessageLog.logMessage("SERVER ERROR OCCURED",
                                 PLUGIN_NAME,
                                 level=Qgis.Info)

    reply = qgs_request.reply()
    if reply.error() is QNetworkReply.NoError:
        # TODO: add proper error handling
        QgsMessageLog.logMessage("SERVER ERROR OCCURED",
                                 PLUGIN_NAME,
                                 level=Qgis.Info)
    return reply
def _sync_get(url):
    global __network_manager
    if __network_manager is None:
        __network_manager = QNetworkAccessManager()
        __network_manager.setProxy(QgsNetworkAccessManager.instance().proxy())
    pause = QEventLoop()
    req = QNetworkRequest(url)
    req.setRawHeader(b"Accept", b"application/xml")
    req.setRawHeader(b"Accept-Language", b"fr")
    reply = __network_manager.get(req)
    reply.finished.connect(pause.quit)
    is_ok = [True]

    def onError(self):
        is_ok[0] = False
        pause.quit()

    reply.error.connect(onError)
    pause.exec_()
    return reply, is_ok[0]
Ejemplo n.º 13
0
 def canvasReleaseEvent(self, event):
     # Make sure the point is transfored to 4326
     pt = self.toMapCoordinates(event.pos())
     canvasCRS = self.canvas.mapSettings().destinationCrs()
     transform = QgsCoordinateTransform(canvasCRS, self.epsg4326,
                                        QgsProject.instance())
     pt = transform.transform(pt.x(), pt.y())
     url = '{}?format=json&lat={:f}&lon={:f}&zoom={:d}&addressdetails=0&polygon_text=1'.format(
         self.settings.reverseURL(), pt.y(), pt.x(),
         self.settings.levelOfDetail)
     # print url
     qurl = QUrl(url)
     if self.reply is not None:
         self.reply.finished.disconnect(self.replyFinished)
         self.reply.abort()
         self.reply = None
     request = QNetworkRequest(qurl)
     request.setRawHeader(
         b"User-Agent",
         b"Mozilla/5.0 (Windows NT 6.1: WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
     )
     request.setRawHeader(b"Connection", b"keep-alive")
     request.setRawHeader(
         b"Accept",
         b"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
     self.reply = QgsNetworkAccessManager.instance().get(request)
     self.reply.finished.connect(self.replyFinished)
     if not self.reverseGeoCodeDialog.isVisible():
         self.show()
Ejemplo n.º 14
0
    def processFreeFormData(self):
        self.geocodes = {}
        addresses = []

        # Get the text for the Address Query Box an dgo through line by line to geocode it
        inputtext = str(self.addressTextEdit.toPlainText())
        lines = inputtext.splitlines()
        self.pointLayer = None
        self.numAddress = 0
        self.numErrors = 0
        self.totalAddress = 0

        # Create a list of all the Addresses. We want to get an accurate count
        for address in lines:
            # Get rid of beginning and end space
            address = address.strip()
            # Skip any blank lines
            if not address:
                continue
            self.numAddress += 1
            addresses.append(address)

        if self.numAddress > self.settings.maxAddress:
            self.iface.messageBar().pushMessage(
                "",
                "Maximum addresses to process were exceeded. Please reduce the number and try again.",
                level=QgsMessageBar.WARNING,
                duration=4)
            return

        # Save the total number of addresses because numAddress will be reduced to 0 as processed
        self.totalAddress = self.numAddress

        if self.numAddress:
            self.createPointLayer()
        maxResults = self.maxResultsSpinBox.value()
        showDetails = int(self.detailedAddressCheckBox.isChecked())
        for address in addresses:
            # Replace internal spaces with + signs
            address2 = re.sub('\s+', '+', address)
            url = '{}?q={}&format=json&limit={}&polygon=0&addressdetails={}'.format(
                self.settings.searchURL(), address2, maxResults, showDetails)
            # print url
            qurl = QUrl(url)
            request = QNetworkRequest(qurl)
            request.setRawHeader(
                b"User-Agent",
                b"Mozilla/5.0 (Windows NT 6.1: WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
            )
            request.setRawHeader(b"Connection", b"keep-alive")
            request.setRawHeader(
                b"Accept",
                b"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
            )
            reply = QgsNetworkAccessManager.instance().get(request)
            self.geocodes[reply] = address
            reply.finished.connect(self.replyFinished)
def _sync_get(url):
    global __network_manager
    if __network_manager is None:
        __network_manager = QNetworkAccessManager()
        __network_manager.setProxy(QgsNetworkAccessManager.instance().proxy())
    pause = QEventLoop()
    req = QNetworkRequest(url)
    req.setRawHeader(b"Accept", b"application/xml")
    req.setRawHeader(b"Accept-Language", bytes(settings.value("default_language", "fr"), "utf8"))
    req.setRawHeader(b"User-Agent", bytes(settings.value('http_user_agent', plugin_name()), "utf8"))
    reply = __network_manager.get(req)
    reply.finished.connect(pause.quit)
    is_ok = [True]
    def onError(self):
        is_ok[0] = False
        pause.quit()
    reply.error.connect(onError)
    pause.exec_()
    return reply, is_ok[0]
def _sync_get(url):
    global __network_manager
    if __network_manager is None:
        __network_manager = QNetworkAccessManager()
        __network_manager.setProxy(QgsNetworkAccessManager.instance().proxy())
    pause = QEventLoop()
    req = QNetworkRequest(url)
    req.setRawHeader(b"Accept", b"application/xml")
    req.setRawHeader(b"Accept-Language",
                     bytes(settings.value("default_language", "fr"), "utf8"))
    req.setRawHeader(
        b"User-Agent",
        bytes(settings.value("http_user_agent", plugin_name()), "utf8"))
    reply = __network_manager.get(req)
    reply.finished.connect(pause.quit)
    is_ok = [True]

    def onError(self):
        is_ok[0] = False
        pause.quit()

    reply.error.connect(onError)
    pause.exec_()
    return reply, is_ok[0]
class ConnectDockWidget(BASE, WIDGET):

    def __init__(self, parent=None, visible=False):
        super(ConnectDockWidget, self).__init__(parent)
        self.setupUi(self)

        self.loggedIn = False
        self.token = None

        self.progressBar.hide()

        self.setVisible(visible)

        self.setWindowIcon(QIcon(os.path.join(pluginPath, 'icons', 'connect.svg')))
        self.svgLogo.load(os.path.join(pluginPath, 'icons', 'connect-logo.svg'))

        self.lblSmallLogo.setPixmap(QPixmap(os.path.join(pluginPath, 'icons', 'connect.png')))
        self.lblSmallLogo.hide()

        btnOk = self.buttonBox.button(QDialogButtonBox.Ok)
        btnOk.setText('Login')

        # setup tab bar
        self.tabsContent.addTab('Knowledge')
        self.tabsContent.addTab('Data')
        self.tabsContent.addTab('Plugins')
        self.tabsContent.setDocumentMode(True)
        self.tabsContent.setDrawBase(False)
        self._toggleCategoriesSelector(True)
        self.tabsContent.setCurrentIndex(0)
        self.tabsContent.currentChanged.connect(self.tabChanged)

        self.buttonBox.helpRequested.connect(self.showHelp)
        self.buttonBox.accepted.connect(self.logIn)
        self.btnSignOut.clicked.connect(self.showLogin)

        self.labelLevel.linkActivated.connect(self.showLogin)
        self.leSearch.buttonClicked.connect(self.search)
        self.leSearch.returnPressed.connect(self.search)
        self.connectWidget.rememberStateChanged.connect(self.updateSettings)

        self.webView.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
        cssFile = os.path.join(pluginPath, "resources", "search.css")
        with open(cssFile) as f:
            content = f.read()

        self.css = content.replace("#PLUGIN_PATH#", QUrl.fromLocalFile(pluginPath).toString())

        self.webView.linkClicked.connect(self.linkClicked)

        for cat, cls in connect.categories.items():
            self.cmbContentType.addItem(cls[1], cat)

        settings = QSettings()
        settings.beginGroup(reposGroup)
        self.authId = settings.value(boundlessRepoName + '/authcfg', '')
        settings.endGroup()
        if self.authId not in QgsAuthManager.instance().configIds():
            self.authId = ''
            utils.setRepositoryAuth(self.authId)

        self._toggleSearchControls(True)
        self.showLogin()

    def showEvent(self, event):
        fillCredentials = pluginSetting("rememberCredentials")
        if self.authId != '' and fillCredentials and not self.loggedIn:
            authConfig = QgsAuthMethodConfig()
            if self.authId in QgsAuthManager.instance().configIds():
                QgsAuthManager.instance().loadAuthenticationConfig(self.authId, authConfig, True)
                username = authConfig.config('username')
                password = authConfig.config('password')
            else:
                self.authId = ''
                utils.setRepositoryAuth(self.authId)
                self._showMessage('Could not find Connect credentials in the database.',
                                  QgsMessageBar.WARNING)
                username = ''
                password = ''

            self.connectWidget.setLogin(username)
            self.connectWidget.setPassword(password)

        BASE.showEvent(self, event)

    def keyPressEvent(self, event):
        if self.stackedWidget.currentIndex() == 0:
            if event.key() in [Qt.Key_Return, Qt.Key_Enter]:
                self.logIn()

        BASE.keyPressEvent(self, event)

    def showLogin(self):
        self.stackedWidget.setCurrentIndex(0)
        self.webView.setVisible(False)
        self.webView.setHtml("")
        self.leSearch.setText("")
        self.tabsContent.setCurrentIndex(0)
        self.svgLogo.show()
        self.lblSmallLogo.hide()
        connect.resetToken()
        self.token = None

        fillCredentials = pluginSetting("rememberCredentials")
        if fillCredentials:
            self.connectWidget.setRemember(Qt.Checked)

            username = ""
            password = ""
            if self.authId != "":
                authConfig = QgsAuthMethodConfig()
                if self.authId in QgsAuthManager.instance().configIds():
                    QgsAuthManager.instance().loadAuthenticationConfig(self.authId, authConfig, True)
                    username = authConfig.config("username")
                    password = authConfig.config("password")
                self.connectWidget.setLogin(username)
                self.connectWidget.setPassword(password)
        else:
            self.connectWidget.setRemember(Qt.Unchecked)
            self.connectWidget.setLogin("")
            self.connectWidget.setPassword("")

    def showHelp(self):
        webbrowser.open_new("file://{}".format(os.path.join(pluginPath, "docs", "html", "index.html")))

    def linkClicked(self, url):
        name = url.toString()
        if name == "next":
            self.search(self.searchPage + 1)
        elif name == "previous":
            self.search(self.searchPage - 1)
        elif name.startswith("canvas"):
            content = self.searchResults[name]
            content.addToCanvas(self.roles)
        elif name.startswith("project"):
            content = self.searchResults[name]
            content.addToDefaultProject(self.roles)
        else:
            content = self.searchResults[name]
            content.open(self.roles)

    def logIn(self):
        if self.connectWidget.login().strip() == "" or self.connectWidget.password().strip() == "":
            self._showMessage("Please enter valid Connect credentials "
                              "to use plugin.")
            return

        setPluginSetting("rememberCredentials", self.connectWidget.remember())

        utils.addBoundlessRepository()

        self.request = QNetworkRequest(QUrl(authEndpointUrl))
        httpAuth = base64.b64encode(b"%s:%s" % (self.connectWidget.login().strip(), self.connectWidget.password().strip())).decode("ascii")
        self.request.setRawHeader('Authorization', 'Basic {}'.format(httpAuth))
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.token = connect.getToken(self.connectWidget.login().strip(), self.connectWidget.password().strip())
        if self.token is None:
            QApplication.restoreOverrideCursor()
            QMessageBox.warning(self, "Error!", "Can not get token. Please check you credentials and endpoint URL in plugin settings.")
            return
        self.reply = QgsNetworkAccessManager.instance().get(self.request)
        self.reply.finished.connect(self.requestFinished)

    def search(self, page=0):
        if self.tabsContent.currentIndex() == 0:
            categories = self.cmbContentType.selectedData(Qt.UserRole)
            if len(categories) == 0:
                categories = list(connect.categories.keys())
            cat = ','.join(categories)
            self._findContent(cat, page)
        elif self.tabsContent.currentIndex() == 1:
            if oauth2_supported():
                self._findBasemaps()
        elif self.tabsContent.currentIndex() == 2:
            self._findPlugins()

        self.svgLogo.hide()
        self.lblSmallLogo.show()

    def _getSearchHtml(self, body):
        html = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
                              <html>
                              <head>
                              <style>
                              {}
                              </style>
                              </head>
                              <body>
                              {}
                              </body>
                              </html>'''.format(self.css, body)
        return html

    def _findContent(self, category, page=0):
        if self.token is None:
            self._showMessage("Seems you have no Connect token. Login with valid Connect credentials and try again.",
                              QgsMessageBar.WARNING)
            return

        text = self.leSearch.text().strip()
        self.searchPage = page
        try:
            self._toggleSearchProgress()
            results = execute(lambda: connect.search(text, category, self.searchPage, self.token))
            if results:
                self.searchResults = {r.url:r for r in results}
                body = "<ul>"
                for r in results:
                    body += "<li>%s</li>" % r.asHtmlEntry(self.roles)
                body += "</ul>"

                if len(results) == connect.RESULTS_PER_PAGE:
                    if self.searchPage == 0:
                        body += "<div class='pagination'><div class='next'><a href='next'>Next</a></div></div>"
                    else:
                        body += "<div class='pagination'><div class='prev'><a href='previous'>Prev</a></div><div class='next'><a href='next'>Next</a></div></div>"
                else:
                    if self.searchPage != 0:
                        body += "<div class='pagination'><div class='prev'><a href='previous'>Prev</a></div></div>"
            else:
                body = ""

            self.webView.setHtml(self._getSearchHtml(body))
            self.webView.setVisible(True)
            self._toggleSearchProgress(False)
        except Exception as e:
            self._toggleSearchProgress(False)
            self.webView.setHtml("")
            self._showMessage("There has been a problem performing the search:\n{}".format(str(e.args[0])),
                              QgsMessageBar.WARNING)

    def _findPlugins(self):
        if self.token is None:
            self._showMessage("Seems you have no Connect token. Login with valid Connect credentials and try again.",
                              QgsMessageBar.WARNING)
            return

        text = self.leSearch.text().strip()
        try:
            self._toggleSearchProgress()
            results = execute(lambda: connect.findAll(text, "PLUG", self.token))
            body = "<h1>{} results</h1><hr/>".format(len(results))
            if results:
                self.searchResults = {r.url:r for r in results}
                body += "<ul>"
                for r in results:
                    body += "<li>%s</li>" % r.asHtmlEntry(self.roles)
                body += "</ul>"

            self.webView.setHtml(self._getSearchHtml(body))
            self.webView.setVisible(True)
            self._toggleSearchProgress(False)
        except Exception as e:
            self._toggleSearchProgress(False)
            self.webView.setHtml("")
            self._showMessage("There has been a problem performing the search:\n{}".format(str(e.args[0])),
                              QgsMessageBar.WARNING)

    def _findBasemaps(self):
        if self.token is None:
            self._showMessage("Seems you have no Connect token. Login with valid Connect credentials and try again.",
                              QgsMessageBar.WARNING)
            return

        text = self.leSearch.text().strip()
        try:
            results = execute(lambda: connect.searchBasemaps(text, self.token))
            body = "<h1>{} results</h1><hr/>".format(len(results))
            if results:
                self.searchResults = {"canvas"+r.url:r for r in results}
                self.searchResults.update({"project"+r.url:r for r in results})
                body += "<ul>"
                for r in results:
                    body += "<li>%s</li>" % r.asHtmlEntry(self.roles)
                body += "</ul>"
            self.webView.setHtml(self._getSearchHtml(body))
            self.webView.setVisible(True)
        except Exception as e:
            self._toggleSearchProgress(False)
            self.webView.setHtml("")
            self._showMessage("There has been a problem performing the search:\n{}".format(str(e.args[0])),
                              QgsMessageBar.WARNING)

    def requestFinished(self):
        QApplication.restoreOverrideCursor()
        reply = self.sender()
        visible = True
        if reply.error() != QNetworkReply.NoError:
            if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 401:
                msg = 'Your credentials seem invalid.\n' \
                      'You will not be able to access any content.\n' \
                      'Please enter valid Connect credentials to use plugin.'
            else:
                msg = 'An error occurred when validating your ' \
                      'credentials. Server responded:\n{}.\n' \
                      'You will not be able to access any content.\n' \
                      'Please enter valid Connect credentials to use plugin'.format(reply.errorString())
            QMessageBox.warning(self, 'Error!', msg)
            return
        else:
            self.btnSignOut.setText("Logout")
            self.saveOrUpdateAuthId()
            self.roles = json.loads(str(reply.readAll()))

            # if this is first login ask if user wants to have basemap
            settings = QSettings()
            firstLogin = settings.value('boundlessconnect/firstLogin', True, bool)
            if firstLogin:
                settings.setValue('boundlessconnect/firstLogin', False)
                if oauth2_supported() and basemaputils.canAccessBasemap(self.roles):
                    ret = QMessageBox.question(self,
                                               self.tr('Base Maps'),
                                               self.tr('Would you like to add Boundless basemap '
                                                       'to your default project? This option can '
                                                       'be disabled at any time in the settings.'),
                                               QMessageBox.Yes | QMessageBox.No,
                                               QMessageBox.No)
                    if ret == QMessageBox.Yes:
                        if self.token is None:
                            self._showMessage("Seems you have no Connect token. Login with valid Connect credentials and try again.",
                                              QgsMessageBar.WARNING)
                            return

                        if self.installBaseMap():
                            pass

        execute(connect.loadPlugins)
        self.stackedWidget.setCurrentIndex(1)
        self.labelLevel.setVisible(visible)
        self.labelLevel.setText("Logged in as: <b>%s</b>" % self.connectWidget.login())

        self.loggedIn = True

        cat = ",".join(list(connect.categories.keys()))
        self._findContent(cat)

    def saveOrUpdateAuthId(self):
        if self.authId == '':
            authConfig = QgsAuthMethodConfig('Basic')
            self.authId = QgsAuthManager.instance().uniqueConfigId()
            authConfig.setId(self.authId)
            authConfig.setConfig('username', self.connectWidget.login().strip())
            authConfig.setConfig('password', self.connectWidget.password().strip())
            authConfig.setName('Boundless Connect Portal')

            authConfig.setUri(pluginSetting('repoUrl'))

            if QgsAuthManager.instance().storeAuthenticationConfig(authConfig):
                utils.setRepositoryAuth(self.authId)
            else:
                self._showMessage('Unable to save credentials.', QgsMessageBar.WARNING)
        else:
            authConfig = QgsAuthMethodConfig()
            QgsAuthManager.instance().loadAuthenticationConfig(self.authId, authConfig, True)
            authConfig.setConfig('username', self.connectWidget.login().strip())
            authConfig.setConfig('password', self.connectWidget.password().strip())
            QgsAuthManager.instance().updateAuthenticationConfig(authConfig)

        # also setup OAuth2 configuration if possible
        if oauth2_supported():
            endpointUrl = "{}/token/oauth?version={}".format(pluginSetting("connectEndpoint"), pluginSetting("apiVersion"))
            setup_oauth(self.connectWidget.login().strip(), self.connectWidget.password().strip(), endpointUrl)

    def tabChanged(self, index):
        if index == 0:
            self._toggleCategoriesSelector(True)
            self._toggleSearchControls(True)
            self.webView.setHtml("")
            categories = self.cmbContentType.selectedData(Qt.UserRole)
            if len(categories) == 0:
                categories = list(connect.categories.keys())
            cat = ','.join(categories)
            self._findContent(cat)
        elif index == 1:
            self._toggleCategoriesSelector(False)
            self._toggleSearchControls(oauth2_supported())
            self.webView.setHtml("")
            if oauth2_supported():
                self._findBasemaps()
        elif index == 2:
            self._toggleCategoriesSelector(False)
            self._toggleSearchControls(True)
            self.webView.setHtml("")
            self._findPlugins()

    def _toggleCategoriesSelector(self, visible):
        self.lblCategorySearch.setVisible(visible)
        self.cmbContentType.setVisible(visible)

    def _toggleSearchControls(self, enabled):
        self.leSearch.setEnabled(enabled)
        self.lblOAuthWarning.setVisible(not enabled)

    def installBaseMap(self):
        authcfg = get_oauth_authcfg()
        if authcfg is None:
            self._showMessage('Could not find a valid authentication configuration!',
                              QgsMessageBar.WARNING)
            return False

        authId = authcfg.id()
        mapBoxStreets = basemaputils.getMapBoxStreetsMap(self.token)

        if os.path.isfile(basemaputils.defaultProjectPath()):
            # default project already exists, make a backup copy
            backup = basemaputils.defaultProjectPath().replace(
                '.qgs', '-%s.qgs' % datetime.now().strftime('%Y-%m-%d-%H_%M_%S'))
            shutil.copy2(basemaputils.defaultProjectPath(), backup)
            self._showMessage("A backup copy of the previous default project "
                              "has been saved to {}".format(backup))

            msgBox = QMessageBox()
            msgBox.setIcon(QMessageBox.Question)
            msgBox.setText("A default project already exists.  Do you "
                           "wish to add the Boundless basemap to your "
                           "existing default project or create a new "
                           "default project?")
            btnAdd = msgBox.addButton("Add", QMessageBox.ActionRole)
            btnCreateNew = msgBox.addButton("Create New", QMessageBox.ActionRole)
            msgBox.exec_()
            if msgBox.clickedButton() == btnAdd:
                if not basemaputils.addToDefaultProject([mapBoxStreets], ["Mapbox Streets"], authId):
                    self._showMessage("Could not update default project with basemap!",
                                      QgsMessageBar.WARNING)
                    return False
            elif msgBox.clickedButton() == btnCreateNew:
                template = basemaputils.PROJECT_DEFAULT_TEMPLATE

                prj = basemaputils.createDefaultProject([mapBoxStreets], ["Mapbox Streets"],
                                                        template, authId)
                if prj is None or prj == '':
                    self._showMessage("Could not create a valid default project from the template '{}'!".format(template),
                                      QgsMessageBar.WARNING)
                    return False

                if not basemaputils.writeDefaultProject(prj):
                    self._showMessage("Could not write the default project on disk!",
                                      QgsMessageBar.WARNING)
                    return False
        else:
            # no default project, create one
            template = basemaputils.PROJECT_DEFAULT_TEMPLATE

            prj = basemaputils.createDefaultProject([mapBoxStreets], ["Mapbox Streets"],
                                               template, authId)
            if prj is None or prj == '':
                self._showMessage("Could not create a valid default project from the template '{}'!".format(template),
                                  QgsMessageBar.WARNING)
                return False

            if not basemaputils.writeDefaultProject(prj):
                self._showMessage("Could not write the default project on disk!",
                                  QgsMessageBar.WARNING)
                return False

        self._showMessage("Basemap added to the default project.")
        return True

    def updateSettings(self, state):
        if state == Qt.Checked:
            setPluginSetting("rememberCredentials", True)
        else:
            setPluginSetting("rememberCredentials", False)

    def _toggleSearchProgress(self, show=True):
        if show:
            self.progressBar.setRange(0, 0)
            self.progressBar.show()
        else:
            self.progressBar.setRange(0, 100)
            self.progressBar.reset()
            self.progressBar.hide()

    def _showMessage(self, message, level=QgsMessageBar.INFO):
        iface.messageBar().pushMessage(
            message, level, iface.messageTimeout())
Ejemplo n.º 18
0
    def request(self,
                url,
                method="GET",
                body=None,
                headers=None,
                redirections=DEFAULT_MAX_REDIRECTS,
                connection_type=None):
        """
        Make a network request by calling QgsNetworkAccessManager.
        redirections argument is ignored and is here only for httplib2 compatibility.
        """
        self.msg_log(u'http_call request: {0}'.format(url))
        self.http_call_result = Response({
            'status': 0,
            'status_code': 0,
            'status_message': '',
            'text': '',
            'ok': False,
            'headers': {},
            'reason': '',
            'exception': None,
        })
        req = QNetworkRequest()
        # Avoid double quoting form QUrl
        if PYTHON_VERSION >= 3:
            url = urllib.parse.unquote(url)
        else:
            url = urllib2.unquote(url)
        req.setUrl(QUrl(url))

        if self.cookie is not None:
            if headers is not None:
                headers['Cookie'] = self.cookie
            else:
                headers = {'Cookie': self.cookie}

        if self.basicauth is not None:
            if headers is not None:
                headers['Authorization'] = self.basicauth
            else:
                headers = {'Authorization': self.basicauth}

        if headers is not None:
            # This fixes a wierd error with compressed content not being correctly
            # inflated.
            # If you set the header on the QNetworkRequest you are basically telling
            # QNetworkAccessManager "I know what I'm doing, please don't do any content
            # encoding processing".
            # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1
            try:
                del headers['Accept-Encoding']
            except KeyError:
                pass
            for k, v in headers.items():
                if PYTHON_VERSION >= 3:
                    if isinstance(k, str):
                        k = k.encode('utf-8')
                    if isinstance(v, str):
                        v = v.encode('utf-8')
                req.setRawHeader(k, v)

        if self.authid:
            self.msg_log("Update request w/ authid: {0}".format(self.authid))
            QgsAuthManager.instance().updateNetworkRequest(req, self.authid)
        if self.reply is not None and self.reply.isRunning():
            self.reply.close()
        if method.lower() == 'delete':
            func = getattr(QgsNetworkAccessManager.instance(),
                           'deleteResource')
        else:
            func = getattr(QgsNetworkAccessManager.instance(), method.lower())
        # Calling the server ...
        # Let's log the whole call for debugging purposes:
        self.msg_log("Sending %s request to %s" %
                     (method.upper(), req.url().toString()))
        headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()}
        for k, v in headers.items():
            self.msg_log("%s: %s" % (k, v))
        if method.lower() in ['post', 'put']:
            if PYTHON_VERSION >= 3:
                if isinstance(body, str):
                    body = body.encode('utf-8')
            self.reply = func(req, body)
        else:
            self.reply = func(req)
        if self.authid:
            self.msg_log("Update reply w/ authid: {0}".format(self.authid))
            QgsAuthManager.instance().updateNetworkReply(
                self.reply, self.authid)

        self.reply.sslErrors.connect(self.sslErrors)
        self.reply.finished.connect(self.replyFinished)

        # Call and block
        self.el = QEventLoop()
        self.reply.finished.connect(self.el.quit)
        self.reply.downloadProgress.connect(self.downloadProgress)

        # Catch all exceptions (and clean up requests)
        try:
            self.el.exec_()
            # Let's log the whole response for debugging purposes:
            self.msg_log("Got response %s %s from %s" % \
                        (self.http_call_result.status_code,
                         self.http_call_result.status_message,
                         self.reply.url().toString()))
            headers = {
                str(h): str(self.reply.rawHeader(h))
                for h in self.reply.rawHeaderList()
            }
            for k, v in headers.items():
                self.msg_log("%s: %s" % (k, v))
            if len(self.http_call_result.text) < 1024:
                self.msg_log("Payload :\n%s" % self.http_call_result.text)
            else:
                self.msg_log("Payload is > 1 KB ...")
        except Exception as e:
            raise e
        finally:
            if self.reply is not None:
                if self.reply.isRunning():
                    self.reply.close()
                self.msg_log("Deleting reply ...")
                self.reply.deleteLater()
                self.reply = None
            else:
                self.msg_log("Reply was already deleted ...")
        if not self.http_call_result.ok:
            if self.http_call_result.exception and not self.exception_class:
                raise self.http_call_result.exception
            else:
                raise self.exception_class(self.http_call_result.reason)
        return (self.http_call_result, self.http_call_result.text)
Ejemplo n.º 19
0
    def handle_download(self):
        result_type_codes_download = [
            "logfiles",
            # non-groundwater codes
            "subgrid_map",
            "flow-aggregate",
            "id-mapping",
            # groundwater codes
            "results-3di",
            "aggregate-results-3di",
            "grid-admin",
        ]
        selection_model = self.dialog.downloadResultTableView.selectionModel()
        proxy_indexes = selection_model.selectedIndexes()
        if len(proxy_indexes) != 1:
            pop_up_info("Please select one result.")
            return
        proxy_selection_index = proxy_indexes[0]
        selection_index = self.dialog.download_proxy_model.mapToSource(
            proxy_selection_index)
        item = self.downloadable_results.rows[selection_index.row()]
        to_download = [
            r for r in item.results.value
            if r["result_type"]["code"] in result_type_codes_download
        ]
        to_download_urls = [dl["attachment_url"] for dl in to_download]
        logger.debug(item.name.value)

        # ask user where to store download
        directory = QFileDialog.getExistingDirectory(None,
                                                     "Choose a directory",
                                                     os.path.expanduser("~"))
        if not directory:
            return
        dir_name = get_valid_filename(item.name.value)
        self.download_directory = os.path.join(directory, dir_name)

        # For now, only work with empty directories that we create ourselves.
        # Because the files are downloaded and processed in chunks, we cannot
        # guarantee data integrity with existing files.
        if os.path.exists(self.download_directory):
            pop_up_info("The directory %s already exists." %
                        self.download_directory)
            return
        logger.info("Creating download directory.")
        os.mkdir(self.download_directory)

        logger.debug(self.download_directory)

        CHUNK_SIZE = 16 * 1024
        # Important note: QNetworkAccessManager is asynchronous, which means
        # the downloads are processed asynchronous using callbacks.
        for url in to_download_urls:
            request = QNetworkRequest(QUrl(url))
            request.setRawHeader(b"username", bytes(self.username, "utf-8"))
            request.setRawHeader(b"password", bytes(self.password, "utf-8"))
            request.setAttribute(USER_DOWNLOAD_DIRECTORY,
                                 self.download_directory)

            reply = self.network_manager.get(request)
            # Get replies in chunks, and process them
            reply.setReadBufferSize(CHUNK_SIZE)
            reply.readyRead.connect(
                self.on_single_download_ready_to_read_chunk)
            reply.finished.connect(self.on_single_download_finished)
        pop_up_info("Download started.")
Ejemplo n.º 20
0
    def reverseGeocode(self):
        layer = self.mMapLayerComboBox.currentLayer()
        if not layer:
            self.iface.messageBar().pushMessage(
                "",
                "No valid point vector layer to reverse geocode",
                level=QgsMessageBar.WARNING,
                duration=2)
            return

        self.numAddress = layer.featureCount()
        self.totalAddress = self.numAddress
        self.numErrors = 0
        if self.numAddress > self.settings.maxAddress:
            self.iface.messageBar().pushMessage(
                "",
                "Maximum geocodes to process were exceeded. Please reduce the number and try again.",
                level=QgsMessageBar.WARNING,
                duration=4)
            return

        layername = self.layerLineEdit.text()
        self.pointLayer = QgsVectorLayer("point?crs=epsg:4326", layername,
                                         "memory")
        self.provider = self.pointLayer.dataProvider()
        self.provider.addAttributes(
            [QgsField("display_name", QVariant.String)])
        self.pointLayer.updateFields()
        if self.showLabelCheckBox.checkState():
            # Display labels
            label = QgsPalLayerSettings()
            label.readFromLayer(self.pointLayer)
            label.enabled = True
            label.fieldName = 'display_name'
            label.placement = QgsPalLayerSettings.AroundPoint
            label.setDataDefinedProperty(QgsPalLayerSettings.Size, True, True,
                                         '8', '')
            label.writeToLayer(self.pointLayer)

        layerCRS = layer.crs()
        epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326")
        transform = QgsCoordinateTransform(layerCRS, epsg4326,
                                           QgsProject.instance())

        iter = layer.getFeatures()
        self.geocodes = {}

        for feature in iter:
            # already know that this is a point vector layer
            pt = feature.geometry().asPoint()
            # make sure the coordinates are in EPSG:4326
            pt = transform.transform(pt.x(), pt.y())
            lat = str(pt.y())
            lon = str(pt.x())
            url = self.settings.reverseURL(
            ) + '?format=json&lat=' + lat + '&lon=' + lon + '&zoom=18&addressdetails=0'
            # print url
            qurl = QUrl(url)
            request = QNetworkRequest(qurl)
            request.setRawHeader(
                b"User-Agent",
                b"Mozilla/5.0 (Windows NT 6.1: WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
            )
            request.setRawHeader(b"Connection", b"keep-alive")
            request.setRawHeader(
                b"Accept",
                b"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
            )
            reply = QgsNetworkAccessManager.instance().get(request)
            self.geocodes[reply] = pt
            reply.finished.connect(self.reverseGeoFinished)
Ejemplo n.º 21
0
    def request(self, url, method="GET", body=None, headers=None, redirections=DEFAULT_MAX_REDIRECTS, connection_type=None, blocking=True):
        """
        Make a network request by calling QgsNetworkAccessManager.
        redirections argument is ignored and is here only for httplib2 compatibility.
        """
        self.msg_log(u'http_call request: {0}'.format(url))

        self.blocking_mode = blocking
        req = QNetworkRequest()
        # Avoid double quoting form QUrl
        url = urllib.parse.unquote(url)
        req.setUrl(QUrl(url))
        if headers is not None:
            # This fixes a wierd error with compressed content not being correctly
            # inflated.
            # If you set the header on the QNetworkRequest you are basically telling
            # QNetworkAccessManager "I know what I'm doing, please don't do any content
            # encoding processing".
            # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1
            try:
                del headers['Accept-Encoding']
            except KeyError:
                pass
            for k, v in list(headers.items()):
                self.msg_log("Setting header %s to %s" % (k, v))
                req.setRawHeader(k, v)
        if self.authid:
            self.msg_log("Update request w/ authid: {0}".format(self.authid))
            QgsAuthManager.instance().updateNetworkRequest(req, self.authid)
        if self.reply is not None and self.reply.isRunning():
            self.reply.close()
        if method.lower() == 'delete':
            func = getattr(QgsNetworkAccessManager.instance(), 'deleteResource')
        else:
            func = getattr(QgsNetworkAccessManager.instance(), method.lower())
        # Calling the server ...
        # Let's log the whole call for debugging purposes:
        self.msg_log("Sending %s request to %s" % (method.upper(), req.url().toString()))
        self.on_abort = False
        headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()}
        for k, v in list(headers.items()):
            self.msg_log("%s: %s" % (k, v))
        if method.lower() in ['post', 'put']:
            if isinstance(body, file):
                body = body.read()
            self.reply = func(req, body)
        else:
            self.reply = func(req)
        if self.authid:
            self.msg_log("Update reply w/ authid: {0}".format(self.authid))
            QgsAuthManager.instance().updateNetworkReply(self.reply, self.authid)

        # necessary to trap local timout manage by QgsNetworkAccessManager
        # calling QgsNetworkAccessManager::abortRequest
        QgsNetworkAccessManager.instance().requestTimedOut.connect(self.requestTimedOut)

        self.reply.sslErrors.connect(self.sslErrors)
        self.reply.finished.connect(self.replyFinished)
        self.reply.downloadProgress.connect(self.downloadProgress)

        # block if blocking mode otherwise return immediatly
        # it's up to the caller to manage listeners in case of no blocking mode
        if not self.blocking_mode:
            return (None, None)

        # Call and block
        self.el = QEventLoop()
        self.reply.finished.connect(self.el.quit)

        # Catch all exceptions (and clean up requests)
        try:
            self.el.exec_(QEventLoop.ExcludeUserInputEvents)
        except Exception as e:
            raise e

        if self.reply:
            self.reply.finished.disconnect(self.el.quit)

        # emit exception in case of error
        if not self.http_call_result.ok:
            if self.http_call_result.exception and not self.exception_class:
                raise self.http_call_result.exception
            else:
                raise self.exception_class(self.http_call_result.reason)

        return (self.http_call_result, self.http_call_result.content)
Ejemplo n.º 22
0
    def request(self,
                url,
                method="GET",
                body=None,
                headers=None,
                redirections=DEFAULT_MAX_REDIRECTS,
                connection_type=None,
                blocking=True):
        """
        Make a network request by calling QgsNetworkAccessManager.
        redirections argument is ignored and is here only for httplib2 compatibility.
        """
        self.msg_log(u'http_call request: {0}'.format(url))

        self.blocking_mode = blocking
        req = QNetworkRequest()
        # Avoid double quoting form QUrl
        url = urllib.parse.unquote(url)
        req.setUrl(QUrl(url))
        if headers is not None:
            # This fixes a wierd error with compressed content not being correctly
            # inflated.
            # If you set the header on the QNetworkRequest you are basically telling
            # QNetworkAccessManager "I know what I'm doing, please don't do any content
            # encoding processing".
            # See: https://bugs.webkit.org/show_bug.cgi?id=63696#c1
            try:
                del headers['Accept-Encoding']
            except KeyError:
                pass
            for k, v in list(headers.items()):
                self.msg_log("Setting header %s to %s" % (k, v))
                if k and v:
                    req.setRawHeader(k.encode(), v.encode())
        if self.authid:
            self.msg_log("Update request w/ authid: {0}".format(self.authid))
            self.auth_manager().updateNetworkRequest(req, self.authid)
        if self.reply is not None and self.reply.isRunning():
            self.reply.close()
        if method.lower() == 'delete':
            func = getattr(QgsNetworkAccessManager.instance(),
                           'deleteResource')
        else:
            func = getattr(QgsNetworkAccessManager.instance(), method.lower())
        # Calling the server ...
        # Let's log the whole call for debugging purposes:
        self.msg_log("Sending %s request to %s" %
                     (method.upper(), req.url().toString()))
        self.on_abort = False
        headers = {str(h): str(req.rawHeader(h)) for h in req.rawHeaderList()}
        for k, v in list(headers.items()):
            self.msg_log("%s: %s" % (k, v))
        if method.lower() in ['post', 'put']:
            if isinstance(body, io.IOBase):
                body = body.read()
            if isinstance(body, str):
                body = body.encode()
            if isinstance(body, dict):
                body = str(json.dumps(body)).encode(encoding='utf-8')
            self.reply = func(req, body)
        else:
            self.reply = func(req)
        if self.authid:
            self.msg_log("Update reply w/ authid: {0}".format(self.authid))
            self.auth_manager().updateNetworkReply(self.reply, self.authid)

        QgsNetworkAccessManager.instance().setTimeout(int(self.timeout) * 1000)

        # necessary to trap local timeout manage by QgsNetworkAccessManager
        # calling QgsNetworkAccessManager::abortRequest
        QgsNetworkAccessManager.instance().requestTimedOut.connect(
            self.requestTimedOut)

        self.reply.sslErrors.connect(self.sslErrors)
        self.reply.finished.connect(self.replyFinished)
        self.reply.downloadProgress.connect(self.downloadProgress)

        # block if blocking mode otherwise return immediatly
        # it's up to the caller to manage listeners in case of no blocking mode
        if not self.blocking_mode:
            return (None, None)

        # Call and block
        self.el = QEventLoop()
        self.reply.finished.connect(self.el.quit)

        # Catch all exceptions (and clean up requests)
        try:
            self.el.exec_(QEventLoop.ExcludeUserInputEvents)
        except Exception as e:
            raise e

        if self.reply:
            self.reply.finished.disconnect(self.el.quit)

        # emit exception in case of error
        if not self.http_call_result.ok:
            if self.http_call_result.exception and not self.exception_class:
                raise self.http_call_result.exception
            else:
                raise self.exception_class(self.http_call_result.reason)

        return (self.http_call_result, self.http_call_result.content)
Ejemplo n.º 23
0
    def processAddressTable(self):
        layer = self.addressMapLayerComboBox.currentLayer()
        if not layer:
            self.iface.messageBar().pushMessage(
                "",
                "No valid table or vector layer to reverse geocode",
                level=QgsMessageBar.WARNING,
                duration=4)
            return
        self.numAddress = self.totalAddress = layer.featureCount()
        if not self.numAddress:
            self.iface.messageBar().pushMessage("",
                                                "No addresses to geocode",
                                                level=QgsMessageBar.WARNING,
                                                duration=4)
            return

        self.numErrors = 0
        if self.numAddress > self.settings.maxAddress:
            self.iface.messageBar().pushMessage(
                "",
                "Maximum geocodes to process were exceeded. Please reduce the number and try again.",
                level=QgsMessageBar.WARNING,
                duration=4)
            return

        maxResults = self.maxResultsSpinBox.value()
        showDetails = int(self.detailedAddressCheckBox.isChecked())
        self.geocodes = {}
        self.pointLayer = None
        self.createPointLayer()

        iter = layer.getFeatures(QgsFeatureRequest().setFlags(
            QgsFeatureRequest.NoGeometry))
        full_address = self.fullAddressComboBox.currentIndex() - 1
        street_num = self.numberComboBox.currentIndex() - 1
        street_name = self.streetNameComboBox.currentIndex() - 1
        city = self.cityComboBox.currentIndex() - 1
        county = self.countyComboBox.currentIndex() - 1
        state = self.stateComboBox.currentIndex() - 1
        country = self.countryComboBox.currentIndex() - 1
        postal = self.postalCodeComboBox.currentIndex() - 1

        for feature in iter:
            self.isfirst = True
            if full_address >= 0:
                address = feature[full_address].strip()
                address2 = re.sub('\s+', '+', address)
                url = self.settings.searchURL() + '?q=' + address2
            else:
                address = ','.join(
                    [str(x) if x else '' for x in feature.attributes()])
                url = self.settings.searchURL() + '?'
                if street_name >= 0:
                    num = ''
                    name = ''
                    if street_num >= 0 and feature[street_num]:
                        num = ('{}'.format(feature[street_num])).strip()
                    if feature[street_name]:
                        name = ('{}'.format(feature[street_name])).strip()
                    street = num + ' ' + name
                    street = street.strip()
                    if street:
                        url += self.formatParam('street', street)
                if city >= 0:
                    url += self.formatParam('city', feature[city])
                if county >= 0:
                    url += self.formatParam('county', feature[county])
                if state >= 0:
                    url += self.formatParam('state', feature[state])
                if country >= 0:
                    url += self.formatParam('country', feature[country])
                if postal >= 0:
                    url += self.formatParam('postalcode', feature[postal])

            url += '&format=json&limit={}&polygon=0&addressdetails={}'.format(
                maxResults, showDetails)
            # print url
            qurl = QUrl(url)
            request = QNetworkRequest(qurl)
            request.setRawHeader(
                b"User-Agent",
                b"Mozilla/5.0 (Windows NT 6.1: WOW64; rv:52.0) Gecko/20100101 Firefox/52.0"
            )
            request.setRawHeader(b"Connection", b"keep-alive")
            request.setRawHeader(
                b"Accept",
                b"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
            )
            reply = QgsNetworkAccessManager.instance().get(request)
            self.geocodes[reply] = address
            reply.finished.connect(self.replyFinished)