Tim Edelmann

Members
  • Content Count

    60
  • Joined

  • Last visited

  • Days Won

    1

Tim Edelmann last won the day on October 15

Tim Edelmann had the most liked content!

About Tim Edelmann

  • Rank
    Advanced Member

Recent Profile Visitors

269 profile views
  1. Hey, I wanted to complete this thread, to halp anyone, who might stumble into this... To make sure ftrack understands files with different filenames AND different versions, we ended up manually naming the associated asset and omit the part where the files differ! example: if we want to publish a file called "my_awsome_file_v001.jpg" and "my_awsome_file_v002.jpg", the created asset gets the name "my_awsome_file". So both files are linked to this asset, which make ftrack understand, that these are both just different versions of the 'same' file. Thanks for your help Tim
  2. Hey Mattias, thanks for the quick answer! Am I correct, that its only concidered the same asset, when the name is equal? As I said, out filenames for rendering hold a version-string like 'v001', 'v002', etc. So each of our versions is treated as a new asset and no versions are shown. Is there a way to get around this, while still having these version-string inside the filenames? Thanks again Tim
  3. Good afternoon, we would like to use the Autodesk RV Player to review AssetVersions linked to a task. These are opened by launching the corresponding hook via web-ui on a selected task. "ftrack_rv_api.py", which comes with the ftrack-plugin for RV, loads two widgets from ftrack (images added as attachments). We noticed, that the 'versions' tab is not showing other versions, if the AssetVersions linked to the task, have different names. As soon as the names is equal and only the 'verion'-field for the AssetVersion differs, the version-field in the RV-widget works as expected. The problem is, that we need our renderings to have the version as part of the filename, resulting in a broken widget, that never shows possible other versions. Is there a way to have assets/assetversions beeing named without our version-tag but the filenames still contain them? So that reviewing with rv would give us a list of versions? We well keep playing around with this, thank you for any hints? Tim
  4. Tim Edelmann

    Multiple Storage Scenarios

    ok. we found it. The error was in an other class and hard to find..(ignored whitespace and indentation, which was ignored by the python interpreter). It looks like, that errors, when happening in custom accessors and or structures, arent addressed properly by error-debug-log.
  5. Tim Edelmann

    Multiple Storage Scenarios

    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
  6. Tim Edelmann

    Multiple Storage Scenarios

    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
  7. Tim Edelmann

    dynamic enumerator and current selection

    ah.. ok thats good to know! I'm glad, this work around does the trick. thank you.
  8. Tim Edelmann

    Hierarchical Custom Attribute Change Event

    any news on this? we also would like to use this functionality A question that is very close to this: We have multiple multi-selection, hierarchical custom attributes. One of them triggers ftrack.update when changing its values (and clicking somewhere outside), the others don't!?!? Can anybody explain this? This is confusing. Thanks in advance Tim
  9. Tim Edelmann

    dynamic enumerator and current selection

    Additional information: We noticed, that the ids look different and we don't know why?? normal ids look like this: '75b59aae-e1bb-11e7-ad88-7ab7a47c9dda' while the one retrieved here looks something like this: '75b59aae-e1bb-11e7-ad88-7ab7a47c9dda_48' this '_48' breaks it! PLUS: The 'entityType' given in 'event['data']['recordData']['entity']['entityType']' is not starting with a Capital letter, which breaks it too! So if we remove the '_48' and use 'TypedContext' instead of the given type, we're able to query the object. Could anybody give us some more insight here? Thanks again
  10. Tim Edelmann

    dynamic enumerator and current selection

    Hey everybody, while setting up a dynamic-enumerator-action, we noticed, that the information on the currently selected element doesn't help to retrieve an actual object. We always get 'None' as a result. This is the event, that comes in: { "topic": "ftrack.dynamic-enumerator", "source": { "id": "c73c09beff154613ba61300782bb836e", "user": { "username": "TEdelmann", "id": "75b59aae-e1bb-11e7-ad88-7ab7a47c9dda" } }, "target": "", "data": { "attributeName": "Briefing_Workflows_00_Maya_Config", "sorters": [], "filters": [ { "disabled": "True", "property": "name", "root": "data", "initialConfig": { "disabled": "True", "property": "name", "root": "data", "id": "ft-dynamicenumerator-2000671-query-filter" }, "id": "ft-dynamicenumerator-2000671-query-filter" } ], "query": "", "groupers": [], "recordData": { "changes": {}, "entity": { "entityId": "883b74ea-132b-11e8-ae79-7ab7a47c9dda_15", "entityType": "task" } } }, "in_reply_to_event": "None", "id": "27304c3ea333491fa793b457e91f7966", "sent": "None" } As you can see, there is given an entity in 'recordData'. But for some reason, we can't query or get the actual object from it. This is what we tried so far.. obj_type = event['data']['recordData']['entity']['entityType'] obj_id = event['data']['recordData']['entity']['entityId'] # obj_id = event['source']['id'] # selected_object = self.session.get('TypedContext', obj_id) # selected_object = self.session.query('Task where id is "{0}"'.format(obj_id)).first() selected_object = self.session.query('{0} where id is "{1}"'.format(obj_type, obj_id)).first() selected_object is always None. any suggestions? How are we supposed to get the current selection, when reacting on 'topic=ftrack.dynamic-enumerator'? Alternatively, it would be very helpful, if the information on what is currently selected, coulde be retrieved in a general way (i.e. like session.getCurrentSelection()) thanks a lot in advance Tim
  11. Tim Edelmann

    adding sorted notes

    yeah, adding a 'custom' date manually is a good idea. thanks a lot Tim
  12. Tim Edelmann

    adding sorted notes

    Hey ftrackers, we recently tried to add notes to a task in a sorted order. We read a number of question from a json which looks like this: [ { "index": 1, "content": "Q1" }, { "index": 2, "content": "Q2" }, { "index": 3, "content": "Q3" }, { "index": 4, "content": "Q4" } ] ..and we would like these questions, to appear in the order given by index. But for some reason, we always get the order visible in attachment: ftrack_question_ordering.PNG Could this be the same problem we have with custom attributes being not sorted? Thanks in advance Tim EDIT: The note, which was altered latest is shown upmost automatically, which implies, that we cannot change the order, right?
  13. Tim Edelmann

    Access hierarchical custom attributes on User object

    Hey Mattias, thanks for getting back on this. Good to hear, that I'm not the only one running into this (so its not just my fault)..
  14. Tim Edelmann

    Access hierarchical custom attributes on User object

    Hey, another thing we noticed: We use a custom attribute of type: dynamic enum which is hierarchical. If the project is selected and we change its values, no 'ftrack.update' gets triggered! On the other hand, if we select a folder (or any other object under project), changes to our custom attribute, do trigger 'ftrack.update'. Is this behavior wanted? For our workflow, it would be great, if the custom attribute changes trigger 'ftrack.update' no matter what is selected. thanks again
  15. Tim Edelmann

    Dynamic Enum not accepting my values??

    yep. my bad I had another action (on another pc) registering for 'topic=ftrack.dynamic-enumerator' as well... So they seem to have interfered. It works when each registering instance makes use of 'event.stop()' if its to be handled here. Thanks for looking into this! Tim