예제 #1
0
파일: Toolbox.py 프로젝트: baskiotisn/Cura
    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
예제 #2
0
파일: Toolbox.py 프로젝트: TinkerGnome/Cura
    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
예제 #3
0
    def on_response(self, reply: QNetworkReply):
        self.progress_bar.set_part(10, 1, 'Чтение ответа')
        error_code = reply.error()

        if error_code == QNetworkReply.NoError:
            bytes_string = reply.readAll()

            json_ar = json.loads(str(bytes_string, 'utf-8'))
            print(json_ar)
            if json_ar['status'] == 'OK':
                self.progress_bar.increment()
                self.read_response.emit(json_ar['data'], self.progress_bar)
                self.finish.emit(json_ar['data'])
                self.progress_bar.on_finish('Успешно синхронизированно')
            else:
                self.progress_bar.abord()
                self.button.setEnabled(True)
                self.error.emit(str(error_code))
                self.progress_bar.on_finish(
                    f'Завершено с ошибкой {json_ar["message"]}')
        else:
            print(error_code)
            self.progress_bar.abord()
            self.button.setEnabled(True)
            self.error.emit(error_code)
            self.progress_bar.on_finish(f'Завершено с ошибкой {error_code}')
예제 #4
0
파일: ping.py 프로젝트: trinitymkt/memority
 def process_response(self, response: QNetworkReply):
     print(f'done {self.__class__.__name__}')
     if response.error() == QNetworkReply.NoError:
         self.finished.emit(True)
     else:
         print(response.errorString())
         self.finished.emit(False)
예제 #5
0
 def base_handler(self, reply: QNetworkReply):
     try:
         response = json.loads(str(reply.readAll(), encoding='utf-8'))
         status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
     except:
         self.parent.warn.add_warn("Http解析错误")
         return
     if reply.error() != QNetworkReply.NoError:
         self.handler_error(response, status_code)
     else:
         self.data.emit(response)
예제 #6
0
 def _parse_result(self, reply: QNetworkReply) -> str:
     if reply.error():
         print(reply.errorString())
     print('parsing reply')
     text = 'no help available'
     try:
         text = bytes(reply.readAll()).decode('ascii', 'ignore')
     except Exception as e:
         print(e)
         pass
     return text
예제 #7
0
    def getResult(self, reply: QNetworkReply):
        error = reply.error()

        # request was successfully made
        if error == QNetworkReply.NoError:
            data = reply.readAll()
            self.successCallback(str(data, 'utf-8'))
        else:
            # request was failed
            errorStr = reply.errorString()
            self.errorCallback(errorStr)
    def on_received_response(self, reply: QNetworkReply):
        if reply.error() != QNetworkReply.NoError:
            error_msg = "Unable to create new print share: {}".format(reply.errorString())
            logging.error(error_msg)
            app_settings.app_data_writer.signals.exchange_share_failed.emit(error_msg)
            return

        share_location = reply.rawHeader(QByteArray(bytes("Location", encoding="utf-8")))
        app_settings.app_data_writer.signals.exchange_share_created.emit(share_location.data().decode())
        reply.deleteLater()
        self.buffer.close()
예제 #9
0
 def done(self, reply: QNetworkReply):
     if reply.error() != QNetworkReply.NoError:
         sys.stderr.write(reply.errorString())
         return
     try:
         json_data = json.loads(str(reply.readAll(), 'utf-8'))
         reply.deleteLater()
         latest = json_data.get('tag_name')
         current = qApp.applicationVersion()
         self.parent.update_available(latest, current)
     except json.JSONDecodeError:
         self.logger.exception('Error retrieving data', exc_info=True)
         raise
예제 #10
0
 def handleNetworkData(self, networkReply: QNetworkReply):
     if networkReply.error() == QNetworkReply.NoError:
         choices = []
         response = networkReply.readAll()
         xml = QXmlStreamReader(response)
         while not xml.atEnd():
             xml.readNext()
             if xml.tokenType() == QXmlStreamReader.StartElement:
                 if xml.name() == 'suggestion':
                     string = xml.attributes().value('data')
                     choices.append(string)
         self.showCompletion(choices)
     networkReply.deleteLater()
예제 #11
0
 def done(self, reply: QNetworkReply) -> None:
     if reply.error() != QNetworkReply.NoError:
         self.logger.error(reply.errorString())
         sys.stderr.write(reply.errorString())
         return
     if os.getenv('DEBUG', False):
         self.log_request(reply)
     # noinspection PyTypeChecker
     jsonobj = json.loads(str(reply.readAll(), 'utf-8'))
     reply.deleteLater()
     latest = parse_version(jsonobj.get('tag_name'))
     current = parse_version(qApp.applicationVersion())
     self.mbox.show_result(latest, current)
예제 #12
0
 def done(self, reply: QNetworkReply) -> None:
     if reply.error() != QNetworkReply.NoError:
         self.logger.error(reply.errorString())
         sys.stderr.write(reply.errorString())
         return
     if os.getenv('DEBUG', False):
         self.log_request(reply)
     try:
         jsonobj = loads(str(reply.readAll(), 'utf-8'))
         reply.deleteLater()
         latest = jsonobj.get('tag_name')
         current = qApp.applicationVersion()
         self.mbox.show_result(latest, current)
     except JSONDecodeError:
         self.logger.exception('Updater JSON decoding error', exc_info=True)
         raise
