Isotropix Forums

Clarisse and ftrack

Clarisse Scripting related topics

Clarisse and ftrack

Unread postby jandersunstar » Mon Feb 18, 2019 7:05 pm

I want to share a basic script I did and another I modify in order to connect ftrack with Clarisse.

First you need to install the ftrack python api script from here:
http://ftrack-python-api.rtd.ftrack.com ... installing

Then you need to create this script and put it into the ftrack plugin folder:
ftrack_plugin_folder.png
open your plugin floder
ftrack_plugin_folder.png (17.14 KiB) Viewed 2696 times

C:\Users\sunst\AppData\Local\ftrack\ftrack-connect-plugins\clarisse_hook\hook\example_clarisse_hook.py

Code: Select all
# :coding: utf-8
# :copyright: Copyright (c) 2015 ftrack

import getpass
import logging
import sys
import pprint
import re
import os

import ftrack_api
import ftrack_connect.application


class LaunchApplicationAction(object):
    '''Launch Clarisse action.'''

    # Unique action identifier.
    identifier = 'my-clarisse-launch-action'

    def __init__(self, applicationStore, launcher, session):
        '''Initialise action with *applicationStore* and *launcher*.

        *applicationStore* should be an instance of
        :class:`ftrack_connect.application.ApplicationStore`.

        *launcher* should be an instance of
        :class:`ftrack_connect.application.ApplicationLauncher`.

        '''
        super(LaunchApplicationAction, self).__init__()

        self.logger = logging.getLogger(
            __name__ + '.' + self.__class__.__name__
        )

        self.applicationStore = applicationStore
        self.launcher = launcher
        self.session = session

        if self.identifier is None:
            raise ValueError('The action must be given an identifier.')

    def is_valid_selection(self, selection):
        '''Return true if the selection is valid.'''
        if (
            len(selection) != 1 or
            selection[0]['entityType'] != 'task'
        ):
            return False

        entity = selection[0]

        task = self.session.get(
            'Task', entity['entityId']
        )


        if task is None:
            return False

        return True

    def register(self, session):
        '''Register action to respond to discover and launch events.'''
        session.event_hub.subscribe(
            'topic=ftrack.action.discover',
            self.discover
        )

        session.event_hub.subscribe(
            'topic=ftrack.action.launch and data.actionIdentifier={0}'.format(
                self.identifier
            ),
            self.launch
        )

    def discover(self, event):
        '''Return available actions based on *event*.

        Each action should contain

            actionIdentifier - Unique identifier for the action
            label - Nice name to display in ftrack
            variant - Variant or version of the application.
            icon(optional) - predefined icon or URL to an image
            applicationIdentifier - Unique identifier to identify application
                                    in store.

        '''

        if not self.is_valid_selection(
            event['data'].get('selection', [])
        ):
            return

        items = []
        applications = self.applicationStore.applications
        applications = sorted(
            applications, key=lambda application: application['label']
        )

        for application in applications:
            applicationIdentifier = application['identifier']
            label = application['label']
            items.append({
                'actionIdentifier': self.identifier,
                'label': label,
                'variant': application.get('variant', None),
                'description': application.get('description', None),
                'icon': application.get('icon', 'default'),
                'applicationIdentifier': applicationIdentifier
            })

        return {
            'items': items
        }

    def launch(self, event):
        '''Callback method for Clarisse action.'''


        if not self.is_valid_selection(
            event['data'].get('selection', [])
        ):
            return

        applicationIdentifier = (
            event['data']['applicationIdentifier']
        )

        context = event['data'].copy()

        return self.launcher.launch(
            applicationIdentifier, context
        )


