diff --git a/plugins/Marketplace/Marketplace.py b/plugins/Marketplace/Marketplace.py index 1ae19718ef..921e9d1290 100644 --- a/plugins/Marketplace/Marketplace.py +++ b/plugins/Marketplace/Marketplace.py @@ -15,14 +15,14 @@ from UM.PluginRegistry import PluginRegistry # To find out where we are stored if TYPE_CHECKING: from PyQt5.QtCore import QObject +ROOT_URL = f"{UltimakerCloudConstants.CuraCloudAPIRoot}/cura-packages/v{UltimakerCloudConstants.CuraCloudAPIVersion}/cura/v{CuraSDKVersion}" # Root of all Marketplace API requests. +PACKAGES_URL = f"{ROOT_URL}/packages" # URL to use for requesting the list of packages. + class Marketplace(Extension): """ The main managing object for the Marketplace plug-in. """ - ROOT_URL = f"{UltimakerCloudConstants.CuraCloudAPIRoot}/cura-packages/v{UltimakerCloudConstants.CuraCloudAPIVersion}/cura/v{CuraSDKVersion}" # Root of all Marketplace API requests. - PACKAGES_URL = f"{ROOT_URL}/packages" # URL to use for requesting the list of packages. - def __init__(self): super().__init__() self._window: Optional["QObject"] = None # If the window has been loaded yet, it'll be cached in here. diff --git a/plugins/Marketplace/PackageList.py b/plugins/Marketplace/PackageList.py index df663a4bd4..dfb0f0ad57 100644 --- a/plugins/Marketplace/PackageList.py +++ b/plugins/Marketplace/PackageList.py @@ -1,14 +1,20 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +from cura.CuraApplication import CuraApplication +from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope # To make requests to the Ultimaker API with correct authorization. from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, Qt -from typing import List, TYPE_CHECKING +from typing import List, Optional, TYPE_CHECKING from UM.Qt.ListModel import ListModel +from UM.TaskManagement.HttpRequestManager import HttpRequestManager # To request the package list from the API. +from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope # To request JSON responses from the API. +from .Marketplace import PACKAGES_URL # To get the list of packages. from .PackageModel import PackageModel # This list is a list of PackageModels. if TYPE_CHECKING: from PyQt5.QtCore import QObject + from PyQt5.QtNetwork import QNetworkReply class PackageList(ListModel): """ @@ -26,7 +32,8 @@ class PackageList(ListModel): super().__init__(parent) self._packages: List[PackageModel] = [] - self.setIsLoading(True) + self._is_loading = True + self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance())) self.requestFirst() @@ -38,6 +45,14 @@ class PackageList(ListModel): """ self.setIsLoading(True) + http = HttpRequestManager.getInstance() + http.get( + PACKAGES_URL, + scope = self._scope, + callback = self._parseResponse, + error_callback = self._onError + ) + isLoadingChanged = pyqtSignal() @pyqtSlot(bool) @@ -54,6 +69,23 @@ class PackageList(ListModel): """ return self._is_loading + def _parseResponse(self, reply: "QNetworkReply") -> None: + """ + Parse the response from the package list API request. + + This converts that response into PackageModels, and triggers the ListModel to update. + :param reply: A reply containing information about a number of packages. + """ + pass # TODO: Parse reply dictionary. + + def _onError(self, reply: "QNetworkReply", error: Optional["QNetworkReply.NetworkError"]) -> None: + """ + Handles networking and server errors when requesting the list of packages. + :param reply: The reply with packages. This will most likely be incomplete and should be ignored. + :param error: The error status of the request. + """ + pass # TODO: Handle errors. + def _update(self) -> None: # TODO: Get list of packages from Marketplace class. pass