diff --git a/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py b/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py index c991f96633..93e24a0651 100644 --- a/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py +++ b/plugins/DigitalLibrary/src/DFFileExportAndUploadManager.py @@ -123,7 +123,7 @@ class DFFileExportAndUploadManager: if isinstance(file_upload_response, DFLibraryFileUploadResponse): file_name = file_upload_response.file_name elif isinstance(file_upload_response, DFPrintJobUploadResponse): - file_name = file_upload_response.job_name + file_name = file_upload_response.job_name if file_upload_response.job_name is not None else "" else: Logger.log("e", "Wrong response type received. Aborting uploading file to the Digital Library") return @@ -273,7 +273,7 @@ class DFFileExportAndUploadManager: if reply_body: reply_dict = json.loads(reply_body) if "errors" in reply_dict and len(reply_dict["errors"]) >= 1 and "title" in reply_dict["errors"][0]: - error_title = reply_dict["errors"][0]["title"] # type: str + error_title = reply_dict["errors"][0]["title"] return error_title def _onUploadError(self, filename: str, reply: "QNetworkReply", error: "QNetworkReply.NetworkError") -> None: diff --git a/plugins/DigitalLibrary/src/DFFileUploader.py b/plugins/DigitalLibrary/src/DFFileUploader.py index 9c5356255e..10fee03c4c 100644 --- a/plugins/DigitalLibrary/src/DFFileUploader.py +++ b/plugins/DigitalLibrary/src/DFFileUploader.py @@ -83,8 +83,10 @@ class DFFileUploader: """ if self._finished: raise ValueError("The upload is already finished") - - Logger.log("i", "Uploading DF file to project '{library_project_id}' via link '{upload_url}'".format(library_project_id = self._df_file.library_project_id, upload_url = self._df_file.upload_url)) + if isinstance(self._df_file, DFLibraryFileUploadResponse): + Logger.log("i", "Uploading Cura project file '{file_name}' via link '{upload_url}'".format(file_name = self._df_file.file_name, upload_url = self._df_file.upload_url)) + elif isinstance(self._df_file, DFPrintJobUploadResponse): + Logger.log("i", "Uploading Cura print file '{file_name}' via link '{upload_url}'".format(file_name = self._df_file.job_name, upload_url = self._df_file.upload_url)) self._http.put( url = cast(str, self._df_file.upload_url), headers_dict = {"Content-Type": cast(str, self._df_file.content_type)}, diff --git a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py index 4342d2623e..20bc555831 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryApiClient.py @@ -24,6 +24,7 @@ from .DFLibraryFileUploadResponse import DFLibraryFileUploadResponse from .DFPrintJobUploadRequest import DFPrintJobUploadRequest from .DigitalFactoryFileResponse import DigitalFactoryFileResponse from .DigitalFactoryProjectResponse import DigitalFactoryProjectResponse +from .PaginationLinks import PaginationLinks from .PaginationManager import PaginationManager CloudApiClientModel = TypeVar("CloudApiClientModel", bound=BaseModel) @@ -104,7 +105,7 @@ class DigitalFactoryApiClient: """ if self.hasMoreProjectsToLoad(): - url = self._projects_pagination_mgr.links.next_page + url = cast(PaginationLinks, cast(PaginationManager, self._projects_pagination_mgr).links).next_page self._http.get(url, scope = self._scope, callback = self._parseCallback(on_finished, DigitalFactoryProjectResponse, failed, pagination_manager = self._projects_pagination_mgr), @@ -119,7 +120,7 @@ class DigitalFactoryApiClient: :return: Whether there are more pages in the projects list available to be retrieved from the API. """ - return self._projects_pagination_mgr and self._projects_pagination_mgr.links and self._projects_pagination_mgr.links.next_page is not None + return self._projects_pagination_mgr is not None and self._projects_pagination_mgr.links is not None and self._projects_pagination_mgr.links.next_page is not None def getListOfFilesInProject(self, library_project_id: str, on_finished: Callable[[List[DigitalFactoryFileResponse]], Any], failed: Callable) -> None: """Retrieves the list of files contained in the project with library_project_id from the Digital Factory Library. @@ -314,4 +315,5 @@ class DigitalFactoryApiClient: timeout = self.DEFAULT_REQUEST_TIMEOUT) def clear(self) -> None: - self._projects_pagination_mgr.reset() + if self._projects_pagination_mgr is not None: + self._projects_pagination_mgr.reset() diff --git a/plugins/DigitalLibrary/src/DigitalFactoryController.py b/plugins/DigitalLibrary/src/DigitalFactoryController.py index cd20479611..62f13be64c 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryController.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryController.py @@ -6,7 +6,7 @@ import tempfile import threading from enum import IntEnum from pathlib import Path -from typing import Optional, List, Dict, Any +from typing import Optional, List, Dict, Any, cast from PyQt5.QtCore import pyqtSignal, QObject, pyqtSlot, pyqtProperty, Q_ENUMS, QUrl from PyQt5.QtNetwork import QNetworkReply @@ -97,7 +97,7 @@ class DigitalFactoryController(QObject): self.file_handlers = {} # type: Dict[str, FileHandler] self.nodes = None # type: Optional[List[SceneNode]] - self.file_upload_manager = None + self.file_upload_manager = None # type: Optional[DFFileExportAndUploadManager] self._has_preselected_project = False # type: bool self._api = DigitalFactoryApiClient(self._application, on_error = lambda error: Logger.log("e", str(error)), projects_limit_per_page = 20) @@ -149,7 +149,7 @@ class DigitalFactoryController(QObject): :return: True if the user account has Digital Library access, else False """ - subscriptions = [] # type: Optional[List[Dict[str, Any]]] + subscriptions = [] # type: List[Dict[str, Any]] if self._account.userProfile: subscriptions = self._account.userProfile.get("subscriptions", []) return len(subscriptions) > 0 @@ -340,46 +340,46 @@ class DigitalFactoryController(QObject): Logger.log("e", "Something went wrong while trying to create a new a project. Error: {}".format(reply_string)) # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int - def setRetrievingProjectsStatus(self, new_status: int) -> None: + def setRetrievingProjectsStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "retrieving library projects" http call. :param new_status: The new status """ self.retrieving_projects_status = new_status - self.retrievingProjectsStatusChanged.emit(new_status) + self.retrievingProjectsStatusChanged.emit(int(new_status)) @pyqtProperty(int, fset = setRetrievingProjectsStatus, notify = retrievingProjectsStatusChanged) def retrievingProjectsStatus(self) -> int: - return self.retrieving_projects_status + return int(self.retrieving_projects_status) # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int - def setRetrievingFilesStatus(self, new_status: int) -> None: + def setRetrievingFilesStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "retrieving files list in the selected library project" http call. :param new_status: The new status """ self.retrieving_files_status = new_status - self.retrievingFilesStatusChanged.emit(new_status) + self.retrievingFilesStatusChanged.emit(int(new_status)) @pyqtProperty(int, fset = setRetrievingFilesStatus, notify = retrievingFilesStatusChanged) def retrievingFilesStatus(self) -> int: - return self.retrieving_files_status + return int(self.retrieving_files_status) # The new_status type is actually "RetrievalStatus" but since the RetrievalStatus cannot be an enum, we leave it as int - def setCreatingNewProjectStatus(self, new_status: int) -> None: + def setCreatingNewProjectStatus(self, new_status: RetrievalStatus) -> None: """ Sets the status of the "creating new library project" http call. :param new_status: The new status """ self.creating_new_project_status = new_status - self.creatingNewProjectStatusChanged.emit(new_status) + self.creatingNewProjectStatusChanged.emit(int(new_status)) @pyqtProperty(int, fset = setCreatingNewProjectStatus, notify = creatingNewProjectStatusChanged) def creatingNewProjectStatus(self) -> int: - return self.creating_new_project_status + return int(self.creating_new_project_status) @staticmethod def _onEngineCreated() -> None: @@ -388,15 +388,15 @@ class DigitalFactoryController(QObject): def _applicationInitializationFinished(self) -> None: self._supported_file_types = self._application.getInstance().getMeshFileHandler().getSupportedFileTypesRead() - @pyqtSlot("QList") - def setSelectedFileIndices(self, file_indices: List[int]) -> None: - """ - Sets the index of the file which is currently selected in the list of files. - - :param file_indices: A list of the indices of the currently selected files - """ - self._selected_file_indices = file_indices - self.selectedFileIndicesChanged.emit(file_indices) + # @pyqtSlot("QList") + # def setSelectedFileIndices(self, file_indices: List[int]) -> None: + # """ + # Sets the index of the file which is currently selected in the list of files. + # + # :param file_indices: A list of the indices of the currently selected files + # """ + # self._selected_file_indices = file_indices + # self.selectedFileIndicesChanged.emit(file_indices) @pyqtSlot() def openSelectedFiles(self) -> None: @@ -546,7 +546,7 @@ class DigitalFactoryController(QObject): library_project_name = self._project_model.items[self._selected_project_idx]["displayName"] # Use the file upload manager to export and upload the 3mf and/or ufp files to the DF Library project - self.file_upload_manager = DFFileExportAndUploadManager(file_handlers = self.file_handlers, nodes = self.nodes, + self.file_upload_manager = DFFileExportAndUploadManager(file_handlers = self.file_handlers, nodes = cast(List[SceneNode], self.nodes), library_project_id = library_project_id, library_project_name = library_project_name, file_name = filename, formats = formats, diff --git a/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py b/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py index c2fe6b969c..c5dc164bda 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryFileProvider.py @@ -31,9 +31,14 @@ class DigitalFactoryFileProvider(FileProvider): Function called every time the 'From Digital Factory' option of the 'Open File(s)' submenu is triggered """ self.loadWindow() + print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa") if self._account.isLoggedIn and self._controller.userAccountHasLibraryAccess(): self._controller.initialize() + + if not self._dialog: + Logger.log("e", "Unable to create the Digital Library Open dialog.") + return self._dialog.show() def loadWindow(self) -> None: diff --git a/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py b/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py index 852c565b5e..202223f9b4 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryOutputDevice.py @@ -72,6 +72,10 @@ class DigitalFactoryOutputDevice(ProjectOutputDevice): df_workspace_information = self._current_workspace_information.getPluginMetadata("digital_factory") self._controller.initialize(preselected_project_id = df_workspace_information.get("library_project_id")) + + if not self._dialog: + Logger.log("e", "Unable to create the Digital Library Save dialog.") + return self._dialog.show() def loadWindow(self) -> None: diff --git a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py index b35e760998..57cd0fd27c 100644 --- a/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py +++ b/plugins/DigitalLibrary/src/DigitalFactoryProjectModel.py @@ -47,7 +47,7 @@ class DigitalFactoryProjectModel(ListModel): self._update(df_projects) def sortProjectsBy(self, sort_by: Optional[str]): - if sort_by: + if sort_by is not None: try: self._projects.sort(key = lambda p: getattr(p, sort_by)) except AttributeError: