# :copyright: Copyright (c) 2015 ftrack
+from ftrack_action_handler.action import BaseAction
-class NoteOnMultipleEntitiesAction(ftrack.Action):
+class NoteOnMultipleEntitiesAction(BaseAction):
'''Action to write note on multiple entities.'''
- def createNotes(self, selection, text, category):
- entityCount = len(selection)
- logging.info('Creating notes on {0} entities'.format(entityCount))
+ def create_notes(self, entities, text, category_id, source):
+ '''Create notes on *entities*.'''
- job = ftrack.createJob(
- 'Creating notes ({0} of {1})'.format(1, entityCount), 'running'
+ # Create new session as sessions are not garantueed to be thread-safe.
+ session = ftrack_api.Session(
+ auto_connect_event_hub=False, plugin_paths=[]
+ category = session.get('NoteCategory', category_id)
+ 'User where username is "{0}"'.format(source['user']['username'])
+ logging.info('Creating notes on {0} entities'.format(len(entities)))
+ job = session.create('Job', {
+ 'description': 'Creating notes on {0} entities'.format(
- for index, item in enumerate(selection, start=1):
- entityType = item['entityType']
- entityId = item['entityId']
- job.setDescription('Creating notes ({0} of {1})'.format(index, entityCount))
- if entityType == 'show':
- entity = ftrack.Project(entityId)
- elif entityType == 'task':
- entity = ftrack.Task(entityId)
- elif entityType == 'assetversion':
- entity = ftrack.AssetVersion(entityId)
- u'Entity ({0}, {1}) not a valid type, skipping..'
- .format(entityId, entityType)
- entity.createNote(text, category)
+ for entity_type, entity_id in entities:
+ entity = session.get(entity_type, entity_id)
+ text, user, category=category
+ entity.create_note(text, user)
- job.setStatus('failed')
+ job['status'] = 'failed'
- logging.info('Note creation completed.')
- def launch(self, event):
+ def discover(self, session, entities, event):
+ '''Return true if the action is discoverable.
+ Action is discoverable if all entities have a notes relationship and
+ at least one entity is selected.
+ entity_type in session.types and
+ 'notes' in session.types[entity_type].attributes.keys()
+ for entity_type, entity_id in entities
+ def launch(self, session, entities, event):
'''Callback method for action.'''
+ u'Launching action with selection {0}'.format(entities)
logging.info(u'Launching action with data: {0}'.format(data))
- selection = data.get('selection', [])
- return {'success': False}
text = data['values'].get('note_text')
- category = data['values'].get('note_category', 'auto')
- self.createNotes(selection, text, category)
- 'message': 'Started creating notes'
+ category_id = data['values'].get('note_category')
+ self.create_notes(entities, text, category_id, event['source'])
- {'label': category.getName(), 'value': category.getId()}
- for category in ftrack.getNoteCategories()
- options.insert(0, {'label': 'Default', 'value': 'auto'})
+ 'message': 'Started creating notes'
+ def interface(self, session, entities, event):
+ '''Return interface.'''
+ values = event['data'].get('values', {})
+ {'label': category['name'], 'value': category['id']}
+ for category in session.query(
+ 'select name, id from NoteCategory'
+ options.insert(0, {'label': 'Default', 'value': 'auto'})
- 'value': '## Writing note on **{0}** items. ##'.format(len(selection)),
+ 'value': '## Writing note on **{0}** items. ##'.format(
-def register(registry, **kw):
- '''Register action. Called when used as an event plugin.'''
- logger = logging.getLogger(
- 'note-on-multiple-entities'
- # Validate that registry is an instance of ftrack.Registry. If not,
- # assume that register is being called from a new or incompatible API and
+def register(session, **kw):
+ '''Register plugin. Called when used as an plugin.'''
+ # 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(registry, ftrack.Registry):
- 'Not subscribing plugin as passed argument {0!r} is not an '
- 'ftrack.Registry instance.'.format(registry)
+ if not isinstance(session, ftrack_api.session.Session):
- action = NoteOnMultipleEntitiesAction()
+ action_handler = NoteOnMultipleEntitiesAction(session)
+ action_handler.register()
def main(arguments=None):
namespace = parser.parse_args(arguments)
+ # Set up basic logging.
logging.basicConfig(level=loggingLevels[namespace.verbosity])
- action = NoteOnMultipleEntitiesAction()
+ session = ftrack_api.Session()
- ftrack.EVENT_HUB.wait()
+ 'Registered actions and listening for events. Use Ctrl-C to abort.'
+ session.event_hub.wait()
if __name__ == '__main__':