Example #1
0
    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)
Example #2
0
 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)
Example #3
0
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']])
Example #4
0
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']])
Example #5
0
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')
Example #6
0
    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)
Example #7
0
 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)
Example #8
0
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
            })
Example #9
0
    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
Example #10
0
def Shotgun():
    return Session(shotgun_api3_registry.connect('sgviewer'))