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