class ApplicationStore(ftrack_connect.application.ApplicationStore):
    '''Store used to find and keep track of available applications.'''

    def _discoverApplications(self):
        '''Return a list of applications that can be launched from this host.
        '''
        applications = []

        if sys.platform == 'darwin':
            prefix = ['/', 'Applications']

            applications.extend(self._searchFilesystem(
                expression=prefix + [
                    'Clarisse*', 'Clarisee.app'
                ],
                label='Clarisse',
                variant='{version}',
                applicationIdentifier='clarisse_{version}'
            ))

        elif sys.platform == 'win32':
            prefix = ['C:\\', 'Program Files.*']

            applications.extend(self._searchFilesystem(
                expression=(
                    prefix +
                    # ['Isotropix', 'Clarisse iFX 3.6 SP3*', 'Clarisse', 'clarisse.exe']
                    ['Isotropix', 'Clarisse iFX*', 'Clarisse', 'clarisse.exe']
                ),
                label='Clarisse',
                variant='{version}',
                applicationIdentifier='clarisse_{version}'
            ))

        self.logger.debug(
            'Discovered applications:\n{0}'.format(
                pprint.pformat(applications)
            )
        )

        return applications


class ApplicationLauncher(ftrack_connect.application.ApplicationLauncher):
    '''Custom launcher to modify environment before launch.'''

    def __init__(self, applicationStore, session):
        '''.'''
        super(ApplicationLauncher, self).__init__(applicationStore)

        self.session = session

    def _getApplicationEnvironment(
        self, application, context=None
    ):
        '''Override to modify environment before launch.'''

        # Make sure to call super to retrieve original environment
        # which contains the selection and ftrack API.
        environment = super(
            ApplicationLauncher, self
        )._getApplicationEnvironment(application, context)

        # Append or Prepend values to the environment.
        # Note that if you assign manually you will overwrite any
        # existing values on that variable.

        entity = context['selection'][0]

        task = self.session.get(
            'Task', entity['entityId']
        )

        taskParent = task.get(
            'parent'
        )

        try:
            environment['FS'] = str(
                int(taskParent['custom_attributes'].get('fstart'))
            )

        except Exception:
            environment['FS'] = '1'

        try:
            environment['FE'] = str(
                int(taskParent['custom_attributes'].get('fend'))
            )

        except Exception:
            environment['FE'] = '1'

        environment['FTRACK_TASKID'] = task.get('id')
        environment['FTRACK_SHOTID'] = task.get('parent_id')


        # Add my custom path to the HOUDINI_SCRIPT_PATH.


        # Always return the environment at the end.
        return environment


def register(session, **kw):
    '''Register hooks.'''

    # Validate that session is an instance of ftrack_api.Session. If not, assume
    # that register is being called from an old or incompatible API and return
    # without doing anything.
    if not isinstance(session, ftrack_api.Session):
        return

    # Create store containing applications.
    applicationStore = ApplicationStore()

    # Create a launcher with the store containing applications.
    launcher = ApplicationLauncher(
        applicationStore,
        session=session
    )

    # Create action and register to respond to discover and launch actions.
    action = LaunchApplicationAction(applicationStore, launcher, session)
    action.register(session)


action.gif

The previous script will make Clarisse available on your ftrack Actions section. Only under a task.
Note: The script is similar at the one it comes as an example for connecting with Houdini.

Once you launch Clarisse using actions you will need to run the following script in order to get the frame range and resolution of the shot.

Code: Select all
import sys

import PySide
from PySide.QtGui import QApplication
from PySide.QtGui import QMessageBox


import ftrack_api
import os
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
app = None

session = ftrack_api.Session(
    server_url='https://XXX.ftrackapp.com',
    api_user='XXXX',
    api_key='XXXXX-XXXX-XXXX-XXXX-XXXXXXX',
    auto_connect_event_hub=False)

# print session.types.items()
# users = session.types['User']
# print users
# print user.keys()

taskid = os.environ['FTRACK_TASKID']
shotid = os.environ['FTRACK_SHOTID']

fstart = os.environ['FS']
fend = os.environ['FE']

tasks = session.query(
    'Task where id is {}'.format(taskid)
)
print "INFO:"
print "\nTasks:"
for task in tasks:
    print task['name']

shots = session.query(
    'Shot where id is {}'.format(shotid)
)

# test = session.query('Shot')
try:
    projectName = shots[0]['_link'][0]['name']
