Merge branch 'CURA-7099_sync_sideloaded_plugins'

This commit is contained in:
Ghostkeeper 2020-02-03 16:12:56 +01:00
commit 66e2ca6aa5
No known key found for this signature in database
GPG key ID: 37E2020986774393
5 changed files with 49 additions and 25 deletions

View file

@ -191,8 +191,6 @@ class CuraApplication(QtApplication):
self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions] self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions]
self._cura_package_manager = None
self._machine_action_manager = None # type: Optional[MachineActionManager.MachineActionManager] self._machine_action_manager = None # type: Optional[MachineActionManager.MachineActionManager]
self.empty_container = None # type: EmptyInstanceContainer self.empty_container = None # type: EmptyInstanceContainer
@ -632,6 +630,12 @@ class CuraApplication(QtApplication):
def showPreferences(self) -> None: def showPreferences(self) -> None:
self.showPreferencesWindow.emit() self.showPreferencesWindow.emit()
# This is called by drag-and-dropping curapackage files.
@pyqtSlot(QUrl)
def installPackageViaDragAndDrop(self, file_url: str) -> Optional[str]:
filename = QUrl(file_url).toLocalFile()
return self._package_manager.installPackage(filename)
@override(Application) @override(Application)
def getGlobalContainerStack(self) -> Optional["GlobalStack"]: def getGlobalContainerStack(self) -> Optional["GlobalStack"]:
return self._global_container_stack return self._global_container_stack

View file

@ -1,23 +1,51 @@
from UM.Logger import Logger
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from ..CloudApiModel import CloudApiModel from ..CloudApiModel import CloudApiModel
from ..UltimakerCloudScope import UltimakerCloudScope from ..UltimakerCloudScope import UltimakerCloudScope
## Manages Cloud subscriptions. When a package is added to a user's account, the user is 'subscribed' to that package
# Whenever the user logs in on another instance of Cura, these subscriptions can be used to sync the user's plugins
class CloudPackageManager: class CloudPackageManager:
def __init__(self, app: CuraApplication) -> None: """Manages Cloud subscriptions
self._request_manager = app.getHttpRequestManager()
self._scope = UltimakerCloudScope(app)
def subscribe(self, package_id: str) -> None: When a package is added to a user's account, the user is 'subscribed' to that package.
data = "{\"data\": {\"package_id\": \"%s\", \"sdk_version\": \"%s\"}}" % (package_id, CloudApiModel.sdk_version) Whenever the user logs in on another instance of Cura, these subscriptions can be used to sync the user's plugins
self._request_manager.put(url=CloudApiModel.api_url_user_packages,
data=data.encode(), Singleton: use CloudPackageManager.getInstance() instead of CloudPackageManager()
scope=self._scope """
)
__instance = None
@classmethod
def getInstance(cls, app: CuraApplication):
if not cls.__instance:
cls.__instance = CloudPackageManager(app)
return cls.__instance
def __init__(self, app: CuraApplication) -> None:
if self.__instance is not None:
raise RuntimeError("This is a Singleton. use getInstance()")
self._scope = UltimakerCloudScope(app) # type: UltimakerCloudScope
app.getPackageManager().packageInstalled.connect(self._onPackageInstalled)
def unsubscribe(self, package_id: str) -> None: def unsubscribe(self, package_id: str) -> None:
url = CloudApiModel.userPackageUrl(package_id) url = CloudApiModel.userPackageUrl(package_id)
self._request_manager.delete(url=url, scope=self._scope) HttpRequestManager.getInstance().delete(url = url, scope = self._scope)
def _subscribe(self, package_id: str) -> None:
"""You probably don't want to use this directly. All installed packages will be automatically subscribed."""
Logger.debug("Subscribing to {}", package_id)
data = "{\"data\": {\"package_id\": \"%s\", \"sdk_version\": \"%s\"}}" % (package_id, CloudApiModel.sdk_version)
HttpRequestManager.getInstance().put(
url = CloudApiModel.api_url_user_packages,
data = data.encode(),
scope = self._scope
)
def _onPackageInstalled(self, package_id: str):
if CuraApplication.getInstance().getCuraAPI().account.isLoggedIn:
# We might already be subscribed, but checking would take one extra request. Instead, simply subscribe
self._subscribe(package_id)

View file

