diff options
author | Remco Burema <41987080+rburema@users.noreply.github.com> | 2022-08-30 17:53:47 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-30 17:53:47 +0300 |
commit | e69b855b2b2a2da1ab336f37251aed79ef92edbe (patch) | |
tree | 79022df51a16103107e50c6700547244f874d768 | |
parent | c7f8fe8feb25e9063df025909983b6711cb72701 (diff) | |
parent | 7ab16e078c15c2697fd18c48192a70b367fab3a3 (diff) |
Merge pull request #13127 from Ultimaker/CURA-9221_show_message_cloud_approval
[CURA-9221] Show message cloud approval
3 files changed, 64 insertions, 16 deletions
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py index 470e57947e..1fc926fe90 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudApiClient.py @@ -189,9 +189,9 @@ class CloudApiClient: Logger.logException("e", "Could not parse the stardust response: %s", error.toDict()) return status_code, {"errors": [error.toDict()]} - def _parseModels(self, response: Dict[str, Any], on_finished: Union[Callable[[CloudApiClientModel], Any], - Callable[[List[CloudApiClientModel]], Any]], model_class: Type[CloudApiClientModel]) -> None: - """Parses the given models and calls the correct callback depending on the result. + def _parseResponse(self, response: Dict[str, Any], on_finished: Union[Callable[[CloudApiClientModel], Any], + Callable[[List[CloudApiClientModel]], Any]], model_class: Type[CloudApiClientModel]) -> None: + """Parses the given response and calls the correct callback depending on the result. :param response: The response from the server, after being converted to a dict. :param on_finished: The callback in case the response is successful. @@ -200,7 +200,10 @@ class CloudApiClient: if "data" in response: data = response["data"] - if isinstance(data, list): + if "status" in data and data["status"] == "wait_approval": + on_finished_empty = cast(Callable[[List], Any], on_finished) + on_finished_empty([]) + elif isinstance(data, list): results = [model_class(**c) for c in data] # type: List[CloudApiClientModel] on_finished_list = cast(Callable[[List[CloudApiClientModel]], Any], on_finished) on_finished_list(results) @@ -242,7 +245,7 @@ class CloudApiClient: if status_code >= 300 and on_error is not None: on_error() else: - self._parseModels(response, on_finished, model) + self._parseResponse(response, on_finished, model) self._anti_gc_callbacks.append(parse) return parse diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 6431d09b7b..6426f01b76 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -3,7 +3,7 @@ from time import time import os -from typing import cast, List, Optional, TYPE_CHECKING +from typing import cast, List, Optional from PyQt6.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot from PyQt6.QtGui import QDesktopServices @@ -21,6 +21,7 @@ from cura.PrinterOutput.PrinterOutputDevice import ConnectionType from .CloudApiClient import CloudApiClient from ..ExportFileJob import ExportFileJob +from ..Messages.PrintJobAwaitingApprovalMessage import PrintJobPendingApprovalMessage from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice from ..Messages.PrintJobUploadBlockedMessage import PrintJobUploadBlockedMessage from ..Messages.PrintJobUploadErrorMessage import PrintJobUploadErrorMessage @@ -230,6 +231,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): :param job_response: The response received from the cloud API. """ + if not self._tool_path: return self._onUploadError() self._pre_upload_print_job = job_response # store the last uploaded job to prevent re-upload of the same file @@ -258,16 +260,21 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): """ self._uploaded_print_job = self._pre_upload_print_job self._progress.hide() - message = PrintJobUploadSuccessMessage() - message.addAction("monitor print", - name=I18N_CATALOG.i18nc("@action:button", "Monitor print"), - icon="", - description=I18N_CATALOG.i18nc("@action:tooltip", "Track the print in Ultimaker Digital Factory"), - button_align=message.ActionButtonAlignment.ALIGN_RIGHT) - df_url = f"https://digitalfactory.ultimaker.com/app/jobs/{self._cluster.cluster_id}?utm_source=cura&utm_medium=software&utm_campaign=message-printjob-sent" - message.pyQtActionTriggered.connect(lambda message, action: (QDesktopServices.openUrl(QUrl(df_url)), message.hide())) - - message.show() + + if response: + message = PrintJobUploadSuccessMessage() + message.addAction("monitor print", + name=I18N_CATALOG.i18nc("@action:button", "Monitor print"), + icon="", + description=I18N_CATALOG.i18nc("@action:tooltip", "Track the print in Ultimaker Digital Factory"), + button_align=message.ActionButtonAlignment.ALIGN_RIGHT) + df_url = f"https://digitalfactory.ultimaker.com/app/jobs/{self._cluster.cluster_id}?utm_source=cura&utm_medium=software&utm_campaign=message-printjob-sent" + message.pyQtActionTriggered.connect(lambda message, action: (QDesktopServices.openUrl(QUrl(df_url)), message.hide())) + + message.show() + else: + PrintJobPendingApprovalMessage(self._cluster.cluster_id).show() + self.writeFinished.emit() def _onPrintUploadSpecificError(self, reply: "QNetworkReply", _: "QNetworkReply.NetworkError"): diff --git a/plugins/UM3NetworkPrinting/src/Messages/PrintJobAwaitingApprovalMessage.py b/plugins/UM3NetworkPrinting/src/Messages/PrintJobAwaitingApprovalMessage.py new file mode 100644 index 0000000000..c60d596da9 --- /dev/null +++ b/plugins/UM3NetworkPrinting/src/Messages/PrintJobAwaitingApprovalMessage.py @@ -0,0 +1,38 @@ +# Copyright (c) 2022 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. +from PyQt6.QtCore import QUrl +from PyQt6.QtGui import QDesktopServices + +from UM import i18nCatalog +from UM.Message import Message + + +I18N_CATALOG = i18nCatalog("cura") + + +class PrintJobPendingApprovalMessage(Message): + """Message shown when waiting for approval on an uploaded print job.""" + + def __init__(self, cluster_id: str) -> None: + super().__init__( + text = I18N_CATALOG.i18nc("@info:status", "You will receive a confirmation via email when the print job is approved"), + title=I18N_CATALOG.i18nc("@info:title", "The print job was successfully submitted"), + message_type=Message.MessageType.POSITIVE + ) + self.addAction("manage_print_jobs", I18N_CATALOG.i18nc("@action", "Manage print jobs"), "", "") + + self.addAction("learn_more", I18N_CATALOG.i18nc("@action", "Learn more"), "", "", + button_style = Message.ActionButtonStyle.LINK, + button_align = Message.ActionButtonAlignment.ALIGN_LEFT) + + self.actionTriggered.connect(self._onActionTriggered) + + self.cluster_id = cluster_id + + def _onActionTriggered(self, message: Message, action: str) -> None: + """ Callback function for the "Manage print jobs" button on the pending approval notification. """ + match action: + case "manage_print_jobs": + QDesktopServices.openUrl(QUrl(f"https://digitalfactory.ultimaker.com/app/jobs/{self._cluster.cluster_id}?utm_source=cura&utm_medium=software&utm_campaign=message-printjob-sent")) + case "learn_more": + QDesktopServices.openUrl(QUrl("https://support.ultimaker.com/hc/en-us/articles/5329940078620?utm_source=cura&utm_medium=software&utm_campaign=message-printjob-sent")) |