except Exception:
    projectName = "Assets"
   
try:
    projectId = shots[0]['_link'][0]['id']
except Exception:
    projectId = '0'
   
print 'project: ' + projectName + ' project ID: ' + projectId

query = session.query(
    'Project where id is {}'.format(projectId)
)
metadata = query[0]['metadata']
resolution = metadata['resolution']
resolution = resolution.split()
resolution_x = resolution[0]
resolution_y = resolution[1]
print resolution_y


print "\nShot:"
for shot in shots:
    print shot['name']

print 'Frame Start: ' + fstart
print 'Frame End: ' + fend

# print shot['custom_attributes'].items()
fps = shot['custom_attributes']['fps']
print 'Fps: ' + str(fps)

fstart = int(fstart)
fend = int(fend)
fps = float(fps)

ix.cmds.SetFps(fps)
ix.cmds.SetCurrentFrameRange(fstart, fend)
ix.cmds.SetValues(["project://scene/image.resolution[0]"], [str(resolution_x)])
ix.cmds.SetValues(["project://scene/image.resolution[1]"], [str(resolution_y)])
ix.cmds.SetValues(["project://scene/image.resolution_multiplier"], ["1"])




# Create the application object
app = None
if not QApplication.instance(): #QtApplication doesn't exist
    app = QApplication(sys.argv)
else:
    app = QApplication.instance()
 
# Create a simple dialog box
msgBox = QMessageBox()
msgBox.setText("Project " + projectName)
msgBox.exec_()


exampleRunningScript.gif

The previous script is still in work in progress, I am just sharing it just in case anyone wants to start making some changes and do a better job.

You can find more info on how to do ftrack queries:
http://ftrack-python-api.rtd.ftrack.com ... rying.html

Cheers!

-Luis
Last edited by jandersunstar on Wed Feb 20, 2019 3:58 pm, edited 1 time in total.
User avatar
jandersunstar
 
Posts: 302
Joined: Fri Jun 06, 2014 8:21 pm
Location: Mexico City

Re: Clarisse and ftrack

Unread postby desmond » Tue Feb 19, 2019 8:34 am

Thanks for sharing Luis!
User avatar
desmond
 
Posts: 59
Joined: Mon Feb 05, 2018 8:46 am

Re: Clarisse and ftrack

Unread postby dboude » Tue Feb 19, 2019 9:37 am

Yes, Thanks for sharing !
Démian
Isotropix
Technical Artist - Clarisse Specialist
User avatar
dboude
 
Posts: 1481
Joined: Mon Jul 03, 2017 10:51 am

Re: Clarisse and ftrack

Unread postby pipelinesolutions » Wed Feb 20, 2019 5:35 pm

hi @jandersunstar,
It's great to see interest (and code!) on integrating ftrack and clarisse !

If you feel like, you can have a look how to package the hook and the rest of the code as plugin here:
https://bitbucket.org/ftrack/ftrack-con ... r/setup.py

It would be great if you could share the code somewhere in bitbucket (ftrack-connect-clarisse ? )so we try to help improving it.
If I can be of any help with it or if you just have questions, please ping me at support@ftrack.com anytime !

Cheers!
Lorenzo Angeli.
pipelinesolutions
 
Posts: 2
Joined: Wed Feb 20, 2019 5:24 pm

Re: Clarisse and ftrack

Unread postby desmond » Sat Feb 23, 2019 5:08 pm

Hi all and ftrack guys @pipelinesolutions,
ive uplodaed Luis stuff to bitbucket as you asked, so you can contribute here : https://bitbucket.org/desmondd/ftrack-connect-clarisse/
thanks to luis and Ftrack guys
User avatar
desmond
 
Posts: 59
Joined: Mon Feb 05, 2018 8:46 am

Re: Clarisse and ftrack

Unread postby pipelinesolutions » Tue Feb 11, 2020 4:32 pm

That's great ! Thanks for sharing!
pipelinesolutions
 
Posts: 2
Joined: Wed Feb 20, 2019 5:24 pm


Return to Scripting
cron