def _onRequestFinished(self, reply: QNetworkReply) -> None: if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") self.setViewPage("errored") self.resetDownload() return if reply.error() == QNetworkReply.HostNotFoundError: Logger.log("w", "Unable to reach server.") self.setViewPage("errored") self.resetDownload() return if reply.operation() == QNetworkAccessManager.GetOperation: for response_type, url in self._request_urls.items(): if reply.url() == url: if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200: try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Check for errors: if "errors" in json_data: for error in json_data["errors"]: Logger.log("e", "%s", error["title"]) return # Create model and apply metadata: if not self._models[response_type]: Logger.log("e", "Could not find the %s model.", response_type) break self._server_response_data[response_type] = json_data["data"] self._models[response_type].setMetadata(self._server_response_data[response_type]) if response_type is "packages": self._models[response_type].setFilter({"type": "plugin"}) self.reBuildMaterialsModels() self.reBuildPluginsModels() elif response_type is "authors": self._models[response_type].setFilter({"package_types": "material"}) self._models[response_type].setFilter({"tags": "generic"}) self.metadataChanged.emit() if self.isLoadingComplete(): self.setViewPage("overview") except json.decoder.JSONDecodeError: Logger.log("w", "Received invalid JSON for %s.", response_type) break else: Logger.log("w", "Unable to connect with the server, we got a response code %s while trying to connect to %s", reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url()) self.setViewPage("errored") self.resetDownload() elif reply.operation() == QNetworkAccessManager.PutOperation: # Ignore any operation that is not a get operation pass
def _onGetPreviewImageFinished(self, reply: QNetworkReply) -> None: reply_url = reply.url().toString() uuid = reply_url[reply_url.find("print_jobs/")+len("print_jobs/"):reply_url.rfind("/preview_image")] print_job = findByKey(self._print_jobs, uuid) if print_job: image = QImage() image.loadFromData(reply.readAll()) print_job.updatePreviewImage(image)
def _handleOnFinished(self, reply: QNetworkReply) -> None: # Due to garbage collection, we need to cache certain bits of post operations. # As we don't want to keep them around forever, delete them if we get a reply. if reply.operation() == QNetworkAccessManager.PostOperation: self._clearCachedMultiPart(reply) if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None: # No status code means it never even reached remote. return self._last_response_time = time() if self._connection_state == ConnectionState.Connecting: self.setConnectionState(ConnectionState.Connected) callback_key = reply.url().toString() + str(reply.operation()) try: if callback_key in self._onFinishedCallbacks: self._onFinishedCallbacks[callback_key](reply) except Exception: Logger.logException("w", "something went wrong with callback")
def _onRequestFinished(self, reply: QNetworkReply) -> None: http_status_code = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if not http_status_code: # Received no or empty reply return if reply.operation() == QNetworkAccessManager.PostOperation: if "/plugin/appkeys/request" in reply.url().toString( ): # Initial AppKey request if http_status_code == 201 or http_status_code == 202: Logger.log("w", "Start polling for AppKeys decision") if not self._appkey_request: return self._appkey_request.setUrl( reply.header(QNetworkRequest.LocationHeader)) self._appkey_request.setRawHeader(b"Content-Type", b"") self._appkey_poll_timer.start() elif http_status_code == 404: Logger.log( "w", "This instance of OctoPrint does not support AppKeys") self._appkey_request = None # type: Optional[QNetworkRequest] else: response = bytes(reply.readAll()).decode() Logger.log( "w", "Unknown response when requesting an AppKey: %d. OctoPrint said %s" % (http_status_code, response)) self._appkey_request = None # type: Optional[QNetworkRequest] if reply.operation() == QNetworkAccessManager.GetOperation: if "/plugin/appkeys/probe" in reply.url().toString( ): # Probe for AppKey support if http_status_code == 204: self._appkeys_supported = True else: self._appkeys_supported = False self.appKeysSupportedChanged.emit() if "/plugin/appkeys/request" in reply.url().toString( ): # Periodic AppKey request poll if http_status_code == 202: self._appkey_poll_timer.start() elif http_status_code == 200: Logger.log("d", "AppKey granted") self._appkey_request = None # type: Optional[QNetworkRequest] try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from octoprint instance.") return self._keys_cache[ self._appkey_instance_id] = json_data["api_key"] self.appKeyReceived.emit() elif http_status_code == 404: Logger.log("d", "AppKey denied") self._appkey_request = None # type: Optional[QNetworkRequest] else: response = bytes(reply.readAll()).decode() Logger.log( "w", "Unknown response when waiting for an AppKey: %d. OctoPrint said %s" % (http_status_code, response)) self._appkey_request = None # type: Optional[QNetworkRequest] if "api/settings" in reply.url().toString( ): # OctoPrint settings dump from /settings: self._instance_in_error = False if http_status_code == 200: Logger.log("d", "API key accepted by OctoPrint.") self._instance_api_key_accepted = True try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from octoprint instance.") json_data = {} if "feature" in json_data and "sdSupport" in json_data[ "feature"]: self._instance_supports_sd = json_data["feature"][ "sdSupport"] if "webcam" in json_data and "streamUrl" in json_data[ "webcam"]: stream_url = json_data["webcam"]["streamUrl"] if stream_url: #not empty string or None self._instance_supports_camera = True elif http_status_code == 401: Logger.log("d", "Invalid API key for OctoPrint.") self._instance_api_key_accepted = False elif http_status_code == 502 or http_status_code == 503: Logger.log("d", "OctoPrint is not running.") self._instance_api_key_accepted = False self._instance_in_error = True self._instance_responded = True self.selectedInstanceSettingsChanged.emit()
def _onRequestFinished(self, reply: QNetworkReply) -> None: if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") self.setViewPage("errored") self.resetDownload() return if reply.error() == QNetworkReply.HostNotFoundError: Logger.log("w", "Unable to reach server.") self.setViewPage("errored") self.resetDownload() return if reply.operation() == QNetworkAccessManager.GetOperation: for response_type, url in self._request_urls.items(): if reply.url() == url: if reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) == 200: try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) # Check for errors: if "errors" in json_data: for error in json_data["errors"]: Logger.log("e", "%s", error["title"]) return # Create model and apply metadata: if not self._models[response_type]: Logger.log("e", "Could not find the %s model.", response_type) break self._server_response_data[ response_type] = json_data["data"] self._models[response_type].setMetadata( self._server_response_data[response_type]) if response_type is "packages": self._models[response_type].setFilter( {"type": "plugin"}) self.reBuildMaterialsModels() self.reBuildPluginsModels() self._notifyPackageManager() elif response_type is "authors": self._models[response_type].setFilter( {"package_types": "material"}) self._models[response_type].setFilter( {"tags": "generic"}) self.metadataChanged.emit() if self.isLoadingComplete(): self.setViewPage("overview") except json.decoder.JSONDecodeError: Logger.log("w", "Received invalid JSON for %s.", response_type) break else: Logger.log( "w", "Unable to connect with the server, we got a response code %s while trying to connect to %s", reply.attribute( QNetworkRequest.HttpStatusCodeAttribute), reply.url()) self.setViewPage("errored") self.resetDownload() elif reply.operation() == QNetworkAccessManager.PutOperation: # Ignore any operation that is not a get operation pass
def _onRequestFinished(self, reply: QNetworkReply) -> None: if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") self.setViewPage("errored") self.resetDownload() return if reply.error() == QNetworkReply.HostNotFoundError: Logger.log("w", "Unable to reach server.") self.setViewPage("errored") self.resetDownload() return if reply.operation() == QNetworkAccessManager.GetOperation: for type, url in self._request_urls.items(): if reply.url() == url: if reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) == 200: try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) # Check for errors: if "errors" in json_data: for error in json_data["errors"]: Logger.log("e", "%s", error["title"]) return # Create model and apply metadata: if not self._models[type]: Logger.log("e", "Could not find the %s model.", type) break # HACK: Eventually get rid of the code from here... if type is "plugins_showcase" or type is "materials_showcase": self._metadata["plugins_showcase"] = json_data[ "data"]["plugin"]["packages"] self._models["plugins_showcase"].setMetadata( self._metadata["plugins_showcase"]) self._metadata[ "materials_showcase"] = json_data["data"][ "material"]["authors"] self._models["materials_showcase"].setMetadata( self._metadata["materials_showcase"]) else: # ...until here. # This hack arises for multiple reasons but the main # one is because there are not separate API calls # for different kinds of showcases. self._metadata[type] = json_data["data"] self._models[type].setMetadata( self._metadata[type]) # Do some auto filtering # TODO: Make multiple API calls in the future to handle this if type is "packages": self._models[type].setFilter( {"type": "plugin"}) if type is "authors": self._models[type].setFilter( {"package_types": "material"}) self.metadataChanged.emit() if self.loadingComplete() is True: self.setViewPage("overview") return except json.decoder.JSONDecodeError: Logger.log( "w", "Toolbox: Received invalid JSON for %s.", type) break else: self.setViewPage("errored") self.resetDownload() return else: # Ignore any operation that is not a get operation pass
def _onRequestFinished(self, reply: QNetworkReply) -> None: if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") self.setViewPage("errored") self.resetDownload() return if reply.error() == QNetworkReply.HostNotFoundError: Logger.log("w", "Unable to reach server.") self.setViewPage("errored") self.resetDownload() return # HACK: These request are not handled independently at this moment, but together from the "packages" call do_not_handle = [ "materials_available", "materials_showcase", "materials_generic", "plugins_available", "plugins_showcase", ] if reply.operation() == QNetworkAccessManager.GetOperation: for type, url in self._request_urls.items(): # HACK: Do nothing because we'll handle these from the "packages" call if type in do_not_handle: continue if reply.url() == url: if reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) == 200: try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) # Check for errors: if "errors" in json_data: for error in json_data["errors"]: Logger.log("e", "%s", error["title"]) return # Create model and apply metadata: if not self._models[type]: Logger.log("e", "Could not find the %s model.", type) break self._metadata[type] = json_data["data"] self._models[type].setMetadata( self._metadata[type]) # Do some auto filtering # TODO: Make multiple API calls in the future to handle this if type is "packages": self._models[type].setFilter( {"type": "plugin"}) self.buildMaterialsModels() self.buildPluginsModels() if type is "authors": self._models[type].setFilter( {"package_types": "material"}) if type is "materials_generic": self._models[type].setFilter( {"tags": "generic"}) self.metadataChanged.emit() if self.loadingComplete() is True: self.setViewPage("overview") return except json.decoder.JSONDecodeError: Logger.log( "w", "Marketplace: Received invalid JSON for %s.", type) break else: self.setViewPage("errored") self.resetDownload() return else: # Ignore any operation that is not a get operation pass
def _registerOnFinishedCallback( self, reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: if on_finished is not None: self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = on_finished
def _onRequestFailed(self, reply: QNetworkReply) -> None: if reply.operation() == QNetworkAccessManager.GetOperation: if "api/settings" in reply.url().toString(): # Repetier settings dump from /settings: Logger.log("w", "Connection refused or timeout when trying to access Repetier at %s" % reply.url().toString()) self._instance_in_error = True self.selectedInstanceSettingsChanged.emit()
def _registerOnFinishedCallback(self, reply: QNetworkReply, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None: if on_finished is not None: self._onFinishedCallbacks[reply.url().toString() + str(reply.operation())] = on_finished
def _onRequestFinished(self, reply: QNetworkReply) -> None: if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Received a timeout on a request to the instance") self._connection_state_before_timeout = self._connection_state self.setConnectionState(ConnectionState.error) return if self._connection_state_before_timeout and reply.error( ) == QNetworkReply.NoError: # There was a timeout, but we got a correct answer again. if self._last_response_time: Logger.log( "d", "We got a response from the instance after %s of silence", time() - self._last_response_time) self.setConnectionState(self._connection_state_before_timeout) self._connection_state_before_timeout = None if reply.error() == QNetworkReply.NoError: self._last_response_time = time() http_status_code = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if not http_status_code: # Received no or empty reply return error_handled = False if reply.operation() == QNetworkAccessManager.GetOperation: if self._api_prefix + "printer" in reply.url().toString( ): # Status update from /printer. if not self._printers: self._createPrinterList() # An OctoPrint instance has a single printer. printer = self._printers[0] update_pace = self._update_slow_interval if http_status_code == 200: update_pace = self._update_fast_interval if not self.acceptsCommands: self._setAcceptsCommands(True) self.setConnectionText( i18n_catalog.i18nc( "@info:status", "Connected to OctoPrint on {0}").format( self._id)) if self._connection_state == ConnectionState.connecting: self.setConnectionState(ConnectionState.connected) try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from octoprint instance.") json_data = {} if "temperature" in json_data: if not self._number_of_extruders_set: self._number_of_extruders = 0 while "tool%d" % self._number_of_extruders in json_data[ "temperature"]: self._number_of_extruders += 1 if self._number_of_extruders > 1: # Recreate list of printers to match the new _number_of_extruders self._createPrinterList() printer = self._printers[0] if self._number_of_extruders > 0: self._number_of_extruders_set = True # Check for hotend temperatures for index in range(0, self._number_of_extruders): extruder = printer.extruders[index] if ("tool%d" % index) in json_data["temperature"]: hotend_temperatures = json_data["temperature"][ "tool%d" % index] extruder.updateTargetHotendTemperature( hotend_temperatures["target"]) extruder.updateHotendTemperature( hotend_temperatures["actual"]) else: extruder.updateTargetHotendTemperature(0) extruder.updateHotendTemperature(0) if "bed" in json_data["temperature"]: bed_temperatures = json_data["temperature"]["bed"] actual_temperature = bed_temperatures[ "actual"] if bed_temperatures[ "actual"] is not None else -1 printer.updateBedTemperature(actual_temperature) target_temperature = bed_temperatures[ "target"] if bed_temperatures[ "target"] is not None else -1 printer.updateTargetBedTemperature( target_temperature) else: printer.updateBedTemperature(-1) printer.updateTargetBedTemperature(0) printer_state = "offline" if "state" in json_data: flags = json_data["state"]["flags"] if flags["error"] or flags["closedOrError"]: printer_state = "error" elif flags["paused"] or flags["pausing"]: printer_state = "paused" elif flags["printing"]: printer_state = "printing" elif flags["cancelling"]: printer_state = "aborted" elif flags["ready"] or flags["operational"]: printer_state = "idle" printer.updateState(printer_state) elif http_status_code == 401: printer.updateState("offline") if printer.activePrintJob: printer.activePrintJob.updateState("offline") self.setConnectionText( i18n_catalog.i18nc( "@info:status", "OctoPrint on {0} does not allow access to print"). format(self._id)) error_handled = True elif http_status_code == 409: if self._connection_state == ConnectionState.connecting: self.setConnectionState(ConnectionState.connected) printer.updateState("offline") if printer.activePrintJob: printer.activePrintJob.updateState("offline") self.setConnectionText( i18n_catalog.i18nc( "@info:status", "The printer connected to OctoPrint on {0} is not operational" ).format(self._id)) error_handled = True elif http_status_code == 502 or http_status_code == 503: printer.updateState("offline") if printer.activePrintJob: printer.activePrintJob.updateState("offline") self.setConnectionText( i18n_catalog.i18nc( "@info:status", "OctoPrint on {0} is not running").format( self._id)) error_handled = True else: printer.updateState("offline") if printer.activePrintJob: printer.activePrintJob.updateState("offline") Logger.log("w", "Received an unexpected returncode: %d", http_status_code) if update_pace != self._update_timer.interval(): self._update_timer.setInterval(update_pace) elif self._api_prefix + "job" in reply.url().toString( ): # Status update from /job: if not self._printers: return # Ignore the data for now, we don't have info about a printer yet. printer = self._printers[0] if http_status_code == 200: try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from octoprint instance.") json_data = {} if printer.activePrintJob is None: print_job = PrintJobOutputModel( output_controller=self._output_controller) printer.updateActivePrintJob(print_job) else: print_job = printer.activePrintJob print_job_state = "offline" if "state" in json_data: if json_data["state"] == "Error": print_job_state = "error" elif json_data["state"] == "Pausing": print_job_state = "pausing" elif json_data["state"] == "Paused": print_job_state = "paused" elif json_data["state"] == "Printing": print_job_state = "printing" elif json_data["state"] == "Cancelling": print_job_state = "abort" elif json_data["state"] == "Operational": print_job_state = "ready" printer.updateState("idle") print_job.updateState(print_job_state) print_time = json_data["progress"]["printTime"] if print_time: print_job.updateTimeElapsed(print_time) if json_data["progress"][ "completion"]: # not 0 or None or "" print_job.updateTimeTotal( print_time / (json_data["progress"]["completion"] / 100)) else: print_job.updateTimeTotal(0) else: print_job.updateTimeElapsed(0) print_job.updateTimeTotal(0) print_job.updateName(json_data["job"]["file"]["name"]) else: pass # See generic error handler below elif self._api_prefix + "settings" in reply.url().toString( ): # OctoPrint settings dump from /settings: if http_status_code == 200: try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from octoprint instance.") json_data = {} if "feature" in json_data and "sdSupport" in json_data[ "feature"]: self._sd_supported = json_data["feature"]["sdSupport"] if "webcam" in json_data and "streamUrl" in json_data[ "webcam"]: self._camera_shares_proxy = False stream_url = json_data["webcam"]["streamUrl"] if not stream_url: #empty string or None self._camera_url = "" elif stream_url[:4].lower() == "http": # absolute uri self._camera_url = stream_url elif stream_url[:2] == "//": # protocol-relative self._camera_url = "%s:%s" % (self._protocol, stream_url) elif stream_url[: 1] == ":": # domain-relative (on another port) self._camera_url = "%s://%s%s" % ( self._protocol, self._address, stream_url) elif stream_url[: 1] == "/": # domain-relative (on same port) self._camera_url = "%s://%s:%d%s" % ( self._protocol, self._address, self._port, stream_url) self._camera_shares_proxy = True else: Logger.log("w", "Unusable stream url received: %s", stream_url) self._camera_url = "" Logger.log("d", "Set OctoPrint camera url to %s", self._camera_url) self.cameraUrlChanged.emit() if "rotate90" in json_data["webcam"]: self._camera_rotation = -90 if json_data["webcam"][ "rotate90"] else 0 if json_data["webcam"]["flipH"] and json_data[ "webcam"]["flipV"]: self._camera_mirror = False self._camera_rotation += 180 elif json_data["webcam"]["flipH"]: self._camera_mirror = True self._camera_rotation += 180 elif json_data["webcam"]["flipV"]: self._camera_mirror = True else: self._camera_mirror = False self.cameraOrientationChanged.emit() if "plugins" in json_data: self._plugin_data = json_data["plugins"] elif reply.operation() == QNetworkAccessManager.PostOperation: if self._api_prefix + "files" in reply.url().toString( ): # Result from /files command: if http_status_code == 201: Logger.log( "d", "Resource created on OctoPrint instance: %s", reply.header( QNetworkRequest.LocationHeader).toString()) else: pass # See generic error handler below reply.uploadProgress.disconnect(self._onUploadProgress) if self._progress_message: self._progress_message.hide() if self._forced_queue or not self._auto_print: location = reply.header(QNetworkRequest.LocationHeader) if location: file_name = QUrl( reply.header(QNetworkRequest.LocationHeader). toString()).fileName() message = Message( i18n_catalog.i18nc( "@info:status", "Saved to OctoPrint as {0}").format(file_name)) else: message = Message( i18n_catalog.i18nc("@info:status", "Saved to OctoPrint")) message.addAction( "open_browser", i18n_catalog.i18nc("@action:button", "OctoPrint..."), "globe", i18n_catalog.i18nc("@info:tooltip", "Open the OctoPrint web interface")) message.actionTriggered.connect(self._openOctoPrint) message.show() elif self._api_prefix + "job" in reply.url().toString( ): # Result from /job command (eg start/pause): if http_status_code == 204: Logger.log("d", "Octoprint job command accepted") else: pass # See generic error handler below elif self._api_prefix + "printer/command" in reply.url().toString( ): # Result from /printer/command (gcode statements): if http_status_code == 204: Logger.log("d", "Octoprint gcode command(s) accepted") else: pass # See generic error handler below else: Logger.log("d", "OctoPrintOutputDevice got an unhandled operation %s", reply.operation()) if not error_handled and http_status_code >= 400: # Received an error reply error_string = reply.attribute( QNetworkRequest.HttpReasonPhraseAttribute) if self._error_message: self._error_message.hide() self._error_message = Message( i18n_catalog.i18nc( "@info:status", "OctoPrint returned an error: {0}.").format(error_string)) self._error_message.show() return
def _onRequestFinished(self, reply: QNetworkReply) -> None: if reply.error() == QNetworkReply.TimeoutError: Logger.log("w", "Got a timeout.") self.setViewPage("errored") self.resetDownload() return if reply.error() == QNetworkReply.HostNotFoundError: Logger.log("w", "Unable to reach server.") self.setViewPage("errored") self.resetDownload() return if reply.operation() == QNetworkAccessManager.GetOperation: for type, url in self._request_urls.items(): if reply.url() == url: try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) # Check for errors: if "errors" in json_data: for error in json_data["errors"]: Logger.log("e", "%s", error["title"]) return # Create model and apply metadata: if not self._models[type]: Logger.log("e", "Could not find the %s model.", type) break # HACK: Eventually get rid of the code from here... if type is "plugins_showcase" or type is "materials_showcase": self._metadata["plugins_showcase"] = json_data["data"]["plugin"]["packages"] self._models["plugins_showcase"].setMetadata(self._metadata["plugins_showcase"]) self._metadata["materials_showcase"] = json_data["data"]["material"]["authors"] self._models["materials_showcase"].setMetadata(self._metadata["materials_showcase"]) else: # ...until here. # This hack arises for multiple reasons but the main # one is because there are not separate API calls # for different kinds of showcases. self._metadata[type] = json_data["data"] self._models[type].setMetadata(self._metadata[type]) # Do some auto filtering # TODO: Make multiple API calls in the future to handle this if type is "packages": self._models[type].setFilter({"type": "plugin"}) if type is "authors": self._models[type].setFilter({"package_types": "material"}) self.metadataChanged.emit() if self.loadingComplete() is True: self.setViewPage("overview") return except json.decoder.JSONDecodeError: Logger.log("w", "Toolbox: Received invalid JSON for %s.", type) break else: # Ignore any operation that is not a get operation pass
def _onRequestFinished(self, reply: QNetworkReply) -> None: if reply.error() == QNetworkReply.TimeoutError: QMessageBox.warning(None, 'Connection Timeout', 'Connection Timeout') return http_status_code = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if not http_status_code: #QMessageBox.warning(None,'Connection Attempt2',http_status_code) # Received no or empty reply Logger.log("d", "Received no or empty reply") return if reply.operation() == QNetworkAccessManager.GetOperation: Logger.log("d", reply.url().toString()) if "printer/info" in reply.url().toString( ): # Repetier settings dump from printer/info: if http_status_code == 200: try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) Logger.log("d", reply.url().toString()) Logger.log("d", json_data) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from Repetier instance.") json_data = {} if "printers" in json_data: Logger.log("d", "DiscoverRepetierAction: printers: %s", len(json_data["printers"])) if len(json_data["printers"]) > 0: self._printers = [""] for printerinfo in json_data["printers"]: Logger.log("d", "Slug: %s", printerinfo["slug"]) self._printers.append(printerinfo["slug"]) if "apikey" in json_data: Logger.log("d", "DiscoverRepetierAction: apikey: %s", json_data["apikey"]) global_container_stack = self._application.getGlobalContainerStack( ) if not global_container_stack: return global_container_stack.setMetaDataEntry( "repetier_api_key", json_data["apikey"]) self._keys_cache[ self.getInstanceId()] = json_data["apikey"] keys_cache = base64.b64encode( json.dumps(self._keys_cache).encode( "ascii")).decode("ascii") self._preferences.setValue("Repetier/keys_cache", keys_cache) self.appKeyReceived.emit() if self._network_plugin: # Ensure that the connection states are refreshed. self._network_plugin.reCheckConnections() if "getPrinterConfig" in reply.url().toString( ): # Repetier settings dump from getPrinterConfig: if http_status_code == 200: Logger.log("d", "API key accepted by Repetier.") self._instance_api_key_accepted = True try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) Logger.log("d", reply.url().toString()) Logger.log("d", json_data) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from Repetier instance.") json_data = {} if "general" in json_data and "sdcard" in json_data[ "general"]: self._instance_supports_sd = json_data["general"][ "sdcard"] if "webcam" in json_data and "dynamicUrl" in json_data[ "webcam"]: Logger.log( "d", "DiscoverRepetierAction: Checking streamurl") Logger.log("d", "DiscoverRepetierAction: %s", reply.url()) stream_url = json_data["webcam"]["dynamicUrl"].replace( "127.0.0.1", re.findall(r'[0-9]+(?:\.[0-9]+){3}', reply.url().toString())[0]) Logger.log("d", "DiscoverRepetierAction: stream_url: %s", stream_url) Logger.log("d", "DiscoverRepetierAction: reply_url: %s", reply.url()) if stream_url: #not empty string or None self._instance_supports_camera = True if "webcams" in json_data: Logger.log("d", "DiscoverRepetierAction: webcams: %s", len(json_data["webcams"])) if len(json_data["webcams"]) > 0: if "dynamicUrl" in json_data["webcams"][0]: Logger.log( "d", "DiscoverRepetierAction: Checking streamurl" ) stream_url = json_data["webcams"][0][ "dynamicUrl"].replace( "127.0.0.1", re.findall(r'[0-9]+(?:\.[0-9]+){3}', reply.url().toString())[0]) Logger.log( "d", "DiscoverRepetierAction: stream_url: %s", stream_url) Logger.log( "d", "DiscoverRepetierAction: reply_url: %s", reply.url()) if stream_url: #not empty string or None self._instance_supports_camera = True elif http_status_code == 401: Logger.log("d", "Invalid API key for Repetier.") self._instance_api_key_accepted = False self._instance_in_error = True self._instance_responded = True self.selectedInstanceSettingsChanged.emit()
def _onRequestFinished(self, reply: QNetworkReply) -> None: http_status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) if not http_status_code: # Received no or empty reply return if reply.operation() == QNetworkAccessManager.PostOperation: if "/plugin/appkeys/request" in reply.url().toString(): # Initial AppKey request if http_status_code == 201 or http_status_code == 202: Logger.log("w", "Start polling for AppKeys decision") if not self._appkey_request: return self._appkey_request.setUrl(reply.header(QNetworkRequest.LocationHeader)) self._appkey_request.setRawHeader(b"Content-Type", b"") self._appkey_poll_timer.start() elif http_status_code == 404: Logger.log("w", "This instance of OctoPrint does not support AppKeys") self._appkey_request = None # type: Optional[QNetworkRequest] else: response = bytes(reply.readAll()).decode() Logger.log("w", "Unknown response when requesting an AppKey: %d. OctoPrint said %s" % (http_status_code, response)) self._appkey_request = None # type: Optional[QNetworkRequest] if reply.operation() == QNetworkAccessManager.GetOperation: if "/plugin/appkeys/probe" in reply.url().toString(): # Probe for AppKey support if http_status_code == 204: self._appkeys_supported = True else: self._appkeys_supported = False self.appKeysSupportedChanged.emit() if "/plugin/appkeys/request" in reply.url().toString(): # Periodic AppKey request poll if http_status_code == 202: self._appkey_poll_timer.start() elif http_status_code == 200: Logger.log("d", "AppKey granted") self._appkey_request = None # type: Optional[QNetworkRequest] try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log("w", "Received invalid JSON from octoprint instance.") return self._keys_cache[self._appkey_instance_id] = json_data["api_key"] self.appKeyReceived.emit() elif http_status_code == 404: Logger.log("d", "AppKey denied") self._appkey_request = None # type: Optional[QNetworkRequest] else: response = bytes(reply.readAll()).decode() Logger.log("w", "Unknown response when waiting for an AppKey: %d. OctoPrint said %s" % (http_status_code, response)) self._appkey_request = None # type: Optional[QNetworkRequest] if "api/settings" in reply.url().toString(): # OctoPrint settings dump from /settings: self._instance_in_error = False if http_status_code == 200: Logger.log("d", "API key accepted by OctoPrint.") self._instance_api_key_accepted = True try: json_data = json.loads(bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log("w", "Received invalid JSON from octoprint instance.") json_data = {} if "feature" in json_data and "sdSupport" in json_data["feature"]: self._instance_supports_sd = json_data["feature"]["sdSupport"] if "webcam" in json_data and "streamUrl" in json_data["webcam"]: stream_url = json_data["webcam"]["streamUrl"] if stream_url: #not empty string or None self._instance_supports_camera = True elif http_status_code == 401: Logger.log("d", "Invalid API key for OctoPrint.") self._instance_api_key_accepted = False elif http_status_code == 502 or http_status_code == 503: Logger.log("d", "OctoPrint is not running.") self._instance_api_key_accepted = False self._instance_in_error = True self._instance_responded = True self.selectedInstanceSettingsChanged.emit()
def _onRequestFinished(self, reply: QNetworkReply) -> None: http_status_code = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute) if not http_status_code: # Received no or empty reply self._onRequestFailed(reply) return if reply.operation() == QNetworkAccessManager.PostOperation: if "/plugin/appkeys/request" in reply.url().toString( ): # Initial AppKey request if http_status_code == 201 or http_status_code == 202: Logger.log("w", "Start polling for AppKeys decision") if not self._appkey_request: return self._appkey_request.setUrl( reply.header(QNetworkRequest.LocationHeader)) self._appkey_request.setRawHeader(b"Content-Type", b"") self._appkey_poll_timer.start() elif http_status_code == 404: Logger.log( "w", "This instance of OctoPrint does not support AppKeys") self._appkey_request = None # type: Optional[QNetworkRequest] else: response = bytes(reply.readAll()).decode() Logger.log( "w", "Unknown response when requesting an AppKey: %d. OctoPrint said %s" % (http_status_code, response)) self._appkey_request = None # type: Optional[QNetworkRequest] if reply.operation() == QNetworkAccessManager.GetOperation: if "/plugin/appkeys/probe" in reply.url().toString( ): # Probe for AppKey support if http_status_code == 204: self._instance_supports_appkeys = True else: self._instance_supports_appkeys = False self.appKeysSupportedChanged.emit() if "/plugin/appkeys/request" in reply.url().toString( ): # Periodic AppKey request poll if http_status_code == 202: self._appkey_poll_timer.start() elif http_status_code == 200: Logger.log("d", "AppKey granted") self._appkey_request = None # type: Optional[QNetworkRequest] try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from octoprint instance.") return api_key = json_data["api_key"] self._keys_cache[self._appkey_instance_id] = api_key global_container_stack = self._application.getGlobalContainerStack( ) if global_container_stack: global_container_stack.setMetaDataEntry( "octoprint_api_key", base64.b64encode( api_key.encode("ascii")).decode("ascii")) self.appKeyReceived.emit() elif http_status_code == 404: Logger.log("d", "AppKey denied") self._appkey_request = None # type: Optional[QNetworkRequest] else: response = bytes(reply.readAll()).decode() Logger.log( "w", "Unknown response when waiting for an AppKey: %d. OctoPrint said %s" % (http_status_code, response)) self._appkey_request = None # type: Optional[QNetworkRequest] if "api/settings" in reply.url().toString( ): # OctoPrint settings dump from /settings: self._instance_in_error = False if http_status_code == 200: Logger.log("d", "API key accepted by OctoPrint.") self._instance_api_key_accepted = True try: json_data = json.loads( bytes(reply.readAll()).decode("utf-8")) except json.decoder.JSONDecodeError: Logger.log( "w", "Received invalid JSON from octoprint instance.") json_data = {} if "feature" in json_data and "sdSupport" in json_data[ "feature"]: self._instance_supports_sd = json_data["feature"][ "sdSupport"] if "webcam" in json_data and "streamUrl" in json_data[ "webcam"]: stream_url = json_data["webcam"]["streamUrl"] if stream_url: #not empty string or None self._instance_supports_camera = True if "plugins" in json_data: self._power_plugins_manager.parsePluginData( json_data["plugins"]) self._instance_installed_plugins = list( json_data["plugins"].keys()) api_key = bytes(reply.request().rawHeader( b"X-Api-Key")).decode("utf-8") self.setApiKey(api_key) # store api key in key cache if self._settings_instance: self._settings_instance.setApiKey(api_key) self._settings_instance.resetOctoPrintUserName() self._settings_instance.getAdditionalData() self._settings_instance.parseSettingsData(json_data) self._settings_instance = None elif http_status_code == 401: Logger.log("d", "Invalid API key for OctoPrint.") self._instance_api_key_accepted = False elif http_status_code == 502 or http_status_code == 503: Logger.log("d", "OctoPrint is not running.") self._instance_api_key_accepted = False self._instance_in_error = True self._instance_responded = True self.selectedInstanceSettingsChanged.emit()
def _onAuthenticationRequired(self, reply: QNetworkReply, authenticator: QAuthenticator) -> None: Logger.log("w", "Request to {url} required authentication, which was not implemented".format(url = reply.url().toString()))
def readJSON(reply: QNetworkReply) -> Any: """ Read a Json response into a Python object (list, dict, str depending on json type)""" try: return json.loads(HttpRequestManager.readText(reply)) except json.decoder.JSONDecodeError: Logger.log("w", "Received invalid JSON: " + str(reply.url()))
def _onAuthenticationRequired(self, reply: QNetworkReply, authenticator: QAuthenticator) -> None: Logger.log( "w", "Request to {url} required authentication, which was not implemented" .format(url=reply.url().toString()))
def _onImageLoaded(self, reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None: if not HttpRequestManager.replyIndicatesSuccess(reply, error): Logger.warning("Requesting preview image failed, response code {0} while trying to connect to {1}".format( reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url())) return self.updatePreviewImageData(reply.readAll())