+# :copyright: Copyright (c) 2015 ftrack
+ '''Run *fn* asynchronously.'''
+ def wrapper(*args, **kwargs):
+ thread = threading.Thread(target=fn, args=args, kwargs=kwargs)
+class NoteOnMultipleEntitiesAction(ftrack.Action):
+ '''Action to write note on multiple entities.'''
+ identifier = 'note-on-multiple-entities'
+ def createNotes(self, selection, text, category):
+ entityCount = len(selection)
+ logging.info('Creating notes on {0} entities'.format(entityCount))
+ job = ftrack.createJob(
+ 'Creating notes ({0} of {1})'.format(1, entityCount), 'running'
+ 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 == ftrack.Project._type:
+ entity = ftrack.Project(entityId)
+ elif entityType == ftrack.Task._type:
+ entity = ftrack.Task(entityId)
+ elif entityType == ftrack.AssetVersion._type:
+ entity = ftrack.AssetVersion(entityId)
+ u'Entity ({0}, {1}) not a valid type, skipping..'
+ .format(entityId, entityType)
+ entity.createNote(text, category)
+ job.setStatus('failed')
+ logging.info('Note creation completed.')
+ def launch(self, event):
+ '''Callback method for action.'''
+ 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'
+ {'label': category.getName(), 'value': category.getId()}
+ for category in ftrack.getNoteCategories()
+ options.insert(0, {'label': 'Default', 'value': 'auto'})
+ 'value': '## Writing note on **{0}** items. ##'.format(len(selection)),
+ 'label': 'Note category',
+ 'name': 'note_category',
+def main(arguments=None):
+ '''Set up logging and register action.'''
+ parser = argparse.ArgumentParser()
+ # Allow setting of logging level from arguments.
+ logging.NOTSET, logging.DEBUG, logging.INFO, logging.WARNING,
+ logging.ERROR, logging.CRITICAL
+ loggingLevels[logging.getLevelName(level).lower()] = level
+ help='Set the logging output verbosity.',
+ choices=loggingLevels.keys(),
+ namespace = parser.parse_args(arguments)
+ logging.basicConfig(level=loggingLevels[namespace.verbosity])
+ action = NoteOnMultipleEntitiesAction()
+ ftrack.EVENT_HUB.wait()
+if __name__ == '__main__':
+ raise SystemExit(main(sys.argv[1:]))