Developing

Creating a new launcher

In order to be able to find and manage applications and integrations, an application launcher has to be provided.

Launchers requires to be either configured or written from scratch using the base libraries included in this module.

The configuration mode is suggested for all the base cases, where the code base approach is suggested in case of special application launch behaviours.

Attributes

Note

For simplicity we’ll be taking the config arguments as example as are easier to read.

Let’s have a look at the common attributes you’ll find in both, split by mandatory and optional attributes.

Mandatory attributes

context:

Provide a list to fill up with named contexts. The launcher will appear only when one of the given contexts is selected.

Note

context can contain one or more entity type name such as “Project”, “Task”, etc… None in code or null in config, will allow to discover the application without any context selected.

identifier:

Defines a unique string identifier for this launcher.

applicationIdentifier:

Defines a unique string identifier for the application to be launch, this also need to contain the potential variant available, so can be uniquely identified.

Note

applicationIdentifier should always include the {variant} variable.

label:

A descriptive label to identify the application.

icon:

An icon to represent the application to launch.

Note

Icon can be either one of the application name mapped or a full url path to a given icon.

variant:

Defines the variant of the application to be launched.

Note

variant should always include the {version} variable.

search_path:

Provide an entry point for each operating system to define where from the application will searched.

Note

The valid operating system are:

  • linux

  • windows

  • darwin

Each operating system will require to define :

prefix

Provide the root search path for all the versions of the given application.

eg:

"prefix":["C:\\", "Program Files.*"],

expression

Provide a regular expression used to extract the versions available for the given application.

eg:

"expression":["Something.*", "Something\\d.+.exe"],

and optionally :

version_expression

Defines a regular expression used to extract the version from the found application paths.

eg:

"version_expression": "Something(?P<version>.*)\\/.+$",

launch_arguments

Allows to specify specific arguments to be passed when the application gets launched.

eg:

"launch_arguments": ["--arguments"]

Optional attributes

priority (optional):

Define the priority on which this event will be discovered.

Note

Negative priorities are higher than positive ones.

integrations (optional):

Provide a way to collect integrations into named groups. If any of the integration requested is not discovered, the application itself won’t be discovered.

eg:

"integrations": {
    "example":["ftrack-example-integration"]
},

Comparing launchers

Below we’ll be looking at the same launch application expressed in configuration and code.

Configuration based launcher

Note

Configuration launchers are based on json language.

{
    "priority": 1000,
    "context": ["Task", "Project"],
    "identifier": "ftrack-connect-launch-application",
    "applicationIdentifier":"an-application_{variant}",
    "label": "An Application",
    "icon": "an_application",
    "variant": "{version}",
    "integrations": {
        "example":["ftrack-example-integration"]
    },
    "search_path":{
        "linux": {
            "prefix":["/", "usr","local","Something.*"],
            "expression":["Something\\d.+"],
            "version_expression": "Something(?P<version>.*)\\/.+$",
            "launch_arguments": ["--arguments"]
        },
        "windows": {
            "prefix":["C:\\", "Program Files.*"],
            "expression":["Something.*", "Something\\d.+.exe"],
            "version_expression": "(?P<version>[\\d.]+[vabc]+[\\dvabc.]*)",
            "launch_arguments": ["--arguments"]
        },
        "darwin": {
            "prefix":["/", "Applications"],
            "expression": ["Something.*", "Something\\d[\\w.]+.app"]
        }
    }
 }

Code based launcher

Note

Code launchers are based on python 3.7 language.



'''

Import base modules and ensure the dependencies are available in the path.

'''

import sys
import os

cwd = os.path.dirname(__file__)

sources = os.path.abspath(os.path.join(cwd, '..', 'dependencies'))

sys.path.append(sources)


import ftrack_api
import ftrack_application_launcher



'''

Create launch action, to limit the context to be discovered.

'''



class LaunchAction(ftrack_application_launcher.ApplicationLaunchAction):
    context = [None, 'Task', 'Project']
    identifier = 'ftrack-connect-launch-application'
    label = 'An Application'


'''

Create application store, to let the system find the application 
versions for the various operating systems.

'''


class ApplicationStore(ftrack_application_launcher.ApplicationStore):

    def _discover_applications(self):
        applications = []

        if self.current_os == 'darwin':
            prefix = ['/', 'Applications']

            applications.extend(self._search_filesystem(
                expression=prefix + ['Something.*', 'Something\\d[\\w.]+.app'],
                label='An Application',
                variant='{version}',
                applicationIdentifier='an-application_{variant}',
                icon='an_application',
                integrations={'example': ['ftrack-example-integration']},
                launchArguments=["--arguments"],

            ))

        if self.current_os == 'windows':
            prefix = ['C:\\', 'Program Files.*']

            applications.extend(self._search_filesystem(
                expression=prefix + ["Something.*", "Something\\d.+.exe"],
                label='An Application',
                variant='{version}',
                applicationIdentifier='an-application_{variant}',
                versionExpression="(?P<version>[\\d.]+[vabc]+[\\dvabc.]*)",
                icon='an_application',
                integrations={'example': ['ftrack-example-integration']},
                launchArguments=["--arguments"],
            ))

        if self.current_os == 'linux':
            prefix = ["/", "usr", "local", "Something.*"]

            applications.extend(self._search_filesystem(
                expression=prefix +["Something.*", "Something\\d.+.exe"],
                label='An Application',
                variant='{version}',
                applicationIdentifier='an-application_{variant}',
                versionExpression="(?P<version>[\\d.]+[vabc]+[\\dvabc.]*)",
                icon='an_application',
                integrations={'example': ['ftrack-example-integration']},
                launchArguments=["--arguments"],
            ))

        return applications


'''

Create application launcher, to let use the default launch action mechanism.

'''

class ApplicationLauncher(ftrack_application_launcher.ApplicationLauncher):
    '''

    This class is usually customised to provide a special launch mechanisms,
    this could involve opening a url or something completely different different.

    def launch(self, applicationIdentifier, context=None):
        [....]

        return {
            'success': success,
            'message': message
        }

    '''


'''
Register the new application launcher.
'''


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

    if not isinstance(session, ftrack_api.session.Session):
        return

    application_store = ApplicationStore(session)

    launcher = ApplicationLauncher(application_store)

    # Create action and register to respond to discover and launch events.
    action = LaunchAction(session, application_store, launcher, priority=1000)
    action.register()

Customising configuration path

If you want to provide alternative configurations for the application launchers, it is possible to override the search path setting the following environment variable to a set of new folder search path.

FTRACK_APPLICATION_LAUNCHER_CONFIG_PATHS