def networkrequest(self, nurl): global reply self.manager = QNetworkAccessManager() url = QUrl(nurl) request = QNetworkRequest(url) self.manager.finished.connect(self.handleResponse) self.manager.get(request)
def __init__(self, auth_file): logger.debug("\n================== ISOGEO API WITH QT ==================") # getting credentials : logger.debug("Getting credentials") self.utils = IsogeoUtils() self.app_creds = self.utils.credentials_loader(auth_file) self.app_id = self.app_creds.get("client_id") self.app_secrets = self.app_creds.get("client_secret") # for connection : self.naMngr = QNetworkAccessManager() self.token_url = "https://id.api.isogeo.com/oauth/token" self.request_url = ( "https://v1.api.isogeo.com/resources/search?_limit=0&_offset=0" ) # init variables : self.token = "" self.search_type = "init" self.checked_kw = {} # for ui (launch and display): logger.debug("Processing and displaying UI") self.app = QApplication(sys.argv) self.ui = AuthWidget() self.ui.resize(400, 100) self.pysdk_checking() self.api_authentification() self.ui.btn_reset.pressed.connect(self.reset) self.ui.show() self.app.exec()
def __init__(self, parent=None, iface=None): self.parent = parent self.iface = iface self.login_accepted = False self.akt_download = 0 self.all_download = 0 self.request_is_aborted = False self.nam = QNetworkAccessManager() self.nam.authenticationRequired.connect(self.set_credentials) self.nam.finished.connect(self.reply_finished)
def is_source_service_valid(self): res = False msg = {'text': '', 'level': Qgis.Warning} url = self.txt_service_endpoint.text().strip() if url: with OverrideCursor(Qt.WaitCursor): self.qgis_utils.status_bar_message_emitted.emit("Checking source service availability (this might take a while)...", 0) QCoreApplication.processEvents() if self.qgis_utils.is_connected(TEST_SERVER): nam = QNetworkAccessManager() request = QNetworkRequest(QUrl(url)) reply = nam.get(request) loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec_() allData = reply.readAll() response = QTextStream(allData, QIODevice.ReadOnly) status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if status == 200: try: data = json.loads(response.readAll()) if 'id' in data and data['id'] == SOURCE_SERVICE_EXPECTED_ID: res = True msg['text'] = QCoreApplication.translate("SettingsDialog", "The tested service is valid to upload files!") msg['level'] = Qgis.Info else: res = False msg['text'] = QCoreApplication.translate("SettingsDialog", "The tested upload service is not compatible: no valid 'id' found in response.") except json.decoder.JSONDecodeError as e: res = False msg['text'] = QCoreApplication.translate("SettingsDialog", "Response from the tested service is not compatible: not valid JSON found.") else: res = False msg['text'] = QCoreApplication.translate("SettingsDialog", "There was a problem connecting to the server. The server might be down or the service cannot be reached at the given URL.") else: res = False msg['text'] = QCoreApplication.translate("SettingsDialog", "There was a problem connecting to Internet.") self.qgis_utils.clear_status_bar_emitted.emit() else: res = False msg['text'] = QCoreApplication.translate("SettingsDialog", "Not valid service URL to test!") return (res, msg)
def __init__(self, settings): super(KfConfig, self).__init__() self.settings = settings self.cached_kf_qlr_filename = None self.allowed_kf_services = {} self.kf_qlr_file = None self.background_category = None self.categories = None # Network self._services_network_manager = QNetworkAccessManager() self._qlr_network_manager = QNetworkAccessManager() self._services_network_manager.finished.connect( self._handle_services_response) self._qlr_network_manager.finished.connect(self._handle_qlr_response)
def download_image(self, url): res = False img = None msg = {'text': '', 'level': Qgis.Warning} if url: self.log.logMessage("Downloading file from {}".format(url), PLUGIN_NAME, Qgis.Info) with OverrideCursor(Qt.WaitCursor): self.qgis_utils.status_bar_message_emitted.emit( "Downloading image from document repository (this might take a while)...", 0) QCoreApplication.processEvents() if self.qgis_utils.is_connected(TEST_SERVER): nam = QNetworkAccessManager() request = QNetworkRequest(QUrl(url)) reply = nam.get(request) loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec_() status = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if status == 200: res = True img = reply.readAll() else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "There was a problem connecting to the server. The server might be down or the service cannot be reached at the given URL." ) else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "There was a problem connecting to Internet.") self.qgis_utils.clear_status_bar_emitted.emit() else: res = False msg['text'] = QCoreApplication.translate("SettingsDialog", "Not valid URL") if not res: self.log.logMessage(msg['text'], PLUGIN_NAME, msg['level']) return (res, img)
def save_wms_image(filename, url, layer, extent): bbox = "%f,%f,%f,%f" % (extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()) h = int(extent.height() / extent.width() * WIDTH) url = ( "%s/wms?request=GetMap&service=WMS&version=1.1.1&srs=EPSG:4326&layers=visualtests:%s&" "styles=visualtests:%s&format=image/png&width=%i&height=%i&bbox=%s" % (url, layer.name(), layer.name(), WIDTH, h, bbox)) nam = QNetworkAccessManager() reply = nam.get(QNetworkRequest(QUrl(url))) loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec() img = QImage() img.loadFromData(reply.readAll()) img.save(filename)
class QgsRequest: def __init__(self, url, method='GET', **data): self.manager = QNetworkAccessManager() self.method = method self.url = QUrl(url) self.request = QNetworkRequest(self.url) def send(self): buf = QBuffer() patchbytes = bytes('OPTIONS', 'UTF-8') verb = QByteArray(patchbytes) # Switch to get the appropriate function to process the request switch = { 'get': self.manager.get, 'options': lambda request: self.manager.sendCustomRequest(request, verb, buf), 'head': self.manager.head, 'put': self.manager.put } access_method = switch.get(self.method.lower()) reply_command = lambda: access_method(self.request) reply = Reply(reply_command, self.url) return reply
def __init__(self, geturl_func, parseresult_func, parent=None): QObject.__init__(self, parent) self.geturl_func = geturl_func self.parseresult_func = parseresult_func self.editor = parent self.networkManager = QNetworkAccessManager() self.selectedObject = None self.isUnloaded = False self.popup = QTreeWidget(parent) #self.popup.setColumnCount(2) self.popup.setColumnCount(1) self.popup.setUniformRowHeights(True) self.popup.setRootIsDecorated(False) self.popup.setEditTriggers(QTreeWidget.NoEditTriggers) self.popup.setSelectionBehavior(QTreeWidget.SelectRows) self.popup.setFrameStyle(QFrame.Box | QFrame.Plain) self.popup.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.popup.header().hide() self.popup.installEventFilter(self) self.popup.setMouseTracking(True) #self.connect(self.popup, SIGNAL("itemClicked(QTreeWidgetItem*, int)"), # self.doneCompletion) self.popup.itemClicked.connect(self.doneCompletion) self.popup.setWindowFlags(Qt.Popup) self.popup.setFocusPolicy(Qt.NoFocus) self.popup.setFocusProxy(parent) self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.setInterval(500) #self.connect(self.timer, SIGNAL("timeout()"), self.autoSuggest) self.timer.timeout.connect(self.autoSuggest) #self.connect(self.editor, SIGNAL("textEdited(QString)"), self.timer, SLOT("start()")) #self.editor.textEdited.connect( self.timer.start ) self.editor.textEdited.connect(self.timer.start) #self.editor.textChanged.connect( self.timer.start ) #self.connect(self.networkManager, SIGNAL("finished(QNetworkReply*)"), # self.handleNetworkData) self.networkManager.finished.connect(self.handleNetworkData)
def download_image(self, url): res = False img = None msg = {'text': '', 'level': Qgis.Warning} if url: self.logger.info(__name__, "Downloading file from {}".format(url)) msg_status_bar = "Downloading image from document repository (this might take a while)..." with ProcessWithStatus(msg_status_bar): if is_connected(TEST_SERVER): nam = QNetworkAccessManager() request = QNetworkRequest(QUrl(url)) reply = nam.get(request) loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec_() status = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if status == 200: res = True img = reply.readAll() else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "There was a problem connecting to the server. The server might be down or the service cannot be reached at the given URL." ) else: res = False msg['text'] = QCoreApplication.translate( "SettingsDialog", "There was a problem connecting to Internet.") else: res = False msg['text'] = QCoreApplication.translate("SettingsDialog", "Not valid URL") if not res: self.logger.log_message(__name__, msg['text'], msg['level']) return res, img
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", 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]
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 __init__(self, geturl_func, parseresult_func, parent = None): QObject.__init__(self, parent) self.geturl_func = geturl_func self.parseresult_func = parseresult_func self.editor = parent self.networkManager = QNetworkAccessManager() self.selectedObject = None self.isUnloaded = False self.popup = QTreeWidget(parent) #self.popup.setColumnCount(2) self.popup.setColumnCount(1) self.popup.setUniformRowHeights(True) self.popup.setRootIsDecorated(False) self.popup.setEditTriggers(QTreeWidget.NoEditTriggers) self.popup.setSelectionBehavior(QTreeWidget.SelectRows) self.popup.setFrameStyle(QFrame.Box | QFrame.Plain) self.popup.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.popup.header().hide() self.popup.installEventFilter(self) self.popup.setMouseTracking(True) #self.connect(self.popup, SIGNAL("itemClicked(QTreeWidgetItem*, int)"), # self.doneCompletion) self.popup.itemClicked.connect( self.doneCompletion ) self.popup.setWindowFlags(Qt.Popup) self.popup.setFocusPolicy(Qt.NoFocus) self.popup.setFocusProxy(parent) self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.setInterval(500) #self.connect(self.timer, SIGNAL("timeout()"), self.autoSuggest) self.timer.timeout.connect( self.autoSuggest ) #self.connect(self.editor, SIGNAL("textEdited(QString)"), self.timer, SLOT("start()")) #self.editor.textEdited.connect( self.timer.start ) self.editor.textEdited.connect( self.timer.start ) #self.editor.textChanged.connect( self.timer.start ) #self.connect(self.networkManager, SIGNAL("finished(QNetworkReply*)"), # self.handleNetworkData) self.networkManager.finished.connect( self.handleNetworkData )
def __init__(self, parent): super().__init__(parent) self.network = QNetworkAccessManager(self)
class BBOXDialog(QDialog, FORM_CLASS): def __init__(self, inp_sparql, triplestoreconf, endpointIndex): super(QDialog, self).__init__() self.setupUi(self) self.inp_sparql = inp_sparql self.triplestoreconf = triplestoreconf self.endpointIndex = endpointIndex self.vl = QgsVectorLayer("Point", "temporary_points", "memory") self.map_canvas = QgsMapCanvas(self) self.layerExtentOrBBOX = False self.map_canvas.setMinimumSize(500, 475) self.map_canvas.move(0, 30) self.nominatimmap = {} actionPan = QAction("Pan", self) actionPan.setCheckable(True) actionPan.triggered.connect(self.pan) self.toolPan = QgsMapToolPan(self.map_canvas) self.toolPan.setAction(actionPan) uri = "url=http://a.tile.openstreetmap.org/{z}/{x}/{y}.png&zmin=0&type=xyz" self.mts_layer = QgsRasterLayer(uri, 'OSM', 'wms') if not self.mts_layer.isValid(): print("Layer failed to load!") self.rect_tool = RectangleMapTool(self.map_canvas) self.circ_tool = CircleMapTool(self.map_canvas, 1) self.poly_tool = PolygonMapTool(self.map_canvas) self.map_canvas.setMapTool(self.rect_tool) self.map_canvas.setExtent(self.mts_layer.extent()) self.map_canvas.setLayers([self.vl, self.mts_layer]) self.map_canvas.setCurrentLayer(self.mts_layer) self.pan() self.selectCircle.hide() self.geocodeSearch = NominatimText(self, self.nominatimmap, self.map_canvas) self.move(120, 0) self.crsdialog = QgsProjectionSelectionWidget(self) self.crsdialog.move(160, 540) self.crsdialog.resize(331, 30) self.crsdialog.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.crsdialog.show() self.nominatimurl = 'https://nominatim.openstreetmap.org/search?format=json&q={address}' self.panButton.clicked.connect(self.pan) self.selectCircle.clicked.connect(self.selectcircle) self.selectPolygon.clicked.connect(self.selectpolygon) self.selectButton.clicked.connect(self.selectarea) self.zoomIn.clicked.connect(self.map_canvas.zoomIn) self.zoomOut.clicked.connect(self.map_canvas.zoomOut) self.b2.clicked.connect(self.setBBOXExtentQuery) self.searchButton.hide() self.searchPlace.hide() self.geocodeSearch.hide() layers = QgsProject.instance().layerTreeRoot().children() for layer in layers: self.chooseBBOXLayer.addItem(layer.name()) self.searchButton.clicked.connect(self.geocode) self.b1.clicked.connect(self.setBBOXInQuery) def geocode(self): try: nominatimurl = self.nominatimurl.format( **{'address': self.geocodeSearch.text()}) self.networkrequest(nominatimurl) except Exception as e: msgBox = QMessageBox() msgBox.setWindowTitle("Mandatory variables missing!") msgBox.setText(str(e)) msgBox.exec() def networkrequest(self, nurl): global reply self.manager = QNetworkAccessManager() url = QUrl(nurl) request = QNetworkRequest(url) self.manager.finished.connect(self.handleResponse) self.manager.get(request) def handleResponse(self, reply): er = reply.error() if er == QNetworkReply.NoError: bytes_string = reply.readAll() print(str(bytes_string, 'utf-8')) results = json.loads(str(bytes_string, 'utf-8')) self.nominatimmap = {} chooselist = [] for rec in results: chooselist.append(rec['display_name']) self.nominatimmap[rec['display_name']] = [ rec['lon'], rec['lat'] ] completer = SPARQLCompleter(chooselist) self.geocodeSearch.setMap(self.nominatimmap) self.geocodeSearch.setCompleter(completer) #self.geocodeSearch.insertCompletion.connect(self.zoomToCoordinates) completer.popup().show() else: print("Error occured: ", er) def zoomToCoordinates(self, completion): msgBox = QMessageBox() msgBox.setText(completion) msgBox.exec() self.map_canvas.zoomWithCenter(self.nominatimmap[completion][0], self.nominatimmap[completion][1], True) def pan(self): self.map_canvas.setMapTool(self.toolPan) def selectarea(self): self.rectangle = True self.circle = False self.polygon = False self.map_canvas.setMapTool(self.rect_tool) def selectcircle(self): self.rectangle = False self.circle = True self.polygon = False self.map_canvas.setMapTool(self.circ_tool) def selectpolygon(self): self.rectangle = False self.circle = False self.polygon = True self.map_canvas.setMapTool(self.poly_tool) def setBBOXExtentQuery(self): if len(QgsProject.instance().layerTreeRoot().children()) > 0: self.mts_layer = QgsProject.instance().layerTreeRoot().children()[ self.chooseBBOXLayer.currentIndex()].layer() self.layerExtentOrBBOX = True self.setBBOXInQuery() self.close() else: msgBox = QMessageBox() msgBox.setWindowTitle("No layer loaded in QGIS!") msgBox.setText( "No layer has been loaded in QGIS to get an extent from!") msgBox.exec() def setBBOXInQuery(self): sourceCrs = None if self.layerExtentOrBBOX: xMax = self.mts_layer.extent().xMaximum() xMin = self.mts_layer.extent().xMinimum() yMin = self.mts_layer.extent().yMinimum() yMax = self.mts_layer.extent().yMaximum() pointt1 = QgsGeometry.fromPointXY(QgsPointXY(xMax, yMin)) pointt2 = QgsGeometry.fromPointXY(QgsPointXY(xMin, yMin)) pointt3 = QgsGeometry.fromPointXY(QgsPointXY(xMin, yMax)) pointt4 = QgsGeometry.fromPointXY(QgsPointXY(xMax, yMax)) sourceCrs = QgsCoordinateReferenceSystem(self.mts_layer.crs()) else: sourceCrs = QgsCoordinateReferenceSystem(self.mts_layer.crs()) destCrs = self.crsdialog.crs() if self.polygon: polygon = self.poly_tool.rb.asGeometry() tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance()) polygon.transform(tr) elif self.circle: pointt1 = QgsGeometry.fromWkt(self.circ_tool.point1.asWkt()) pointt2 = QgsGeometry.fromWkt(self.circ_tool.point2.asWkt()) pointt3 = QgsGeometry.fromWkt(self.circ_tool.point3.asWkt()) pointt4 = QgsGeometry.fromWkt(self.circ_tool.point4.asWkt()) else: pointt1 = QgsGeometry.fromWkt(self.rect_tool.point1.asWkt()) pointt2 = QgsGeometry.fromWkt(self.rect_tool.point2.asWkt()) pointt3 = QgsGeometry.fromWkt(self.rect_tool.point3.asWkt()) pointt4 = QgsGeometry.fromWkt(self.rect_tool.point4.asWkt()) if sourceCrs != None: tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance()) pointt1.transform(tr) pointt2.transform(tr) pointt3.transform(tr) pointt4.transform(tr) polygon = QgsGeometry.fromPolylineXY([ pointt1.asPoint(), pointt2.asPoint(), pointt3.asPoint(), pointt4.asPoint() ]) center = polygon.centroid() #distance = QgsDistanceArea() #distance.setSourceCrs(destCrs) #distance.setEllipsoidalMode(True) #distance.setEllipsoid('WGS84') curquery = self.inp_sparql.toPlainText() if self.rectangle or self.circle: widthm = 100 #distance.measureLine(pointt1, pointt2) self.curbbox = [] self.curbbox.append(pointt1) self.curbbox.append(pointt2) self.curbbox.append(pointt3) self.curbbox.append(pointt4) self.close() if "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self. endpointIndex]["bboxquery"]["type"] == "geosparql": curquery = curquery[ 0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%x1%%", str(pointt1.asPoint().x())).replace( "%%x2%%", str(pointt3.asPoint().x())).replace( "%%y1%%", str(pointt1.asPoint().y())).replace( "%%y2%%", str(pointt3.asPoint().y()) ) + "}\n" + curquery[curquery.rfind('}') + 1:] elif "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self.endpointIndex]["bboxquery"]["type"] == "minmax": curquery = curquery[ 0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%minPoint%%", pointt2.asWkt()).replace( "%%maxPoint%%", pointt4.asWkt() ) + curquery[curquery.rfind('}') + 1:] elif "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self. endpointIndex]["bboxquery"]["type"] == "pointdistance": curquery = curquery[ 0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%lat%%", str(center.asPoint().y())).replace( "%%lon%%", str(center.asPoint().x())).replace( "%%distance%%", str(widthm / 1000) ) + curquery[curquery.rfind('}') + 1:] elif polygon: widthm = 100 if "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self. endpointIndex]["bboxquery"]["type"] == "geosparql": curquery = curquery[0:curquery.rfind( '}')] + "FILTER(geof:sfIntersects(?geo,\"" + polygon.asWkt( ) + "\"^^geo:wktLiteral))" elif "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self.endpointIndex]["bboxquery"]["type"] == "minmax": curquery = curquery[ 0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%minPoint%%", "POINT(" + str(polygon.boundingBox().yMinimum()) + " " + str(polygon.boundingBox().xMinimum()) + ")").replace( "%%maxPoint%%", "POINT(" + str(polygon.boundingBox().yMaximum()) + " " + str(polygon.boundingBox().xMaximum()) + ")") + curquery[curquery.rfind('}') + 1:] elif "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self. endpointIndex]["bboxquery"]["type"] == "pointdistance": curquery = curquery[ 0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%lat%%", str(polygon.boundingBox().center().asPoint().y( ))).replace( "%%lon%%", str(polygon.boundingBox().center().asPoint().x( ))).replace("%%distance%%", str( widthm / 1000)) + curquery[curquery.rfind('}') + 1:] self.inp_sparql.setPlainText(curquery) self.close()
class NetManager(QObject): def __init__(self, parent): super().__init__(parent) self.network = QNetworkAccessManager(self) ############# def _pre_send_request(self,conn_info, endpoint, kw_request=dict()): assert(isinstance(endpoint,str)) request = make_conn_request(conn_info, endpoint,**kw_request) return request def _post_send_request(self, reply, conn_info, kw_prop=dict()): set_qt_property(reply, conn_info=conn_info, **kw_prop) def _send_request(self,conn_info, endpoint, kw_request=dict(), kw_prop=dict()): request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.get(request) self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply ############# # TODO: remove callback params def get_statistics(self, conn_info): reply = self._get_space_(conn_info, "statistics") timeout = TIMEOUT_COUNT QTimer.singleShot(timeout, reply.abort) return reply def get_count(self, conn_info): reply = self._get_space_(conn_info, "count") return reply def get_meta(self, conn_info): return self._get_space_(conn_info, "space_meta") def _get_space_(self, conn_info, reply_tag): tag = "/" + reply_tag if reply_tag != "space_meta" else "" endpoint = "/spaces/{space_id}" + tag kw_request = dict() kw_prop = dict(reply_tag=reply_tag) return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def list_spaces(self, conn_info): endpoint = "/spaces" kw_request = dict(includeRights="true") kw_prop = dict(reply_tag="spaces") return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def add_space(self, conn_info, space_info): space_info = prepare_new_space_info(space_info) endpoint = "/spaces" kw_request = dict(req_type="json") kw_prop = dict(reply_tag="add_space") request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.post(request, make_payload(space_info)) self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply def edit_space(self, conn_info, space_info): endpoint = "/spaces/{space_id}" kw_request = dict(req_type="json") kw_prop = dict(reply_tag="edit_space") request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) buffer = make_buffer(space_info) reply = self.network.sendCustomRequest(request, b"PATCH", buffer) buffer.setParent(reply) self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply def del_space(self, conn_info): endpoint = "/spaces/{space_id}" kw_request = dict() kw_prop = dict(reply_tag="del_space") request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.sendCustomRequest(request, b"DELETE") self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply def load_features_bbox(self, conn_info, bbox, **kw): endpoint = "/spaces/{space_id}/bbox" kw_request = dict(bbox) kw_request.update(kw) kw_prop = dict(reply_tag="bbox") kw_prop.update(kw) kw_prop["bbox"] = bbox return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def load_features_tile(self, conn_info, tile_id="0", tile_schema="quadkey", **kw): reply_tag = "tile" tile_url = "tile/{tile_schema}/{tile_id}".format( tile_schema=tile_schema, tile_id=tile_id) endpoint = "/spaces/{space_id}/" + tile_url return self._load_features_endpoint(endpoint, conn_info, reply_tag=reply_tag, **kw) def load_features_iterate(self, conn_info, **kw_iterate): reply_tag = kw_iterate.pop("reply_tag","iterate") endpoint = "/spaces/{space_id}/iterate" return self._load_features_endpoint(endpoint, conn_info, reply_tag=reply_tag, **kw_iterate) def load_features_search(self, conn_info, **kw_iterate): reply_tag = kw_iterate.pop("reply_tag","search") endpoint = "/spaces/{space_id}/search" return self._load_features_endpoint(endpoint, conn_info, reply_tag=reply_tag, **kw_iterate) def _load_features_endpoint(self, endpoint, conn_info, reply_tag=None, **kw_iterate): """ Iterate through all ordered features (no feature is repeated twice) """ kw_request = dict(kw_iterate) kw_prop = dict(reply_tag=reply_tag) kw_prop.update(kw_iterate) return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) ###### feature function def add_features(self, conn_info, added_feat, **kw): send_request = self.network.post # create or modify (merge existing feature with payload) # might add attributes return self._add_features(conn_info, added_feat, send_request, **kw) def modify_features(self, conn_info, added_feat, **kw): return self.add_features(conn_info, added_feat, **kw) def replace_features(self, conn_info, added_feat, **kw): send_request = self.network.put # create or replace (replace existing feature with payload) # might add or drop attributes return self._add_features(conn_info, added_feat, send_request, **kw) def _add_features(self, conn_info, added_feat, send_request, **kw): # POST, payload: list of FeatureCollection endpoint = "/spaces/{space_id}/features" if "tags" in kw: kw["addTags"] = kw["tags"] kw_request = dict(req_type="geo", **kw) # kw: query kw_prop = dict(reply_tag="add_feat") kw_prop.update(kw) request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) payload = make_payload(added_feat) reply = send_request(request, payload) self._post_send_request(reply, conn_info, kw_prop=kw_prop) #parallel case (merge output ? split input?) return reply def del_features(self, conn_info, removed_feat, **kw): # DELETE by Query URL, required list of feat_id query_del = {"id": ",".join(str(i) for i in removed_feat)} kw.update(query_del) endpoint = "/spaces/{space_id}/features" kw_request = dict(kw) # kw: query kw_prop = dict(reply_tag="del_feat") request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.sendCustomRequest(request, b"DELETE") self._post_send_request(reply, conn_info, kw_prop=kw_prop) return reply
def upload_files(self, layer, field_index, features): """ Upload given features' source files to remote server and return a dict formatted as changeAttributeValues expects to update 'datos' attribute to a remote location. """ if not QSettings().value( 'Asistente-LADM_COL/sources/document_repository', False, bool): self.message_with_duration_emitted.emit( QCoreApplication.translate( "SourceHandler", "The source files were not uploaded to the document repository because you have that option unchecked. You can still upload the source files later using the 'Upload Pending Source Files' menu." ), Qgis.Info, 10) return dict() # Test if we have Internet connection and a valid service dlg = self.qgis_utils.get_settings_dialog() res, msg = dlg.is_source_service_valid() if not res: msg['text'] = QCoreApplication.translate( "SourceHandler", "No file could be uploaded to the document repository. You can do it later from the 'Upload Pending Source Files' menu. Reason: {}" ).format(msg['text']) self.message_with_duration_emitted.emit( msg['text'], Qgis.Info, 20) # The data is still saved, so always show Info msg return dict() file_features = [ feature for feature in features if not feature[field_index] == NULL and os.path.isfile(feature[field_index]) ] total = len(features) not_found = total - len(file_features) upload_dialog = UploadProgressDialog(len(file_features), not_found) upload_dialog.show() count = 0 upload_errors = 0 new_values = dict() for feature in file_features: data_url = feature[field_index] file_name = os.path.basename(data_url) nam = QNetworkAccessManager() #reply.downloadProgress.connect(upload_dialog.update_current_progress) multiPart = QHttpMultiPart(QHttpMultiPart.FormDataType) textPart = QHttpPart() textPart.setHeader(QNetworkRequest.ContentDispositionHeader, QVariant("form-data; name=\"driver\"")) textPart.setBody(QByteArray().append('Local')) filePart = QHttpPart() filePart.setHeader( QNetworkRequest.ContentDispositionHeader, QVariant("form-data; name=\"file\"; filename=\"{}\"".format( file_name))) file = QFile(data_url) file.open(QIODevice.ReadOnly) filePart.setBodyDevice(file) file.setParent( multiPart ) # we cannot delete the file now, so delete it with the multiPart multiPart.append(filePart) multiPart.append(textPart) service_url = '/'.join([ QSettings().value( 'Asistente-LADM_COL/sources/service_endpoint', DEFAULT_ENDPOINT_SOURCE_SERVICE), SOURCE_SERVICE_UPLOAD_SUFFIX ]) request = QNetworkRequest(QUrl(service_url)) reply = nam.post(request, multiPart) #reply.uploadProgress.connect(upload_dialog.update_current_progress) reply.error.connect(self.error_returned) multiPart.setParent(reply) # We'll block execution until we get response from the server loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec_() response = reply.readAll() data = QTextStream(response, QIODevice.ReadOnly) content = data.readAll() if content is None: self.log.logMessage( "There was an error uploading file '{}'".format(data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue try: response = json.loads(content) except json.decoder.JSONDecodeError: self.log.logMessage( "Couldn't parse JSON response from server for file '{}'!!!" .format(data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue if 'error' in response: self.log.logMessage( "STATUS: {}. ERROR: {} MESSAGE: {} FILE: {}".format( response['status'], response['error'], response['message'], data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue reply.deleteLater() if 'url' not in response: self.log.logMessage( "'url' attribute not found in JSON response for file '{}'!" .format(data_url), PLUGIN_NAME, Qgis.Critical) upload_errors += 1 continue url = self.get_file_url(response['url']) new_values[feature.id()] = {field_index: url} count += 1 upload_dialog.update_total_progress(count) if not_found > 0: self.message_with_duration_emitted.emit( QCoreApplication.translate( "SourceHandler", "{} out of {} records {} not uploaded to the document repository because {} file path is NULL or it couldn't be found in the local disk!" ).format( not_found, total, QCoreApplication.translate("SourceHandler", "was") if not_found == 1 else QCoreApplication.translate( "SourceHandler", "were"), QCoreApplication.translate("SourceHandler", "its") if not_found == 1 else QCoreApplication.translate( "SourceHandler", "their")), Qgis.Info, 0) if len(new_values): self.message_with_duration_emitted.emit( QCoreApplication.translate( "SourceHandler", "{} out of {} files {} uploaded to the document repository and {} remote location stored in the database!" ).format( len(new_values), total, QCoreApplication.translate("SourceHandler", "was") if len(new_values) == 1 else QCoreApplication.translate( "SourceHandler", "were"), QCoreApplication.translate("SourceHandler", "its") if len(new_values) == 1 else QCoreApplication.translate( "SourceHandler", "their")), Qgis.Info, 0) if upload_errors: self.message_with_duration_emitted.emit( QCoreApplication.translate( "SourceHandler", "{} out of {} files could not be uploaded to the document repository because of upload errors! See log for details." ).format(upload_errors, total), Qgis.Info, 0) return new_values
class KfConfig(QtCore.QObject): kf_con_error = QtCore.pyqtSignal() kf_settings_warning = QtCore.pyqtSignal() loaded = QtCore.pyqtSignal() def __init__(self, settings): super(KfConfig, self).__init__() self.settings = settings self.cached_kf_qlr_filename = None self.allowed_kf_services = {} self.kf_qlr_file = None self.background_category = None self.categories = None # Network self._services_network_manager = QNetworkAccessManager() self._qlr_network_manager = QNetworkAccessManager() self._services_network_manager.finished.connect( self._handle_services_response) self._qlr_network_manager.finished.connect(self._handle_qlr_response) def begin_load(self): self.cached_kf_qlr_filename = ( self.settings.value("cache_path") + hashlib.md5(self.settings.value("token").encode()).hexdigest() + "_kortforsyning_data.qlr") self.allowed_kf_services = {} if self.settings.is_set(): try: self._request_services() except Exception as e: log_message(traceback.format_exc()) self.kf_con_error.emit() self.background_category = None self.categories = [] self.debug_write_allowed_services() else: self.kf_settings_warning.emit() self.background_category = None self.categories = [] def _request_services(self): url_to_get = self.insert_token(KF_SERVICES_URL) self._services_network_manager.get(QNetworkRequest(QUrl(url_to_get))) def _handle_services_response(self, network_reply): if network_reply.error(): self.background_category = None self.categories = [] self.kf_con_error.emit() log_message( f"Network error getting services from kf. Error code : " + str(network_reply.error())) return response = str(network_reply.readAll(), "utf-8") doc = QtXml.QDomDocument() doc.setContent(response) service_types = doc.documentElement().childNodes() i = 0 allowed = {} allowed["any_type"] = {"services": []} while i < service_types.count(): service_type = service_types.at(i) service_type_name = service_type.nodeName() allowed[service_type_name] = {"services": []} services = service_type.childNodes() j = 0 while j < services.count(): service = services.at(j) service_name = service.nodeName() allowed[service_type_name]["services"].append(service_name) allowed["any_type"]["services"].append(service_name) j = j + 1 i = i + 1 self.allowed_kf_services = allowed if not allowed["any_type"]["services"]: self.kf_con_error.emit() log_message( f"Kortforsyningen returned an empty list of allowed services for token: {self.settings.value('token')}" ) # Go on and get QLR self._get_qlr_file() def _get_qlr_file(self): local_file_exists = os.path.exists(self.cached_kf_qlr_filename) if local_file_exists: local_file_time = datetime.datetime.fromtimestamp( os.path.getmtime(self.cached_kf_qlr_filename)) use_cached = local_file_time > datetime.datetime.now( ) - FILE_MAX_AGE if use_cached: # Skip requesting remote qlr self._load_config_from_cached_kf_qlr() return # Get qlr from KF self._request_kf_qlr_file() def _request_kf_qlr_file(self): url_to_get = self.settings.value("kf_qlr_url") self._qlr_network_manager.get(QNetworkRequest(QUrl(url_to_get))) def _handle_qlr_response(self, network_reply): if network_reply.error(): log_message("No contact to the configuration at " + self.settings.value("kf_qlr_url") + ". Error code : " + str(network_reply.error())) else: response = str(network_reply.readAll(), "utf-8") response = self.insert_token(response) self.write_cached_kf_qlr(response) # Now load and use it self._load_config_from_cached_kf_qlr() def _load_config_from_cached_kf_qlr(self): self.kf_qlr_file = QlrFile(self._read_cached_kf_qlr()) self.background_category, self.categories = self.get_kf_categories() self.loaded.emit() def get_categories(self): return self.categories def get_background_category(self): return self.background_category def get_maplayer_node(self, id): return self.kf_qlr_file.get_maplayer_node(id) def get_kf_categories(self): kf_categories = [] kf_background_category = None groups_with_layers = self.kf_qlr_file.get_groups_with_layers() for group in groups_with_layers: kf_category = {"name": group["name"], "selectables": []} for layer in group["layers"]: if self.user_has_access(layer["service"]): kf_category["selectables"].append({ "type": "layer", "source": "kf", "name": layer["name"], "id": layer["id"], }) if len(kf_category["selectables"]) > 0: kf_categories.append(kf_category) if group["name"] == "Baggrundskort": kf_background_category = kf_category return kf_background_category, kf_categories def user_has_access(self, service_name): return service_name in self.allowed_kf_services["any_type"]["services"] def get_custom_categories(self): return [] def _read_cached_kf_qlr(self): # return file(unicode(self.cached_kf_qlr_filename)).read() f = QFile(self.cached_kf_qlr_filename) f.open(QIODevice.ReadOnly) return f.readAll() def write_cached_kf_qlr(self, contents): """We only call this function IF we have a new version downloaded""" # Remove old versions file for filename in glob.glob( self.settings.value("cache_path") + "*_kortforsyning_data.qlr"): os.remove(filename) # Write new version with codecs.open(self.cached_kf_qlr_filename, "w", "utf-8") as f: f.write(contents) def debug_write_allowed_services(self): try: debug_filename = (self.settings.value("cache_path") + self.settings.value("username") + ".txt") if os.path.exists(debug_filename): os.remove(debug_filename) with codecs.open(debug_filename, "w", "utf-8") as f: f.write( json.dumps( self.allowed_kf_services["any_type"]["services"], indent=2).replace("[", "").replace("]", "")) except Exception: pass def insert_token(self, text): result = text replace_vars = {} replace_vars["kf_token"] = self.settings.value("token") for i, j in replace_vars.items(): result = result.replace("{{" + str(i) + "}}", str(j)) return result
class Download: def __init__(self, parent=None, iface=None): self.parent = parent self.iface = iface self.login_accepted = False self.akt_download = 0 self.all_download = 0 self.request_is_aborted = False self.nam = QNetworkAccessManager() self.nam.authenticationRequired.connect(self.set_credentials) self.nam.finished.connect(self.reply_finished) def layer_exists(self, name): if len(QgsProject.instance().mapLayersByName(name)) != 0: return True else: return False def get_image(self, url, filename, lat_tx, lon_tx, load_to_canvas=True): layer_name = "%s%s.hgt" % (lat_tx, lon_tx) if not self.layer_exists(layer_name): self.filename = filename self.load_to_canvas = True download_url = QUrl(url) req = QNetworkRequest(download_url) self.nam.get(req) def set_credentials(self, reply, authenticator): if not self.request_is_aborted: self.get_settings() self.login = Login(self.username, self.password) if self.login.exec_(): self.authenticator = authenticator self.authenticator.setUser(self.login.username) self.authenticator.setPassword(self.login.password) if self.login.chk_save_credentials.isChecked(): self.set_settings() else: reply.abort() self.request_is_aborted = True self.parent.download_finished(show_message=False, abort=True) def reply_finished(self, reply): if reply != None: possibleRedirectUrl = reply.attribute( QNetworkRequest.RedirectionTargetAttribute) # If the URL is not empty, we're being redirected. if possibleRedirectUrl != None: request = QNetworkRequest(possibleRedirectUrl) result = self.nam.get(request) self.parent.init_progress() self.parent.add_download_progress(reply) result.downloadProgress.connect( lambda done, all, reply=result: self.progress( done, all, reply)) else: if reply.error() != None: if reply.error() == QNetworkReply.ContentNotFoundError: self.parent.set_progress() reply.abort() reply.deleteLater() elif reply.error() == QNetworkReply.NoError: result = reply.readAll() f = open(self.filename, 'wb') f.write(result) f.close() out_image = self.unzip(self.filename) (dir, file) = os.path.split(out_image) if not self.layer_exists(file): self.iface.addRasterLayer(out_image, file) self.parent.set_progress() # Clean up. */ reply.deleteLater() def progress(self, akt, max, reply): is_image = QFileInfo( reply.url().path()).completeSuffix() == 'SRTMGL1.hgt.zip' if is_image: current_row = self.parent.progress_widget_item_list[QFileInfo( reply.url().path()).baseName()] progress_widget = self.parent.tableWidget.cellWidget( current_row, 1) progress_widget.setValue(akt) progress_widget.setMaximum(max) if reply.isFinished(): self.drop_row(current_row) def drop_row(self, i): self.parent.tableWidget.removeRow(i) for key, value in self.parent.progress_widget_item_list.items(): if value == i: self.parent.progress_widget_item_list.pop(key) break for key, value in self.parent.progress_widget_item_list.items(): if value > i: self.parent.progress_widget_item_list[key] = value - 1 def unzip(self, zip_file): import zipfile (dir, file) = os.path.split(zip_file) if not dir.endswith(':') and not os.path.exists(dir): os.mkdir(dir) try: zf = zipfile.ZipFile(zip_file) # extract files to directory structure for i, name in enumerate(zf.namelist()): if not name.endswith('/'): outfile = open(os.path.join(dir, name), 'wb') outfile.write(zf.read(name)) outfile.flush() outfile.close() return os.path.join(dir, name) except: return None def _makedirs(self, directories, basedir): """ Create any directories that don't currently exist """ for dir in directories: curdir = os.path.join(basedir, dir) if not os.path.exists(curdir): os.mkdir(curdir) def _listdirs(self, file): """ Grabs all the directories in the zip structure This is necessary to create the structure before trying to extract the file to it. """ zf = zipfile.ZipFile(file) dirs = [] for name in zf.namelist(): if name.endswith('/'): dirs.append(name) dirs.sort() return dirs def set_settings(self): settings = QSettings() mySettingsPath = "/SRTM-Downloader" settings.setValue(mySettingsPath + "/username", self.login.username) settings.setValue(mySettingsPath + "/password", self.login.password) def get_settings(self): settings = QSettings() mySettingsPath = "/SRTM-Downloader" self.username = settings.value(mySettingsPath + "/username") self.password = settings.value(mySettingsPath + "/password")
class NetManager(QObject): def __init__(self, parent): super().__init__(parent) self.network = QNetworkAccessManager(self) ############# def _pre_send_request(self, conn_info, endpoint, kw_request=dict()): assert (isinstance(endpoint, str)) request = make_conn_request(conn_info, endpoint, **kw_request) return request def _post_send_request(self, reply, conn_info, kw_prop=dict()): set_qt_property(reply, conn_info=conn_info, **kw_prop) def _send_request(self, conn_info, endpoint, kw_request=dict(), kw_prop=dict()): request = self._pre_send_request(conn_info, endpoint, kw_request=kw_request) reply = self.network.get(request) self._post_send_request(reply, conn_info, kw_prop=kw_prop) return reply ############# # TODO: remove callback params def get_statistics(self, conn_info): reply = self._get_space_(conn_info, "statistics") timeout = TIMEOUT_COUNT QTimer.singleShot(timeout, reply.abort) return reply def get_count(self, conn_info): reply = self._get_space_(conn_info, "count") return reply def get_meta(self, conn_info): return self._get_space_(conn_info, "space_meta") def _get_space_(self, conn_info, reply_tag): tag = "/" + reply_tag if reply_tag != "space_meta" else "" endpoint = "/spaces/{space_id}" + tag kw_request = dict() kw_prop = dict(reply_tag=reply_tag) return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def list_spaces(self, conn_info): endpoint = "/spaces" kw_request = dict(includeRights="true") kw_prop = dict(reply_tag="spaces") return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def add_space(self, conn_info, space_info): space_info = prepare_new_space_info(space_info) endpoint = "/spaces" kw_request = dict(req_type="json") kw_prop = dict(reply_tag="add_space") request = self._pre_send_request(conn_info, endpoint, kw_request=kw_request) reply = self.network.post(request, make_payload(space_info)) self._post_send_request(reply, conn_info, kw_prop=kw_prop) return reply def edit_space(self, conn_info, space_info): endpoint = "/spaces/{space_id}" kw_request = dict(req_type="json") kw_prop = dict(reply_tag="edit_space") request = self._pre_send_request(conn_info, endpoint, kw_request=kw_request) buffer = make_buffer(space_info) reply = self.network.sendCustomRequest(request, b"PATCH", buffer) buffer.setParent(reply) self._post_send_request(reply, conn_info, kw_prop=kw_prop) return reply def del_space(self, conn_info): endpoint = "/spaces/{space_id}" kw_request = dict() kw_prop = dict(reply_tag="del_space") request = self._pre_send_request(conn_info, endpoint, kw_request=kw_request) reply = self.network.sendCustomRequest(request, b"DELETE") self._post_send_request(reply, conn_info, kw_prop=kw_prop) return reply def _prefix_query(self, txt, prefix="p.", prefixes=tuple()): """ return prefix to xyz query: prefixes = ["p.", "f."] # add prefix if none in prefixes exists prefixes = [] # always add prefix, dont check existing """ return prefix if not any(map(txt.startswith, prefixes)) else "" def _process_queries(self, kw): selection = ",".join( "{prefix}{name}".format(name=p, prefix=self._prefix_query(p, "p.")) for p in kw.pop("selection", "").split(",") if p) if selection: kw["selection"] = selection self._process_raw_queries(kw) def _process_raw_queries(self, kw): filters = [ "{prefix}{name}{operator}{value}".format(name=p["name"], operator=p["operator"], value=p["values"], prefix=self._prefix_query( p["name"], "p.")) for p in kw.pop("filters", list()) ] if filters: kw.setdefault("raw_queries", list()).extend(filters) def load_features_bbox(self, conn_info, bbox, **kw): reply_tag = "bbox" endpoint = "/spaces/{space_id}/bbox" self._process_queries(kw) kw_request = dict(bbox, **kw) kw_prop = dict(reply_tag=reply_tag, bbox=bbox, **kw) return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def load_features_tile(self, conn_info, tile_id="0", tile_schema="quadkey", **kw): reply_tag = "tile" kw_tile = dict(tile_schema=tile_schema, tile_id=tile_id) tile_url = "tile/{tile_schema}/{tile_id}".format(**kw_tile) endpoint = "/spaces/{space_id}/" + tile_url self._process_queries(kw) kw_prop = dict(reply_tag=reply_tag, **dict(kw, **kw_tile)) return self._send_request(conn_info, endpoint, kw_request=kw, kw_prop=kw_prop) def load_features_iterate(self, conn_info, **kw): reply_tag = kw.pop("reply_tag", "iterate") endpoint = "/spaces/{space_id}/iterate" self._process_queries(kw) kw_prop = dict(reply_tag=reply_tag, **kw) return self._send_request(conn_info, endpoint, kw_request=kw, kw_prop=kw_prop) def load_features_search(self, conn_info, **kw): reply_tag = kw.pop("reply_tag", "search") endpoint = "/spaces/{space_id}/search" self._process_queries(kw) kw_prop = dict(reply_tag=reply_tag, **kw) return self._send_request(conn_info, endpoint, kw_request=kw, kw_prop=kw_prop) ###### feature function def add_features(self, conn_info, added_feat, **kw): send_request = self.network.post # create or modify (merge existing feature with payload) # might add attributes return self._add_features(conn_info, added_feat, send_request, **kw) def modify_features(self, conn_info, added_feat, **kw): return self.add_features(conn_info, added_feat, **kw) def replace_features(self, conn_info, added_feat, **kw): send_request = self.network.put # create or replace (replace existing feature with payload) # might add or drop attributes return self._add_features(conn_info, added_feat, send_request, **kw) def _add_features(self, conn_info, added_feat, send_request, **kw): # POST, payload: list of FeatureCollection endpoint = "/spaces/{space_id}/features" if "tags" in kw: kw["addTags"] = kw["tags"] kw_request = dict(req_type="geo", **kw) # kw: query kw_prop = dict(reply_tag="add_feat") kw_prop.update(kw) request = self._pre_send_request(conn_info, endpoint, kw_request=kw_request) payload = make_payload(added_feat) reply = send_request(request, payload) self._post_send_request(reply, conn_info, kw_prop=kw_prop) #parallel case (merge output ? split input?) return reply def del_features(self, conn_info, removed_feat, **kw): # DELETE by Query URL, required list of feat_id query_del = {"id": ",".join(str(i) for i in removed_feat)} kw.update(query_del) endpoint = "/spaces/{space_id}/features" kw_request = dict(kw) # kw: query kw_prop = dict(reply_tag="del_feat") request = self._pre_send_request(conn_info, endpoint, kw_request=kw_request) reply = self.network.sendCustomRequest(request, b"DELETE") self._post_send_request(reply, conn_info, kw_prop=kw_prop) return reply
class KeyWordsSelection: def __init__(self, auth_file): logger.debug("\n================== ISOGEO API WITH QT ==================") # getting credentials : logger.debug("Getting credentials") self.utils = IsogeoUtils() self.app_creds = self.utils.credentials_loader(auth_file) self.app_id = self.app_creds.get("client_id") self.app_secrets = self.app_creds.get("client_secret") # for connection : self.naMngr = QNetworkAccessManager() self.token_url = "https://id.api.isogeo.com/oauth/token" self.request_url = ( "https://v1.api.isogeo.com/resources/search?_limit=0&_offset=0" ) # init variables : self.token = "" self.search_type = "init" self.checked_kw = {} # for ui (launch and display): logger.debug("Processing and displaying UI") self.app = QApplication(sys.argv) self.ui = AuthWidget() self.ui.resize(400, 100) self.pysdk_checking() self.api_authentification() self.ui.btn_reset.pressed.connect(self.reset) self.ui.show() self.app.exec() def pysdk_checking(self): logger.debug("\n--------------- isogeo-pysdk ---------------") logger.debug("Checking credentials") try: isogeo = Isogeo(self.app_id, self.app_secrets) isogeo.connect() except OSError as e: logger.debug("Credentials issue : {}".format(e)) return except ValueError as e: logger.debug("Credentials issue : {}".format(e)) return if self.search_type == "init": result = isogeo.search( whole_share=0, page_size=0, augment=0, tags_as_dicts=1 ) else: query = " ".join(list(self.checked_kw.keys())) result = isogeo.search( whole_share=0, page_size=0, augment=0, tags_as_dicts=1, query=query ) self.tags_expected = result.get("tags") self.kw_expected_nb = len(self.tags_expected.get("keywords")) self.ui.lbl_expected.setText( "Expected : {} resources and {} keywords".format( result.get("total"), self.kw_expected_nb ) ) logger.debug( "isogeo-pysdk validates the authentication file, {} accessible resources".format( result.get("total") ) ) def api_authentification(self): logger.debug("\n------------------ Authentication ------------------") # 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 ct_header_value = QByteArray() ct_header_value.append("application/json") # creating request token_rqst = QNetworkRequest(QUrl(self.token_url)) # setting headers token_rqst.setRawHeader(crd_header_name, crd_header_value) token_rqst.setHeader(token_rqst.ContentTypeHeader, ct_header_value) # creating data data = QByteArray() data.append(urlencode({"grant_type": "client_credentials"})) # 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)) def api_handle_token(self, reply): logger.debug("Token asked and API reply received") # formating API response bytarray = reply.readAll() content = bytarray.data().decode("utf8") # check API response structure try: parsed_content = json.loads(content) except: logger.debug("Reply format issue") return # check API response content if "access_token" in parsed_content: self.token = "Bearer " + parsed_content.get("access_token") self.api_get_request() else: logger.debug("ya une couille dans la magouille : {}".format(parsed_content)) 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)) def api_handle_request(self, reply): logger.debug("Request sent and API reply received") bytarray = reply.readAll() content = bytarray.data().decode("utf8") if reply.error() == 0: # check API response structure try: parsed_content = json.loads(content) except: logger.debug("Reply format issue") return # check API response content self.tags_found = parsed_content.get("tags") self.kw_found = {} for tag in sorted(self.tags_found): if tag.startswith("keyword:is"): self.kw_found[tag] = self.tags_found.get(tag) else: pass # displaying result self.ui.lbl_found.setText( "Found : {} resources and {} keywords".format( parsed_content.get("total"), len(self.kw_found) ) ) if self.search_type == "init": if len(self.kw_found) == self.kw_expected_nb: logger.debug("!!! It's working !!!") else: logger.debug("It's NOT working") else: pass # filling keywords checkable combo box self.pop_kw_cbbox() elif self.search_type != "init": logger.debug("token expired, renewing it") self.api_authentification() else: pass def pop_kw_cbbox(self): logger.debug("\n-------------- Poping Keywords ComboBox --------------") # to prepare the filling self.ui.kw_cbbox.clear() if self.search_type != "init": self.ui.kw_cbbox.activated.disconnect(self.get_checked_kw) # filling the combobox with checkable items self.ui.kw_cbbox.addItem("-- Keywords --") first_item = self.ui.kw_cbbox.model().item(0, 0) first_item.setEnabled(False) i = 1 for kw_code, kw_lbl in self.kw_found.items(): if self.search_type == "kw" and kw_code in self.checked_kw.keys(): self.ui.kw_cbbox.insertItem(1, kw_lbl) item = self.ui.kw_cbbox.model().item(1, 0) item.setCheckState(Qt.Checked) else: self.ui.kw_cbbox.addItem(kw_lbl) item = self.ui.kw_cbbox.model().item(i, 0) item.setCheckState(Qt.Unchecked) item.setData(kw_code, 32) i += 1 logger.debug("Keywords Combobox filled") self.ui.kw_cbbox.setEnabled(True) # connecting to a signal returning the checked item's index self.ui.kw_cbbox.activated.connect(self.get_checked_kw) def get_checked_kw(self, index): logger.debug("\n------------ Getting Checked Keywords ------------") self.ui.kw_cbbox.setEnabled(False) self.ui.kw_cbbox.setCurrentText(self.ui.kw_cbbox.itemText(index)) # Testing if checked keyword is already in the dict is easier than # testing if the user checked or unchecked it : # removing the selected keyword from the dict if it is already in if self.ui.kw_cbbox.itemData(index, 32) in self.checked_kw.keys(): del self.checked_kw[self.ui.kw_cbbox.itemData(index, 32)] # adding the selected keyword to the dict if it is not already in else: self.checked_kw[ self.ui.kw_cbbox.itemData(index, 32) ] = self.ui.kw_cbbox.itemText(index) logger.debug("ckeched kw : {}".format(self.checked_kw)) self.ui.lbl_selection.setText( "{} keywords selected".format(len(self.checked_kw)) ) self.ui.kw_cbbox.setToolTip(" / ".join(list(self.checked_kw.values()))) # now selected keywords are stocked, time to request the API self.kw_search() def kw_search(self): logger.debug("\n------------ Searching with keywords -------------") # preparing the request self.search_type = "kw" self.request_url = self.url_builder() self.pysdk_checking() # launching the request self.api_get_request() def url_builder(self): logger.debug("\n------------------ Building URL ------------------") # adding selected keywords to the request URL search_url = "https://v1.api.isogeo.com/resources/search?q=" for kw in self.checked_kw: search_url += "{} ".format(str(kw)) logger.debug("URL : {}".format(search_url)) return search_url[:-1] def reset(self): logger.debug("----------------- RESET -------------------") self.search_type = "reset" self.checked_kw = {} self.request_url = ( "https://v1.api.isogeo.com/resources/search?_limit=0&_offset=0" ) self.ui.lbl_selection.setText("") self.ui.kw_cbbox.setToolTip("") self.pysdk_checking() self.api_get_request()
class ApiConnection: def __init__(self, auth_file): logger.debug( "\n================== ISOGEO API WITH QT ==================") # getting credentials : logger.debug("Getting credentials") self.utils = IsogeoUtils() self.app_creds = self.utils.credentials_loader(auth_file) self.app_id = self.app_creds.get("client_id") self.app_secrets = self.app_creds.get("client_secret") # for connection : self.naMngr = QNetworkAccessManager() self.token_url = "https://id.api.isogeo.com/oauth/token" self.request_url = ( "https://v1.api.isogeo.com/resources/search?_limit=0&_offset=0") self.token = "" # for ui : logger.debug("Processing and displaying UI") self.app = QApplication([]) self.ui = AuthWidget() self.ui.resize(350, 100) self.ui.btn.clicked.connect(self.api_authentification) self.pysdk_checking() self.ui.show() self.app.exec() def pysdk_checking(self): logger.debug("\n------------------ isogeo-pysdk ------------------") logger.debug("Checking credentials") try: isogeo = Isogeo(self.app_id, self.app_secrets) isogeo.connect() except OSError as e: logger.debug("Credentials issue : {}".format(e)) return except ValueError as e: logger.debug("Credentials issue : {}".format(e)) return self.md_expected = isogeo.search(whole_share=0, page_size=0, augment=0).get("total") self.ui.lbl_expected.setText("{} expected resources".format( self.md_expected)) logger.debug( "isogeo-pysdk validates the authentication file, {} accessible resources" .format(self.md_expected)) 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)) def api_handle_token(self, reply): logger.debug("\n------------------ Token retrieval ------------------") logger.debug("Token asked and API reply received : {}".format(reply)) logger.debug("Storage and formatting of the reply") bytarray = reply.readAll() content = bytarray.data().decode("utf8") # check API response structure try: parsed_content = json.loads(content) except: logger.debug("Reply format issue") return logger.debug("Reply format is good") if "access_token" in parsed_content: self.token = "Bearer " + parsed_content.get("access_token") logger.debug("TOKEN STORED") self.api_get_request() else: logger.debug( "ya une couille dans la magouille : {}".format(parsed_content)) def api_get_request(self): logger.debug("\n------------------ Sending request ------------------") # creating credentials header logger.debug("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)) logger.debug("Creating request : {}".format(rqst.url())) # setting credentials header rqst.setRawHeader(crd_header_name, crd_header_value) logger.debug("Setting credentials header : {}".format( rqst.rawHeader(crd_header_name))) # sending request rqst_reply = self.naMngr.get(rqst) logger.debug("Sending request") rqst_reply.finished.connect( partial(self.api_handle_request, reply=rqst_reply)) def api_handle_request(self, reply): logger.debug("\n------------------ Reply retrieval ------------------") logger.debug("Request sent and API reply received : {}".format(reply)) logger.debug("Storage and formatting of the reply") bytarray = reply.readAll() content = bytarray.data().decode("utf8") # check API response structure try: parsed_content = json.loads(content) except: logger.debug("Reply format issue") return logger.debug("Reply format is good") self.md_found = parsed_content.get("total") logger.debug("RESULT STORED") self.ui.lbl_found.setText("{} resources found".format(self.md_found)) if self.md_found == self.md_expected: logger.debug("!!! It's working !!!") else: logger.debug("It's NOT working")
address = response_data["Response"]["View"][0]["Result"][0]["Location"]["Address"]["Label"] our_layer.startEditing() address_col= our_layer.dataProvider().fieldNameIndex("address") our_layer.changeAttributeValue(fid, address_col, address) our_layer.commitChanges() QtWidgets.QMessageBox.information(None, "Success", "Location has been reverse geocoded: {}".format(address)) here_api_key = 'insert_your_here_api_key_here' our_layer = '[% @layer_id %]' QgsMessageLog.logMessage("Selected layer ID is {}".format(str(our_layer))) our_layer = QgsProject.instance().mapLayer(our_layer) fid = [% $id %] QgsMessageLog.logMessage("Selected feature ID is {}".format(str(fid))) feature = our_layer.getFeature(fid) point = feature.geometry().asPoint() lat, lng = point.y(), point.x() QgsMessageLog.logMessage("Selected coordinates are {}, {}".format(lat, lng)) manager = QNetworkAccessManager() manager.finished.connect(handle_response) do_request(manager, lat, lng, here_api_key)
class AutoSuggest(QObject): def __init__(self, geturl_func, parseresult_func, parent = None): QObject.__init__(self, parent) self.geturl_func = geturl_func self.parseresult_func = parseresult_func self.editor = parent self.networkManager = QNetworkAccessManager() self.selectedObject = None self.isUnloaded = False self.popup = QTreeWidget(parent) #self.popup.setColumnCount(2) self.popup.setColumnCount(1) self.popup.setUniformRowHeights(True) self.popup.setRootIsDecorated(False) self.popup.setEditTriggers(QTreeWidget.NoEditTriggers) self.popup.setSelectionBehavior(QTreeWidget.SelectRows) self.popup.setFrameStyle(QFrame.Box | QFrame.Plain) self.popup.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.popup.header().hide() self.popup.installEventFilter(self) self.popup.setMouseTracking(True) #self.connect(self.popup, SIGNAL("itemClicked(QTreeWidgetItem*, int)"), # self.doneCompletion) self.popup.itemClicked.connect( self.doneCompletion ) self.popup.setWindowFlags(Qt.Popup) self.popup.setFocusPolicy(Qt.NoFocus) self.popup.setFocusProxy(parent) self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.setInterval(500) #self.connect(self.timer, SIGNAL("timeout()"), self.autoSuggest) self.timer.timeout.connect( self.autoSuggest ) #self.connect(self.editor, SIGNAL("textEdited(QString)"), self.timer, SLOT("start()")) #self.editor.textEdited.connect( self.timer.start ) self.editor.textEdited.connect( self.timer.start ) #self.editor.textChanged.connect( self.timer.start ) #self.connect(self.networkManager, SIGNAL("finished(QNetworkReply*)"), # self.handleNetworkData) self.networkManager.finished.connect( self.handleNetworkData ) def eventFilter(self, obj, ev): if obj != self.popup: return False if ev.type() == QEvent.MouseButtonPress: self.popup.hide() self.editor.setFocus() return True if ev.type() == QEvent.KeyPress: consumed = False key = ev.key() if key == Qt.Key_Enter or key == Qt.Key_Return: self.doneCompletion() consumed = True elif key == Qt.Key_Escape: self.editor.setFocus() self.popup.hide() consumed = True elif key in (Qt.Key_Up, Qt.Key_Down, Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown): pass else: self.editor.setFocus() self.editor.event(ev) self.popup.hide() return consumed return False def showCompletion(self, rows): # Rows is an iterable of tuples like [("text",object1),("text2", object2),...] pal = self.editor.palette() color = pal.color(QPalette.Disabled, QPalette.WindowText) self.popup.setUpdatesEnabled(False) self.popup.clear() if rows is None or len( rows ) < 1: return for row in rows: item = QTreeWidgetItem(self.popup) item.setText(0, row[0]) #item.setText(1, hit['type']) item.setTextAlignment(1, Qt.AlignRight) item.setForeground(1, color) item.setData(2, Qt.UserRole, (row[1],)) # Try immutable py obj #http://stackoverflow.com/questions/9257422/how-to-get-the-original-python-data-from-qvariant self.popup.setCurrentItem(self.popup.topLevelItem(0)) self.popup.resizeColumnToContents(0) #self.popup.resizeColumnToContents(1) self.popup.adjustSize() self.popup.setUpdatesEnabled(True) h = self.popup.sizeHintForRow(0) * min(15, len(rows)) + 3 w = max(self.popup.width(), self.editor.width()) self.popup.resize(w, h) self.popup.move(self.editor.mapToGlobal(QPoint(0, self.editor.height()))) self.popup.setFocus() self.popup.show() def doneCompletion(self): self.timer.stop() self.popup.hide() self.editor.setFocus() item = self.popup.currentItem() if item: self.editor.setText(item.text(0) ) obj = item.data(2, Qt.UserRole) #.toPyObject() self.selectedObject = obj[0] e = QKeyEvent(QEvent.KeyPress, Qt.Key_Enter, Qt.NoModifier) QApplication.postEvent(self.editor, e) e = QKeyEvent(QEvent.KeyRelease, Qt.Key_Enter, Qt.NoModifier) QApplication.postEvent(self.editor, e) def preventSuggest(self): self.timer.stop() def autoSuggest(self): term = self.editor.text() if term: qurl = self.geturl_func( term ) if qurl: # TODO: Cancel existing requests: http://qt-project.org/forums/viewthread/18073 self.networkManager.get(QNetworkRequest( qurl )) #QUrl(url))) def handleNetworkData(self, networkReply): url = networkReply.url() #print "received url:", url.toString() if not networkReply.error(): response = networkReply.readAll() pystring = str(response, 'utf-8') #print "Response: ", response rows = self.parseresult_func( pystring ) self.showCompletion( rows ) networkReply.deleteLater() def unload( self ): # Avoid processing events after QGIS shutdown has begun self.popup.removeEventFilter(self) self.isUnloaded = True
def __init__(self): super().__init__() self.isKill = None self.responseAllFinished = None self.nam = QNetworkAccessManager(self) self.nam.finished.connect( self.replyFinished )
class NetManager(QObject): def __init__(self, parent): super().__init__(parent) self.network = QNetworkAccessManager(self) ############# def _pre_send_request(self,conn_info, endpoint, kw_request=dict()): assert(isinstance(endpoint,str)) request = make_conn_request(conn_info, endpoint,**kw_request) return request def _post_send_request(self, reply, conn_info, kw_prop=dict()): set_qt_property(reply, conn_info=conn_info, **kw_prop) def _send_request(self,conn_info, endpoint, kw_request=dict(), kw_prop=dict()): request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.get(request) self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply ############# # TODO: remove callback params def get_statistics(self, conn_info): return self._get_space_(conn_info, "statistics") def get_count(self, conn_info): reply = self._get_space_(conn_info, "count") # timeout = 1000 # QTimer.singleShot(timeout, reply.abort) return reply def get_meta(self, conn_info): return self._get_space_(conn_info, "space_meta") def _get_space_(self, conn_info, reply_tag): tag = "/" + reply_tag if reply_tag != "space_meta" else "" endpoint = "/spaces/{space_id}" + tag kw_request = dict() kw_prop = dict(reply_tag=reply_tag) return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def list_spaces(self, conn_info): endpoint = "/spaces" kw_request = dict(includeRights="true") kw_prop = dict(reply_tag="spaces") return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def add_space(self, conn_info, space_info): space_info = prepare_new_space_info(space_info) endpoint = "/spaces" kw_request = dict(req_type="json") kw_prop = dict(reply_tag="add_space") request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.post(request, make_payload(space_info)) self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply def edit_space(self, conn_info, space_info): endpoint = "/spaces/{space_id}" kw_request = dict(req_type="json") kw_prop = dict(reply_tag="edit_space") request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.sendCustomRequest(request, b"PATCH", make_payload(space_info)) self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply def del_space(self, conn_info): endpoint = "/spaces/{space_id}" kw_request = dict() kw_prop = dict(reply_tag="del_space") request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.sendCustomRequest(request, b"DELETE") self._post_send_request(reply,conn_info, kw_prop=kw_prop) return reply def load_features_bbox(self, conn_info, bbox, **kw): endpoint = "/spaces/{space_id}/bbox" kw_request = dict(bbox) kw_request.update(kw) kw_prop = dict(reply_tag="bbox") kw_prop.update(kw) kw_prop["bbox"] = bbox return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) def load_features_iterate(self, conn_info, **kw_iterate): reply_tag = kw_iterate.pop("reply_tag","iterate") endpoint = "/spaces/{space_id}/iterate" return self._load_features_endpoint(endpoint, conn_info, reply_tag=reply_tag, **kw_iterate) def load_features_search(self, conn_info, **kw_iterate): reply_tag = kw_iterate.pop("reply_tag","search") endpoint = "/spaces/{space_id}/search" return self._load_features_endpoint(endpoint, conn_info, reply_tag=reply_tag, **kw_iterate) def _load_features_endpoint(self, endpoint, conn_info, reply_tag=None, **kw_iterate): """ Iterate through all ordered features (no feature is repeated twice) """ kw_request = dict(kw_iterate) kw_prop = dict(reply_tag=reply_tag) kw_prop.update(kw_iterate) return self._send_request(conn_info, endpoint, kw_request=kw_request, kw_prop=kw_prop) ###### feature function def add_features(self, conn_info, added_feat, layer_id=None, **kw): # POST, payload: list of FeatureCollection endpoint = "/spaces/{space_id}/features" kw_request = dict(req_type="geo", **kw) # kw: query kw_prop = dict(reply_tag="add_feat",layer_id=layer_id) kw_prop.update(kw) request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) buffer = make_payload(added_feat) reply = self.network.post(request, buffer) self._post_send_request(reply, conn_info, kw_prop=kw_prop) #parallel case (merge output ? split input?) return reply def del_features(self, conn_info, removed_feat, layer_id, **kw): # DELETE by Query URL, required list of feat_id query_del = {"id": ",".join(str(i) for i in removed_feat)} kw.update(query_del) endpoint = "/spaces/{space_id}/features" kw_request = dict(kw) # kw: query kw_prop = dict(reply_tag="del_feat",layer_id=layer_id) request = self._pre_send_request(conn_info,endpoint,kw_request=kw_request) reply = self.network.sendCustomRequest(request, b"DELETE") self._post_send_request(reply, conn_info, kw_prop=kw_prop) return reply def sync(self, conn_info, feat, layer_id, **kw): added_feat, removed_feat = feat token, space_id = conn_info.get_xyz_space() if not added_feat is None: self.add_features(conn_info, added_feat, layer_id) if len(removed_feat): self.del_features(conn_info, removed_feat, layer_id)
class AutoSuggest(QObject): def __init__(self, geturl_func, parseresult_func, parent=None): QObject.__init__(self, parent) self.geturl_func = geturl_func self.parseresult_func = parseresult_func self.editor = parent self.networkManager = QNetworkAccessManager() self.selectedObject = None self.isUnloaded = False self.popup = QTreeWidget(parent) #self.popup.setColumnCount(2) self.popup.setColumnCount(1) self.popup.setUniformRowHeights(True) self.popup.setRootIsDecorated(False) self.popup.setEditTriggers(QTreeWidget.NoEditTriggers) self.popup.setSelectionBehavior(QTreeWidget.SelectRows) self.popup.setFrameStyle(QFrame.Box | QFrame.Plain) self.popup.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.popup.header().hide() self.popup.installEventFilter(self) self.popup.setMouseTracking(True) #self.connect(self.popup, SIGNAL("itemClicked(QTreeWidgetItem*, int)"), # self.doneCompletion) self.popup.itemClicked.connect(self.doneCompletion) self.popup.setWindowFlags(Qt.Popup) self.popup.setFocusPolicy(Qt.NoFocus) self.popup.setFocusProxy(parent) self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.setInterval(500) #self.connect(self.timer, SIGNAL("timeout()"), self.autoSuggest) self.timer.timeout.connect(self.autoSuggest) #self.connect(self.editor, SIGNAL("textEdited(QString)"), self.timer, SLOT("start()")) #self.editor.textEdited.connect( self.timer.start ) self.editor.textEdited.connect(self.timer.start) #self.editor.textChanged.connect( self.timer.start ) #self.connect(self.networkManager, SIGNAL("finished(QNetworkReply*)"), # self.handleNetworkData) self.networkManager.finished.connect(self.handleNetworkData) def eventFilter(self, obj, ev): if obj != self.popup: return False if ev.type() == QEvent.MouseButtonPress: self.popup.hide() self.editor.setFocus() return True if ev.type() == QEvent.KeyPress: consumed = False key = ev.key() if key == Qt.Key_Enter or key == Qt.Key_Return: self.doneCompletion() consumed = True elif key == Qt.Key_Escape: self.editor.setFocus() self.popup.hide() consumed = True elif key in (Qt.Key_Up, Qt.Key_Down, Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown): pass else: self.editor.setFocus() self.editor.event(ev) self.popup.hide() return consumed return False def showCompletion(self, rows): # Rows is an iterable of tuples like [("text",object1),("text2", object2),...] pal = self.editor.palette() color = pal.color(QPalette.Disabled, QPalette.WindowText) self.popup.setUpdatesEnabled(False) self.popup.clear() if rows is None or len(rows) < 1: return for row in rows: item = QTreeWidgetItem(self.popup) item.setText(0, row[0]) #item.setText(1, hit['type']) item.setTextAlignment(1, Qt.AlignRight) item.setForeground(1, color) item.setData( 2, Qt.UserRole, (row[1], ) ) # Try immutable py obj #http://stackoverflow.com/questions/9257422/how-to-get-the-original-python-data-from-qvariant self.popup.setCurrentItem(self.popup.topLevelItem(0)) self.popup.resizeColumnToContents(0) #self.popup.resizeColumnToContents(1) self.popup.adjustSize() self.popup.setUpdatesEnabled(True) h = self.popup.sizeHintForRow(0) * min(15, len(rows)) + 3 w = max(self.popup.width(), self.editor.width()) self.popup.resize(w, h) self.popup.move( self.editor.mapToGlobal(QPoint(0, self.editor.height()))) self.popup.setFocus() self.popup.show() def doneCompletion(self): self.timer.stop() self.popup.hide() self.editor.setFocus() item = self.popup.currentItem() if item: self.editor.setText(item.text(0)) obj = item.data(2, Qt.UserRole) #.toPyObject() self.selectedObject = obj[0] e = QKeyEvent(QEvent.KeyPress, Qt.Key_Enter, Qt.NoModifier) QApplication.postEvent(self.editor, e) e = QKeyEvent(QEvent.KeyRelease, Qt.Key_Enter, Qt.NoModifier) QApplication.postEvent(self.editor, e) def preventSuggest(self): self.timer.stop() def autoSuggest(self): term = self.editor.text() if term: qurl = self.geturl_func(term) if qurl: # TODO: Cancel existing requests: http://qt-project.org/forums/viewthread/18073 self.networkManager.get(QNetworkRequest(qurl)) #QUrl(url))) def handleNetworkData(self, networkReply): url = networkReply.url() #print "received url:", url.toString() if not networkReply.error(): response = networkReply.readAll() pystring = str(response, 'utf-8') #print "Response: ", response rows = self.parseresult_func(pystring) self.showCompletion(rows) networkReply.deleteLater() def unload(self): # Avoid processing events after QGIS shutdown has begun self.popup.removeEventFilter(self) self.isUnloaded = True
class AccessSite(QObject): abortReply = pyqtSignal() finished = pyqtSignal(dict) send_data = pyqtSignal(QByteArray) status_download = pyqtSignal(int, int) status_erros = pyqtSignal(list) ErrorCodeAttribute = { 10: 'Canceled request', 400: 'Bad request syntax', 401: 'Unauthorized', 402: 'Payment required', 403: 'Forbidden', 404: 'Not found', 500: 'Internal error', 501: 'Not implemented', 502: 'Bad Gateway' } def __init__(self): super().__init__() self.isKill = None self.responseAllFinished = None self.nam = QNetworkAccessManager(self) self.nam.finished.connect( self.replyFinished ) def _connectReply(self, reply, isConnect=True): ss = [ { 'signal': reply.readyRead, 'slot': self.readyRead }, { 'signal': reply.sslErrors, 'slot': self.sslErrors } ] if isConnect: if not self.responseAllFinished: reply.downloadProgress.connect( self.downloadProgress ) for item in ss: item['signal'].connect( item['slot'] ) else: if not self.responseAllFinished: reply.downloadProgress.disconnect( self.downloadProgress ) for item in ss: item['signal'].disconnect( item['slot'] ) def _closeReply(self, reply): def connect(isConnect=True): f_nam = self.nam.finished.connect if isConnect else self.nam.finished.disconnect f_nam( self.replyFinished ) if not self.responseAllFinished: self._connectReply( reply, isConnect ) # reply.close() call replyFinished connect(False) reply.close() connect() reply.deleteLater() def _redirectionReply(self, reply, url): self._closeReply( reply ) if url.isRelative(): url = url.resolved( url ) request = QNetworkRequest( url ) reply = self.nam.get( request ) if reply is None: response = { 'isOk': False, 'message': "Netwok error", 'errorCode': -1 } self.finished.emit( response ) return if not self.responseAllFinished: self._connectReply( reply ) def _emitErrorCodeAttribute(self, code, reply): msg = 'Error network' if not code in self.ErrorCodeAttribute.keys() else self.ErrorCodeAttribute[ code ] response = { 'isOk': False, 'message': msg, 'errorCode': code } self._closeReply( reply ) self.finished.emit( response ) def _checkRedirectionAttribute(self, reply): urlRedir = reply.attribute( QNetworkRequest.RedirectionTargetAttribute ) if not urlRedir is None and urlRedir != reply.url(): self._redirectionReply( reply, urlRedir ) return { 'isOk': True } codeAttribute = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute ) if not ( 200 <= codeAttribute <= 299 ): self._emitErrorCodeAttribute( codeAttribute, reply ) return { 'isOk': False } return { 'isOk': True } def _clearResponse(self, response): if 'data' in response: response['data'].clear() del response[ 'data' ] if 'statusRequest' in response: del response['statusRequest'] if response['isOk']: if 'errorCode' in response: del response['errorCode'] def requestUrl(self, paramsAccess, addFinishedResponse, setFinished): @pyqtSlot(dict) def finished( response): loop.quit() self.finished.disconnect( finished ) if 'notResponseAllFinished' in paramsAccess: self.send_data.disconnect( paramsAccess['notResponseAllFinished']['writePackageImage'] ) self.status_download.disconnect( paramsAccess['notResponseAllFinished']['progressPackageImage'] ) response = addFinishedResponse( response ) if response['isOk']: self._clearResponse( response ) setFinished( response ) def run(): def sslVerifyNone(req): conf = req.sslConfiguration() conf.setPeerVerifyMode( QSslSocket.VerifyNone ) req.setSslConfiguration( conf ) req = QNetworkRequest( url ) sslVerifyNone( req ) # Need for Windows, error 'Handshake failed' if json_request is None: reply = self.nam.get( req ) else: req.setHeader( QNetworkRequest.ContentTypeHeader, "application/json" ) data = QByteArray() data.append( json.dumps( json_request ) ) reply = self.nam.post( req, data ) if reply is None: response = { 'isOk': False, 'message': "Network error", 'errorCode': -1 } self.finished.emit( response ) return self.abortReply.connect( reply.abort ) if not self.responseAllFinished: self._connectReply( reply ) loop = QEventLoop() self.finished.connect( finished ) json_request = None if not 'json_request' in paramsAccess else paramsAccess['json_request'] self.responseAllFinished = True if 'notResponseAllFinished' in paramsAccess: self.responseAllFinished = False self.send_data.connect( paramsAccess['notResponseAllFinished']['writePackageImage'] ) self.status_download.connect( paramsAccess['notResponseAllFinished']['progressPackageImage'] ) url = paramsAccess['url'] if 'credential' in paramsAccess: userInfo = "{user}:{pwd}".format( user=paramsAccess['credential']['user'], pwd=paramsAccess['credential']['password'] ) url.setUserInfo( userInfo ) self.isKill = False run() loop.exec_() def isHostLive(self, url, setFinished): def addFinishedResponse(response): if response['isOk']: return response else: if response['errorCode'] == QNetworkReply.HostNotFoundError: response['message'] = "{}\nURL = {}".format( response['message'], self.urlGeoserver ) else: response['isOk'] = True return response p = { 'url': QUrl( url ) } self.requestUrl( p, addFinishedResponse, setFinished ) def getThumbnail(self, url, setFinished): def addFinishedResponse(response): if not response['isOk']: return response if 'data' in response: # The user can quickly change a item pixmap = QPixmap() if not pixmap.loadFromData( response['data'] ): response['isOk'] = False response['message'] = 'Invalid image from Mapbiomas server' else: response['thumbnail'] = pixmap return response p = { 'url': QUrl( url ) } self.requestUrl( p, addFinishedResponse, setFinished ) @pyqtSlot('QNetworkReply*') def replyFinished(self, reply) : if self.isKill: self._emitErrorCodeAttribute(10, reply ) return if reply.error() != QNetworkReply.NoError: response = { 'isOk': False, 'message': reply.errorString(), 'errorCode': reply.error() } self._closeReply( reply ) self.finished.emit( response ) return r = self._checkRedirectionAttribute( reply ) if not r['isOk']: return statusRequest = { 'contentTypeHeader': reply.header( QNetworkRequest.ContentTypeHeader ), 'lastModifiedHeader': reply.header( QNetworkRequest.LastModifiedHeader ), 'contentLengthHeader': reply.header( QNetworkRequest.ContentLengthHeader ), 'statusCodeAttribute': reply.attribute( QNetworkRequest.HttpStatusCodeAttribute ), 'reasonPhraseAttribute': reply.attribute( QNetworkRequest.HttpReasonPhraseAttribute ) } response = { 'isOk': True, 'statusRequest': statusRequest } if self.responseAllFinished: response['data'] = reply.readAll() self._closeReply( reply ) self.finished.emit( response ) @pyqtSlot() def readyRead(self): reply = self.sender() if self.isKill: self._emitErrorCodeAttribute(10, reply ) return r = self._checkRedirectionAttribute( reply ) if not r['isOk']: return if not reply.isOpen(): reply.open( QNetworkReply.ReadOnly ) data = reply.readAll() if data is None: return self.send_data.emit( data ) @pyqtSlot('qint64', 'qint64') def downloadProgress(self, bytesReceived, bytesTotal): reply = self.sender() if self.isKill: self._emitErrorCodeAttribute(10, reply ) else: self.status_download.emit( bytesReceived, bytesTotal ) @pyqtSlot('QList<QSslError>') def sslErrors(self, errors): reply = self.sender() lstErros = map( lambda e: e.errorString(), errors ) self.status_erros.emit( lstErros ) reply.ignoreSslErrors() @staticmethod def loadJsonData(response): data = response['data'].data() sdata = str(data, encoding='utf-8') return json.loads( sdata )
def __init__(self, url, method='GET', **data): self.manager = QNetworkAccessManager() self.method = method self.url = QUrl(url) self.request = QNetworkRequest(self.url)