Beispiel #1
0
    QtCore.QCoreApplication.processEvents()
    # check for open file change
    global g_current_file
    cur_file = tde4.getProjectPath()
    if g_current_file != cur_file:
        if cur_file:
            engine = tank.platform.current_engine()
            context = engine.context
            new_context = engine.tank.context_from_path(cur_file, context)
            if new_context != context:
                tank.platform.change_context(new_context)
        g_current_file = cur_file


if __name__ == '__main__':
    engine = tank.platform.current_engine()
    if not engine:
        from tank_vendor.shotgun_authentication import ShotgunAuthenticator
        user = ShotgunAuthenticator(tank.util.CoreDefaultsManager()).get_user()
        tank.set_authenticated_user(user)
        context = tank.context.deserialize(os.environ.get("TANK_CONTEXT"))
        engine = tank.platform.start_engine('tk-3de4', context.tank, context)

    # Qt
    if not QtCore.QCoreApplication.instance():
        QtGui.QApplication([])
        global g_current_file
        g_current_file = tde4.getProjectPath()
        tde4.setTimerCallbackFunction("_timer", 50)
        engine.post_qt_init()
Beispiel #2
0
    def run(self, splash, version, **kwargs):
        """
        Run the engine.

        This method is called from the GUI bootstrap to setup the application
        and to run the Qt event loop.

        :param splash: Splash screen widget we can display messages on. Can be ``None``
        :param version: Version of the Shotgun Desktop installer code.
        :param startup_version: Version of the Desktop Startup code. Can be omitted.
        :param startup_descriptor: Descriptor of the Desktop Startup code. Can be omitted.
        """
        self.app_version = version

        # Startup version will not be set if we have an old installer invoking
        # this engine.
        self.startup_version = kwargs.get("startup_version")
        self.startup_descriptor = kwargs.get("startup_descriptor")
        server = kwargs.get("server")

        # Log usage statistics about the Shotgun Desktop executable and the desktop startup.
        sgtk.util.log_user_attribute_metric("tk-framework-desktopstartup",
                                            self.startup_version)
        sgtk.util.log_user_attribute_metric("Shotgun Desktop version",
                                            self.app_version)
        # If a server is passed down from the desktop startup, it means we won't be using the engine-based
        # websocket server.
        sgtk.util.log_user_attribute_metric("Engine-Websockets",
                                            "no" if server else "yes")

        if self.uses_legacy_authentication():
            self._migrate_credentials()

        # We need to initialize current login
        # We know for sure there is a default user, since either the migration was done
        # or we logged in as an actual user with the new installer.
        human_user = ShotgunAuthenticator(
            # We don't want to get the script user, but the human user, so tell the
            # CoreDefaultsManager manager that we are not interested in the script user. Do not use
            # the regular shotgun_authentication.DefaultsManager to get this user because it will
            # not know about proxy information.
            sgtk.util.CoreDefaultsManager(mask_script_user=True
                                          )).get_default_user()
        # Cache the user so we can refresh the credentials before launching a background process
        self._user = human_user
        # Retrieve the current logged in user information. This will be used when creating
        # event log entries.
        self._current_login = self._engine.sgtk.shotgun.find_one(
            "HumanUser", [["login", "is", human_user.login]], ["id", "login"])

        # Initialize Qt app
        from tank.platform.qt import QtGui

        app = QtGui.QApplication.instance()
        if app is None:
            app = QtGui.QApplication(sys.argv)

        # update the app icon
        icon = QtGui.QIcon(":tk-desktop/default_systray_icon")
        app.setWindowIcon(icon)

        if splash:
            splash.set_message("Building UI")

        # setup the global look and feel
        self._engine._initialize_dark_look_and_feel()

        # load custom font
        QtGui.QFontDatabase.addApplicationFont(
            ":/tk-desktop/fonts/OpenSans-Bold.ttf")
        QtGui.QFontDatabase.addApplicationFont(
            ":/tk-desktop/fonts/OpenSans-Regular.ttf")
        QtGui.QFontDatabase.addApplicationFont(
            ":/tk-desktop/fonts/OpenSans-CondLight.ttf")
        QtGui.QFontDatabase.addApplicationFont(
            ":/tk-desktop/fonts/OpenSans-Light.ttf")

        # merge in app specific look and feel
        css_file = os.path.join(self._engine.disk_location, "resources",
                                "desktop_dark.css")
        f = open(css_file)
        css = app.styleSheet() + "\n\n" + f.read()
        f.close()
        app.setStyleSheet(css)

        # If server is passed down to this method, it means we are running an older version of the
        # desktop startup code, which runs its own browser integration.
        #
        # Sadly, we can't tear down the previous server and restart it. Attempting to tear_down() and
        # instantiate a new server will raise an error.ReactorNotRestartable exception. So we'll start
        # our websocket integration only if there is no server running from the desktop startup.
        # Note that the server argument is set regardless of whether the server launched or crashed,
        # so we have to actually get its value instead of merely checking for existence.
        if server is None:
            # Initialize all of this after the style-sheet has been applied so any prompt are also
            # styled after the Shotgun Desktop's visual-style.
            if splash:
                splash.set_message("Initializing browser integration.")
            try:
                desktop_server_framework = sgtk.platform.get_framework(
                    "tk-framework-desktopserver")
                desktop_server_framework.launch_desktop_server(
                    self._user.host, self._current_login["id"], parent=splash)
            except Exception:
                logger.exception(
                    "Unexpected error while trying to launch the browser integration:"
                )
            else:
                logger.debug("Browser integration was launched successfully.")

        # hide the splash if it exists
        if splash is not None:
            splash.hide()

        # desktop_window needs to import shotgun_authentication globally. However, doing so
        # can cause a crash when running Shotgun Desktop installer 1.02 code. We used to
        # not restart Desktop when upgrading the core, which caused the older version of core
        # to be kept in memory and the newer core to not be used until the app was reloaded.
        #
        # Since pre 0.16 cores didn't have a shotgun_authentication module, we
        # would have crashed if this had been imported at init time. Note that earlier
        # in this method we forcefully restarted the application if we noticed
        # that the core was upgraded without restarting. Which means that if we
        # end up here, it's now because we're in a good state.
        from . import desktop_window

        # initialize System Tray
        self.desktop_window = desktop_window.DesktopWindow()

        # We need for the dialog to exist for messages to get to the UI console.
        if kwargs.get("server") is not None:
            logger.warning(
                "You are running an older version of the Shotgun Desktop which is not fully compatible "
                "with the Shotgun Integrations. Please install the latest version."
            )

        # run the commands that are configured to be executed at startup
        self._run_startup_commands()

        # make sure we close down our rpc threads
        app.aboutToQuit.connect(self._engine.destroy_engine)

        # and run the app
        result = app.exec_()
        return result
