def publishAsset(self): '''Publish the asset''' task = self.exportAssetOptionsWidget.getTask() taskId = task.getId() shot = self.exportAssetOptionsWidget.getShot() assettype = self.exportAssetOptionsWidget.getAssetType() assetName = self.exportAssetOptionsWidget.getAssetName() status = self.exportAssetOptionsWidget.getStatus() comment = self.exportOptionsWidget.getComment() options = self.exportOptionsWidget.getOptions() thumbnail = self.exportOptionsWidget.getThumbnail() if assetName == '': self.showWarning('Missing assetName', 'assetName can not be blank') return prePubObj = ftrack_connector.FTAssetObject(options=options, taskId=taskId) result, message = self.connector.prePublish(prePubObj, assettype) if not result: self.showWarning('Prepublish failed', message) return self.exportOptionsWidget.setProgress(0) asset = shot.createAsset(assetName, assettype) assetVersion = asset.createVersion(comment=comment, taskid=taskId) pubObj = ftrack_connector.FTAssetObject( assetVersionId=assetVersion.getId(), options=options) try: publishedComponents, message = self.connector.publishAsset(pubObj) except: self.exportOptionsWidget.setProgress(100) self.showError('Publish failed. Please check the console.') raise if publishedComponents: self.connector.publishAssetFiles(publishedComponents, assetVersion, pubObj) else: self.exportOptionsWidget.setProgress(100) # Update status of task. ftTask = ftrack.Task(id=taskId) if (ftTask and ftTask.get('object_typeid') == '11c137c0-ee7e-4f9c-91c5-8c77cec22b2c'): for taskStatus in ftrack.getTaskStatuses(): if (taskStatus.getName() == status and taskStatus.get('statusid') != ftTask.get('statusid')): try: ftTask.setStatus(taskStatus) except Exception, error: print 'warning: {0}'.format(error) break
def _preProcessMeta(self, key, value): '''Pre-process metadata *key* and *value* to strong types. For example, a key of 'status' would be converted to a strong TaskStatus object in ftrack. ''' if key == 'status': value = str(value) nativeStatus = None available = [] for status in ftrack.getTaskStatuses(): available.append(status.getName()) if status.getName() == status: nativeStatus = status break if not nativeStatus: raise ValueError( 'Unable to find the status "{0}" in {1}'.format( value, available)) value = nativeStatus return value
def get_status_by_name(name): statuses = ftrack.getTaskStatuses() result = None for s in statuses: if s.get('name').lower() == name.lower(): result = s return result
def GetStatusByName(name): statuses = ftrack.getTaskStatuses() result = None for s in statuses: if s.get('name').lower() == name.lower(): result = s return result
def GetStatusByName(self, name): statuses = ftrack.getTaskStatuses() result = None for s in statuses: if s.get('name').lower() == name.lower(): result = s return result
def main(): job_status = sys.argv[0] job = sys.argv[1] # Setup environment from job. if job.GetJobEnvironmentKeys(): for key in job.GetJobEnvironmentKeys(): value = job.GetJobEnvironmentKeyValue(key) os.environ[str(key)] = str(value) status_mapping = { "OnJobSubmitted": "Processing Queued", "OnJobStarted": "Processing", "OnJobFinished": "Processing Done", "OnJobRequeued": "Processing Queued", "OnJobFailed": "Processing Failed", "OnJobSuspended": "Processing Queued", "OnJobResumed": "Processing Queued", "OnJobPended": "Processing Queued", "OnJobReleased": "Processing Queued", } # Fail safe for non-existing job statuses if job_status not in status_mapping.keys(): return # Need to find the status by name sys.path.append(job.GetJobEnvironmentKeyValue("PYTHONPATH")) import ftrack ft_status = None for status in ftrack.getTaskStatuses(): if status.getName() == status_mapping[job_status]: ft_status = status break task = ftrack.Task(job.GetJobEnvironmentKeyValue("FTRACK_TASKID")) task.setStatus(ft_status) print "Setting \"{0}\" to \"{1}\"".format(task.getName(), ft_status.getName())
def publishAsset(self): '''Publish the asset''' task = self.exportAssetOptionsWidget.getTask() taskId = task.getId() shot = self.exportAssetOptionsWidget.getShot() assettype = self.exportAssetOptionsWidget.getAssetType() assetName = self.exportAssetOptionsWidget.getAssetName() status = self.exportAssetOptionsWidget.getStatus() comment = self.exportOptionsWidget.getComment() options = self.exportOptionsWidget.getOptions() thumbnail = self.exportOptionsWidget.getThumbnail() if assetName == '': self.showWarning('Missing assetName', 'assetName can not be blank') return prePubObj = ftrack_connector.FTAssetObject( options=options, taskId=taskId ) result, message = self.connector.prePublish(prePubObj) if not result: self.showWarning('Prepublish failed', message) return self.exportOptionsWidget.setProgress(0) asset = shot.createAsset(assetName, assettype) assetVersion = asset.createVersion(comment=comment, taskid=taskId) pubObj = ftrack_connector.FTAssetObject( assetVersionId=assetVersion.getId(), options=options ) try: publishedComponents, message = self.connector.publishAsset(pubObj) except: self.exportOptionsWidget.setProgress(100) self.showError('Publish failed. Please check the console.') raise if publishedComponents: self.connector.publishAssetFiles( publishedComponents, assetVersion, pubObj ) else: self.exportOptionsWidget.setProgress(100) # Update status of task. ftTask = ftrack.Task(id=taskId) if ( ftTask and ftTask.get('object_typeid') == '11c137c0-ee7e-4f9c-91c5-8c77cec22b2c' ): for taskStatus in ftrack.getTaskStatuses(): if ( taskStatus.getName() == status and taskStatus.get('statusid') != ftTask.get('statusid') ): try: ftTask.setStatus(taskStatus) except Exception, error: print 'warning: {0}'.format(error) break
def setupUI(self): css_task_global = """ QLabel { padding: 0px; background: none; } /*QTabWidget::pane { border-top: 2px solid #151515; top: -2px;} QTabBar::tab { padding: 6px 10px; background: #151515; border-top: 2px solid #151515; border-right: 2px solid #151515; border-left: 2px solid #151515; border-radius: 0px; } QTabBar::tab:selected { background: #333; border-top-left-radius: 4px; border-top-right-radius: 4px; } QTabBar::tab:hover { background: #222; } QTabBar::tab:!selected { margin-top: 2px; }*/ """ css_task_name_lbl = "font-size: 13px;" css_task_name = "color: #c3cfa4; font-size: 13px; font-weight: bold;" self.setStyleSheet(css_task_global) task_frame_layout = QtWidgets.QVBoxLayout(self) task_frame_layout.setContentsMargins(0, 0, 0, 0) task_frame_layout.setSpacing(15) # Display Task infos task_info_layout = QtWidgets.QFormLayout() task_info_layout.setContentsMargins(10, 10, 10, 10) task_info_layout.setSpacing(10) task_name_lbl = QtWidgets.QLabel("Task", self) task_name_lbl.setStyleSheet(css_task_name_lbl) self._task_name = QtWidgets.QLabel(self._t_name, self) self._task_name.setStyleSheet(css_task_name) project_lbl = QtWidgets.QLabel("Project", self) self._project_name = QtWidgets.QLabel(self._t_project_name, self) shot_lbl = QtWidgets.QLabel("Shot", self) shot_layout = QtWidgets.QHBoxLayout() shot_layout.setSpacing(6) self._shot_name = QtWidgets.QLabel(self) self._separator_shot = QtWidgets.QLabel("/", self) self._separator_shot.setVisible(False) self._sequence_name = QtWidgets.QLabel(self) spacer_shot = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) shot_layout.addWidget(self._sequence_name) shot_layout.addWidget(self._separator_shot) shot_layout.addWidget(self._shot_name) shot_layout.addItem(spacer_shot) shot_status_lbl = QtWidgets.QLabel("Shot status", self) shot_status = ftrack.getShotStatuses() self._shot_status = StatusWidget(shot_status, self) task_status_lbl = QtWidgets.QLabel("Task status", self) task_status = ftrack.getTaskStatuses() self._task_status = StatusWidget(task_status, self) due_date_lbl = QtWidgets.QLabel("Due date", self) self._due_date = QtWidgets.QLabel(self) task_info_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, task_name_lbl) task_info_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self._task_name) task_info_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, project_lbl) task_info_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self._project_name) task_info_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, shot_lbl) task_info_layout.setItem(2, QtWidgets.QFormLayout.FieldRole, shot_layout) task_info_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, shot_status_lbl) task_info_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self._shot_status) task_info_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, task_status_lbl) task_info_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self._task_status) task_info_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, due_date_lbl) task_info_layout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self._due_date) task_frame_layout.addItem(task_info_layout) self._tab_widget = QtWidgets.QTabWidget(self) # Display Nuke Assets from this task self.tab_asset_tree = QtWidgets.QWidget() self.tab_asset_tree.busy_overlay = LoadingOverlay(self.tab_asset_tree) self.tab_asset_tree.busy_overlay.hide() tab_asset_tree_layout = QtWidgets.QVBoxLayout(self.tab_asset_tree) tab_asset_tree_layout.setContentsMargins(0, 8, 0, 0) self.assets_widget = SceneAssetsWidget(self) self.assets_widget.worker_started.connect( self.tab_asset_tree.busy_overlay.show) self.assets_widget.worker_started.connect( self.tab_asset_tree.busy_overlay.raise_) self.assets_widget.worker_stopped.connect( self.tab_asset_tree.busy_overlay.hide) tab_asset_tree_layout.addWidget(self.assets_widget) self._tab_widget.addTab(self.tab_asset_tree, "All Scene Assets") task_frame_layout.addWidget(self._tab_widget)
def setupUI(self): css_asset_global = """ QFrame { padding: 3px; background: #222; color: #FFF; font-size: 13px; } QLabel { padding: 0px; background: none; } """ self._css_lbl = "color: #AAA;" css_asset_name = "color: #c3cfa4; font-weight: bold;" css_asset_version = "color: #de8888; font-weight: bold;" css_comment = """ color: #f0f0f0; background: #444; padding: 3px ; border-radius: 2px; """ self._css_value = "color: #FFF; text-decoration: none;" self.setMinimumWidth(700) asset_frame_layout = QtGui.QVBoxLayout(self) asset_frame_layout.setContentsMargins(0, 0, 0, 0) asset_frame_layout.setSpacing(10) asset_main_frame = QtGui.QFrame(self) asset_main_frame.setStyleSheet(css_asset_global) asset_main_frame_layout = QtGui.QHBoxLayout(asset_main_frame) asset_main_frame_layout.setSpacing(10) asset_name_lbl = QtGui.QLabel("Asset", asset_main_frame) self._asset_name = QtGui.QLabel("...", asset_main_frame) self._asset_name.setStyleSheet(css_asset_name) spacer_asset = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) asset_version_lbl = QtGui.QLabel("Version", asset_main_frame) self._asset_version = QtGui.QLabel("...", asset_main_frame) self._asset_version.setStyleSheet(css_asset_version) asset_main_frame_layout.addWidget(asset_name_lbl) asset_main_frame_layout.addWidget(self._asset_name) asset_main_frame_layout.addItem(spacer_asset) asset_main_frame_layout.addWidget(asset_version_lbl) asset_main_frame_layout.addWidget(self._asset_version) asset_frame_layout.addWidget(asset_main_frame) overview_layout = QtGui.QHBoxLayout() overview_layout.setContentsMargins(0, 0, 0, 0) overview_layout.setSpacing(10) self._thumbnail_widget = ThumbnailWidget(self) overview_layout.addWidget(self._thumbnail_widget) self._infos_layout = QtGui.QFormLayout() self._infos_layout.setContentsMargins(0, 0, 0, 0) self._infos_layout.setSpacing(10) asset_type_lbl = QtGui.QLabel("Asset type", self) asset_type_lbl.setStyleSheet(self._css_lbl) self._asset_type = QtGui.QLabel(self) self.set_asset_type("...") status_lbl = QtGui.QLabel("Status", self) status_lbl.setStyleSheet(self._css_lbl) self._status = StatusWidget(ftrack.getTaskStatuses(), self) self._status.set_read_only(True) publish_lbl = QtGui.QLabel("Published by", self) publish_lbl.setStyleSheet(self._css_lbl) self._owner = QtGui.QLabel("...", self) self._owner.setTextFormat(QtCore.Qt.RichText) self._owner.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) self._owner.setOpenExternalLinks(True) date_lbl = QtGui.QLabel("on", self) date_lbl.setStyleSheet(self._css_lbl) self._date = QtGui.QLabel(self) self._date.setStyleSheet(self._css_value) self._editor = None self._date_edit = None availability_lbl = QtGui.QLabel("Availability", self) availability_lbl.setStyleSheet(self._css_lbl) self._availability = QtGui.QLabel(self) self._availability.setStyleSheet(self._css_value) comment_lbl = QtGui.QLabel("Comment", self) comment_lbl.setStyleSheet(self._css_lbl) self._comment = QtGui.QLabel("...", self) self._comment.setWordWrap(True) self._comment.setStyleSheet(css_comment) self._infos_layout.setWidget(0, QtGui.QFormLayout.LabelRole, asset_type_lbl) self._infos_layout.setWidget(0, QtGui.QFormLayout.FieldRole, self._asset_type) self._infos_layout.setWidget(1, QtGui.QFormLayout.LabelRole, status_lbl) self._infos_layout.setWidget(1, QtGui.QFormLayout.FieldRole, self._status) self._infos_layout.setWidget(2, QtGui.QFormLayout.LabelRole, publish_lbl) self._infos_layout.setWidget(2, QtGui.QFormLayout.FieldRole, self._owner) self._infos_layout.setWidget(3, QtGui.QFormLayout.LabelRole, date_lbl) self._infos_layout.setWidget(3, QtGui.QFormLayout.FieldRole, self._date) self._infos_layout.setWidget(4, QtGui.QFormLayout.LabelRole, availability_lbl) self._infos_layout.setWidget(4, QtGui.QFormLayout.FieldRole, self._availability) self._infos_layout.setWidget(5, QtGui.QFormLayout.LabelRole, comment_lbl) self._infos_layout.setWidget(5, QtGui.QFormLayout.FieldRole, self._comment) overview_layout.addItem(self._infos_layout) spacer_overview = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) overview_layout.addItem(spacer_overview) asset_frame_layout.addItem(overview_layout) self._tab_widget = QtGui.QTabWidget(self) css_tab = """ /* QTabWidget::pane { border-top: 2px solid #151515; top: -2px; border-top-left-radius: 0px; border-top-right-radius: 0px; background: #282828; } QTabBar::tab { padding: 6px 10px; background: #151515; border-top: 2px solid #151515; border-right: 2px solid #151515; border-left: 2px solid #151515; border-radius: 0px; } QTabBar::tab:selected { background: #333; border-top-left-radius: 4px; border-top-right-radius: 4px; } QTabBar::tab:hover { background: #222; } QTabBar::tab:!selected { margin-top: 2px; } */ """ self._tab_widget.setStyleSheet(css_tab) # Display asset history tab_asset_history = QtGui.QWidget() tab_asset_history_layout = QtGui.QVBoxLayout(tab_asset_history) tab_asset_history_layout.setContentsMargins(0, 8, 0, 0) self._graph_widget = StatisticWidget(self.scene_version, self) tab_asset_history_layout.addWidget(self._graph_widget) self._tab_widget.addTab(tab_asset_history, "Asset history") asset_frame_layout.addWidget(self._tab_widget) spacer_global = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) asset_frame_layout.addItem(spacer_global)
status_mapping = { "None": "Processing Queued", "FirstCheck": "Processing Queued", "WaitForJobs": "Processing Queued", "ScriptPreRender": "Processing Queued", "PreviewRender": "Processing Queued", "ScriptAfterPreview": "Processing Queued", "WaitForApprovalMain": "Processing Queued", "WaitForJobsAfterPreview": "Processing Queued", "MainRender": "Processing", "ScriptPostRender": "Processing", "WaitForApprovalDone": "Processing", "ScriptFinished": "Processing", "Finished": "Processing Done" } status = None for ft_status in ftrack.getTaskStatuses(): if ft_status.getName() == status_mapping[event_type]: status = ft_status break # Setting status task = ftrack.Task(job.custom_Str("FTRACK_TASKID")) task.setStatus(ft_status) msg = "Setting \"{0}\" to \"{1}\"".format( task.getName(), status.getName() ) print msg
def renameandcopytoVFX(self, copypath, FTRACK_SERVER='http://192.168.9.200', FTRACK_APIKEY='b445309f-1c5d-40ac-b68b-3fdfb4f3ccb9', LOGNAME='andyguo', PROJECTNAME='Piggy Bank' ): digitregex = re.compile(r'(\d{3,})') os.environ['FTRACK_SERVER'] = FTRACK_SERVER os.environ['FTRACK_APIKEY'] = FTRACK_APIKEY os.environ['LOGNAME'] = LOGNAME import ftrack try: project = ftrack.getProject(PROJECTNAME) print('== get asset types ==') platetypes = [x for x in ftrack.getAssetTypes() if x.get('name') == 'Plate'] # print(platetypes) print('== get task types ==') tasktypes = [x for x in ftrack.getTaskTypes() if x.get('name') == 'Plate'] # print(tasktypes) except: print('this project not available in ftrack') for j in xrange(len(self._cliplist)): # rename every frame as VFX needs item = self._cliplist[j] duration = int(item['endframe']) - int(item['startframe']) + 1 for i in xrange(duration): # diframe = str(item['startframe'] + i).zfill(m.end() - m.start()) oldname = item['metadata'][i]['filepath'] newname = item['sequence'][0] + '_' + item['shot'][0] + '_plate_' + ('%04d' % (1001 + i)) + \ os.path.splitext(oldname)[-1] try: newname = os.path.join(os.path.dirname(oldname), newname) os.rename(oldname, newname) except: print('something error in rename files') # print(oldname, newname) copyfoldername = os.path.dirname(oldname) if self._shouldrenamefolder: oldfolder = os.path .dirname(oldname) newfolder = os.path.join(os.path.dirname(os.path.dirname(oldname)), ('%04d' % (j + 1)) + '_' + item['sequence'][0] + '_' + item['shot'][0]) # print(oldfolder, newfolder) try: os.rename(oldfolder, newfolder) copyfoldername = newfolder except: print('something error in rename folders') # copy to NAS using rsync cmd = 'rsync -avr --progress %s %s' % (copyfoldername.replace(' ', r'\ '), copypath.replace(' ', '\ ')) print(cmd) terminal = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=1) with terminal.stdout: for line in iter(terminal.stdout.readline, b''): print line, terminal.wait() # update ftrack Assetbuild and shot try: print('== update shot info ==') shot = ftrack.getShot([PROJECTNAME, item['sequence'][0], item['shot'][0]]) except: print('no such shot %s_%s' % (item['sequence'][0], item['shot'][0])) break try: assetbuildname = '%s_%s_plate' % (item['sequence'][0], item['shot'][0]) previousvesions = [x for x in ftrack.getShot([PROJECTNAME, 'Asset builds']).getShots() if assetbuildname in x.getName()] # print(previousvesions) print('== check previous versions ==') if len(previousvesions) > 0: # print('already got %d verions' % len(previousvesions)) assetbuildname = '%s_%s_plate_%02d' % (item['sequence'][0], item['shot'][0], len(previousvesions)+1) else: assetbuildname = '%s_%s_plate_01' % (item['sequence'][0], item['shot'][0]) print('== create new assetbuild ==') newassetbuild = project.createAssetBuild(assetbuildname) newassetbuild.set('typeid', tasktypes[0].get('typeid')) temp = {} temp['01_sequence'] = item['sequence'][0] temp['02_shot'] = item['shot'][0] temp['05_s3d'] = item['s3d'] temp['06_metadata'] = str(item['metadata']) temp['03_startframe'] = item['startframe'] temp['04_endframe'] = item['endframe'] newassetbuild.setMeta(temp) print('== create new asset ==') asset = newassetbuild.createAsset(name=assetbuildname, assetType=platetypes[0].get('short')) version = asset.createVersion(comment='uploaded by IOFTRACK') for index, frame in enumerate(item['metadata']): # print(item['sequence'][0] + '_' + item['shot'][0] # + '_plate_' + # ('%04d' % (1001 + index)) + # os.path.splitext(oldname)[-1] # ) version.createComponent(name=(item['sequence'][0] + '_' + item['shot'][0] + '_plate_' + ('%04d' % (1001 + index)) + os.path.splitext(oldname)[-1] ), path=(item['sequence'][0] + '_' + item['shot'][0] + '_plate_' + ('%04d' % (1001 + index)) + os.path.splitext(oldname)[-1] )) asset.publish() try: print('== link asset to shot and link reverse ==') # print('asset', newassetbuild) # print('shot', shot) newassetbuild.addSuccessor(shot) newassetbuild.addPredecessor(shot) except: print('something error in link asset to shot') break newassetbuild.createTask('upload by IO', taskType=[x for x in ftrack.getTaskTypes() if x.get('name') == 'Plate'][0], taskStatus=[y for y in ftrack.getTaskStatuses() if y.get('name') == 'Approved'][0]) try: print('== create thumbnails ==') convertcmd = 'convert %s -size 1280x720 %s' % ( os.path.join(os.path.dirname(item['metadata'][0]['filepath']), (item['sequence'][0] + '_' + item['shot'][0] + '_plate_' + ('%04d' % (1001)) + os.path.splitext(oldname)[-1] )).replace(' ', r'\ '), os.path.join(APP_PATH, assetbuildname+'.jpg').replace(' ', r'\ ')) print(convertcmd) convermessage = subprocess.Popen(convertcmd, shell=True, stdout=subprocess.PIPE).communicate()[0] newassetbuild.createThumbnail(os.path.join(APP_PATH, assetbuildname + '.jpg')) except: print('== something error in creating thumbnails') except: print('something error with creating assetbuild') break