Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 06/23/2020 in all areas

  1. Just wanted to follow up on this - is it supported in the API yet, or still not? Doesn't seem to be possible still via the web interface, is that correct?
    2 points
  2. Hi @MattM, One way of handling this could be to provide a secondary location (with a lower priority than you main one ) to be used to move copy the data you want to archive. Such a solution can also provide various optional features, like archiving only approved data and backup dependent components. Although at the moment we do not provide such a feature off the shelf, our api can provide you all the basic building blocks to build it. Below some resources which can help you getting a grip with those: Location : https://help.ftrack.com/en/articles/1040442-locations Location API: http://ftrack-python-api.rtd.ftrack.com/en/stable/locations/index.html Location Webinar: https://www.ftrack.com/en/intro-to-locations-webinar Actions (to trigger the data archiving) https://help.ftrack.com/en/articles/1040465-actions Actions API: http://ftrack-python-api.rtd.ftrack.com/en/stable/handling_events.html Depending on where you want to archive the data (if not on your local storage) you could also use third party accessors such as the Amazon S3 one to have cloud backups: https://pypi.org/project/ftrack-s3-accessor/ If you want to get your feet wet with Location I also suggest having a look into our Recipes repository for inspiration: https://bitbucket.org/ftrack/ftrack-recipes/src/master/python/actions/multi_site_location/ Hope it helps. If you have any further question please let us know! L.
    1 point
  3. Hi, you could try now pip install ftrack-python-api==2.2.0rc1 or https://bitbucket.org/ftrack/ftrack-python-api/branch/backlog/threading/story#diff that is indented to solve threading issue.
    1 point
  4. Hi, You essentially have to delete the user assignment, here's a function below that removes all users given a specific task_id, it might not be exactly what you need since you might only want to remove a specific user but this should point you in the right direction. # Assumes a session is already established def unassing_users_from_task(task_id): # Queries users assigned to a task users_assigned_to_tasks = session.query( 'select assignments.context_id from User ' 'where assignments any (context_id = "{0}")'.format(task_id) ) for user in users_assigned_to_tasks: assignments = user['assignments'] for assignment in assignments: if assignment['context_id'] == task_id: session.delete(assignment) # Remember to use session.commit() I would only do this if you had in fact removed an assignment. session.commit()
    1 point
  5. @Bryan FordneyFYI, I have noticed that when you add shots to a review, it seems dependent on the order you select them. I have to presort my reviews properly in the main Ftrack view, and then shift select a block of them, and they will get added in that order I've selected them.
    1 point
  6. Hi Vlad, The Python API has a convenience method on ProjectSchema objects project_schema = session.query( 'ProjectSchema where name is "{}"'.format( "foo" ) ).one() # This is optional, and only needed if you have per-type status overrides in your schema. task_type = session.query( 'Type where name is "{}"'.format( "bar" ) ) task_statuses = project_schema.get_statuses( schema='Task', type_id=task_type['id'], ) https://bitbucket.org/ftrack/ftrack-python-api/src/master/source/ftrack_api/entity/project_schema.py The function is implemented in the linked file, and you could get some inspiration from there if you wanted to reimplement it yourself instead.
    1 point
  7. Hi Kristin, does it work to create an object, like "Shot" and place your tasks in there?
    1 point
  8. There's not an obvious (to me) way to override that, but if you used the legacy API to make your own TempData object, you can specify the expiry yourself. It sounds clunky, but you could duplicate a playlist created in the usual way, and make the copy long-lasting. I'll see whether STHLM has a better idea.
    1 point
  9. Hi @John Kesig thanks for the suggestion ! We usually prefer to leave these customisation to end users to better match their local workflow. Soon though, there'll be more agile ways to provide what you are after. Cheers. L.
    1 point
  10. Hey Peter, What you're running in to is the fact that populate() constructs a query using that attribute string, and we don't support typecasting in a projection. see https://bitbucket.org/ftrack/ftrack-python-api/src/23f582cd146e71f871ba8a17da30c0ad831de836/source/ftrack_api/session.py#lines-1070 We do support passing a list, tuple or QueryResult, so my workaround would be something like the populate line in this snippet. The rest is just included to set up my example / test. shot = session.query('select children from Shot where children is_not None').first() session.populate(shot['children'][:], 'status') with session.auto_populating(False): print(shot['children'][0]['name']) print(shot['children'][0]['status']) I suppose the root cause of all this is that children maps to Contexts, which can include Projects, which themselves do not have statuses.
    1 point
  11. I'm coming in 2 years late, but I was attempting to do this myself and found some info which might help others: If api_user == target_user, then target_user will never receive any notification. It can only be found in the sent items of author_user. The browser notification will always be from api_user. The note itself will correctly be from author_user.
    1 point
  12. Hi Johannes, Towards the bottom of this page (search for "subclass") we show some examples of casting a result to a single type: https://help.ftrack.com/en/articles/1040506-query-syntax In your case, I believe you query string would be: "AssetVersion where task.assignments.resource[User].memberships.group.name is {}"
    1 point
  13. vp9 is possible at the moment make sure to use a mp4 container though... with webm as an extension it wont work. x265 I think is problematic as the browser support is still limited. We use log c jpgs in RV a lot so, having OCIO ideally in the browser would be great. Have been having the same dream to have log encoded media in the web too. While talking about VP9, we have not made the switch cause the encoding times with ffmpeg compared to x264 are ridiculously high... this was a year ago maybe.... I have not tried 10 bit... cheers Johannes
    1 point
  14. Perhaps not a full solution, but would it be possible for fTrack event sources to contain operating system info? This would be very useful for filtering as it's a primary reason for Ftrack Connect logins on multiple machines.
    1 point
  15. import logging import ftrack_api import sys import pprint import ftrack_connect.application class ApplicationStore(ftrack_connect.application.ApplicationStore): '''Store used to find and keep track of available applications.''' def _discoverApplications(self): '''Return a list of applications that can be launched from this host.''' applications = [] if sys.platform == 'darwin': prefix = ['/', 'Applications'] applications.extend(self._searchFilesystem( expression=prefix + [ 'Blender*', 'Blender.app' ], label='Blender {version}', applicationIdentifier='blender_{version}' )) elif sys.platform == 'win32': prefix = ['C:\\', 'Program Files.*'] applications.extend(self._searchFilesystem( expression=( prefix + ['Blender Foundation', 'Blender*', 'blender.exe'] ), label='Blender {version}', applicationIdentifier='blender_{version}' )) self.logger.debug( 'Discovered applications:\n{0}'.format( pprint.pformat(applications) ) ) return applications class BlenderAction(object): '''Launch Blender action.''' # Unique action identifier. identifier = 'blender-launch-action' def __debug(self, message): f = open("C:\\Users\\aaron\\Desktop\\output.txt", "a") f.write(pprint.pformat(message)) f.close() def __init__(self, applicationStore, launcher): '''Initialise action with *applicationStore*.''' super(BlenderAction, self).__init__() self.logger = logging.getLogger( __name__ + '.' + self.__class__.__name__ ) self.applicationStore = applicationStore self.launcher = launcher if self.identifier is None: raise ValueError('The action must be given an identifier.') def register(self, session): '''Register action.''' session.event_hub.subscribe( 'topic=ftrack.action.discover', self.discover ) session.event_hub.subscribe( 'topic=ftrack.action.launch and data.actionIdentifier={0}'.format( self.identifier ), self.launch ) self.session = session def is_component(self, selection): if ( len(selection) != 1 or selection[0]['entityType'] != 'Component' ): return False return True def discover(self, event): '''Return action based on *event*.''' launchArguments = [] selection = event['data'].get('selection', []) if self.is_component(selection): component = self.session.get('Component', selection[0]['entityId']) if component is not None: location = self.session.pick_location() url = location.get_filesystem_path(component) launchArguments.append(url) items = [] applications = self.applicationStore.applications applications = sorted( applications, key=lambda application: application['label'] ) for application in applications: applicationIdentifier = application['identifier'] label = application['label'] items.append({ 'actionIdentifier': self.identifier, 'label': label, 'icon': 'http://icons.iconarchive.com/icons/dakirby309/simply-styled/256/Blender-icon.png', 'applicationIdentifier': applicationIdentifier, 'launchArguments': ['c:\\Users\\aaron\\Desktop\\lookdev_addon.blend'] #launchArguments }) return { 'items': items } def launch(self, event): '''Callback method for Blender action.''' applicationIdentifier = ( event['data']['applicationIdentifier'] ) context = event['data'].copy() return self.launcher.launch( applicationIdentifier, context ) class ApplicationLauncher(ftrack_connect.application.ApplicationLauncher): '''Custom launcher to modify environment before launch.''' def __debug(self, message): f = open("C:\\Users\\aaron\\Desktop\\output.txt", "a") f.write(pprint.pformat(message)) f.close() def _getApplicationLaunchCommand(self, application, context=None): command = ftrack_connect.application.ApplicationLauncher._getApplicationLaunchCommand(self, application, context) self.__debug(command) return command def register(session, **kw): '''Register action in Connect.''' # Validate that session is an instance of ftrack_api.Session. If not, assume # that register is being called from an old or incompatible API and return # without doing anything. if not isinstance(session, ftrack_api.Session): return applicationStore = ApplicationStore() launcher = ApplicationLauncher( applicationStore ) action = BlenderAction(applicationStore, launcher) action.register(session) Here's the full hook. To be honest, it's not too much different from the Houdini example in the docs at the moment, which is why I'm not sure what's going on. Let me know if something sticks out.
    1 point
  16. Erik

    Working with Tags

    I'm digging up this old thread as well. We are making a new asset library and wanna tag versions with things like maya,maya_2017,vray,vray_3.5,character,fur,projectname and then be able to do a reasonably fast query against this through the API. Would modifying a custom enum attribute and add more values as we go along still be the best or only option? Feels like that attribute would get pretty crazy pretty quickly.
    1 point
  17. Hi Remus, thank you for the request - we are already considering this (follow/unfollow) as part of a future change to the notifications feature. I will make sure to incorporate this information any future research
    1 point
  18. tokejepsen

    Time logging

    Being able to change the time log for other people as a supervisor or coordinator would be good.
    1 point
×
×
  • Create New...