def launch(self, event): if 'values' in event['data']: # Do something with the values or return a new form. values = event['data']['values'] success = True msg = 'Asset deleted.' asset = ftrack.Asset(values['asset']) asset.delete() return { 'success': success, 'message': msg } data = [] shot = ftrack.Task(event['data']['selection'][0]['entityId']) for asset in shot.getAssets(): if asset.getName(): data.append({'label': asset.getName(), 'value': asset.getId()}) else: data.append({'label': 'None', 'value': asset.getId()}) return { 'items': [ { 'label': 'Asset', 'type': 'enumerator', 'name': 'asset', 'data': data } ] }
def launch(self, event): if "values" in event["data"]: # Do something with the values or return a new form. values = event["data"]["values"] success = True msg = "Asset deleted." # deleting all assets if values["asset"] == "all": entity = None try: entity = ftrack.Project( event["data"]["selection"][0]["entityId"]) except: entity = ftrack.Task( event["data"]["selection"][0]["entityId"]) for asset in entity.getAssets(): asset.delete() return {"success": success, "message": "All assets deleted."} asset = ftrack.Asset(values["asset"]) asset.delete() return {"success": success, "message": msg} data = [] entity = None try: entity = ftrack.Project(event["data"]["selection"][0]["entityId"]) except: entity = ftrack.Task(event["data"]["selection"][0]["entityId"]) for asset in entity.getAssets(): if asset.getName(): name = "{0} ({1})".format(asset.getName(), asset.getType().getName()) data.append({"label": name, "value": asset.getId()}) else: data.append({"label": "None", "value": asset.getId()}) if len(data) > 1: data.append({"label": "All", "value": "all"}) return { "items": [{ "label": "Asset", "type": "enumerator", "name": "asset", "data": data }] }
def publish_script_panel(self): task = self.current_task asset_name = self.asset_name thumbnail = self.asset_thumbnail comment = self.comment asset_type = self.current_asset_type import tempfile tmp_script = tempfile.NamedTemporaryFile(suffix='.nk', delete=False).name nuke.scriptSaveAs(tmp_script) task = ftrack.Task(task.getId()) parent = task.getParent() if isinstance(parent, ftrack.Project): msg = 'Cannot publish asset "%s" under project "%s"' self.header.setMessage(msg % (task.getName(), parent.getName()), 'error') asset_id = parent.createAsset(name=asset_name, assetType=asset_type).getId() asset = ftrack.Asset(asset_id) version = asset.createVersion(comment=comment, taskid=task.getId()) version.createComponent(name='nukescript', path=tmp_script) logging.info(thumbnail) if thumbnail: version.createThumbnail(thumbnail) scene_metas = SceneNodeAnalyser() version.setMeta('mft.node_numbers', json.dumps(scene_metas.node_number_meta)) dependencies = get_dependencies() logging.info(dependencies.values()) version.addUsesVersions(versions=dependencies.values()) result = version.publish() if result: self.header.setMessage('Asset %s correctly published' % asset.getName()) if self.current_shot_status_changed(): task.shot.ftrack_object.setStatus(self.current_shot_status) if self.current_task_status_changed(): task.setStatus(self.current_task_status)
def attachThumbnail(thumbnail, task, asset, version): # Currently, it is not possible to set thumbnails using new API # This is a workaround using the old API. task_old_api = ftrack.Task(id=task['id']) asset_old_api = ftrack.Asset(id=asset['id']) for vers in asset_old_api.getVersions(): if vers.getId() == version['id']: version_old_api = vers try: attachment = version_old_api.createThumbnail(thumbnail) task_old_api.setThumbnail(attachment) except Exception: print "Thumbnail upload error" break
def objectById(identifier): '''Return object from *identifier*.''' obj = None if identifier != '': if 'ftrack://' in identifier: url = urlparse.urlparse(identifier) query = urlparse.parse_qs(url.query) entityType = query.get('entityType')[0] identifier = url.netloc if entityType == 'assettake': obj = ftrack.Component(identifier) elif entityType == 'asset_version': obj = ftrack.AssetVersion(identifier) elif entityType == 'asset': obj = ftrack.Asset(identifier) elif entityType == 'show': obj = ftrack.Project(identifier) elif entityType == 'task': obj = ftrack.Task(identifier) else: ftrackObjectClasses = [ ftrack.Task, ftrack.Asset, ftrack.AssetVersion, ftrack.Component, ftrack.Project ] for cls in ftrackObjectClasses: try: obj = cls(id=identifier) break except: pass return obj
def CreateFTrackVersion(job, ftrackKVPs): #Set up the environment needed to connect to FTrack config = RepositoryUtils.GetEventPluginConfig("FTrack") ftrackURL = config.GetConfigEntryWithDefault("FTrackURL", "").strip() ftrackKey = config.GetConfigEntryWithDefault("FTrackAPIKey", "").strip() ftrackProxy = config.GetConfigEntryWithDefault("FTrackProxy", "").strip() username = ftrackKVPs.get("FT_Username", "") os.environ["FTRACK_SERVER"] = ftrackURL os.environ["FTRACK_APIKEY"] = ftrackKey if ftrackProxy: os.environ["FTRACK_PROXY"] = ftrackProxy if username: os.environ["LOGNAME"] = username #Import FTrack API eggPath = ftrackPath = RepositoryUtils.GetRootDirectory( "events/FTrack/API") sys.path.append(eggPath) import ftrack ftrack.setup(False) #TODO: Handle errors in a nicer way projectID = ftrackKVPs.get("FT_ProjectId", "") project = ftrack.Project(id=projectID) #Fetch project with given ID taskID = ftrackKVPs.get("FT_TaskId", "") task = ftrack.Task(id=taskID) #Fetch task with given ID assetID = ftrackKVPs.get("FT_AssetId", "") asset = ftrack.Asset(id=assetID) #Fetch asset with given ID description = ftrackKVPs.get("FT_Description", "") version = asset.createVersion(comment=description, taskid=taskID) #Set version status based on the Deadline Job's status dlStatus = job.Status ftStatusName = "" if dlStatus == JobStatus.Active: if job.RenderingChunks > 0: ftStatusName = config.GetConfigEntryWithDefault( "VersionStatusStarted", "").strip() else: ftStatusName = config.GetConfigEntryWithDefault( "VersionStatusQueued", "").strip() elif dlStatus == JobStatus.Failed: ftStatusName = config.GetConfigEntryWithDefault( "VersionStatusFailed", "").strip() elif dlStatus == JobStatus.Completed: ftStatusName = config.GetConfigEntryWithDefault( "VersionStatusFinished", "").strip() #Set the components based on the Job's output (if available) for i in range(len(job.OutputDirectories)): outPath = os.path.normpath(job.OutputDirectories[i]) outPath = RepositoryUtils.CheckPathMapping(outPath, True) if i < len(job.OutputFileNames): outPath = os.path.join(outPath, job.OutputFileNames[i]) #Change out our '#' padding for python-style padding, which FTrack expects match = re.search("#+", outPath) if match: padding = match.group(0) outPath = "{0} [{1}]".format( outPath.replace(padding, "%%0%dd" % len(padding)), job.FramesList) ClientUtils.LogText( "Creating Component for Deadline output '{0}'...".format( outPath)) try: #Job's complete, so output should be present now, let FTrack pick a location for us version.createComponent(name=("Deadline_Output_%d" % i), path=outPath) except: #That failed =/ ClientUtils.LogText(traceback.format_exc()) ClientUtils.LogText( "Failed to create component for output '%s'. No component will be created." % outPath) ClientUtils.LogText("Done creating Components.") if ftStatusName: statuses = project.getVersionStatuses() ftStatus = None for status in statuses: if status.getName().lower() == ftStatusName.lower(): ftStatus = status break if ftStatus == None: ClientUtils.LogText( "Could not find valid Asset Version Status with name '%s'. The Version Status might not be set properly." % ftStatusName) else: ClientUtils.LogText("Setting Asset Version to status '%s'." % ftStatusName) version.setStatus(ftStatus) version.publish() return version.getId()
def process(self, instance, context): # skipping instance if ftrackData isn't present if not context.has_data('ftrackData'): self.log.info('No ftrackData present. Skipping this instance') return # skipping instance if ftrackComponents isn't present if not instance.has_data('ftrackComponents'): self.log.info('No ftrackComponents found. Skipping this instance') return ftrack_data = context.data('ftrackData').copy() task = ftrack.Task(ftrack_data['Task']['id']) parent = task.getParent() asset_data = None create_version = False # creating asset if instance.data('ftrackAssetCreate'): asset = None # creating asset from ftrackAssetName if instance.has_data('ftrackAssetName'): asset_name = instance.data('ftrackAssetName') if instance.has_data('ftrackAssetType'): asset_type = instance.data('ftrackAssetType') else: asset_type = ftrack_data['Task']['code'] asset = parent.createAsset(name=asset_name, assetType=asset_type, task=task) msg = "Creating new asset cause ftrackAssetName" msg += " (\"%s\") doesn't exist." % asset_name self.log.info(msg) else: # creating a new asset asset_name = ftrack_data['Task']['type'] asset_type = ftrack_data['Task']['code'] asset = parent.createAsset(name=asset_type, assetType=asset_type, task=task) msg = "Creating asset cause no asset is present." self.log.info(msg) create_version = True # adding asset to ftrack data asset_data = {'id': asset.getId(), 'name': asset.getName()} if not asset_data: asset_data = instance.data('ftrackAsset') instance.set_data('ftrackAsset', value=asset_data) # creating version version = None if instance.data('ftrackAssetVersionCreate') or create_version: asset = ftrack.Asset(asset_data['id']) taskid = ftrack_data['Task']['id'] version_number = int(context.data('version')) version = self.GetVersionByNumber(asset, version_number) if not version: version = asset.createVersion(comment='', taskid=taskid) version.set('version', value=version_number) msg = 'Creating new asset version by %s.' % version_number self.log.info(msg) else: msg = 'Using existing asset version by %s.' % version_number self.log.info(msg) asset_version = {'id': version.getId(), 'number': version_number} instance.set_data('ftrackAssetVersion', value=asset_version) version.publish() else: # using existing version asset_version = instance.data('ftrackAssetVersion') version = ftrack.AssetVersion(asset_version['id']) # adding asset version to ftrack data instance.set_data('ftrackAssetVersion', value=asset_version)
def getEntityById(self, identifier, throw=True): '''Return an entity represented by the given *identifier*. If *throw* is True then raise :py:exc:`FnAssetAPI.exceptions.InvalidEntityReference` if no entity can be found, otherwise return None. ''' entity = None if identifier != '': if 'ftrack://' in identifier: url = urlparse.urlparse(identifier) query = urlparse.parse_qs(url.query) entityType = query.get('entityType')[0] identifier = url.netloc try: return self._memoiser.cache.get(identifier) except KeyError: pass try: if entityType == 'component': entity = ftrack.Component(identifier) elif entityType == 'asset_version': entity = ftrack.AssetVersion(identifier) elif entityType == 'asset': entity = ftrack.Asset(identifier) elif entityType == 'show': entity = ftrack.Project(identifier) elif entityType == 'task': entity = ftrack.Task(identifier) elif entityType == 'tasktype': entity = ftrack.TaskType(identifier) except: pass else: ftrackObjectClasses = [ ftrack.Task, ftrack.Asset, ftrack.AssetVersion, ftrack.Component, ftrack.Project, ftrack.TaskType ] try: return self._memoiser.cache.get(identifier) except KeyError: pass for cls in ftrackObjectClasses: try: entity = cls(id=identifier) break except ftrack.FTrackError as error: if error.message.find('was not found') == -1: raise pass except Exception, error: FnAssetAPI.logging.log( 'Exception caught trying to create {0}: {1}'. format(cls.__name__, error), FnAssetAPI.logging.kError) raise
def changeVersion(self, newVersion=None, row=None): '''Change version.''' if row is None: sender = self.sender() row = self.ui.AssertManagerTableWidget.indexAt(sender.pos()).row() newVersion = sender.itemText(newVersion) latestVersion = self.ui.AssertManagerTableWidget.item(row, 6).text() objectName = self.ui.AssertManagerTableWidget.item(row, 8).text() componentName = self.ui.AssertManagerTableWidget.item(row, 1).text() assetId = self.ui.AssertManagerTableWidget.item(row, 12).text() currentVersion = self.ui.AssertManagerTableWidget.item(row, 14).text() ftrackAsset = ftrack.Asset(assetId) assetVersions = ftrackAsset.getVersions() newftrackAssetVersion = None # Check the next suitable chosen version. for version in assetVersions: # If there's a matching version , use that one. if str(version.getVersion()) == str(newVersion): newftrackAssetVersion = version break else: # Otherwise, fall back on the latest available. newftrackAssetVersion = assetVersions[-1] try: newComponent = newftrackAssetVersion.getComponent(componentName) except: print 'Could not getComponent for main. Trying with sequence' componentName = 'sequence' newComponent = newftrackAssetVersion.getComponent(componentName) # Build a new api component object. ftrack_component = self.connector.session.get('Component', newComponent.getId()) location = self.connector.session.pick_location( component=ftrack_component) if location is None: raise ftrack.FTrackError( 'Cannot load version data as no accessible location ' 'containing the version is available.') path = location.get_filesystem_path(ftrack_component) importObj = FTAssetObject(filePath=path, componentName=componentName, componentId=newComponent.getId(), assetVersionId=newftrackAssetVersion.getId()) before = set(self.connector.getAssets()) result = self.connector.changeVersion(iAObj=importObj, applicationObject=objectName) after = set(self.connector.getAssets()) diff = after.difference(before) if result: cellWidget = self.ui.AssertManagerTableWidget.cellWidget(row, 0) if newVersion == latestVersion: cellWidget.setStyleSheet(''' QPushButton { background-color: #1CBC90; border: none; } ''') self.connector.setNodeColor(applicationObject=objectName, latest=True) else: cellWidget.setStyleSheet(''' QPushButton { background-color: #E36316; border: none; } ''') self.connector.setNodeColor(applicationObject=objectName, latest=False) self.ui.AssertManagerTableWidget.item(row, 14).setText(str(newVersion)) if diff: newName = list(diff)[0][1] self.ui.AssertManagerTableWidget.item(row, 8).setText(newName) self.updateSignalMapper(row) else: cellWidget = self.ui.AssertManagerTableWidget.cellWidget(row, 5) fallbackIndex = cellWidget.findText(currentVersion) cellWidget.setCurrentIndex(fallbackIndex)
def _publish(self, entity=None, assetName=None, assetType=None, versionDescription='', taskId=None, components=None, previewPath=None, thumbnailFilePath=None, asset=None): '''If *asset* is specified, publish a new version of it. Otherwise, get or create an asset of *assetType* on *entity*. *taskId*, *versionDescription*, *components*, *previewPath* and *thumbnailFilePath* are optional. Each component in *components* should be represented by a dictionary containing name, filepath and a list of locations. ''' version = None self.publishStarted.emit() try: if not (asset or assetType): self.publishFinished.emit(False) raise ftrack_connect.error.ConnectError( 'No asset type selected.') if not entity: self.publishFinished.emit(False) raise ftrack_connect.error.ConnectError('No entity found') if components is None: components = [] task = None if taskId: task = self.session.get('Context', taskId) new_entity = self.session.get('Context', entity.getId()) if not asset: asset_type = self.session.get('AssetType', assetType.getId()) if assetName is None: assetName = asset_type['name'] asset = self.session.create('Asset', { 'name': assetName, 'type': asset_type, 'parent': new_entity }) # For compatibily reasons, emit old asset ftrack type. self.session.commit() old_ftrack_asset_type = ftrack.Asset(asset['id']) self.assetCreated.emit(old_ftrack_asset_type) else: asset = self.session.get('Asset', asset.getId()) version = self.session.create('AssetVersion', { 'asset': asset, 'comment': versionDescription, 'task': task, }) self.session.commit() origin_location = self.session.query( 'Location where name is "ftrack.origin"') for componentData in components: component = version.create_component( componentData.get('filePath'), {'name': componentData.get('name', None)}, location=None) for location in componentData.get('locations', []): new_location = self.session.get('Location', location['id']) new_location.add_component(component, source=origin_location) self.logger.info( u'Publish {0!r} to location: {1!r}.'.format( component, new_location['name'])) if previewPath: self.session.event_hub.publish(event.base.Event( 'ftrack.connect.publish.make-web-playable', data=dict(versionId=version['id'], path=previewPath)), synchronous=True) if thumbnailFilePath: version.create_thumbnail(thumbnailFilePath) version['is_published'] = True self.session.commit() self.publishFinished.emit(True) # Catch any errors, emit *publishFinished*, clean up and re-raise. except Exception as error: self.logger.exception(u'Failed to publish: {0}'.format(error)) self.publishFinished.emit(False) self._cleanupFailedPublish(version=version) raise