def _load_service(self): """ Attempts to defined the service via WADL """ url = self.web_service_url_edit.text().strip() url = WadlServiceParser.find_url(url) request = QNetworkRequest(QUrl(url)) request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) reply = QgsNetworkAccessManager.instance().get(request) def response_finished(_reply: QNetworkReply): """ Triggered when the response is finished """ self.button_load_service.setEnabled(True) self.button_load_service.setText( self.tr('Load Web Service Capabilities')) content = _reply.readAll() try: self._set_state_from_wadl( WadlServiceParser.parse_wadl(content, self.service_type, url)) except AssertionError: self.message_bar.pushMessage( '', self.tr('Could not load web service capabilities from {}'. format(url)), Qgis.Critical, 0) self.button_load_service.setEnabled(False) self.button_load_service.setText(self.tr('Loading')) reply.finished.connect(partial(response_finished, reply))
def fetch_missing(self): """ Fetches missing results """ # pop first missing origin from front of queue and fetch it self.message.emit( self.tr( 'Returned XML was incomplete. {} missing origins left to fetch' ).format(len(self.missing_origins)), Qgis.Warning) remaining = list(self.missing_origins) next_origin = remaining[0] self.missing_origins = set(remaining[1:]) # change smi: prefix to http:// parts = next_origin.split(":") next_origin = 'http://' + ':'.join(parts[1:]) self.is_missing_origin_request = True request = QNetworkRequest(QUrl(next_origin)) request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) reply = QgsNetworkAccessManager.instance().get(request) reply.finished.connect(lambda r=reply: self._reply_finished(r)) reply.downloadProgress.connect(self._reply_progress)
def fetch_data(self): """ Starts the fetch request """ request = QNetworkRequest(QUrl(self.generate_url())) request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) reply = QgsNetworkAccessManager.instance().get(request) reply.finished.connect(lambda r=reply: self._reply_finished(r)) reply.downloadProgress.connect(self._reply_progress)
def fetch_basic_mdp(self): self.require_mdp_basic_text_request = False self.is_mdp_basic_text_request = True self.message.emit(self.tr('Fetching MDPs'), Qgis.Info) self.pending_event_ids = self.macro_pending_event_ids[:1] self.macro_pending_event_ids = self.macro_pending_event_ids[1:] request = QNetworkRequest(QUrl(self.generate_url())) request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) reply = QgsNetworkAccessManager.instance().get(request) reply.finished.connect(lambda r=reply: self._reply_finished(r)) reply.downloadProgress.connect(self._reply_progress)
def _refresh_contributors(self): self.edit_contributor_id.clear() url = SERVICE_MANAGER.get_contributor_endpoint(self.service_type, self.service_id) if not url: return self.button_refresh_contributors.setEnabled(False) request = QNetworkRequest(QUrl(url)) request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) reply = QgsNetworkAccessManager.instance().get(request) reply.finished.connect(lambda r=reply: self._reply_finished(r))
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 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 _fetch_fields(self): """ Triggers fetching fields """ if not self.service_uri: return self.label_fields.setText(self.tr('Fetching fields...')) # is_wms = 'wms' in self.service_uri # seems this must ALWAYS be WFS! url = self.service_uri + 'version=1.3.0&request=describeFeatureType&outputFormat=application/json&service={}'.format( 'WFS') request = QNetworkRequest(QUrl(url)) request.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) reply = QgsNetworkAccessManager.instance().get(request) def response_finished(_reply: QNetworkReply): """ Triggered when the response is finished """ if sip.isdeleted(self.label_fields): # pylint:disable=no-member return self.label_fields.setText(self.tr('List of fields')) res = json.load(BytesIO(_reply.readAll().data())) self.layers_def = {} for _type in res['featureTypes']: type_name = _type['typeName'] if CqlBuilderWidget._clean_layer_name( type_name) not in self.layer_names: continue self.layer_combo.addItem(type_name) layer_fields = [] for prop in _type['properties']: layer_fields.append({ 'name': prop['name'], 'type': prop['localType'] }) self.layers_def[type_name] = layer_fields self._layer_combo_changed() reply.finished.connect(partial(response_finished, reply))
def fetch(self): """Fetch the content (in the background). :return: (status, error message) :rtype: (boolean, string) """ # Initialize some properties again self._content = None self._network_finished = False self._network_timeout = False request = QNetworkRequest(QUrl(self._url)) request.setAttribute( QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) if self._auth_cfg and qgis_version() >= 21200: LOGGER.debug('Update request with auth_cfg %s' % self._auth_cfg) QgsAuthManager.instance().updateNetworkRequest( request, self._auth_cfg ) self._reply = self._network_manager.get(request) self._reply.finished.connect(self.fetch_finished) self._network_manager.requestTimedOut.connect(self.request_timeout) while not self._reply.isFinished(): # noinspection PyArgumentList QCoreApplication.processEvents() # Finished description = None if self._reply.error() != QNetworkReply.NoError: status = False description = self._reply.errorString() else: status = True self._content = self._reply.readAll() self._reply.deleteLater() return status, description
def fetch(self): """Fetch the content.""" # Initialize some properties again self._content = None self._network_finished = False self._network_timeout = False request = QNetworkRequest(QUrl(self._url)) request.setAttribute( QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) if self._auth_cfg and qgis_version() >= 21200: LOGGER.info('Update request with auth_cfg %s' % self._auth_cfg) QgsAuthManager.instance().updateNetworkRequest( request, self._auth_cfg ) self._reply = self._network_manager.get(request) self._reply.finished.connect(self.fetch_finished) self._network_manager.requestTimedOut.connect(self.request_timeout) while not self._reply.isFinished(): # noinspection PyArgumentList QCoreApplication.processEvents() # Finished description = None if self._reply.error() != QNetworkReply.NoError: status = False description = self._reply.errorString() else: status = True self._content = self._reply.readAll() self._reply.deleteLater() return status, description
def download_file(url, filename, on_progress=None, on_finished=None, on_error=None, on_success=None): """ Will download the file from url to a local filename. The method will only return once it's finished. While downloading it will repeatedly report progress by calling on_progress with two parameters bytes_received and bytes_total. If an error occurs, it raises a NetworkError exception. It will return the filename if everything was ok. """ network_access_manager = QgsNetworkAccessManager.instance() req = QNetworkRequest(QUrl(url)) req.setAttribute(QNetworkRequest.CacheSaveControlAttribute, False) req.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) req.setAttribute(QNetworkRequest.FollowRedirectsAttribute, True) reply = network_access_manager.get(req) def on_download_progress(bytes_received, bytes_total): on_progress(bytes_received, bytes_total) def finished(filename, reply, on_error, on_success, on_finished): file = QFile(filename) file.open(QIODevice.WriteOnly) file.write(reply.readAll()) file.close() if reply.error() and on_error: on_error(reply.error(), reply.errorString()) elif not reply.error() and on_success: on_success() if on_finished: on_finished() reply.deleteLater() replies.remove(reply) if on_progress: reply.downloadProgress.connect(on_download_progress) on_reply_finished = functools.partial(finished, filename, reply, on_error, on_success, on_finished) reply.finished.connect(on_reply_finished) replies.append(reply) if not on_finished and not on_success: loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec_() if reply.error(): raise NetworkError(reply.error(), reply.errorString()) else: return filename
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
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.")
class QgsPluginInstallerInstallingDialog(QDialog, Ui_QgsPluginInstallerInstallingDialogBase): # ----------------------------------------- # def __init__(self, parent, plugin): QDialog.__init__(self, parent) self.setupUi(self) self.plugin = plugin self.mResult = "" self.progressBar.setRange(0, 0) self.progressBar.setFormat("%p%") self.labelName.setText(plugin["name"]) self.buttonBox.clicked.connect(self.abort) self.url = QUrl(plugin["download_url"]) self.redirectionCounter = 0 fileName = plugin["filename"] tmpDir = QDir.tempPath() tmpPath = QDir.cleanPath(tmpDir + "/" + fileName) self.file = QFile(tmpPath) self.requestDownloading() def requestDownloading(self): self.request = QNetworkRequest(self.url) self.request.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorClass), "QgsPluginInstallerInstallingDialog") authcfg = repositories.all()[self.plugin["zip_repository"]]["authcfg"] if authcfg and isinstance(authcfg, str): if not QgsApplication.authManager().updateNetworkRequest( self.request, authcfg.strip()): self.mResult = self.tr( "Update of network request with authentication " "credentials FAILED for configuration '{0}'").format(authcfg) self.request = None if self.request is not None: self.reply = QgsNetworkAccessManager.instance().get(self.request) self.reply.downloadProgress.connect(self.readProgress) self.reply.finished.connect(self.requestFinished) self.stateChanged(4) def exec_(self): if self.request is None: return QDialog.Rejected QDialog.exec_(self) # ----------------------------------------- # def result(self): return self.mResult # ----------------------------------------- # def stateChanged(self, state): messages = [ QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Installing…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Resolving host name…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Connecting…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Host connected. Sending request…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Downloading data…"), self.tr("Idle"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Closing connection…"), self.tr("Error") ] self.labelState.setText(messages[state]) # ----------------------------------------- # def readProgress(self, done, total): if total > 0: self.progressBar.setMaximum(total) self.progressBar.setValue(done) # ----------------------------------------- # def requestFinished(self): reply = self.sender() self.buttonBox.setEnabled(False) if reply.error() != QNetworkReply.NoError: self.mResult = reply.errorString() if reply.error() == QNetworkReply.OperationCanceledError: self.mResult += "<br/><br/>" + QCoreApplication.translate("QgsPluginInstaller", "If you haven't canceled the download manually, it might be caused by a timeout. In this case consider increasing the connection timeout value in QGIS options.") self.reject() reply.deleteLater() return elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) in (301, 302): redirectionUrl = reply.attribute(QNetworkRequest.RedirectionTargetAttribute) self.redirectionCounter += 1 if self.redirectionCounter > 4: self.mResult = QCoreApplication.translate("QgsPluginInstaller", "Too many redirections") self.reject() reply.deleteLater() return else: if redirectionUrl.isRelative(): redirectionUrl = reply.url().resolved(redirectionUrl) # Fire a new request and exit immediately in order to quietly destroy the old one self.url = redirectionUrl self.requestDownloading() reply.deleteLater() return self.file.open(QFile.WriteOnly) self.file.write(reply.readAll()) self.file.close() self.stateChanged(0) reply.deleteLater() pluginDir = qgis.utils.home_plugin_path tmpPath = self.file.fileName() # make sure that the parent directory exists if not QDir(pluginDir).exists(): QDir().mkpath(pluginDir) # if the target directory already exists as a link, remove the link without resolving: QFile(pluginDir + str(QDir.separator()) + self.plugin["id"]).remove() try: unzip(str(tmpPath), str(pluginDir)) # test extract. If fails, then exception will be raised and no removing occurs # removing old plugin files if exist removeDir(QDir.cleanPath(pluginDir + "/" + self.plugin["id"])) # remove old plugin if exists unzip(str(tmpPath), str(pluginDir)) # final extract. except: self.mResult = self.tr("Failed to unzip the plugin package. Probably it's broken or missing from the repository. You may also want to make sure that you have write permission to the plugin directory:") + "\n" + pluginDir self.reject() return try: # cleaning: removing the temporary zip file QFile(tmpPath).remove() except: pass self.close() # ----------------------------------------- # def abort(self): if self.reply.isRunning(): self.reply.finished.disconnect() self.reply.abort() del self.reply self.mResult = self.tr("Aborted by user") self.reject()
class QgsPluginInstallerInstallingDialog(QDialog, Ui_QgsPluginInstallerInstallingDialogBase): # ----------------------------------------- # def __init__(self, parent, plugin, stable=True): QDialog.__init__(self, parent) self.setupUi(self) self.plugin = plugin self.mResult = "" self.progressBar.setRange(0, 0) self.progressBar.setFormat("%p%") self.labelName.setText(plugin["name"]) self.buttonBox.clicked.connect(self.abort) self.url = QUrl(plugin["download_url_stable"] if stable else plugin["download_url_experimental"]) self.redirectionCounter = 0 fileName = plugin["filename"] tmpDir = QDir.tempPath() tmpPath = QDir.cleanPath(tmpDir + "/" + fileName) self.file = QFile(tmpPath) self.requestDownloading() def requestDownloading(self): self.request = QNetworkRequest(self.url) self.request.setAttribute(QNetworkRequest.Attribute(QgsNetworkRequestParameters.AttributeInitiatorClass), "QgsPluginInstallerInstallingDialog") authcfg = repositories.all()[self.plugin["zip_repository"]]["authcfg"] if authcfg and isinstance(authcfg, str): if not QgsApplication.authManager().updateNetworkRequest( self.request, authcfg.strip()): self.mResult = self.tr( "Update of network request with authentication " "credentials FAILED for configuration '{0}'").format(authcfg) self.request = None if self.request is not None: self.reply = QgsNetworkAccessManager.instance().get(self.request) self.reply.downloadProgress.connect(self.readProgress) self.reply.finished.connect(self.requestFinished) self.stateChanged(4) def exec_(self): if self.request is None: return QDialog.Rejected QDialog.exec_(self) # ----------------------------------------- # def result(self): return self.mResult # ----------------------------------------- # def stateChanged(self, state): messages = [ QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Installing…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Resolving host name…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Connecting…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Host connected. Sending request…"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Downloading data…"), self.tr("Idle"), QCoreApplication.translate('QgsPluginInstallerInstallingDialog', "Closing connection…"), self.tr("Error") ] self.labelState.setText(messages[state]) # ----------------------------------------- # def readProgress(self, done, total): if total > 0: self.progressBar.setMaximum(total) self.progressBar.setValue(done) # ----------------------------------------- # def requestFinished(self): reply = self.sender() self.buttonBox.setEnabled(False) if reply.error() != QNetworkReply.NoError: self.mResult = reply.errorString() if reply.error() == QNetworkReply.OperationCanceledError: self.mResult += "<br/><br/>" + QCoreApplication.translate("QgsPluginInstaller", "If you haven't canceled the download manually, it might be caused by a timeout. In this case consider increasing the connection timeout value in QGIS options.") self.reject() reply.deleteLater() return elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) in (301, 302): redirectionUrl = reply.attribute(QNetworkRequest.RedirectionTargetAttribute) self.redirectionCounter += 1 if self.redirectionCounter > 4: self.mResult = QCoreApplication.translate("QgsPluginInstaller", "Too many redirections") self.reject() reply.deleteLater() return else: if redirectionUrl.isRelative(): redirectionUrl = reply.url().resolved(redirectionUrl) # Fire a new request and exit immediately in order to quietly destroy the old one self.url = redirectionUrl self.requestDownloading() reply.deleteLater() return self.file.open(QFile.WriteOnly) self.file.write(reply.readAll()) self.file.close() self.stateChanged(0) reply.deleteLater() pluginDir = qgis.utils.home_plugin_path tmpPath = self.file.fileName() # make sure that the parent directory exists if not QDir(pluginDir).exists(): QDir().mkpath(pluginDir) # if the target directory already exists as a link, remove the link without resolving: QFile(pluginDir + str(QDir.separator()) + self.plugin["id"]).remove() try: unzip(str(tmpPath), str(pluginDir)) # test extract. If fails, then exception will be raised and no removing occurs # removing old plugin files if exist removeDir(QDir.cleanPath(pluginDir + "/" + self.plugin["id"])) # remove old plugin if exists unzip(str(tmpPath), str(pluginDir)) # final extract. except: self.mResult = self.tr("Failed to unzip the plugin package. Probably it's broken or missing from the repository. You may also want to make sure that you have write permission to the plugin directory:") + "\n" + pluginDir self.reject() return try: # cleaning: removing the temporary zip file QFile(tmpPath).remove() except: pass self.close() # ----------------------------------------- # def abort(self): if self.reply.isRunning(): self.reply.finished.disconnect() self.reply.abort() del self.reply self.mResult = self.tr("Aborted by user") self.reject()
def request(self, url, method="GET", body=None, headers=None, redirections=DEFAULT_MAX_REDIRECTS, connection_type=None, authenticate=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.http_call_result = Response({ 'status': 0, 'status_code': 0, 'status_message': '', 'text': '', 'ok': False, 'headers': {}, 'reason': '', 'exception': None, }) req = QNetworkRequest() req.setAttribute(QNetworkRequest.CookieSaveControlAttribute, QNetworkRequest.Manual) req.setAttribute(QNetworkRequest.CookieLoadControlAttribute, QNetworkRequest.Manual) # 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 and authenticate: 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)
def image_reply_finished(self): reply = self.sender() error = reply.error() fid = reply.request().attribute(QNetworkRequest.User) image_id = reply.request().attribute(QNetworkRequest.User + 1) file_path = reply.request().attribute(QNetworkRequest.User + 2) if error == QNetworkReply.NoError: url = reply.attribute(QNetworkRequest.RedirectionTargetAttribute) if url is not None and url != reply.url(): if url.isRelative(): url = reply.url().resolved(url) log.debug(f'Redirected to {url.toString()}') req = QNetworkRequest(url) req.setAttribute(QNetworkRequest.User, fid) req.setAttribute(QNetworkRequest.User + 1, image_id) req.setAttribute(QNetworkRequest.User + 2, file_path) self.replies.remove(reply) reply.deleteLater() # noinspection PyUnusedLocal reply = None # noinspection PyArgumentList reply = QgsNetworkAccessManager.instance().get(req) self.replies.append(reply) reply.finished.connect(self.image_reply_finished) return status = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) msg = reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute) log.debug(f'Request finished: {status} - {msg}') with open(file_path, "wb") as f: data = reply.readAll() f.write(data) self.replies.remove(reply) reply.deleteLater() # noinspection PyUnusedLocal reply = None # noinspection PyUnresolvedReferences self.fileDownloaded.emit((fid, file_path)) if len(self.replies) == 0: # noinspection PyUnresolvedReferences self.finished.emit() else: # report any errors except for the one we have caused # by cancelling the request if error != QNetworkReply.OperationCanceledError: msg = "Network request failed: {}".format(reply.errorString()) log.debug(msg) # noinspection PyUnresolvedReferences self.errored.emit(msg) self.replies.remove(reply) reply.deleteLater() # noinspection PyUnusedLocal reply = None if len(self.replies) == 0: # noinspection PyUnresolvedReferences self.finished.emit()