Jump to content

Multiple Storage Scenarios


Tim Edelmann

Recommended Posts

Hey there again, 

 

its been a while since my last post..

 

We currently exploring, whats the best way to tell a project, thats all its files, components, asset versions are now stored somewhere else. 

The background for this is, that we want to be able to move a project after its creation. For this we could listen to "ftrack.api.session.configure-location" and configure a custom location. But how can access the storage scenario to setup new mount-points?

 

Is it even possible to set the storage scenario via ftrack_api?

 

 

thanks in advance

 

 

Tim

Link to comment
Share on other sites

What we tried so far...

 

We are getting this error:

ftrack_connect.ui.widget.publisher.Publisher - ERROR - Failed to publish: Failed to transfer component <FileComponent(ccfee77a-266c-4248-9431-bc573e7cc3f4)> data to location <Location("Infected_custom_location", 96865d31-ddb8-4ef9-bbde-79fdc5a7e8dd)> due to error:
    'Session' object has no attribute '__getitem__'
    Transferred component data that may require cleanup: []
Traceback (most recent call last):
  File "c:\python27\lib\site-packages\ftrack_connect-1.1.3-py2.7.egg\ftrack_connect\ui\widget\publisher.py", line 298, in _publish
    component, source=origin_location
  File "c:\python27\lib\site-packages\ftrack_python_api-1.4.0-py2.7.egg\ftrack_api\entity\location.py", line 78, in add_component
    [component], sources=source, recursive=recursive
  File "c:\python27\lib\site-packages\ftrack_python_api-1.4.0-py2.7.egg\ftrack_api\entity\location.py", line 211, in add_components
    transferred=transferred
LocationError: Failed to transfer component <FileComponent(ccfee77a-266c-4248-9431-bc573e7cc3f4)> data to location <Location("Infected_custom_location", 96865d31-ddb8-4ef9-bbde-79fdc5a7e8dd)> due to error:
    'Session' object has no attribute '__getitem__'
    Transferred component data that may require cleanup: []
2018-08-09 13:23:25,811 - root - ERROR - Logging an uncaught exception
Traceback (most recent call last):
  File "c:\python27\lib\site-packages\ftrack_connect-1.1.3-py2.7.egg\ftrack_connect\asynchronous.py", line 21, in exceptHookWrapper
    method(*args, **kwargs)
  File "c:\python27\lib\site-packages\ftrack_connect-1.1.3-py2.7.egg\ftrack_connect\ui\widget\publisher.py", line 298, in _publish
    component, source=origin_location
  File "c:\python27\lib\site-packages\ftrack_python_api-1.4.0-py2.7.egg\ftrack_api\entity\location.py", line 78, in add_component
    [component], sources=source, recursive=recursive
  File "c:\python27\lib\site-packages\ftrack_python_api-1.4.0-py2.7.egg\ftrack_api\entity\location.py", line 211, in add_components
    transferred=transferred
LocationError: Failed to transfer component <FileComponent(ccfee77a-266c-4248-9431-bc573e7cc3f4)> data to location <Location("Infected_custom_location", 96865d31-ddb8-4ef9-bbde-79fdc5a7e8dd)> due to error:
    'Session' object has no attribute '__getitem__'
    Transferred component data that may require cleanup: []

 

We setup a customized version of the Resolver.py, doing this:

 

The Resolver.py listens to:

session.event_hub.subscribe('topic=ftrack.storage-scenario.activate', resolver.activate_storage_scenario)
session.event_hub.subscribe('topic=ftrack.api.session.configure-location', resolver.configure_location)
session.event_hub.subscribe('topic=ftrack.location.request-resolve and source.user.username="{0}"'.format(session.api_user), resolver)

 