예제 #13
0
    def on_finish(self, reply: QNetworkReply):
        if reply.error() == QNetworkReply.NoError:
            bytes_string = reply.readAll()
            data = JsonParser.read(str(bytes_string, 'utf-8'))
            response = Response.load(**data, class_=self.response_type)
            if response.status == response.Status.OK:
                self.response.emit(response.data)
            else:
                self.error.emit(response)
        else:
            QMessageBox().information(
                None, "Загрузка информации с сервера",
                f"Сервер не смог ответить на запрос.\n код ошибки: {str(reply.error())}"
            )

        self.deleteLater()
예제 #14
0
 def handle_finished(self, reply: QNetworkReply) -> None:
     reply.deleteLater()
     if reply is not self._current_reply:
         return
     if reply.error() == QNetworkReply.OperationCanceledError:
         return
     results, error_string = self.process_reply(reply)
     if isinstance(results, Iterable):
         for result in results:
             item = QStandardItem(result)
             self.appendRow(item)
     if isinstance(error_string, str) and error_string:
         self._error_string = error_string
     else:
         self._error_string = ""
     self._current_reply = None
     self.finished.emit()
예제 #15
0
    def saveServerFinished(self, reply: QNetworkReply):
        # if error on server occured
        if reply.error():
            QMessageBox.critical(self.app, 'Query error', reply.errorString())
            return

        try:
            data = loads(bytes(reply.readAll()))
            QMessageBox.information(self.app, 'Success query', data['message'])
        except Exception as e:
            QMessageBox.critical(self.app, 'Query error', 'Error in parsing')
            print(e)
            return

        # save path to clipboard
        cb: QClipboard = QApplication.clipboard()
        cb.setText(data['path'], mode=cb.Clipboard)
예제 #16
0
def parse_qt_network_reply(
        reply: QtNetwork.QNetworkReply) -> ParsedNetworkReply:
    http_status_code = reply.attribute(
        QtNetwork.QNetworkRequest.HttpStatusCodeAttribute)
    http_status_reason = reply.attribute(
        QtNetwork.QNetworkRequest.HttpReasonPhraseAttribute)
    error = reply.error()
    if error == QtNetwork.QNetworkReply.NoError:
        qt_error = None
    else:
        qt_error = _Q_NETWORK_REPLY_ERROR_MAP[error]
    body = reply.readAll()
    return ParsedNetworkReply(
        http_status_code=http_status_code,
        http_status_reason=http_status_reason,
        qt_error=qt_error,
        response_body=body,
    )
예제 #17
0
    def login_response(self, response: QNetworkReply):
        self.is_waiting = False
        self.login_button.setEnabled(True)

        err = response.error()
        if err == QNetworkReply.NoError:
            reply = str(response.readAll(), 'utf-8')
            reply_json = json.loads(reply)
            print(reply_json)
            if "success" in reply_json and reply_json["success"]:
                self.state.login(reply_json["email"], reply_json["score"])
                self.state.sensor_values = eval(reply_json["sensor_data"])
                self.loginSuccess.emit()
                self.close()
            else:
                self.error_dialog.showMessage('아이디나 비밀번호가 맞지 않습니다!')
        else:
            self.error_dialog.showMessage("서버 연결에 실패했습니다. 에러 코드=" + str(err))
예제 #18
0
    def __request_finished(self, reply: QNetworkReply):
        """
        Slot attached to finished signal of network access manager
        Retrieves HTTP data and sets image appropriately
        """

        pix = QPixmap()

        if reply.error() != QNetworkReply.NoError:
            qDebug(f"Unable to fetch image at {reply.url()}")
        else:
            img_data = reply.readAll()
            pix.loadFromData(img_data)
            reply.deleteLater()

        if pix.isNull():
            pix.load(R"img/default_photo.png")

        # Emit signal
        self.image_request_finished.emit(reply.url().toString(), pix)
예제 #19
0
    def handleNetworkData(self, reply: QNetworkReply) -> None:
        img = QImage()
        tp = reply.request().attribute(QNetworkRequest.User)
        if not reply.error():
            if not img.load(reply, ""):
                img = QImage()
        reply.deleteLater()
        self.m_tilePixmaps[QPointH(tp)] = (
            self.m_emptyTile if img.isNull() else QPixmap.fromImage(img)
        )
        self.updated.emit(self.tileRect(tp))

        # purge unused spaces
        bound = self.m_tilesRect.adjusted(-2, -2, 2, 2)
        self.m_tilePixmaps = {
            tp: pixmap
            for tp, pixmap in self.m_tilePixmaps.items()
            if bound.contains(tp)
        }

        self.download()
예제 #20
0
    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 _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()
예제 #22
0
파일: Toolbox.py 프로젝트: qin2512/Cura
    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"})
                            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", "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
예제 #23
0
파일: Toolbox.py 프로젝트: CPS-3/Cura
    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:
            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