예제 #1
0
    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
                }
            ]
        }
예제 #2
0
    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)
예제 #4
0
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
예제 #5
0
    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
예제 #6
0
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()
예제 #7
0
    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
예제 #9
0
    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)
예제 #10
0
    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