From 9ca3d616131749b25896478e00e4434ff6296e32 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 26 Oct 2018 12:19:37 +0200 Subject: [PATCH] Action register to user that match session.api_user --- pype/ftrack/actions/action_Apps.py | 13 +- pype/ftrack/actions/action_syncToAvalon.py | 7 +- .../actions/connect_discoverApplications.py | 169 ------------------ .../vendor/ftrack_action_handler/appaction.py | 67 ++++--- 4 files changed, 55 insertions(+), 201 deletions(-) delete mode 100644 pype/ftrack/actions/connect_discoverApplications.py diff --git a/pype/ftrack/actions/action_Apps.py b/pype/ftrack/actions/action_Apps.py index 8efef6434a..70461d6ac7 100644 --- a/pype/ftrack/actions/action_Apps.py +++ b/pype/ftrack/actions/action_Apps.py @@ -1,8 +1,9 @@ import os import logging +import toml import ftrack_api from ftrack_action_handler.appaction import AppAction -from avalon import io +from avalon import io, lib os.environ['AVALON_PROJECTS'] = 'tmp' @@ -20,6 +21,8 @@ s = ftrack_api.Session( def register(session): apps=[] actions = [] + icon = None + for project in projects: os.environ['AVALON_PROJECT'] = project['name'] for app in project['config']['apps']: @@ -27,8 +30,14 @@ def register(session): apps.append(app) for app in apps: - AppAction(session, app['label'], app['name']).register() + if 'nuke' in app['name']: + icon = "https://mbtskoudsalg.com/images/nuke-icon-png-2.png" + elif 'maya' in app['name']: + icon = "http://icons.iconarchive.com/icons/froyoshark/enkel/256/Maya-icon.png" + else: + icon = None + AppAction(session, app['label'], app['name'], icon).register() session.event_hub.wait() diff --git a/pype/ftrack/actions/action_syncToAvalon.py b/pype/ftrack/actions/action_syncToAvalon.py index b027a0f4be..8b9061045e 100644 --- a/pype/ftrack/actions/action_syncToAvalon.py +++ b/pype/ftrack/actions/action_syncToAvalon.py @@ -65,6 +65,7 @@ class SyncToAvalon(BaseAction): # set AVALON_PROJECT env os.environ["AVALON_PROJECT"] = entityProj["full_name"] + os.environ["AVALON_ASSET"] = entityProj['full_name'] # Get apps from Ftrack / TODO Exceptions?!!! apps = [] @@ -87,8 +88,6 @@ class SyncToAvalon(BaseAction): template = {"schema": "avalon-core:inventory-1.0"} # --- Create project and assets in Avalon --- - os.environ['AVALON_ASSET'] = entityProj['full_name'] - io.install() # If project don't exists -> ELSE if (io.find_one( @@ -98,6 +97,10 @@ class SyncToAvalon(BaseAction): io.update_many({'type': 'project','name': entityProj['full_name']}, {'$set':{'config':config}}) + # Store info about project (FtrackId) + io.update_many({'type': 'project','name': entityProj['full_name']}, + {'$set':{'data':{'ftrackId':entityProj['id'],'entityType':entityProj.entity_type}}}) + # Store project Id projectId = io.find_one({"type": "project", "name": entityProj["full_name"]})["_id"] if custAttrName in entityProj['custom_attributes'] and entityProj['custom_attributes'][custAttrName] is '': diff --git a/pype/ftrack/actions/connect_discoverApplications.py b/pype/ftrack/actions/connect_discoverApplications.py deleted file mode 100644 index 190467ef5e..0000000000 --- a/pype/ftrack/actions/connect_discoverApplications.py +++ /dev/null @@ -1,169 +0,0 @@ -def _discoverApplications(self): - '''Return a list of applications that can be launched from this host. - - An application should be of the form: - - dict( - 'identifier': 'name_version', - 'label': 'Name', - 'variant': 'version', - 'description': 'description', - 'path': 'Absolute path to the file', - 'version': 'Version of the application', - 'icon': 'URL or name of predefined icon' - ) - - ''' - applications = [] - - if sys.platform == 'darwin': - prefix = ['/', 'Applications'] - - elif sys.platform == 'win32': - prefix = ['C:\\', 'Program Files.*'] - - self.logger.debug( - 'Discovered applications:\n{0}'.format( - pprint.pformat(applications) - ) - ) - - return applications - -class ApplicationLauncher(object): - '''Launch applications described by an application store. - - Launched applications are started detached so exiting current process will - not close launched applications. - - ''' - - def __init__(self, applicationStore): - '''Instantiate launcher with *applicationStore* of applications. - - *applicationStore* should be an instance of :class:`ApplicationStore` - holding information about applications that can be launched. - - ''' - super(ApplicationLauncher, self).__init__() - self.logger = logging.getLogger( - __name__ + '.' + self.__class__.__name__ - ) - - self.applicationStore = applicationStore - - def launch(self, applicationIdentifier, context=None): - '''Launch application matching *applicationIdentifier*. - - *context* should provide information that can guide how to launch the - application. - - Return a dictionary of information containing: - - success - A boolean value indicating whether application launched - successfully or not. - message - Any additional information (such as a failure message). - - ''' - # Look up application. - applicationIdentifierPattern = applicationIdentifier - if applicationIdentifierPattern == 'hieroplayer': - applicationIdentifierPattern += '*' - - application = self.applicationStore.getApplication( - applicationIdentifierPattern - ) - - if application is None: - return { - 'success': False, - 'message': ( - '{0} application not found.' - .format(applicationIdentifier) - ) - } - - # Construct command and environment. - command = self._getApplicationLaunchCommand(application, context) - environment = self._getApplicationEnvironment(application, context) - - # Environment must contain only strings. - self._conformEnvironment(environment) - - success = True - message = '{0} application started.'.format(application['label']) - - try: - options = dict( - env=environment, - close_fds=True - ) - - # Ensure that current working directory is set to the root of the - # application being launched to avoid issues with applications - # locating shared libraries etc. - applicationRootPath = os.path.dirname(application['path']) - options['cwd'] = applicationRootPath - - # Ensure subprocess is detached so closing connect will not also - # close launched applications. - if sys.platform == 'win32': - options['creationflags'] = subprocess.CREATE_NEW_CONSOLE - else: - options['preexec_fn'] = os.setsid - - launchData = dict( - command=command, - options=options, - application=application, - context=context - ) - ftrack.EVENT_HUB.publish( - ftrack.Event( - topic='ftrack.connect.application.launch', - data=launchData - ), - synchronous=True - ) - ftrack_connect.session.get_shared_session().event_hub.publish( - ftrack_api.event.base.Event( - topic='ftrack.connect.application.launch', - data=launchData - ), - synchronous=True - ) - - # Reset variables passed through the hook since they might - # have been replaced by a handler. - command = launchData['command'] - options = launchData['options'] - application = launchData['application'] - context = launchData['context'] - - self.logger.debug( - 'Launching {0} with options {1}'.format(command, options) - ) - process = subprocess.Popen(command, **options) - - except (OSError, TypeError): - self.logger.exception( - '{0} application could not be started with command "{1}".' - .format(applicationIdentifier, command) - ) - - success = False - message = '{0} application could not be started.'.format( - application['label'] - ) - - else: - self.logger.debug( - '{0} application started. (pid={1})'.format( - applicationIdentifier, process.pid - ) - ) - - return { - 'success': success, - 'message': message - } diff --git a/pype/vendor/ftrack_action_handler/appaction.py b/pype/vendor/ftrack_action_handler/appaction.py index 60cfe8f557..a1c19c1f3c 100644 --- a/pype/vendor/ftrack_action_handler/appaction.py +++ b/pype/vendor/ftrack_action_handler/appaction.py @@ -33,9 +33,9 @@ class AppAction(object): self._session = session self.label = label self.identifier = name - self.icon = None - self.variant = None - self.description = None + self.icon = icon + self.variant = variant + self.description = description @property @@ -46,13 +46,10 @@ class AppAction(object): def register(self): '''Registers the action, subscribing the the discover and launch topics.''' self.session.event_hub.subscribe( - 'topic=ftrack.action.discover', self._discover + 'topic=ftrack.action.discover and source.user.username={0}'.format( + self.session.api_user + ), self._discover ) - # self.session.event_hub.subscribe( - # 'topic=ftrack.action.discover and source.user.username={0}'.format( - # getpass.getuser() - # ), self._discover - # ) self.session.event_hub.subscribe( 'topic=ftrack.action.launch and data.actionIdentifier={0}'.format( @@ -96,8 +93,6 @@ class AppAction(object): *event* the unmodified original event ''' - if len(entities) > 1: - return False entity_type, entity_id = entities[0] entity = session.get(entity_type, entity_id) @@ -106,18 +101,27 @@ class AppAction(object): # if entity.entity_type != 'Task': # return False - ft_project = entity['project'] + # TODO Should return False if more than one entity is selected ?!!! + # if len(entities) > 1: + # return False + + + ft_project = entity['project'] if (entity.entity_type != 'Project') else entity os.environ['AVALON_PROJECT'] = ft_project['full_name'] io.install() project = io.find_one({"type": "project", "name": ft_project['full_name']}) io.uninstall() - apps = [] - for app in project['config']['apps']: - apps.append(app['name']) - if self.identifier not in apps: + if project is None: return False + else: + apps = [] + for app in project['config']['apps']: + apps.append(app['name']) + + if self.identifier not in apps: + return False return True @@ -202,28 +206,35 @@ class AppAction(object): ''' # TODO Delete this line - print("Action < {0} ({1}) > just started".format(self.label, self.identifier)) + print("Action - {0} ({1}) - just started".format(self.label, self.identifier)) # Get path to execute st_temp_path = os.environ['PYPE_STUDIO_TEMPLATES'] os_plat = platform.system().lower() - # Path to folder with .bat + # Path to folder with launchers path = os.path.join(st_temp_path, 'bin', os_plat) - file = self.identifier + # Full path to executable launcher + execfile = None - ''' NEED TO ADD FILE NAMES FOR OTHER SYSTEMS ''' - if os_plat == 'windows': - file += ".bat" + for ext in os.environ["PATHEXT"].split(os.pathsep): + fpath = os.path.join(path.strip('"'), self.identifier + ext) + if os.path.isfile(fpath) and os.access(fpath, os.X_OK): + execfile = fpath + break - abspath = os.path.join(path.strip('"'), file) - - if os.path.isfile(abspath) and os.access(abspath, os.X_OK): - os.startfile(abspath) + if execfile is not None: + os.startfile(execfile) else: - return False + return { + 'success': False, + 'message': "We didn't found launcher for {0}".format(self.label) + } - return True + return { + 'success': True, + 'message': "Launching {0}".format(self.label) + } def _interface(self, *args): interface = self.interface(*args)