in activate_storage_scenario we do the following: 

    def activate_storage_scenario(self, event):
        self.logger.info('activate_storage_scenario was called...\n{0}'.format(event))
        scenario_name = 'Infected_custom_storage_scenario'
        location = self.get_or_create_location()
        mount_points = {}
        mount_points['windows'] = '\\\\infsan\\FTrack'
        mount_points['osx'] = '/Volumes/FTrack'
        mount_points['linux'] = '/mnt/FTrack'
        setting_value = json.dumps({
            'scenario': scenario_name,
            'data': {
                'location_id': location['id'],
                'location_name': location['name'],
                'accessor': {
                    'mount_points': {
                        'linux': mount_points['linux'],
                        'osx': mount_points['osx'],
                        'windows': mount_points['windows']
                    }
                }
            }
        })
        self.storage_scenario['value'] = setting_value
        self.session.commit()
        # Broadcast an event that storage scenario has been configured.
        self.session.event_hub.publish(ftrack_api.event.base.Event(topic='ftrack.storage-scenario.configure-done'))
        self.logger.info('activate_storage_scenario - done. ')

This is essentially a copy of the code from "_centralized_storage_scenario.py" from the ftrack_api, but changed to our needs (is ths propably the cause for the error?)

 

configure_location does this:

    def configure_location(self, event):
        # location = event['data']['session'].query('Location where name is "studio.central-storage-location"').one()
        # location = event['data']['session'].query('Location where name is "Infected_custom_location"').one()
        location = self.get_or_create_location()
        location.structure = InfectedStructure.Structure.InfectedStructure(session=event['data']['session'])
        location.accessor = ftrack_api.accessor.disk.DiskAccessor(prefix='')
        location.priority = 0
        self.logger.info('configure_location - done. ')

 

When the Resolver gets called, it executes this:

    def __call__(self, event):
        self.session.reset()
        self.logger.info('Resolver got called with event: {0}'.format(event))
        #event['data']['locationName'] = 'Infected_custom_location' # override location name...
        location_name = event['data'].get('locationName')
        component_id = event['data']['componentId']
        location = None
        if location_name is None:
            component = self.session.get('Component', component_id)
            self.logger.info('component keys: {0}'.format(component.keys()))
            location = self.session.pick_location(component)
            self.logger.error( u'No location name given, picked location {0!r} for {1!r}.'.format( location, component ) )
            if location is None:
                self.logger.error(u'Location cannot be found')
                return
            location_name = location['name']
        if not self.filter_locations(location_name):
            self.logger.error( u'Skipping resolve for location {0}.'.format( location_name ) )
            return    
        if location is None:
            location = self.session.query( 'Location where name is "{0}"'.format( location_name ) ).one()       
        if not location.accessor:
            self.logger.error(u'Skipping resolve for location without accessor: {0!r}.'.format( location ) )
            return
        component = self.session.get('Component', component_id)
        resource_identifier = location.get_resource_identifier(component)
        path = None
        try:
            project = self.getProjectFromComponent(component)
            if not project: 
                self.logger.info('no project found to load location_mapping')
                return
            self.logger.info('PROJECT_Location: {0}'.format(project['custom_attributes']['PROJECT_Location'][0]))
            location.accessor.prefix = location.structure.location_mapping[project['custom_attributes']['PROJECT_Location'][0]]
            path = location.accessor.get_filesystem_path(resource_identifier)
        except ftrack_api.exception.AccessorUnsupportedOperationError:
            try:
                path = location.accessor.get_url(resource_identifier)
            except ftrack_api.exception.AccessorUnsupportedOperationError:
                self.logger.error(u'Unable to get URL from accessor. Unsupported operation')
                pass
        if path is None:
            raise ValueError(u'Could not resolve {0!r} and {1!r} to a file system path or URL.'.format( component, location ) )
            self.logger.error(u'Could not resolve {0!r} and {1!r} to a file system path or URL.'.format( component, location ))
        self.logger.info(u'Successfully resolved {0!r}.'.format(path))
        return dict(path=path)

 

and finally get_or_create_location does this:

    def get_or_create_location(self):
        location = self.session.ensure('Location',
        {
            'name': 'Infected_custom_location',
            'label': 'Infected_custom_location_label',
            'description': ('Infected_custom_location_description')
        })
        return location

 

 

I hope this is all information regarding the error above. If anybody has an idea, some insights or has seen this before -> let us know. Until then, we're trying to get our head around this...

 

Thanks

 

 

Tim

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...