@ -38,7 +38,8 @@ class SyncOrchestrator(Extension):
self._name = "SyncOrchestrator" self._name = "SyncOrchestrator"
self._package_manager = app.getPackageManager() self._package_manager = app.getPackageManager()
self._cloud_package_manager = CloudPackageManager(app) # Keep a reference to the CloudPackageManager. it watches for installed packages and subscribes to them
self._cloud_package_manager = CloudPackageManager.getInstance(app) # type: CloudPackageManager
self._checker = CloudPackageChecker(app) # type: CloudPackageChecker self._checker = CloudPackageChecker(app) # type: CloudPackageChecker
self._checker.discrepancies.connect(self._onDiscrepancies) self._checker.discrepancies.connect(self._onDiscrepancies)
@ -84,7 +85,6 @@ class SyncOrchestrator(Extension):
message = "Could not install {}".format(item["package_id"]) message = "Could not install {}".format(item["package_id"])
self._showErrorMessage(message) self._showErrorMessage(message)
continue continue
self._cloud_package_manager.subscribe(item["package_id"])
has_changes = True has_changes = True
else: else:
self._cloud_package_manager.unsubscribe(item["package_id"]) self._cloud_package_manager.unsubscribe(item["package_id"])

View file

@ -21,7 +21,6 @@ from cura.Machines.ContainerTree import ContainerTree
from .CloudApiModel import CloudApiModel from .CloudApiModel import CloudApiModel
from .AuthorsModel import AuthorsModel from .AuthorsModel import AuthorsModel
from .CloudSync.CloudPackageManager import CloudPackageManager
from .CloudSync.LicenseModel import LicenseModel from .CloudSync.LicenseModel import LicenseModel
from .PackagesModel import PackagesModel from .PackagesModel import PackagesModel
from .UltimakerCloudScope import UltimakerCloudScope from .UltimakerCloudScope import UltimakerCloudScope
@ -44,7 +43,6 @@ class Toolbox(QObject, Extension):
self._sdk_version = ApplicationMetadata.CuraSDKVersion # type: Union[str, int] self._sdk_version = ApplicationMetadata.CuraSDKVersion # type: Union[str, int]
# Network: # Network:
self._cloud_package_manager = CloudPackageManager(application) # type: CloudPackageManager
self._download_request_data = None # type: Optional[HttpRequestData] self._download_request_data = None # type: Optional[HttpRequestData]
self._download_progress = 0 # type: float self._download_progress = 0 # type: float
self._is_downloading = False # type: bool self._is_downloading = False # type: bool
@ -147,10 +145,6 @@ class Toolbox(QObject, Extension):
self._application.getHttpRequestManager().put(url, data = data.encode(), scope = self._scope) self._application.getHttpRequestManager().put(url, data = data.encode(), scope = self._scope)
@pyqtSlot(str)
def subscribe(self, package_id: str) -> None:
self._cloud_package_manager.subscribe(package_id)
def getLicenseDialogPluginFileLocation(self) -> str: def getLicenseDialogPluginFileLocation(self) -> str:
return self._license_dialog_plugin_file_location return self._license_dialog_plugin_file_location
@ -377,7 +371,6 @@ class Toolbox(QObject, Extension):
def onLicenseAccepted(self): def onLicenseAccepted(self):
self.closeLicenseDialog.emit() self.closeLicenseDialog.emit()
package_id = self.install(self.getLicenseDialogPluginFileLocation()) package_id = self.install(self.getLicenseDialogPluginFileLocation())
self.subscribe(package_id)
@pyqtSlot() @pyqtSlot()
@ -681,7 +674,6 @@ class Toolbox(QObject, Extension):
installed_id = self.install(file_path) installed_id = self.install(file_path)
if installed_id != package_id: if installed_id != package_id:
Logger.error("Installed package {} does not match {}".format(installed_id, package_id)) Logger.error("Installed package {} does not match {}".format(installed_id, package_id))
self.subscribe(installed_id)
# Getter & Setters for Properties: # Getter & Setters for Properties:
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------

View file

@ -238,7 +238,7 @@ UM.MainWindow
if (filename.toLowerCase().endsWith(".curapackage")) if (filename.toLowerCase().endsWith(".curapackage"))
{ {
// Try to install plugin & close. // Try to install plugin & close.
CuraApplication.getPackageManager().installPackageViaDragAndDrop(filename); CuraApplication.installPackageViaDragAndDrop(filename);
packageInstallDialog.text = catalog.i18nc("@label", "This package will be installed after restarting."); packageInstallDialog.text = catalog.i18nc("@label", "This package will be installed after restarting.");
packageInstallDialog.icon = StandardIcon.Information; packageInstallDialog.icon = StandardIcon.Information;
packageInstallDialog.open(); packageInstallDialog.open();