Beispiel #3
0
    def _set_authenticated_user(self, bootstrap_user, bootstrap_user_login,
                                serialized_user):
        """
        Sets the authenticated user.

        If the project that is being bootstrapped into is configured to use a script user inside
        shotgun.yml, the passed in user will be ignored.

        If the new core API can't deserialize the user, the error will be logged and passed in
        user will be used instead.

        :param user: User that was used for bootstrapping.
        :param bootstrap_user_login: Login of the user.
        :param serialized_user: Serialized version of the user.

        :returns: If authentication is supported, a :class:`ShotgunUser` will be returned. Otherwise
            ``None``.
        """
        # perform a local import here to make sure we are getting
        # the newly swapped in core code

        # It's possible we're bootstrapping into a core that doesn't support the authentication
        # module, so try to import.
        try:
            # Use backwards compatible imports.
            from tank_vendor.shotgun_authentication import ShotgunAuthenticator, deserialize_user
            from ..util import CoreDefaultsManager
        except ImportError:
            log.debug(
                "Using pre-0.16 core, no authenticated user will be set.")
            return None

        from .. import api

        log.debug("The project's core supports the authentication module.")

        # By default, we'll assume we couldn't find a user with the authenticator.
        project_user = None

        try:
            # Try to deserialize the bootstrap user.
            project_user = deserialize_user(serialized_user)
        except Exception:
            log.exception(
                "Couldn't deserialize the user object with the new core API. "
                "Current user will be used.")
            log.error(
                "Startup will continue, but you should look into what caused this issue and fix it. "
                "Please contact %s to troubleshoot this issue.",
                constants.SUPPORT_EMAIL)
            project_user = bootstrap_user

        # If we couldn't find a relevant user with the project's authentication module...
        if not project_user:

            # Retrieve the user associated with the current project.
            default_user = ShotgunAuthenticator(
                CoreDefaultsManager()).get_default_user()

            # If the project core's authentication code found a user...
            # (Note that in the following code, a user with no login is a script user.)
            if default_user:
                # If the project uses a script user, we'll use that.
                if not default_user.login:
                    log.debug(
                        "User retrieved for the project is a script user.")
                    project_user = default_user
                # If the project didn't use a script, but the bootstrap did, we'll keep using it.
                elif not bootstrap_user_login:
                    # We'll keep using the bootstrap user. This is because configurations like tk-
                    # config-basic or tk-config-default are meant to be used with whatever credentials
                    # were used during bootstrapping when used with a CachedDescriptor. The bootstrap
                    # user is a script user and the project's user is not a script user, so we'll keep
                    # using the script user.

                    # If the host server is different in the project, for example someone might have set
                    # up a server to answer queries for the webapp and another to answer API requests,
                    # it means that we'll not be using the correct server with the project. This seems
                    # to be an edge-case and more likely a misconfiguration error, so we'll keep the
                    # code simple. We're logging the user being used at the end of this method, so it
                    # will be clear during support what actually happened.
                    log.debug(
                        "User retrieved for the project is not a script, but bootstrap was. Using the "
                        "bootsraps's user.")
                elif default_user.login == bootstrap_user_login:
                    # In theory, the login should be the same, but they might not be. This is because
                    # when core swapping between a more recent version of core to an older one,
                    # there might be new ways to retrieve credentials that the older core's
                    # ShotgunAuthenticator might not be aware of.
                    #
                    # This also handle the case where a local install has a server dedicated to the webapp
                    # traffic and another for API traffic.
                    log.debug(
                        "User retrieved for the project (%r) is the same as for the bootstrap.",
                        default_user)
                    project_user = default_user
                else:
                    # At this point, different human users are returned by the two cores. We will log
                    # a warning.
                    log.warning(
                        "It appears the user '%s' used for bootstrap is different than the one for the "
                        "project '%s'. Toolkit will use the user from the bootstrap for coherence.",
                        bootstrap_user_login, default_user.login)
                    pass
            else:
                log.debug(
                    "No user associated with the project was found. Falling back on the bootstrap user."
                )

        # Dump all authentication information.
        log.debug("Authenticated host: %s.", project_user.host)
        log.debug("Authenticated login: %s.", project_user.login)
        log.debug("Authenticated http proxy: %s.", project_user.http_proxy)

        api.set_authenticated_user(project_user)
        return project_user