Resolve circular imports for CuraAPI

This commit is contained in:
Lipu Fei 2018-09-28 12:06:57 +02:00
parent 3b70e5eb6b
commit dd150bbab9
8 changed files with 81 additions and 31 deletions

View file

@ -1,15 +1,18 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, Dict
from typing import Optional, Dict, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
from UM.i18n import i18nCatalog
from UM.Message import Message
from cura.OAuth2.AuthorizationService import AuthorizationService
from cura.OAuth2.Models import OAuth2Settings
from UM.Application import Application
from UM.i18n import i18nCatalog
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
i18n_catalog = i18nCatalog("cura")
@ -26,8 +29,9 @@ class Account(QObject):
# Signal emitted when user logged in or out.
loginStateChanged = pyqtSignal(bool)
def __init__(self, parent = None) -> None:
def __init__(self, application: "CuraApplication", parent = None) -> None:
super().__init__(parent)
self._application = application
self._error_message = None # type: Optional[Message]
self._logged_in = False
@ -47,7 +51,11 @@ class Account(QObject):
AUTH_FAILED_REDIRECT="{}/app/auth-error".format(self._oauth_root)
)
self._authorization_service = AuthorizationService(Application.getInstance().getPreferences(), self._oauth_settings)
self._authorization_service = AuthorizationService(self._oauth_settings)
def initialize(self) -> None:
self._authorization_service.initialize(self._application.getPreferences())
self._authorization_service.onAuthStateChanged.connect(self._onLoginStateChanged)
self._authorization_service.onAuthenticationError.connect(self._onLoginStateChanged)
self._authorization_service.loadAuthDataFromPreferences()

View file

@ -1,9 +1,12 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Tuple, Optional
from typing import Tuple, Optional, TYPE_CHECKING
from cura.Backups.BackupsManager import BackupsManager
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
## The back-ups API provides a version-proof bridge between Cura's
# BackupManager and plug-ins that hook into it.
@ -13,9 +16,10 @@ from cura.Backups.BackupsManager import BackupsManager
# api = CuraAPI()
# api.backups.createBackup()
# api.backups.restoreBackup(my_zip_file, {"cura_release": "3.1"})``
class Backups:
manager = BackupsManager() # Re-used instance of the backups manager.
def __init__(self, application: "CuraApplication") -> None:
self.manager = BackupsManager(application)
## Create a new back-up using the BackupsManager.
# \return Tuple containing a ZIP file with the back-up data and a dict

View file

@ -1,8 +1,12 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
## The Interface.Settings API provides a version-proof bridge between Cura's
# (currently) sidebar UI and plug-ins that hook into it.
#
@ -19,8 +23,9 @@ from cura.CuraApplication import CuraApplication
# api.interface.settings.addContextMenuItem(data)``
class Settings:
# Re-used instance of Cura:
application = CuraApplication.getInstance() # type: CuraApplication
def __init__(self, application: "CuraApplication") -> None:
self.application = application
## Add items to the sidebar context menu.
# \param menu_item dict containing the menu item to add.

View file

@ -1,9 +1,15 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import TYPE_CHECKING
from UM.PluginRegistry import PluginRegistry
from cura.API.Interface.Settings import Settings
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
## The Interface class serves as a common root for the specific API
# methods for each interface element.
#
@ -20,5 +26,6 @@ class Interface:
# For now we use the same API version to be consistent.
VERSION = PluginRegistry.APIVersion
def __init__(self, application: "CuraApplication") -> None:
# API methods specific to the settings portion of the UI
settings = Settings()
self.settings = Settings(application)

View file

@ -1,5 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtProperty
from UM.PluginRegistry import PluginRegistry
@ -7,6 +9,9 @@ from cura.API.Backups import Backups
from cura.API.Interface import Interface
from cura.API.Account import Account
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
## The official Cura API that plug-ins can use to interact with Cura.
#
@ -19,14 +24,30 @@ class CuraAPI(QObject):
# For now we use the same API version to be consistent.
VERSION = PluginRegistry.APIVersion
def __init__(self, application: "CuraApplication") -> None:
super().__init__(parent = application)
self._application = application
# Accounts API
self._account = Account(self._application)
# Backups API
backups = Backups()
self._backups = Backups(self._application)
# Interface API
interface = Interface()
self._interface = Interface(self._application)
_account = Account()
def initialize(self) -> None:
self._account.initialize()
@pyqtProperty(QObject, constant = True)
def account(self) -> Account:
return CuraAPI._account
def account(self) -> "Account":
return self._account
@property
def backups(self) -> "Backups":
return self._backups
@property
def interface(self) -> "Interface":
return self._interface

View file

@ -1,10 +1,12 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Dict, Optional, Tuple
from typing import Dict, Optional, Tuple, TYPE_CHECKING
from UM.Logger import Logger
from cura.Backups.Backup import Backup
if TYPE_CHECKING:
from cura.CuraApplication import CuraApplication
@ -13,8 +15,8 @@ from cura.CuraApplication import CuraApplication
#
# Back-ups themselves are represented in a different class.
class BackupsManager:
def __init__(self):
self._application = CuraApplication.getInstance()
def __init__(self, application: "CuraApplication") -> None:
self._application = application
## Get a back-up of the current configuration.
# \return A tuple containing a ZipFile (the actual back-up) and a dict

View file

@ -44,6 +44,7 @@ from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Operations.SetTransformOperation import SetTransformOperation
from cura.API import CuraAPI
from cura.Arranging.Arrange import Arrange
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
@ -204,7 +205,7 @@ class CuraApplication(QtApplication):
self._quality_profile_drop_down_menu_model = None
self._custom_quality_profile_drop_down_menu_model = None
self._cura_API = None
self._cura_API = CuraAPI(self)
self._physics = None
self._volume = None
@ -713,6 +714,9 @@ class CuraApplication(QtApplication):
default_visibility_profile = self._setting_visibility_presets_model.getItem(0)
self.getPreferences().setDefault("general/visible_settings", ";".join(default_visibility_profile["settings"]))
# Initialize Cura API
self._cura_API.initialize()
# Detect in which mode to run and execute that mode
if self._is_headless:
self.runWithoutGUI()
@ -900,10 +904,7 @@ class CuraApplication(QtApplication):
self._custom_quality_profile_drop_down_menu_model = CustomQualityProfilesDropDownMenuModel(self)
return self._custom_quality_profile_drop_down_menu_model
def getCuraAPI(self, *args, **kwargs):
if self._cura_API is None:
from cura.API import CuraAPI
self._cura_API = CuraAPI()
def getCuraAPI(self, *args, **kwargs) -> "CuraAPI":
return self._cura_API
## Registers objects for the QML engine to use.

View file

@ -29,7 +29,7 @@ class AuthorizationService:
# Emit signal when authentication failed.
onAuthenticationError = Signal()
def __init__(self, preferences: Optional["Preferences"], settings: "OAuth2Settings") -> None:
def __init__(self, settings: "OAuth2Settings", preferences: Optional["Preferences"] = None) -> None:
self._settings = settings
self._auth_helpers = AuthorizationHelpers(settings)
self._auth_url = "{}/authorize".format(self._settings.OAUTH_SERVER_URL)
@ -38,6 +38,8 @@ class AuthorizationService:
self._preferences = preferences
self._server = LocalAuthorizationServer(self._auth_helpers, self._onAuthStateChanged, daemon=True)
def initialize(self, preferences: Optional["Preferences"] = None) -> None:
self._preferences = preferences
if self._preferences:
self._preferences.addPreference(self._settings.AUTH_DATA_PREFERENCE_KEY, "{}")