need some hep with a event listener
3 3

5 posts in this topic

Hello. I am trying to create an event Listener that basically prevents people from moving assets inside ftrack.

I found an example and tried to do it my self, but Iam getting some issues.

the script is suscribed to 'topic=ftrack.update', and will always revert changes,but it seems the "revert function" also activates the listener,

so it enters in an infinite loop.

these are the functions used in my script. Any help would be very appreciated:

 

def MoveAssetsBlock(session, event):
    reverted= False
    for entity in event['data'].get('entities', []):

        if (entity.get("entityType") == "task" and entity["action"] == "move"):
            entity_id = entity['entityId']
            
            fObject = session.query("Context where id is '{0}' ".format(entity_id))[0]
            fObject['parent_id'] = entity["changes"]["parent_id"]["old"]
            reverted=True
            
    if reverted:
        try:
            session.commit()
        except Exception:
            session.rollback()
            raise
        

    

    
def register(session, **kw):
    if not isinstance(session, ftrack_api.Session):
        return

    handle_event = functools.partial(
         MoveAssetsBlock, session)
    
    session.event_hub.subscribe('topic=ftrack.update', handle_event)

 

 

Share this post


Link to post
Share on other sites

Although there are a few items in the event that could indicate that this has happened from the web UI, none of the are really reliable.

It is not ideal but I think you could build a dictionary with "original" parent_id. Disclaimer; this is just what I came up with on top of my head:

should_revert = original_parent_ids.get(entity_id) !== new_parent_id

if should_revert:
	# Revert to old_parent_id

if entity_id not in original_parent_ids:
    # Save the original parent id.
    original_parent_ids[entity_id] = old_parent_id

 

Share this post


Link to post
Share on other sites

Hi Eder,

we run into this issue as well. I think you run the event listener on the Ftrack server (needs to run all the time).

Our solution was to run the actions from the Ftrack server with 'Ftrack' user and allow only to the Ftrack user to revert it and skip checking the events generated by Ftrack user.

I hope it makes sens. 

Example:

ALLOWED_USERS = ['ftrack']

def MoveAssetsBlock(session, event):

.....

user_id = event['source'].get('user', {}).get('id', None)

username = session.get('User', user_id)['username']

if username in ALLOWED_USERS:

     continue

else:

    revert 
....

 

Share this post


Link to post
Share on other sites

These action based solutions that correct bad input after the fact can be confusing to users and also have to deal with lots of complexity from potential side-effects. E.g. did some other action run in response to the initial change and that also has to be reverted.

It would be much more interesting if the action could run prior to ftrack performing the change. A 'validation' event of sorts. Obviously the listener would likely have to run on / near the actual ftrack server to give suitable performance, but, for those interested in more validation control, the performance tradeoff might be worth it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
3 3