mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 15:37:27 -06:00
Always subscribe to packages after installing them
Now that we subscribe for all situations where a package is installed, it makes sense to watch package installs and create a 1:1 relation that way. Prevents code duplication. CURA-7099
This commit is contained in:
parent
5cedb2933e
commit
d4eb463f2d
5 changed files with 48 additions and 23 deletions
|
@ -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
|
||||||
|
@ -476,7 +474,7 @@ class CuraApplication(QtApplication):
|
||||||
"CuraEngineBackend", #Cura is useless without this one since you can't slice.
|
"CuraEngineBackend", #Cura is useless without this one since you can't slice.
|
||||||
"FileLogger", #You want to be able to read the log if something goes wrong.
|
"FileLogger", #You want to be able to read the log if something goes wrong.
|
||||||
"XmlMaterialProfile", #Cura crashes without this one.
|
"XmlMaterialProfile", #Cura crashes without this one.
|
||||||
"Toolbox", #This contains the interface to enable/disable plug-ins, so if you disable it you can't enable it back.
|
"Toolbox", #This contains the interface to enable/disable plug-ins and the Cloud functionality.
|
||||||
"PrepareStage", #Cura is useless without this one since you can't load models.
|
"PrepareStage", #Cura is useless without this one since you can't load models.
|
||||||
"PreviewStage", #This shows the list of the plugin views that are installed in Cura.
|
"PreviewStage", #This shows the list of the plugin views that are installed in Cura.
|
||||||
"MonitorStage", #Major part of Cura's functionality.
|
"MonitorStage", #Major part of Cura's functionality.
|
||||||
|
@ -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
|
||||||
|
|
|
@ -1,23 +1,53 @@
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
||||||
|
from cura.API import Account
|
||||||
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:
|
||||||
|
"""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
|
||||||
|
|
||||||
|
Singleton: use CloudPackageManager.getInstance() instead of CloudPackageManager()
|
||||||
|
"""
|
||||||
|
|
||||||
|
__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:
|
def __init__(self, app: CuraApplication) -> None:
|
||||||
self._request_manager = app.getHttpRequestManager()
|
if self.__instance is not None:
|
||||||
self._scope = UltimakerCloudScope(app)
|
raise Exception("This is a Singleton. use getInstance()")
|
||||||
|
|
||||||
|
self._request_manager = app.getHttpRequestManager() # type: HttpRequestManager
|
||||||
|
self.account = app.getCuraAPI().account # type: Account
|
||||||
|
self._scope = UltimakerCloudScope(app) # type: UltimakerCloudScope
|
||||||
|
|
||||||
|
app.getPackageManager().packageInstalled.connect(self._onPackageInstalled)
|
||||||
|
|
||||||
|
def unsubscribe(self, package_id: str) -> None:
|
||||||
|
url = CloudApiModel.userPackageUrl(package_id)
|
||||||
|
self._request_manager.delete(url=url, scope=self._scope)
|
||||||
|
|
||||||
def subscribe(self, package_id: str) -> None:
|
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)
|
data = "{\"data\": {\"package_id\": \"%s\", \"sdk_version\": \"%s\"}}" % (package_id, CloudApiModel.sdk_version)
|
||||||
self._request_manager.put(url=CloudApiModel.api_url_user_packages,
|
self._request_manager.put(url=CloudApiModel.api_url_user_packages,
|
||||||
data=data.encode(),
|
data=data.encode(),
|
||||||
scope=self._scope
|
scope=self._scope
|
||||||
)
|
)
|
||||||
|
|
||||||
def unsubscribe(self, package_id: str) -> None:
|
def _onPackageInstalled(self, package_id: str):
|
||||||
url = CloudApiModel.userPackageUrl(package_id)
|
if self.account.isLoggedIn:
|
||||||
self._request_manager.delete(url=url, scope=self._scope)
|
# We might already be subscribed, but checking would take one extra request. Instead, simply subscribe
|
||||||
|
self.subscribe(package_id)
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -86,7 +87,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"])
|
||||||
|
|
|
@ -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,11 +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:
|
|
||||||
if self._application.getCuraAPI().account.isLoggedIn:
|
|
||||||
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
|
||||||
|
|
||||||
|
@ -378,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()
|
||||||
|
@ -682,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:
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue