def __init__(self): sg = Shotgun() self.sg = self.fix = fix = Fixture(sg) proj = fix.Project('Example Project') seqs = [proj.Sequence(code, project=proj) for code in ('AA', 'BB')] shots = [ seq.Shot('%s_%03d' % (seq['code'], i), project=proj) for seq in seqs for i in range(1, 3) ] steps = [ fix.find_or_create('Step', code=code, short_name=code) for code in ('Anm', 'Comp', 'Model') ] tasks = [ shot.Task(step['code'] + ' something', step=step, entity=shot, project=proj) for step in steps for shot in shots ] self.proj = minimal(proj) self.seqs = map(minimal, seqs) self.shots = map(minimal, shots) self.steps = map(minimal, steps) self.tasks = map(minimal, tasks) self.session = Session(self.sg) self.sgfs = SGFS(root=sandbox, session=self.session)
def session(self): # Set the session, building it from a generic Shotgun if nothing was # given. This requires a `shotgun_api3_registry.connect()` function. if not self._shotgun and not self._session: import shotgun_api3_registry self._shotgun = shotgun_api3_registry.connect( auto_name_stack_depth=1) return self._session or Session(self._shotgun)
def callback(event): # Must be setting it to a non-zero version. # NOTE: We MUST check the meta for this, otherwise we are liable to # schedule this job multiple times as the `entity` field is always # up to date. version = event.meta.get('new_value') if not version: log.info('Publish is still being created; skipping') return sg = Session(connect()) entity = sg.merge(event)['entity'] if not entity: log.info('Publish appeares to have been retired; skipping') return entity.fetch(('sg_link', 'sg_link.Task.step.Step.short_name', 'sg_type')) # For now, we only run for the Testing Sandbox. #if event['project']['id'] != 66: # log.info('Project %r in not Testing Sandbox; skipping' % (event['project'].get('name') or event['project']['id'])) # return # Our first job, is to create camera and geocache publishes from generic maya scenes. pub_type = entity.get('sg_type') if pub_type != 'maya_scene': log.info('sg_type %r is not maya_scene; skipping' % pub_type) return step_code = entity.get('sg_link.Task.step.Step.short_name') if step_code not in ('Anim', 'Roto', 'Rotomation'): log.info('sg_link.step.short_code %s is not Anim or Roto; skipping' % step_code) return # TODO: Make sure they don't already exist. log.info('Delegating to sgactions') call_in_subprocess('%s:republish' % __file__, [entity['id']])
def callback(event): sg = Session() version = sg.merge(event.entity) if event.event_type == 'Shotgun_Version_New': shot_name, project = version.fetch(('entity.Shot.name', 'project')) sg.update('Shot', version['entity']['id'], dict(sg_latest_version=version)) m = re.match(r'([A-Z]{2})\d+', shot_name) if not m: print 'Shot name does not match specs.' return seq_code = m.group(1) update_playlist(sg, project, seq_code) elif event.event_type == 'Shotgun_Version_Change': shot = version.fetch('entity') sg.share_thumbnail([shot], source_entity=version, filmstrip_thumbnail=event['attribute_name'] == 'filmstrip_image')
if e.event_type == 'Shotgun_Version_Change': return e.get('attribute_name') in ('image', 'filmstrip_image') __sgevents__ = dict( type='callback', callback=callback, callback_in_subprocess=False, filter=filter, ) if __name__ == '__main__': sg = Session() for seq in sg.find('Sequence', ()): print seq update_playlist(sg, seq['project'], seq['code'][:2]) for shot in sg.find('Shot', ()): version = sg.find_one('Version', [ ('entity', 'is', shot), ], order=[{'field_name':'created_at', 'direction':'desc'}]) print shot, version if version: sg.update('Shot', shot['id'], dict(sg_latest_version=version)) sg.share_thumbnail([shot], source_entity=version, filmstrip_thumbnail=False) sg.share_thumbnail([shot], source_entity=version, filmstrip_thumbnail=True)
def setUp(self): self.shotgun = Shotgun() self.fixture = Fixture(self.shotgun) self.session = Session(self.shotgun, **self.session_kwargs) self.sgfs = self.SGFS(**self.sgfs_kwargs)
def callback(event): sg = Session() print event['entity'] if event['project']['id'] != 74: return "checking project id is not 74 " + str(event['project']['id']) elif event['meta']['new_value'] != 'rev': return "checking new value is not rev" + str( event['meta']['new_value']) elif event['event_type'] != "Shotgun_Task_Change": return "checking: event['event_type']" + str(event['event_type']) else: seq_link = "" task_id = event['entity']['id'] task = sg.find_one('Task', [('id', 'is', task_id)], ['entity']) shot_id = task['entity']['id'] if 'sg_sequence' in task['entity']: seq_id = task['entity']['sg_sequence']['id'] print seq_id seq_type = task['entity']['sg_sequence']['type'] print seq_type seq_name = task['entity']['sg_sequence']['name'] print seq_name seq_link = '\n<https://markmedia.shotgunstudio.com/detail/Shot/' + str( shot_id ) + '|Shot Link> \n<https://markmedia.shotgunstudio.com/detail/Shot/' + str( shot_id) + '#' + str(seq_type) + '_' + str(seq_id) + '_' + str( seq_name) + '|Sequence Link>' print "checking else statement" print event['project']['id'], event['meta']['new_value'], event[ 'event_type'] print "\n" requests.get( 'https://slack.com/api/chat.postMessage', params={ 'channel': SLACK_CHANNEL, 'fallback': 'This is ready for review: ' + str(task['entity']['name']) + '>' + str(event['entity']['name']), 'params': None, 'attachments': json.dumps([{ 'fallback': 'This is ready for review: ' + str(task['entity']['name']) + ' > ' + str(event['entity']['name']), 'title': 'This is ready for review: ' + str(task['entity']['name']) + ' > ' + str(event['entity']['name']), 'text': '<https://markmedia.shotgunstudio.com/detail/Task/' + str(event['entity']['id']) + '/|' + str(task['entity']['name']) + ' ' + str(event['entity']['name']) + ">\nProject: " + str(event['project']['name']) + seq_link }]), 'token': SLACK_TOKEN, 'username': '******', 'as_user': True })
def handle_event(self, event): # Must be setting it to a non-zero version. # NOTE: We MUST check the meta for this, otherwise we are liable to # schedule this job multiple times as the `entity` field is always # up to date. version = event.meta.get('new_value') if not version: self.log.debug('Publish is still being created; skipping') return # Make a clean one every time so that we don't slowly fill up memory. sg = Session() publish = sg.merge(event)['entity'] if not publish: self.log.warning('Publish appears to have been deleted; skipping') return _, login, step_code, step_name, publish_type = publish.fetch(( 'code', 'created_by.HumanUser.login', 'sg_link.Task.step.Step.code', 'sg_link.Task.step.Step.short_name', 'sg_type', )) steps = set((step_code.title(), step_name.title())) related = None for src_types, dst_types, src_steps, func, args, kwargs in self._funcs: # Make sure it is the right type. if publish_type not in src_types: self.log.debug('sg_type %r is not %s; skipping' % (publish_type, '/'.join(sorted(src_types)))) continue # Make sure it is from the correct step. # We've title-cased all step names at this point, and are comparing # against both the step code and name, so this should be forgiving. if src_steps and not src_steps.intersection(steps): self.log.debug('step %s is not %s; skipping' % ('/'.join(sorted(steps)), '/'.join(sorted(src_steps)))) continue # Make sure we haven't already derived it, or are in progress of # deriving it. if related is None: related = get_related_publishes(publish, fields=['code', 'sg_type']) skip = False for x in related: if x['sg_type'] in dst_types: self.log.warning('Derived %s publish %d "%s", already exists; skipping' % ( x['sg_type'], x['id'], x['code'], )) skip = True if skip: continue # If it is a string, dispatch it to Qube. if isinstance(func, basestring): # Run it as the correct user; assume their Shotgun login matches. login = publish.get('created_by.HumanUser.login') user = login.split('@')[0] if login else None qube_args = [publish.minimal] qube_args.extend(args or ()) qube_name = 'Republish %s %s "%s" as %s' % ( publish['sg_type'], publish['id'], publish['code'], '/'.join(sorted(dst_types)) ) import qbfutures future = qbfutures.submit_ext(func, args=qube_args, kwargs=kwargs or {}, name=qube_name, user=user, priority=8000, ) self.log.info('Qube job %d: %s' % (future.job_id, qube_name)) else: func(publish, *(args or ()), **(kwargs or {})) # Only run the first one! return
def Shotgun(): return Session(shotgun_api3_registry.connect('sgviewer'))