def getentitiesfromshotgun(name): sg = Shotgun(const.SHOTGUN_URL, const.API_NAME, const.API_KEY) sgname = name if name in const.ENTITY_MAP: sgname = const.ENTITY_MAP[name] fields = sg.schema_field_read(sgname) rawents = sg.find(sgname, [['project', 'is', { 'type': 'Project', 'id': 70 }]], list(fields.keys())) pp(rawents) clean = [] for ent in rawents: if 'image' in ent and ent['image']: directory = "data/filestorage/%s/%s/%s" % (name, ent['id'], "image") if not os.path.exists(os.path.dirname(directory)): os.makedirs(os.path.dirname(directory)) sg.download_attachment({'url': ent['image']}, directory) ent['image'] = directory for field in fields: if fields[field]['data_type']['value'] == 'url' and ent[field]: pp(ent) directory = "data/filestorage/%s/%s/%s" % (name, ent['id'], ent[field]['name']) if not isinstance(ent['id'], int): directory = "data/filestorage/%s/%s/%s" % ( name, ent['id']['value'], ent[field]['name']) if not os.path.exists(os.path.dirname(directory)): os.makedirs(os.path.dirname(directory)) sg.download_attachment(ent[field], directory) ent[field] = directory ent[field] = { "value": ent[field], "type": fields[field]['data_type']['value'] } ent.pop("created_at", None) ent.pop("created_by", None) ent.pop("updated_at", None) ent.pop("updated_by", None) ent.pop("filmstrip_image", None) ent.pop("cached_display_name", None) dic = {} dic['type'] = {'type': 'text', 'value': ent.pop('type')} for f in ent: dic[fields[f]['name']['value']] = ent[f] clean.append(dic) return clean
def getentitydatafromshotgun(): sg = Shotgun(const.SHOTGUN_URL, const.API_NAME, const.API_KEY) entityData = sg.schema_entity_read({'type': 'Project', 'id': 70}) visibleEntities = [] for entityName in entityData: fields = sg.schema_field_read(entityName) if 'project' in fields: if entityData[entityName]['visible']['value']: visibleEntities.append(entityData[entityName]['name']['value']) print("\"" + entityData[entityName]['name']['value'] + "\": \"" + entityName + "\",") return visibleEntities
class ShotgunUtils(): ''' this module is a collection of functions to conect the Asset manager to shogun studio website, to update, create and manages all attributes and parameters from the different entities. ''' def __init__(self): ''' creates the connection to the server and connects to database. creates list of Ids form the database collections that needs to convert to shotgun collections ''' ''' shotgun conection ''' SERVER_PATH = "https://hcpstudio.shotgunstudio.com" SCRIPT_NAME = 'sgApi' SCRIPT_KEY = '3899a8466f2cea694c2ba5341d871da845509d18d96a4feb7fb8d147de0fa819' self.sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) '''Shotgun Dictionaries for status and Piepeline Step and Entity''' self.sgStatusList = { 'CBB': 'cbb', 'CURRENT': 'crnt', 'DEPRECATED': 'dep', 'FINAL': 'fin', 'HOLD': 'hld', 'IN PROGRESS': 'ip', 'OMIT': 'omt', 'OUTDATED': 'outd', 'READY TO START': 'rdy', 'APPROVED': 'apr', 'REJECTED': 'rej', 'RETAKE': 'rtk', 'SUBMIT FOR APPROVAL': 'app', 'VARIANT': 'vari' } self.amStatusList = dict(map(reversed, self.sgStatusList.iteritems())) self.sgEntityDic = { 'ITEM': 'Asset', 'DIGITALMEDIA': 'Version', 'SHOT': 'shot', 'SEQUENCE': 'Sequence' } self.amEntityDic = dict(map(reversed, self.sgEntityDic.iteritems())) ''' DAO master conection ''' config = ConfigParser.ConfigParser() config.read("__database_config.ini") master = DaoMaster(instance=config.get('database_connection', 'instance'), db=config.get('database_connection', 'db')) session = master.getSession() storedFunctions = master.getStoredFunctions() self.ItemStatusConvert = storedFunctions.getCatalogItemStatusStoredFunctions( ) self.ShotStatusConvert = storedFunctions.getCatalogShotStatusStoredFunctions( ) self.SequenceStatusConvert = storedFunctions.getCatalogSequenceStatusStoredFunctions( ) self.DMStatusConvert = storedFunctions.getCatalogDigitalMediaStatusStoredFunctions( ) self.TaskStatusConvert = storedFunctions.getCatalogTaskStatusStoredFunctions( ) self.TaskStepConvert = storedFunctions.getCatalogTaskPipelineStepStoredFunctions( ) ''' instance entities from database ''' self.itemInstance = session.getItemDao() self.projectInstance = session.getProjectDao() self.sequenceInstance = session.getSequenceDao() self.shotInstance = session.getShotDao() self.taskInstance = session.getTaskDao() self.dmInstance = session.getDigitalMediaDao() self.userInstance = session.getUserDao() ''' Catalog instance ''' self.catalogDepartment = session.getCatalogDepartmentDao() self.catalogDMType = session.getCatalogDigitalMediaStatusDao() self.catalogDMStatus = session.getCatalogDigitalMediaStatusDao() self.catalogItemClass = session.getCatalogItemClassDao() self.catalogItemComplex = session.getCatalogItemComplexDao() self.catalogItemFormat = session.getCatalogItemFormatDao() self.catalogItemStatus = session.getCatalogItemStatusDao() self.catalogItemType = session.getCatalogItemTypeDao() self.catalogSequenceComplex = session.getCatalogSequenceComplexityDao() self.catalogSequenceStatus = session.getCatalogSequenceStatusDao() self.catalogShotComplex = session.getCatalogShotComplexityDao() self.catalogShotPriority = session.getCatalogShotPriorityDao() self.catalogShotStatus = session.getCatalogShotStatusDao() self.catalogTaskComplex = session.getCatalogTaskComplexityDao() self.catalogTaskEntity = session.getCatalogTaskEntityDao() self.catalogTaskName = session.getCatalogTaskNameDao() self.catalogTaskPipelineStep = session.getCatalogTaskPipelineStepDao() self.catalogTaskPriority = session.getCatalogTaskPriorityDao() self.catalogTaskStatus = session.getCatalogTaskStatusDao() self.ItemStatusList = self.getCatalogItemStatus() self.ItemType = self.getCatalogItemType() self.ItemClass = self.getCatalogItemCalss() self.ItemComplexity = self.getCatalogItemComplex() self.Department = self.getCatalogDepartment() self.DMStatus = self.getCatalogDMStatus() self.DMType = self.getCatalogDMType() self.SequenceComplex = self.getCatalogSequenceComplex() self.SequenceStatus = self.getCatalogSequenceStatus() self.ShotComplex = self.getCatalogShotComplex() self.ShotPriority = self.getCatalogShotPriority() self.ShotStatus = self.getCatalogShotStatus() self.TaskEntity = self.getCatalogTaskEntity() self.TaskName = self.getCatalogTaskName() self.TaskStep = self.getCatalogTaskPipelineStep() self.TaskPriority = self.getCatalogTaskPriority() self.TaskStatus = self.getCatalogTaskStatus() self.TaskComplex = self.getCatalogTaskComplex() self.sgPiepelineStepTag2IdDic = self.getSgStepsDic() self.sgPiepelineStepId2TagDic = dict( map(reversed, self.sgPiepelineStepTag2IdDic.iteritems())) def getParameterSchema(self, fieldType, fieldName=None): ''' utility function to search fields in a given entity. :param fieldType: entity to search parameters 'Project', 'Sequence', 'Shot', 'Asset', 'Version', etc. :param fieldName: name of the field to search 'id', 'name', 'coce', etc. :return: retruns a dictionary with the properties of given parameter ''' squemaDic = self.sg.schema_field_read(fieldType, fieldName) print squemaDic for field in squemaDic: print field return squemaDic def getEntities(self): ''' utility function to find all the Entities in shotgun for developing :return: renturn a list of all entities ''' squemaDic = self.sg.schema_entity_read() for entity in squemaDic: print entity return squemaDic def sgDicListFromDaoItemSubscription(self, itemSubscription): sgItemDictionaryList = [] if itemSubscription == []: return sgItemDictionaryList else: for item in itemSubscription: subscription = self.itemInstance.readOneByProperties( self.itemInstance.Properties.Id, item) if self.sg.find_one( 'Asset', [['id', 'is', subscription.getShotgunID()]]): sgDic = { 'type': 'Asset', 'id': subscription.getShotgunID() } sgItemDictionaryList.append(sgDic) else: pass return sgItemDictionaryList def sgDicListFromDaoShotSubscription(self, shotSubscription): sgShotDictionaryList = [] if shotSubscription == []: return sgShotDictionaryList else: for shot in shotSubscription: subscription = self.shotInstance.readOneByProperties( self.shotInstance.Properties.Id, shot) if self.sg.find_one( 'Shot', [['id', 'is', subscription.getShotgunID()]]): sgDic = {'type': 'Shot', 'id': subscription.getShotgunID()} sgShotDictionaryList.append(sgDic) else: pass return sgShotDictionaryList def sgDicListFromDaoSequenceSubscription(self, sequenceSubscription): sgSequenceDictionaryList = [] if sequenceSubscription == []: return sgSequenceDictionaryList else: for sequence in sequenceSubscription: subscription = self.sequenceInstance.readOneByProperties( self.sequenceInstance.Properties.Id, sequence) if self.sg.find_one( 'Sequence', [['id', 'is', subscription.getShotgunID()]]): sgDic = { 'type': 'Sequence', 'id': subscription.getShotgunID() } sgSequenceDictionaryList.append(sgDic) else: pass return sgSequenceDictionaryList def sgDicListFromDaoDMSubscription(self, dmSubscription): sgDMDictionaryList = [] if dmSubscription == []: return sgDMDictionaryList else: for dm in dmSubscription: subscription = self.dmInstance.readOneByProperties( self.dmInstance.Properties.Id, dm) if self.sg.find_one( 'Version', [['id', 'is', subscription.getShotgunID()]]): sgDic = { 'type': 'Version', 'id': subscription.getShotgunID() } sgDMDictionaryList.append(sgDic) else: pass return sgDMDictionaryList def sgDicListFromDaoUserSubscription(self, userSubscription): sgUserDictionaryList = [] if userSubscription == []: return sgUserDictionaryList else: for user in userSubscription: subscription = self.userInstance.readOneByProperties( self.userInstance.Properties.Id, user) if not subscription.getShotgunID() == 0: if self.sg.find_one( 'HumanUser', [['id', 'is', subscription.getShotgunID()]]): sgDic = { 'type': 'HumanUser', 'id': subscription.getShotgunID() } sgUserDictionaryList.append(sgDic) else: pass return sgUserDictionaryList def sgDicListFromDaoTaskSubscription(self, taskSubscription): sgUserDictionaryList = [] if taskSubscription == []: return sgUserDictionaryList else: for task in taskSubscription: subscription = self.taskInstance.readOneByProperties( self.taskInstance.Properties.Id, task) if not subscription.getShotgunID() == 0: if self.sg.find_one( 'Task', [['id', 'is', subscription.getShotgunID()]]): sgDic = { 'type': 'Task', 'id': subscription.getShotgunID() } sgUserDictionaryList.append(sgDic) else: pass return sgUserDictionaryList def amItemIdListFromSgItemSubscriptionDicList(self, sgDicList): amSubscriptionList = [] if sgDicList == []: return amSubscriptionList else: for sgDic in sgDicList: item = self.itemInstance.readOneByProperties( self.itemInstance.Properties.Id, sgDic['id']) if item: amSubscriptionList.append(item.getId()) else: pass return amSubscriptionList def amShotIdListFromSgShotSubscriptionDicList(self, sgDicList): amSubscriptionList = [] if sgDicList == []: return amSubscriptionList else: for sgDic in sgDicList: entity = self.shotInstance.readOneByProperties( self.shotInstance.Properties.Id, sgDic['id']) if entity: amSubscriptionList.append(entity.getId()) else: pass return amSubscriptionList def amSequenceIdListFromSgSequenceSubscriptionDicList(self, sgDicList): amSubscriptionList = [] if sgDicList == []: return amSubscriptionList else: for sgDic in sgDicList: entity = self.sequenceInstance.readOneByProperties( self.sequenceInstance.Properties.Id, sgDic['id']) if entity: amSubscriptionList.append(entity.getId()) else: pass return amSubscriptionList def amDMIdListFromSgDMSubscriptionDicList(self, sgDicList): amSubscriptionList = [] if sgDicList == []: return amSubscriptionList else: for sgDic in sgDicList: entity = self.dmInstance.readOneByProperties( self.dmInstance.Properties.Id, sgDic['id']) if entity: amSubscriptionList.append(entity.getId()) else: pass return amSubscriptionList def amTaskIdListFromSgTaskSubscriptionDicList(self, sgDicList): amSubscriptionList = [] if sgDicList == []: return amSubscriptionList else: for sgDic in sgDicList: entity = self.dmInstance.readOneByProperties( self.dmInstance.Properties.Id, sgDic['id']) if entity: amSubscriptionList.append(entity.getId()) else: pass return amSubscriptionList def sgIdFromItemId(self, itemId): if not itemId == 0: entity = self.itemInstance.readOneByProperties( self.itemInstance.Properties.Id, itemId) return entity.getShotgunID() else: return 0 def sgIdFromShotId(self, shotId): if not shotId == 0: entity = self.shotInstance.readOneByProperties( self.shotInstance.Properties.Id, shotId) return entity.getShotgunID() else: return 0 def sgIdFromSquenceId(self, sequenceId): if not sequenceId == 0: entity = self.sequenceInstance.readOneByProperties( self.sequenceInstance.Properties.Id, sequenceId) return entity.getShotgunID() else: return 0 def sgIdFromProjectId(self, projectId): if not projectId == 0: entity = self.projectInstance.readOneByProperties( self.projectInstance.Properties.Id, projectId) return entity.getShotgunID() else: return 0 def sgIdFromDmId(self, dmId): if not dmId == 0: entity = self.dmInstance.readOneByProperties( self.dmInstance.Properties.Id, dmId) return entity.getShotgunID() else: return 0 def sgIdFromTaskId(self, taskId): if not taskId == 0: entity = self.taskInstance.readOneByProperties( self.taskInstance.Properties.Id, taskId) return entity.getShotgunID() else: return 0 def getCatalogDepartment(self): listFromCatalog = [] catalogAll = self.catalogDepartment.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogDMStatus(self): listFromCatalog = [] catalogAll = self.catalogDMStatus.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogDMType(self): listFromCatalog = [] catalogAll = self.catalogDMType.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogItemCalss(self): listFromCatalog = [] catalogAll = self.catalogItemClass.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogItemComplex(self): listFromCatalog = [] catalogAll = self.catalogItemComplex.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def itemStatus2Dao(self, status): return self.ItemStatusConvert.getIdFromTag(status) def shotStatus2Dao(self, status): return self.ShotStatusConvert.getIdFromTag(status) def sequenceStatus2Dao(self, status): return self.SequenceStatusConvert.getIdFromTag(status) def dmStatus2Dao(self, status): return self.SequenceStatusConvert.getIdFromTag(status) def taskStatus2Dao(self, status): return self.TaskStatusConvert.getIdFromTag(status) def getCatalogItemStatus(self): listFromCatalog = [] catalogAll = self.catalogItemStatus.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogItemType(self): listFromCatalog = [] catalogAll = self.catalogItemType.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogSequenceComplex(self): listFromCatalog = [] catalogAll = self.catalogSequenceComplex.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogSequenceStatus(self): listFromCatalog = [] catalogAll = self.catalogSequenceStatus.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogShotComplex(self): listFromCatalog = [] catalogAll = self.catalogShotComplex.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogShotPriority(self): listFromCatalog = [] catalogAll = self.catalogShotPriority.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogShotStatus(self): listFromCatalog = [] catalogAll = self.catalogShotStatus.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogTaskComplex(self): listFromCatalog = [] catalogAll = self.catalogTaskComplex.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogTaskEntity(self): listFromCatalog = [] catalogAll = self.catalogTaskEntity.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogTaskName(self): listFromCatalog = [] catalogAll = self.catalogTaskName.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogTaskPipelineStep(self): listFromCatalog = [] catalogAll = self.catalogTaskPipelineStep.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogTaskPriority(self): listFromCatalog = [] catalogAll = self.catalogTaskPriority.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getCatalogTaskStatus(self): listFromCatalog = [] catalogAll = self.catalogTaskStatus.readAll() for catalog in catalogAll: listFromCatalog.append(catalog.getTag()) return listFromCatalog def getSgStepsDic(self): sgFields = ['id', 'code'] dictionaryList = self.sg.find('Step', [], sgFields) stepDic = {} for dictionary in dictionaryList: stepDic.update({dictionary['code']: dictionary['id']}) return stepDic def daoitem2sgDic(self, itemId): entity = self.itemInstance.readOneByProperties( self.itemInstance.Properties.Id, itemId) sgDic = {} if entity: if not entity.getShotgunID() == 0: sgDic = {'type': 'Asset', 'id': entity.getShotgunID()} return sgDic else: return None else: return None def daoShot2sgDic(self, itemId): entity = self.shotInstance.readOneByProperties( self.shotInstance.Properties.Id, itemId) sgDic = {} if entity: if not entity.getShotgunID() == 0: sgDic = {'type': 'Shot', 'id': entity.getShotgunID()} return sgDic else: return None else: return None def daoSequence2sgDic(self, itemId): entity = self.sequenceInstance.readOneByProperties( self.sequenceInstance.Properties.Id, itemId) sgDic = {} if entity: if not entity.getShotgunID() == 0: sgDic = {'type': 'Sequence', 'id': entity.getShotgunID()} return sgDic else: return None else: return None def daoDM2sgDic(self, itemId): entity = self.dmInstance.readOneByProperties( self.dmInstance.Properties.Id, itemId) sgDic = {} if entity: if not entity.getShotgunID() == 0: sgDic = {'type': 'Version', 'id': entity.getShotgunID()} return sgDic else: return None else: return None def daoHumanUser2sgDic(self, itemId): entity = self.userInstance.readOneByProperties( self.userInstance.Properties.Id, itemId) sgDic = {} if entity: if not entity.getShotgunID() == 0: sgDic = {'type': 'Asset', 'id': entity.getShotgunID()} return sgDic else: return None else: return None def daoTask2sgDic(self, itemId): entity = self.taskInstance.readOneByProperties( self.taskInstance.Properties.Id, itemId) sgDic = {} if entity: if not entity.getShotgunID() == 0: sgDic = {'type': 'Task', 'id': entity.getShotgunID()} return sgDic else: return None else: return None
class genericUtils: def __init__(self): self.sg = Shotgun('https://' + URL, name, API) def getFields(self, entity): '''get the fields for a type/entity as a list so we can pass it as an arg easily this is used all the time to make sure we get all the fields that we may ever need for a type/entity ''' allFields = [] fields = self.sg.schema_field_read(entity) for field in fields: allFields.append(field) return allFields def project(self, project): '''Gets the Shotgun project name and ID ''' retFields = self.getFields('Project') project = project.replace('_', ' ') return self.sg.find_one("Project", [["name", "is", project]], retFields) def sequence(self, project, sequence): '''Returns the shotgun sequence name and ID Parameters : (project, sequence) ''' retFields = self.getFields('Sequence') return self.sg.find_one( "Sequence", [["code", "is", sequence], ['project', 'is', project]], retFields) def shot(self, project, shot): '''Returns the shotgun shot name and ID Parameters : (project, shot) ''' retFields = self.getFields('Shot') return self.sg.find_one( 'Shot', [['code', 'is', shot], ['project', 'is', project]], retFields) def createProject(self, project): '''Creates a project in Shotgun given a project name Parameters : (project) ''' filters = [['code', 'is', 'a']] template = self.sg.find_one('Project', [['name', 'is', 'a']], ['layout_project', 'id']) data = {'name': project, 'layout_project': template} return self.sg.create('Project', data) def createSequence(self, project, sequence): '''Creates a sequence in shotgun given Parameters : (project, sequence) ''' data = { 'project': { "type": "Project", "id": project['id'] }, 'code': sequence } return self.sg.create('Sequence', data) def createShot(self, project, shot, seq='', taskTemplateName=''): '''Creates a sequence in shotgun given Parameters : (project, shot, seq='', taskTemplateName='Basic shot template' ''' filters = [['code', 'is', taskTemplateName]] template = self.sg.find_one('TaskTemplate', filters) data = { 'project': { "type": "Project", "id": project['id'] }, 'code': shot, 'task_template': template, 'description': '', 'self.sg_sequence': seq, 'self.sg_status_list': 'wtg' } result = self.sg.create('Shot', data) return result def notesFind(self, shotID): '''Find all notes on a shot Parameters : (shotID) Output : Note data : ['tasks', 'attachments', 'updated_at', 'replies', 'id', 'subject', 'playlist', ' addressings_to', 'created_by', 'content', 'sg_status_list', 'reply_content', 'updated_by', 'addressings_cc', 'read_by_current_user', 'user', 'note_links', 'created_at', 'sg_note_from', 'project', 'sg_note_type', 'tag_list'] ''' note = self.sg.find('Note', [['note_links', 'is', shotID]], ['subject', 'content', 'created_at'], [{ 'field_name': 'created_at', 'direction': 'desc' }]) return note def notesFindLatest(self, shotID): '''Find the latest note on a shot Parameters : (shotID) Call with notesFindLatest(shot)['content'] for the note content only Output : Note data: ['tasks', 'attachments', 'updated_at', 'replies', 'id', 'subject', 'playlist', ' addressings_to', 'created_by', 'content', 'sg_status_list', 'reply_content', 'updated_by', 'addressings_cc', 'read_by_current_user', 'user', 'note_links', 'created_at', 'sg_note_from', 'project', 'sg_note_type', 'tag_list'] ''' note = self.notesFind(shotID)[0] return note def notesCreate(self, project, shotID, subject, content): '''Create a note for a shot given Parameters : (project, shotID, subject, content) Output : noteID ''' # enter data here for a note to create data = { 'subject': subject, 'content': content, 'note_links': [shotID], 'project': project } # create the note noteID = self.sg.create('Note', data) return noteID def versionCreate(self, project, shot, verName, description, framePath, firstFrame, lastFrame, clientName=None, sourceFile=None, task=None, user=None, final=False, makeThumb=False, makeThumbShot=False): '''Create a version Parameters : (project, shotID, verName, description, framePath, firstFrame, lastFrame, clientName=None, sourceFile=None, task=None) Output : versionID ''' data = { 'project': project, 'code': verName, 'description': description, 'sg_path_to_frames': framePath, #'sg_frame_range': str(firstFrame) + '-' + str(lastFrame), 'sg_first_frame': int(firstFrame), 'sg_last_frame': int(lastFrame), 'sg_status_list': 'rev', 'entity': shot } #if user != None: #data['user'] if task != None: filters = [['content', 'is', task], ['entity', 'is', shot]] taskID = self.sg.find_one('Task', filters) data['sg_task'] = taskID #if final == True and 'send # in case we're putting a client version in here we need this code. # we are expecting a field called self.sg_client_name in the version table. # please make sure you create this in the shotgun setup # read the schema and if the client_name is not found, create it. ''' versionFields = self.sg.schema_field_read('Version') if 'sg_client_name' not in versionFields and clientName != None: newField = self.sg.schema_field_create('Version','text','Client Name') if clientName != None : data['sg_client_name'] = clientName #'user': {'type':'HumanUser', 'id':165} } # here we need to create a field for storing the source file that created this version. # if it's not there, create the field, and if it's there just update it. if 'sg_source_file' not in versionFields and sourceFile != None: newField = self.sg.schema_field_create('Version','text','Source File') if sourceFile != None: data['sg_source_file'] = sourceFile ''' versionData = self.sg.create('Version', data) # handle the thumbnail grabbing here middleFrame = (int(firstFrame) + int(lastFrame)) / 2 padding, padString = fxpipe.framePad(framePath) paddedFrame = padString % (middleFrame) if makeThumb == True: thumbData = self.sg.upload_thumbnail( 'Version', versionData['id'], framePath.replace(padding, paddedFrame)) if makeThumbShot == True: thumbData = self.sg.upload_thumbnail( 'Shot', shot['id'], framePath.replace(padding, paddedFrame)) return versionData #add a task version to the system def versionCreateTask(self, project, shot, verName, description, framePath, firstFrame, lastFrame, task, sourceFile=''): ''' DEPRECATED : USE versionCreate instead with the task='TASKNAME' Parameters : (project, shot, verName, description, framePath, firstFrame, lastFrame, task, sourceFile = '') Output : Version ID ''' filters = [['content', 'is', task], ['entity', 'is', shot]] taskID = self.sg.find_one('Task', filters) data = { 'project': project, 'code': verName, 'description': description, 'self.sg_path_to_frames': framePath, 'frame_range': str(firstFrame) + '-' + str(lastFrame), 'self.sg_first_frame': firstFrame, 'self.sg_last_frame': lastFrame, #'self.sg_uploaded_movie': '/Users/throb/Downloads/test.m4v', #'self.sg_first_frame': 1, #'self.sg_last_frame': 100, 'self.sg_status_list': 'rev', 'self.sg_task': taskID, 'entity': shot } # here we need to create a field for storing the source file that created this version. # if it's not there, create the field, and if it's there just update it. try: tmp2 = {} tmp2 = tmp['self.sg_source_file'] except: newField = self.sg.schema_field_create('Version', 'text', 'Source File') if sourceFile != '': data['self.sg_source_file'] = sourceFile return self.sg.create('Version', data) # look for specific version def versionFind(self, versionID): '''Find all versions in a shot with most recent first Parameters : (shotID) Output : Version data: ['sg_version_type', 'open_notes_count', 'code', 'playlists', 'sg_task', 'image', 'updated_at', 'sg_output', 'sg_path_to_frames', 'tasks', 'frame_range', 'id', 'description', 'sg_uploaded_movie_webm', 'open_notes', 'tank_published_file', 'task_template', 'created_by', 'sg_movie_type', 'sg_status_list', 'notes', 'sg_client_name', 'sg_uploaded_movie_mp4', 'updated_by', 'sg_send_for_final', 'user', 'sg_uploaded_movie_frame_rate', 'entity', 'step_0', 'sg_client_version', 'sg_uploaded_movie_transcoding_status', 'created_at', 'sg_qt', 'project', 'filmstrip_image', 'tag_list', 'frame_count', 'flagged'] ''' retFields = self.getFields('Version') return self.sg.find('Version', [['id', 'is', versionID]], retFields, [{ 'field_name': 'created_at', 'direction': 'desc' }])[0] # look for versions in a shot: def versionFindShot(self, shotID): '''Find all versions in a shot with most recent first Parameters : (shotID) Output : Version data: ['sg_version_type', 'open_notes_count', 'code', 'playlists', 'sg_task', 'image', 'updated_at', 'sg_output', 'sg_path_to_frames', 'tasks', 'frame_range', 'id', 'description', 'sg_uploaded_movie_webm', 'open_notes', 'tank_published_file', 'task_template', 'created_by', 'sg_movie_type', 'sg_status_list', 'notes', 'sg_client_name', 'sg_uploaded_movie_mp4', 'updated_by', 'sg_send_for_final', 'user', 'sg_uploaded_movie_frame_rate', 'entity', 'step_0', 'sg_client_version', 'sg_uploaded_movie_transcoding_status', 'created_at', 'sg_qt', 'project', 'filmstrip_image', 'tag_list', 'frame_count', 'flagged'] ''' retFields = self.getFields('Version') return self.sg.find('Version', [['entity', 'is', shotID]], retFields, [{ 'field_name': 'created_at', 'direction': 'desc' }]) def versionFindLatest(self, shotID): '''Find only the most recent version Parameters : (shotID) Output : Version data: ['sg_version_type', 'open_notes_count', 'code', 'playlists', 'sg_task', 'image', 'updated_at', 'sg_output', 'sg_path_to_frames', 'tasks', 'frame_range', 'id', 'description', 'sg_uploaded_movie_webm', 'open_notes', 'tank_published_file', 'task_template', 'created_by', 'sg_movie_type', 'sg_status_list', 'notes', 'sg_client_name', 'sg_uploaded_movie_mp4', 'updated_by', 'sg_send_for_final', 'user', 'sg_uploaded_movie_frame_rate', 'entity', 'step_0', 'sg_client_version', 'sg_uploaded_movie_transcoding_status', 'created_at', 'sg_qt', 'project', 'filmstrip_image', 'tag_list', 'frame_count', 'flagged'] ''' retFields = self.getFields('Version') return self.sg.find_one('Version', [['entity', 'is', shotID]], retFields, [{ 'field_name': 'created_at', 'direction': 'desc' }]) # search for the latest task given shotID and task info def versionFindLatestTask(self, shotID, task): retFields = self.getFields('Version') # first look for the task and get the ID filters = [['content', 'is', task], ['entity', 'is', shotID]] taskID = self.sg.find_one('Task', filters) # then look for the latest #version using the task ID. note that we need to use the [0] or else we're sending the array versus the hash versionLatest = self.sg.find_one( 'Version', [['entity', 'is', shotID], ['self.sg_task', 'is', taskID]], retFields, [{ 'field_name': 'created_at', 'direction': 'desc' }]) return versionLatest ## The following requires a field called "client_version" be added to shotgun def versionClientUpdate(self, shotID, version, clientVersionName='Client Version'): '''This takes the shotID and version (int) and updates the shot with this client version number Sometimes the client wants to see different version numbers versus the internal ones. This option allows for it. You will need to create a field. Client Version is what I have used but you can specify what you want here. Parameters: (shotID, version, clientVersionName ='Client Version') Output : Version data ''' sgFieldName = 'sg_' + clientVersionName.lower().replace(' ', '_') data = {sgFieldName: version} try: result = self.sg.update('Shot', shotID['id'], data) except: newField = self.sg.schema_field_create('Shot', 'number', clientVersionName) result = self.sg.update('Shot', shotID['id'], data) return result def uploadQT(self, entityType, item, path): '''Upload a file to shotgun in the 'self.sg_qt' field. If you do this for a shot, you will need to add this to a field the field should be called 'qt' as shotgun will add the self.sg_ to it Shotgun provides the self.sg_qt for versions automatically Parameters: (entity,item,path) uploadQT ('Version',versionData, '/my/file.mov') ''' # Make sure first letter is capitalized entity = entityType.capitalize() # upload that mother if entity.lower() == 'shot': try: result = self.sg.upload(entity, item['id'], path, 'sg_qt') except: newField = self.sg.schema_field_create('Shot', 'url', 'QT') result = self.sg.upload(entity, item['id'], path, 'sg_qt') elif entity.lower() == 'version': result = self.sg.upload(entity, item['id'], path, 'sg_uploaded_movie') return result def versionClientGet(self, shotID, clientVersion='Client Version'): '''Get latest client version number Parameters : (hotID, clientVersion='Client Version') Output : Version data ''' sgFieldName = 'sg_' + clientVersionName.lower().replace(' ', '_') try: currentVersion = shotID[sgFieldName] except: currentVersion = 0 if currentVersion == None: return 0 return currentVersion def playlistFind(self, project, playlistName): '''Search for a playlist given a project and name Parameters : (project, playlistName) Output : playlist data: ['code', 'description', 'versions', 'created_at', 'sg_cinesync_session_url', 'updated_at', 'created_by', 'project', 'filmstrip_image', 'notes', 'image', 'updated_by', 'sg_cinesync_session_key', 'sg_status', 'tag_list', 'id', 'sg_date_and_time'] ''' retFields = self.getFields('Playlist') return self.sg.find_one( 'Playlist', [['code', 'is', playlistName], ['project', 'is', project]], retFields) def playlistCreate(self, project, playlistName, playlistDescription=''): '''Create a playlist given a playlist name Parameters : (project, playlistName, playlistDescription='') Output : playlist data ''' data = { 'project': project, 'code': playlistName, 'description': playlistDescription } return self.sg.create('Playlist', data) # Add a version to a playlist def playlistAddVersion(self, project, playlistName, version): ''' Description :\n This adds a version (existing version in the system) to a playlist.\n You need to give it: (in order)\r shotgun connection class\r project (dict of the project info including name and id)\r playlist name (string of the name of the playlist)\r version (dict of the version you wish to add\n It will return with a dict of the playlist ''' my_playlist_list = self.sg.find_one( 'Playlist', [['code', 'is', playlistName], ['project', 'is', project]], ['versions']) if len(my_playlist_list): ver_list = my_playlist_list['versions'] ver_list.append({ 'type': 'Version', 'name': version['code'], 'id': version['id'] }) result = self.sg.update('Playlist', my_playlist_list['id'], {'versions': ver_list}) return result def playlistInfo(self, project, playlistName): '''Get playlist info (eg version name and description) Parameters : (project, playlistName) Output : version data ''' data = [] versionData = [] retFields = self.getFields('Version') for versionInPlaylist in self.sg.find_one( 'Playlist', [['code', 'is', playlistName], ['project', 'is', project]], ['versions'])['versions']: data.append( self.sg.find_one('Version', [['id', 'is', versionInPlaylist['id']]], retFields)) #for items in data: # versionData.append({'name':items['code'],'desc':items['description'],'first_frame':items['self.sg_first_frame}) return data def getTimeShot(self, shot): '''Given shot (as dict) return total time on shot as [0] and other times for each task on shot ''' outputData = [] retFields = ['content', 'time_logs_sum'] totalTime = 0 for curTask in shot['tasks']: taskData = self.sg.find_one('Task', [['id', 'is', curTask['id']]], fields=retFields) totalTime += taskData['time_logs_sum'] outputData.append({ 'name': taskData['content'], 'time': taskData['time_logs_sum'] }) outputData.insert(0, {'name': shot['code'], 'time': totalTime}) return outputData
class genericUtils: def __init__(self): self.sg = Shotgun('https://' + URL,name,API) def getFields (self, entity): '''get the fields for a type/entity as a list so we can pass it as an arg easily this is used all the time to make sure we get all the fields that we may ever need for a type/entity ''' allFields = [] fields = self.sg.schema_field_read(entity) for field in fields: allFields.append(field) return allFields def project (self, project): '''Gets the Shotgun project name and ID ''' retFields = self.getFields('Project') project = project.replace('_', ' ') return self.sg.find_one("Project", [["name", "is", project]], retFields ) def sequence (self, project, sequence): '''Returns the shotgun sequence name and ID Parameters : (project, sequence) ''' retFields = self.getFields('Sequence') return self.sg.find_one("Sequence", [["code", "is", sequence],['project','is',project]], retFields) def shot (self, project, shot): '''Returns the shotgun shot name and ID Parameters : (project, shot) ''' retFields = self.getFields('Shot') return self.sg.find_one('Shot',[['code','is',shot],['project','is',project]],retFields) def createProject (self, project): '''Creates a project in Shotgun given a project name Parameters : (project) ''' filters = [['code','is','a']] template = self.sg.find_one('Project',[['name','is','a']],['layout_project','id']) data = {'name':project, 'layout_project': template } return self.sg.create('Project',data) def createSequence (self, project, sequence): '''Creates a sequence in shotgun given Parameters : (project, sequence) ''' data = {'project': {"type":"Project","id": project['id']}, 'code': sequence} return self.sg.create('Sequence', data) def createShot (self, project, shot, seq='', taskTemplateName=''): '''Creates a sequence in shotgun given Parameters : (project, shot, seq='', taskTemplateName='Basic shot template' ''' filters = [['code','is',taskTemplateName ]] template = self.sg.find_one('TaskTemplate',filters) data = { 'project': {"type":"Project","id": project['id']}, 'code': shot, 'task_template' : template, 'description': '', 'self.sg_sequence': seq, 'self.sg_status_list': 'wtg' } result = self.sg.create('Shot', data) return result def notesFind (self, shotID): '''Find all notes on a shot Parameters : (shotID) Output : Note data : ['tasks', 'attachments', 'updated_at', 'replies', 'id', 'subject', 'playlist', ' addressings_to', 'created_by', 'content', 'sg_status_list', 'reply_content', 'updated_by', 'addressings_cc', 'read_by_current_user', 'user', 'note_links', 'created_at', 'sg_note_from', 'project', 'sg_note_type', 'tag_list'] ''' note = self.sg.find('Note',[['note_links','is', shotID]],['subject','content', 'created_at'],[{'field_name':'created_at','direction':'desc'}]) return note def notesFindLatest (self, shotID): '''Find the latest note on a shot Parameters : (shotID) Call with notesFindLatest(shot)['content'] for the note content only Output : Note data: ['tasks', 'attachments', 'updated_at', 'replies', 'id', 'subject', 'playlist', ' addressings_to', 'created_by', 'content', 'sg_status_list', 'reply_content', 'updated_by', 'addressings_cc', 'read_by_current_user', 'user', 'note_links', 'created_at', 'sg_note_from', 'project', 'sg_note_type', 'tag_list'] ''' note = self.notesFind(shotID)[0] return note def notesCreate(self, project, shotID, subject, content): '''Create a note for a shot given Parameters : (project, shotID, subject, content) Output : noteID ''' # enter data here for a note to create data = {'subject':subject,'content':content,'note_links':[shotID],'project':project} # create the note noteID = self.sg.create('Note',data) return noteID def versionCreate(self, project, shot, verName, description, framePath, firstFrame, lastFrame, clientName=None, sourceFile=None, task=None, user=None, final=False, makeThumb=False, makeThumbShot=False): '''Create a version Parameters : (project, shotID, verName, description, framePath, firstFrame, lastFrame, clientName=None, sourceFile=None, task=None) Output : versionID ''' data = {'project': project, 'code': verName, 'description': description, 'sg_path_to_frames': framePath, #'sg_frame_range': str(firstFrame) + '-' + str(lastFrame), 'sg_first_frame' : int(firstFrame), 'sg_last_frame' : int(lastFrame), 'sg_status_list': 'rev', 'entity': shot} #if user != None: #data['user'] if task != None: filters = [['content','is',task],['entity','is',shot]] taskID = self.sg.find_one('Task',filters) data['sg_task']=taskID #if final == True and 'send # in case we're putting a client version in here we need this code. # we are expecting a field called self.sg_client_name in the version table. # please make sure you create this in the shotgun setup # read the schema and if the client_name is not found, create it. ''' versionFields = self.sg.schema_field_read('Version') if 'sg_client_name' not in versionFields and clientName != None: newField = self.sg.schema_field_create('Version','text','Client Name') if clientName != None : data['sg_client_name'] = clientName #'user': {'type':'HumanUser', 'id':165} } # here we need to create a field for storing the source file that created this version. # if it's not there, create the field, and if it's there just update it. if 'sg_source_file' not in versionFields and sourceFile != None: newField = self.sg.schema_field_create('Version','text','Source File') if sourceFile != None: data['sg_source_file'] = sourceFile ''' versionData = self.sg.create('Version',data) # handle the thumbnail grabbing here middleFrame = (int(firstFrame) + int(lastFrame)) / 2 padding, padString = fxpipe.framePad(framePath) paddedFrame = padString % (middleFrame) if makeThumb == True: thumbData = self.sg.upload_thumbnail('Version', versionData['id'], framePath.replace(padding,paddedFrame)) if makeThumbShot == True: thumbData = self.sg.upload_thumbnail('Shot', shot['id'], framePath.replace(padding,paddedFrame)) return versionData #add a task version to the system def versionCreateTask(self, project, shot, verName, description, framePath, firstFrame, lastFrame, task, sourceFile = ''): ''' DEPRECATED : USE versionCreate instead with the task='TASKNAME' Parameters : (project, shot, verName, description, framePath, firstFrame, lastFrame, task, sourceFile = '') Output : Version ID ''' filters = [['content','is',task],['entity','is',shot]] taskID = self.sg.find_one('Task',filters) data = {'project': project, 'code': verName, 'description': description, 'self.sg_path_to_frames': framePath, 'frame_range': str(firstFrame) + '-' + str(lastFrame), 'self.sg_first_frame' : firstFrame, 'self.sg_last_frame' : lastFrame, #'self.sg_uploaded_movie': '/Users/throb/Downloads/test.m4v', #'self.sg_first_frame': 1, #'self.sg_last_frame': 100, 'self.sg_status_list': 'rev', 'self.sg_task': taskID, 'entity': shot} # here we need to create a field for storing the source file that created this version. # if it's not there, create the field, and if it's there just update it. try: tmp2 = {} tmp2 = tmp['self.sg_source_file'] except: newField = self.sg.schema_field_create('Version','text','Source File') if sourceFile != '': data['self.sg_source_file'] = sourceFile return self.sg.create('Version',data) # look for specific version def versionFind(self, versionID): '''Find all versions in a shot with most recent first Parameters : (shotID) Output : Version data: ['sg_version_type', 'open_notes_count', 'code', 'playlists', 'sg_task', 'image', 'updated_at', 'sg_output', 'sg_path_to_frames', 'tasks', 'frame_range', 'id', 'description', 'sg_uploaded_movie_webm', 'open_notes', 'tank_published_file', 'task_template', 'created_by', 'sg_movie_type', 'sg_status_list', 'notes', 'sg_client_name', 'sg_uploaded_movie_mp4', 'updated_by', 'sg_send_for_final', 'user', 'sg_uploaded_movie_frame_rate', 'entity', 'step_0', 'sg_client_version', 'sg_uploaded_movie_transcoding_status', 'created_at', 'sg_qt', 'project', 'filmstrip_image', 'tag_list', 'frame_count', 'flagged'] ''' retFields = self.getFields('Version') return self.sg.find('Version',[['id','is',versionID]],retFields,[{'field_name':'created_at','direction':'desc'}])[0] # look for versions in a shot: def versionFindShot(self, shotID): '''Find all versions in a shot with most recent first Parameters : (shotID) Output : Version data: ['sg_version_type', 'open_notes_count', 'code', 'playlists', 'sg_task', 'image', 'updated_at', 'sg_output', 'sg_path_to_frames', 'tasks', 'frame_range', 'id', 'description', 'sg_uploaded_movie_webm', 'open_notes', 'tank_published_file', 'task_template', 'created_by', 'sg_movie_type', 'sg_status_list', 'notes', 'sg_client_name', 'sg_uploaded_movie_mp4', 'updated_by', 'sg_send_for_final', 'user', 'sg_uploaded_movie_frame_rate', 'entity', 'step_0', 'sg_client_version', 'sg_uploaded_movie_transcoding_status', 'created_at', 'sg_qt', 'project', 'filmstrip_image', 'tag_list', 'frame_count', 'flagged'] ''' retFields = self.getFields('Version') return self.sg.find('Version',[['entity','is',shotID]],retFields,[{'field_name':'created_at','direction':'desc'}]) def versionFindLatest(self, shotID): '''Find only the most recent version Parameters : (shotID) Output : Version data: ['sg_version_type', 'open_notes_count', 'code', 'playlists', 'sg_task', 'image', 'updated_at', 'sg_output', 'sg_path_to_frames', 'tasks', 'frame_range', 'id', 'description', 'sg_uploaded_movie_webm', 'open_notes', 'tank_published_file', 'task_template', 'created_by', 'sg_movie_type', 'sg_status_list', 'notes', 'sg_client_name', 'sg_uploaded_movie_mp4', 'updated_by', 'sg_send_for_final', 'user', 'sg_uploaded_movie_frame_rate', 'entity', 'step_0', 'sg_client_version', 'sg_uploaded_movie_transcoding_status', 'created_at', 'sg_qt', 'project', 'filmstrip_image', 'tag_list', 'frame_count', 'flagged'] ''' retFields = self.getFields('Version') return self.sg.find_one('Version',[['entity','is',shotID]],retFields,[{'field_name':'created_at','direction':'desc'}]) # search for the latest task given shotID and task info def versionFindLatestTask(self, shotID, task): retFields = self.getFields('Version') # first look for the task and get the ID filters = [['content','is',task],['entity','is',shotID]] taskID = self.sg.find_one('Task',filters) # then look for the latest #version using the task ID. note that we need to use the [0] or else we're sending the array versus the hash versionLatest = self.sg.find_one('Version',[['entity','is',shotID],['self.sg_task','is',taskID]],retFields,[{'field_name':'created_at','direction':'desc'}]) return versionLatest ## The following requires a field called "client_version" be added to shotgun def versionClientUpdate (self, shotID, version, clientVersionName ='Client Version'): '''This takes the shotID and version (int) and updates the shot with this client version number Sometimes the client wants to see different version numbers versus the internal ones. This option allows for it. You will need to create a field. Client Version is what I have used but you can specify what you want here. Parameters: (shotID, version, clientVersionName ='Client Version') Output : Version data ''' sgFieldName = 'sg_' + clientVersionName.lower().replace(' ','_') data = { sgFieldName: version} try: result = self.sg.update('Shot', shotID['id'], data) except: newField = self.sg.schema_field_create('Shot', 'number', clientVersionName) result = self.sg.update('Shot', shotID['id'], data) return result def uploadQT (self, entityType, item, path): '''Upload a file to shotgun in the 'self.sg_qt' field. If you do this for a shot, you will need to add this to a field the field should be called 'qt' as shotgun will add the self.sg_ to it Shotgun provides the self.sg_qt for versions automatically Parameters: (entity,item,path) uploadQT ('Version',versionData, '/my/file.mov') ''' # Make sure first letter is capitalized entity = entityType.capitalize() # upload that mother if entity.lower() == 'shot': try: result = self.sg.upload (entity, item['id'], path,'sg_qt') except: newField = self.sg.schema_field_create('Shot', 'url', 'QT') result = self.sg.upload (entity, item['id'], path,'sg_qt') elif entity.lower() == 'version': result = self.sg.upload (entity, item['id'], path,'sg_uploaded_movie') return result def versionClientGet (self, shotID, clientVersion='Client Version'): '''Get latest client version number Parameters : (hotID, clientVersion='Client Version') Output : Version data ''' sgFieldName = 'sg_' + clientVersionName.lower().replace(' ','_') try : currentVersion = shotID[sgFieldName] except : currentVersion = 0 if currentVersion == None: return 0 return currentVersion def playlistFind (self, project, playlistName): '''Search for a playlist given a project and name Parameters : (project, playlistName) Output : playlist data: ['code', 'description', 'versions', 'created_at', 'sg_cinesync_session_url', 'updated_at', 'created_by', 'project', 'filmstrip_image', 'notes', 'image', 'updated_by', 'sg_cinesync_session_key', 'sg_status', 'tag_list', 'id', 'sg_date_and_time'] ''' retFields = self.getFields('Playlist') return self.sg.find_one('Playlist',[['code','is',playlistName],['project','is',project]],retFields) def playlistCreate (self, project, playlistName, playlistDescription=''): '''Create a playlist given a playlist name Parameters : (project, playlistName, playlistDescription='') Output : playlist data ''' data = {'project':project,'code':playlistName, 'description':playlistDescription} return self.sg.create('Playlist',data) # Add a version to a playlist def playlistAddVersion (self, project, playlistName, version): ''' Description :\n This adds a version (existing version in the system) to a playlist.\n You need to give it: (in order)\r shotgun connection class\r project (dict of the project info including name and id)\r playlist name (string of the name of the playlist)\r version (dict of the version you wish to add\n It will return with a dict of the playlist ''' my_playlist_list = self.sg.find_one('Playlist',[['code','is',playlistName],['project','is',project]],['versions']); if len(my_playlist_list): ver_list = my_playlist_list['versions']; ver_list.append({'type':'Version','name':version['code'],'id':version['id']}) result = self.sg.update('Playlist', my_playlist_list['id'], {'versions' : ver_list}) return result def playlistInfo (self, project, playlistName): '''Get playlist info (eg version name and description) Parameters : (project, playlistName) Output : version data ''' data = [] versionData = [] retFields = self.getFields('Version') for versionInPlaylist in self.sg.find_one('Playlist',[['code','is',playlistName],['project','is',project]],['versions'])['versions']: data.append (self.sg.find_one('Version',[['id','is',versionInPlaylist['id']]],retFields)) #for items in data: # versionData.append({'name':items['code'],'desc':items['description'],'first_frame':items['self.sg_first_frame}) return data def getTimeShot(self, shot): '''Given shot (as dict) return total time on shot as [0] and other times for each task on shot ''' outputData = [] retFields = ['content','time_logs_sum'] totalTime = 0 for curTask in shot['tasks']: taskData = self.sg.find_one('Task',[['id','is',curTask['id']]],fields=retFields) totalTime += taskData['time_logs_sum'] outputData.append({'name':taskData['content'],'time':taskData['time_logs_sum']}) outputData.insert(0,{'name':shot['code'],'time':totalTime}) return outputData
class ShotgunUtils(): ''' a light version of the shotgun utils class to connect and update shotgun task for external artist ''' def __init__(self): ''' creates the connection to the shotgun site by api ''' ''' shotgun conection ''' SERVER_PATH = "https://hcpstudio.shotgunstudio.com" SCRIPT_NAME = 'Tracker' SCRIPT_KEY = '99b5c166044037cc2d04646b1dfd58b2f44e8a146b710b425b8f561f2a21e49d' self.sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) self.userId = None self.userDic = {} self.tasks = None self.projectPath = None def getsgParameters(self, sgType, parameter=None): schema = self.sg.schema_field_read(sgType, parameter) print schema def getUserId(self, userName): filters = [['name', 'is', userName]] field = ['id', 'name', 'sg_projectpath', 'sg_keyword', 'login'] user = self.sg.find_one('HumanUser', filters, field) if user: self.userId = user['id'] self.projectPath = user['sg_projectpath'] self.userDic = user return user['id'] else: print "no {0} User found ".format(userName) return None def taskByUser(self): if not self.userId == None: filter = [[ 'task_assignees', 'is', { 'type': 'HumanUser', 'id': self.userId } ], ['sg_status_list', 'is_not', 'fin'], ['sg_status_list', 'is_not', 'apr'], ['sg_status_list', 'is_not', 'cmpt']] fields = [ 'id', 'content', 'sg_status_list', 'start_date', 'due_date', 'sg_complexity', 'sg_priority_1', 'sg_note', 'project', 'entity', 'sg_digitalmedia', 'sg_displayname' ] order = [{ 'field_name': 'due_date', 'direction': 'asc' }, { 'field_name': 'sg_priority_1', 'direction': 'asc' }, { 'field_name': 'sg_complexity', 'direction': 'desc' }] taskList = self.sg.find('Task', filter, fields, order) if taskList: self.tasks = taskList return taskList else: self.tasks = [] print "no task Asigned to: ", self.userId return taskList else: taskList = [] print "no Id found" return taskList def getTaskById(self, taskId): filter = [['id', 'is', taskId]] fields = [ 'id', 'content', 'sg_status_list', 'start_date', 'due_date', 'sg_complexity', 'sg_priority_1', 'sg_note', 'project', 'entity', 'sg_digitalmedia', 'sg_displayname' ] task = self.sg.find_one('Task', filter, fields) if task: return task else: print 'no task found' return None def updateStatusFromUser(self, taskId, status): task = self.getTaskById(taskId) if task: project = task['project'] sgStatus = status data = {'project': project, 'sg_status_list': sgStatus} self.sg.update('Task', taskId, data) return 1 else: print 'No task by this id' return None def updateProjectPath(self, projectPath): data = {'sg_projectpath': projectPath} self.sg.update('HumanUser', self.userId, data) def getNotes(self, sgTaskId): task = self.getTaskById(sgTaskId) if task: filters = [['tasks', 'is', task]] fields = ['content', 'created_at', 'user', 'addressings_to'] order = [{'field_name': 'created_at', 'direction': 'asc'}] notes = self.sg.find('Note', filters, fields, order) return notes else: print 'no Task' return None def createNote(self, taskId, content): task = self.getTaskById(taskId) if task: data = { 'project': task['project'], 'content': content, 'tasks': [task], 'user': self.userDic, 'subject': 'Note' } note = self.sg.create('Note', data) return note['id'] else: return None def uploadAttachment(self, taskId, filePath, tag): task = self.getTaskById(taskId) if task: entity = task['entity'] if entity: entityType = entity['type'] entityId = entity['id'] uploadedfile = self.sg.upload(entityType, entityId, filePath) if uploadedfile: data = {'sg_type': tag, 'sg_taskid': taskId} self.sg.update('Attachment', uploadedfile, data) return uploadedfile else: return None else: print 'no entity set' return None def downloadAttachment(self, taskId, downloadPath, parent=None): filters = [['sg_taskid', 'is', taskId], ['sg_type', 'is', 'REFERENCE']] fields = ['id', 'attachment_links', 'filename', 'created_at'] attachments = self.sg.find('Attachment', filters, fields) if attachments: progressBar = QtGui.QProgressBar(parent) progressBar.show() size = len(attachments) for x, attach in enumerate(attachments): extension = path.splitext(attach['filename']) dt = attach['created_at'].strftime("%Y_%m_%d_%H-%M-%S") name = attach['attachment_links'][0]['id'] namePadded = '{0}_{3}.{1:04d}{2}'.format( name, x, extension[-1], dt) fullPath = path.join(downloadPath, namePadded) dwFile = self.sg.download_attachment(attach, fullPath, attach['id']) progressBar.setValue(((x + 1) / size) * 100) progressBar.close() return attachments else: return None def uploadReference(self, entityType, entityId, filePath, tag, taskId): uploadedfile = self.sg.upload(entityType, entityId, filePath) if uploadedfile: data = { 'sg_type': tag, 'sg_type': 'REFERENCE', 'sg_taskid': taskId } self.sg.update('Attachment', uploadedfile, data) return uploadedfile else: return None
if method == 'find': result = sg.find(payload['entity'], payload['filters'], payload['fields'], payload['order'], payload['filter_operator'], payload['limit'], payload['retired_only']) elif method == 'find_one': result = sg.find_one(payload['entity'], payload['filters'], payload['fields'], payload['order'], payload['filter_operator']) elif method == 'create': result = sg.create(payload['entity'], payload['data']) elif method == 'update': result = sg.update(payload['entity'], payload['id'], payload['data']) elif method == 'delete': result = sg.delete(payload['entity'], payload['id']) elif method == 'upload': result = sg.upload(payload['entity'], payload['id'], payload['path'], payload['field_name'], payload['display_name']) elif method == 'upload_thumbnail': result = sg.upload_thumbnail(payload['entity'], payload['id'], payload['path']) elif method == 'schema_field_read': result = sg.schema_field_read(payload['entity']) elif method == 'schema_field_create': result = sg.schema_field_create(payload['entity'], payload['type'], payload['name'], payload['attrs']) elif method == '_url_for_attachment_id': entity_id = payload['id'] # Do a lot of legwork (based on Shotgun.download_attachment()) sid = sg._get_session_token() domain = urlparse(sg.base_url)[1].split(':',1)[0] cj = cookielib.LWPCookieJar() c = cookielib.Cookie('0', '_session_id', sid, None, False, domain, False, False, "/", True, False, None, True, None, None, {}) cj.set_cookie(c) cookie_handler = urllib2.HTTPCookieProcessor(cj) urllib2.install_opener(urllib2.build_opener(cookie_handler)) url = '%s/file_serve/attachment/%s' % (sg.base_url, entity_id)
class ShotgunUtils(): ''' this module is a collection of functions to conect the Asset manager to shogun studio website, to update, create and manages all attributes and parameters from the different entities. ''' def __init__(self): ''' creates the connection to the server and connects to database. creates list of Ids form the database collections that needs to convert to shotgun collections ''' SERVER_PATH = "https://hcpstudio.shotgunstudio.com" SCRIPT_NAME = 'sgApi' SCRIPT_KEY = '3899a8466f2cea694c2ba5341d871da845509d18d96a4feb7fb8d147de0fa819' self.sg = Shotgun(SERVER_PATH, SCRIPT_NAME, SCRIPT_KEY) self.dbObjectID = ObjectId() master = DaoMaster() session = DaoMaster.getSession() self.itemInstance = session.getItemsDao() self.ItemStatusList = ['rdy', 'ip', 'app', 'crnt', 'outd','dep', 'vari', 'rej'] self.ItemType = ['Source', 'Prop', 'Environment', 'Character', 'Rig', 'Fx', 'Template', 'Geometry', 'Art', 'Shader', 'Texture', 'Cache', 'ImageSequence', 'DCC', 'None'] self.ItemClass = ['Item', 'Asset', 'superAsset'] def getParameterSchema(self, fieldType, fieldName = None): ''' utility function to search fields in a given entity. :param fieldType: entity to search parameters 'Project', 'Sequence', 'Shot', 'Asset', 'Version', etc. :param fieldName: name of the field to search 'id', 'name', 'coce', etc. :return: retruns a dictionary with the properties of given parameter ''' squemaDic = self.sg.schema_field_read(fieldType, fieldName) print squemaDic for field in squemaDic: print field return squemaDic def getEntities(self): ''' utility function to find all the Entities in shotgun for developing :return: renturn a list of all entities ''' squemaDic = self.sg.schema_entity_read() for entity in squemaDic: print entity return squemaDic def createProject(self, sgName, sgStatus, sgType): ''' creates a Project using the given name, status, type,start date, end date. the status parameter is a list:: Bidding Active Lost Hold the type parameter is a list: Feature Episodic Commercial Game Cinematic AAA Game Mobile Game Audio Mocap Misc ''' data = {'name': sgName, 'sg_status': 'Active', 'sg_type': 'Feature'} fields = ['id'] project = self.sg.create('Project', data, fields) return project def createSequence(self, projectID, sqName): ''' creates a Sequence for the project set by the Id, :return: a dictionary containing the basic info of the sequence ''' data = {'project': {'type': 'Project', 'id': projectID}, 'code': sqName} fields = ['id'] sequence = self.sg.create('Sequence', data, fields) print sequence return sequence def createShot(self, projectID, shotName, sqID): data = {'project': {'type': 'Project', 'id': projectID}, 'code': shotName, 'sg_sequence': {'type': 'Sequence', 'id': sqID}} fields = ['id'] shot = self.sg.create('Shot', data, fields) print shot return shot def createItem(self, projectID, itemName, itemType): ''' creates an Item from an existing one inside the assetManager, use the parameters of given mongo objcet and updates the id of the mongo object with the shotgunId attribute of the mongo object. :return: a dictionary with the parameters defined in shotgun ''' data = {'project': {'type': 'Project', 'id': projectID}, 'code': itemName, 'sg_asset_type': itemType} fields = ['id'] item = self.sg.create('Asset', data, fields) print item return item def createDigitalMedia(self, projectID, dmName, dmType, taskID, entityType, entityID): data = {'project': {'type': 'Project', 'id': projectID}, 'code': dmName, 'sg_version_type': dmType, 'sg_task': {'type': 'Task', 'id': taskID}, 'entity': {'type': entityType, 'id': entityID} } fields = ['id'] dm = self.sg.create('Version', data, fields) print dm return dm def createUser(self, firstName, lastName, userMail): data = {'firstname': firstName, 'lastname': lastName, 'email': userMail, 'sg_status_list': 'dis', 'login': '******'.format(firstName,lastName)} fields = ['id'] user = self.sg.create('HumanUser', data, fields) print user return user def createTask(self, projectID, entityType, entityID, taskName): data = {'project': {'type': 'Project', 'id': projectID}, 'task_assignees': [{'type': 'HumanUser', 'id': 86, 'name': 'Huevo Cartoon'}], 'content': taskName, 'entity': {'type': entityType, 'id': entityID} } fields = ['id'] task = self.sg.create('Task', data, fields) print task return task
from shotgun_api3 import Shotgun import json SCRIPT_NAME = 'Samuel - API' SCRIPT_KEY = '2b3f3b6e442242c067501a9e17503bac1d27b6ea244a4e4b5987e26d5f6520e2' sg = Shotgun("https://objeus.shotgunstudio.com", SCRIPT_NAME, SCRIPT_KEY) also = ['code', 'description'] ignore = ['sg_status_list', 'sg_opent_tickets'] spellfields = sg.schema_field_read('CustomEntity01') releventfields = {} returnfields = [] for field in spellfields: if ('sg_' in field or field in also) and field not in ignore: returnfields.append(field) if 'sg_' in field: releventfields[field] = field[3:].replace('_', '') if field == 'code': releventfields[field] = "name" if field == 'description': releventfields[field] = "desc" sg_spells = sg.find('CustomEntity01', [], returnfields) spells = {} for spell in sg_spells: spells[spell['code']] = {} for field in spell: