Popular Content

Showing content with the highest reputation since 11/29/2019 in all areas

  1. 2 points
    Justin Porter

    Change schema

    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. 1 point
    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 {}"
  3. 1 point

    HDR/LOG 10bit Review-mp4

    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
  4. 1 point
    Mike Overbeck

    Multiple instance of Ftrack-Connect

    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.
  5. 1 point
    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.
  6. 1 point
    oh, projection should be fast enough. Thank you. Just to clarify: Project dosen't have some property that holds users from tasks?
  7. 1 point
    I like the API but I'm not a huge fan of writing the queries as text, so I made something a while back using inspiration from SQLAlchemy. As a very quick example, if the original code is this: episode = session.query('Episode').first() task_link = session.query('select link from Task where (name not like "%task%" or name is "new") and parent.id is "{}" order by name descending'.format(episode['id'])).first() It would be constructed like this: task_link = session.Task.where( or_(~entity.name.like('%task%'), name='new'), parent=session.Episode.first(), ).select(entity.link).sort(entity.name.desc()).first() It's able to do everything I've come across so far, if anyone is interested in using it the github page is here.
  8. 1 point
    Hello, A coworker brought up today that it would be useful to sync or be able to export one's schedule with Outlook/Thunderbird/etc to Ftrack. I was thinking it might be achievable in a similar fashion to the excel import in the tasks view, but in the context of events (Rows/Columns of event name, time, users assigned, etc); just to make it easier to manage and not have to be manually inputted, especially when someone has several meetings that need to be scheduled daily. Thanks, -Phil F
  9. 1 point
    Mikhail Pasechnik

    Golang api

    Hi, I created ftrack-golang-api https://github.com/conducte/ftrack-golang-api ! Inspired by ftrack-javascript-api Is anyone interested in it? Currently EventHub is not implemeted and Entity's represented throught golang map (dictionary) what is a little bit verbose. Basic usage of the api: package main import ( "flag" "github.com/conducte/ftrack-golang-api/ftrack" "log" ) func main() { apiKey := flag.String("api_key", "", "Ftrack Api Key from Settings -> Api Keys") apiUser := flag.String("api_user", "", "Ftrack Api User username from enabled user") serverUrl := flag.String("server_url", "", "Ftrack Server Url server url eg https://ftrack.com") flag.Parse() // Construct Session from command line arguments session, err := ftrack.NewSession(ftrack.SessionConfig{ ApiKey: *apiKey, ApiUser: *apiUser, ServerUrl: *serverUrl, }) if err != nil { log.Fatal(err) } // Query single Task from server result, err := session.Query("select name, parent.project from Task limit 1") if err != nil { log.Fatal(err) } task := result.Data[0] log.Println("Task: ", task) }
  10. 1 point
    Would love to be able to upload .mp3 and .wav files for review, the same as videos and images.
  11. 1 point
    Lorenzo Angeli

    Ftrack for Unity

    @Andrea Perisano I've been checking an on the upcoming release we are already set to use Python for unity api 2.0 . Stay tuned for more info. L.
  12. 1 point
    OK. Thanks @Lorenzo Angeli.
  13. 1 point
    +1 for this feature request. I see two potential use cases. A live read-only calendar(s) that ftrack users can subscribe to (authentication managed by the ftrack instance) so they can keep track of their ftrack schedule within their main calendar app. One-time export of a schedule snapshot as a static .ics file. This would be a good simple way to share schedule info with users outside the organization who don't need access to ftrack. The same could also be achieved with subscriptions, but a snapshot export would be a simpler way to manage non-sensitive data without worrying about managing credentials.
  14. 1 point
    Mani Varma

    Note Component's Storage Usage

    Hi, I cooked up a script to delete File Component from Note's belonging to a specific Project and has worked out fine, but it doesn't seem to reflect on Ftrack Storage Usage. Query for NoteComponent doesn't return anything anymore and I don't understand where NoteComponent get it's storage space from if it's not in Ftrack Storage. def get_filter_string(entity_ids): return ', '.join( '"{0}"'.format(entity_id) for entity_id in entity_ids ) note_entities = [] project_component = session.query('select name, descendants from Project where id is "{0}"'.format( entity_id )).one() note_entities.append(project_component['id']) for hierarchy_item in project_component['descendants']: note_entities.append(hierarchy_item['id']) note_components = session.query('select component, component.file_type, component.name ' 'from NoteComponent where note.parent_id in ({0})'.format( get_filter_string(note_entities) )).all() # Download happens from note_components information then delete. for note_component in note_components: session.delete(note_component['component']) session.commit()
  15. 1 point
    Lorenzo Angeli

    Py3K early access

    @jen_at_floyd we are looking on adding your proposed fix (with few changes) to the api 2.0 branch. If you want you can test this before cloning the repo , changing branch and installing it into a virtualenv. This fix is likely to end up in the api 2.0 branch soon though, let us know in case you test. Cheers. L.
  16. 1 point
    Lorenzo Angeli


    Glad to hear @Konstantin Maslyuk ! The branch still requires some tweaks and details, but should soon get to master. More news and info on the branch itself L.
  17. 1 point
    Representing the scheduled events in a project as a CalDAV calendar is a feature we've always wanted with any project management software we use at my company. Presenting the events using the CalDAV protocol would allow all major calendar apps to view basic ftrack schedules which would go a long way towards replacing the need for a mobile app. This seems like a no-brainer to us in terms of propagating our studio's schedule out in the easiest to view way possible, so we will absolutely be developing this ourselves internally if ftrack doesn't get to it first. 😉 Our idea is basically to represent everything as read-only, which simplifies the needs. People don't need to edit from Outlook, they just need to see things. Using the calDAV Python library should go a long way to making this possible. The only design decision I still need to make is weather the calendars should be presented directly from the script itself, requiring open ports and a DNS address to point to wherever that script lives.... or, it could integrate with another calendar provider like Google Calendar, and simply sync the events to that service, making the calendars available for any users of that service instead.
  18. 1 point
    Hi Alican, Sorry for the late reply. We tried to reproduce this issue but was unable to do so. Your conclusion might very well be correct. CineSync is a great option if you're still having this issue in ftrack since we are now under the same banner Have a nice day! Regards Simon
  19. 1 point
    Ok, I've talked to our development team and we will add this as a feature request. Thanks for bringing this to our attention. Regards Simon
  20. 1 point
    Hi @jen_at_floyd, there's a patch already merged in connect to mitigate this and it'll be available in an upcoming version of connect.
  21. 1 point
    Lorenzo Angeli


    Download 0.2.3 Originally written by Mike Datsik What's new * Ensure loads correctly under latest version of houdini (18.0) * Update to latest QtExt to Fix QStringListModel compatibility for PySide2 5.9+. * Update plugin built for pip 19+ * Update icon path How to install stop ftrack-connect-package download and uncompress the new version in : <ftrack-connect-package>/resource/connect-standard-plugins/ restart ftrack-connect-package
  22. 1 point
    Simon Stålner

    Private tasks

    Hello Chris, Thank you for your feedback! I've added this as a feature request and development will take at look at it. Thanks again. Ragards Simon
  23. 1 point
    Hi @Chandler there no boilerplate at the moment, but I'll try to find time new year to come up with one. As you find out though, there was one once, and is the one I'll try to bring back to life or close to what that was at least. Hope it helps. L.
  24. 1 point
    Regexp for project and any created entities would be great. We got listeners for fixing most things but it would give better feedback to the people that inputted weird things instead of magically changing the name on them.
  25. 1 point
    Hi Ozen, Yes, this is being investigated. We should have more information during Q1 2020. Regards, Johan
  26. 1 point

    Parent attributes available on Child

    Hey Guys, We've had it come up multiple times where we have needed an attribute from a parent to be available for the child. Here are some examples: Shot seconds, or complexity information be available for Tasks lines Bid days, worked days, +/- days available for Versions lines and views. Just being able to access the parent information for any asset/shot from any view would be SUPER helpful. Thank you, Ozen
  27. 1 point
    Hey Alican, I didn't read through the entire thread but I think all you wanna do is adding a reviewable version to an assetversion. If that's correct you just can use the encode_media helper method from the asset_version itself and call it a day. With that method the media will be uploaded and encoded. ... asset_version = session.create('AssetVersion', {'asset': asset}) asset_version.encode_media(local_path_to_media) Best, Julian
  28. 1 point
    Hi @Alican you cannot use the location.get_url(component) as path for the component as is relative to the server, path requires to be a local path to your file system. What you might be after, if I'm getting it right , is an event which collect the data which might have been manually uploaded and then transfer them first to you local disk , before being re uploaded as reviewable. For this to work , you need to have a listener running which will intercept the update event for components and use that to move the data from the ftrack.server to the local storage. Something along these lines should work (https://bitbucket.org/snippets/ftrack/ynxGp4) Hope it helps. L.
  29. 1 point
    Hi Andrea, Thanks for valuable feedback. We are looking at enhancements on this, so I have added your input to that task. Also, I moved this thread to ftrack Studio/Feature requests. Regards, Johan
  30. 1 point
    HI @Alican just gave it a go with default connect and actions and I can see them appearing on both Chrome instances I've open (application launchers). May I ask where the actions are hosted ? On each ftrack-connect-package plugin folder (local to the user) , in a shared place and mapped through FTRACK_CONNECT_PLUGIN_PATH / FTRACK_EVENT_PLUGIN_PATH or are running as standalone event listeners ? Also, to help us investigate, removing custom events and actions does still trigger your issue ? Looking forward to hear more from you . L.
  31. 1 point

    Gantt Chart - export

    A small update for everyone listening here: I've made the first steps for creating the Gantt-exporter. It's not finished, but might be sufficient for some of you already: https://github.com/TDArlt/ftrack/tree/master/ftrack-connect/export-gantt-chart I will keep you updated 🙂
  32. 1 point

    Nothing happens after clicking 'Actions'

    Hi Alican, Are you experiencing an empty box for actions or no box at all? When you look at others, where it works, are you in the same project and same context? Regards, Johan
  33. 1 point
    Lucas Correia

    HTTP: Update task's status

    The Python API Client often uses relationships (e.g. status) to update entities, but when using the raw API backend or the JS API client I recommend that you instead the relationship key attributes instead. In this case, that would be `status_id`. A more complete example of a request body would be: [ { "action": "update", "entity_type": "Task", "entity_key": [ "12bd29be-72b0-11e7-96a7-0a580ae40a16" ], "entity_data": { "status_id": "44dd9fb2-4164-11df-9218-0019bb4983d8", "__entity_type__": "Task" } } ] Regards, Lucas
  34. 1 point
    Julian Martinz

    Project Creation Dialog

    Hey Johan, Actually, this is exactly what I (and Tim, if I understood him correctly, too) want to do. The question is where to find the default one. Best, Julian
  35. 1 point
    nick young

    User Attribute

    Hi, I am new to ftrack and scripting, but I am excited about creating custom attributes, but need a little help. I successfully went through the tutorial for adding the Day Rate, Cost and Estimate attributes. However I wanted the the Cost calculation to use the day rate of each user, not a single project based value. I have added a user attribute for day rate, but I need to sum all the day rates of Users assigned to the Task, multiplied by bid. Any ideas on what the script would look like? Cheers Nick
  36. 1 point
    Hi all, Hope you're well, Off the back of Remus' ticket (here: https://forum.ftrack.com/topic/1350-advanced-filter-settings-any-condition-for-all-entity-types/?tab=comments#comment-5950) I'd like to check in on an ETA for advanced filtering on multiple entity types (in particular Milestones and Tasks) I'd also like to see if there's plans in the works to be able to create global queries not set per type (Milestone, Task, Shot etc) As far as I've deduced currently there is no way we'd be able to create filters that would show us solely e.g Animation Tasks and Milestones. Using the above as an example, with the help of Remus we used a Shot Query filter of children[Task].type.name is Animation OR children[Milestone].type.name is Producing however as this is a shot query filter once it's met the criteria on a shot level it shows all of the tasks and milestones under that shot rather than filtering solely the criteria in query. For Production, Milestones and Client Deliverables are an important and critical part of scheduling from Producer to Line Producer/PM. Sadly without this I've noticed scheduling is being conducted in Excel rather than ftrack. Any information you could provide would be greatly appreciated! I couldn't see this on Trello / I'm not sure if Trello is still an active way of viewing the current roadmaps for ftrack?
  37. 1 point

    Download all

    Hi there, At the moment you have to download them one by one. But we have a feature request for a solution to download all items at once. Regards, Johan
  38. 1 point
    Hi, With the code you have there you are only removing the component file from the server location. Instead, try to remove the component itself: session.delete(component) session.commit()
  39. 1 point

    Workday Length start and end time

    The steps I do are the following: Add start date Add bid days save Right click and say Adjust to bid. OR Add bid days Add start date save Right click and say Adjust to bid. Both end up with the same outcome. Ideally we would have an option of Adjust to Start, or Adjust to End that would automatically then add the End or start date for the task.
  40. 1 point
    Hello! Is there a way to sort projects in the "Projects" drop-down tab other than by "Name" or by "Date", like by custom project attributes? We would essentially like to find ways to look at our projects in that view in groups, Animation, Video, and Stills. Is there any way to do this? I've searched for a while and can't find anything. Jared
  41. 1 point
    I need that as well. Actually, I just found there are two functions we can use. You can get the sub menu while clicking right-mouse-click. So that you can see Collapse all and Expand all. It's not the short key. But it's still very convenient. BTW. I'm using ver. 3.3.41
  42. 1 point

    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.
  43. 1 point
    Unfortunately there is no reliable way of detecting the machine from the browser, not in a way that can be re-created from python. I've made a small plugin (see code below) that detects if there are multiple instances of Connect running for a user and pops up a message. If this functionality makes sense and you like it, we may bundle the plugin in Connect. import logging import socket import functools from QtExt import QtWidgets, QtCore import ftrack_api import ftrack_connect.util import ftrack_connect.ui.application logger = logging.getLogger( 'multiple-instances-plugin' ) def open_warning_dialog(message): '''Open warning window.''' parent = None for item in QtCore.QCoreApplication.instance().topLevelWidgets(): if isinstance(item, ftrack_connect.ui.application.Application): parent = item dialog = QtWidgets.QMessageBox(parent=parent) dialog.setText(message) dialog.setIcon(QtWidgets.QMessageBox.Critical) dialog.exec_() def handle_reply(event): '''Handle reply event if someone else is already running Connect.''' logger.warning('Someone else is already running connect: {0}'.format(event)) ftrack_connect.util.invoke_in_main_thread( open_warning_dialog, u'ftrack Connect is already running on machine: {0}'.format( event['data']['machine'] ) ) def callback(event): '''Handle start of another connect.''' logger.warning('Someone just started ftrack Connect: {0}'.format(event)) ftrack_connect.util.invoke_in_main_thread( functools.partial( open_warning_dialog, u'Connect just opened on machine: {0}'.format( event['data']['machine'] ) ) ) return {'machine': socket.gethostname()} def register(session, **kw): '''Register hooks.''' logger.info( 'Register detection of multiple Connect instances' ) # Validate that session is an instance of ftrack_api.session.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): logger.debug( 'Not subscribing plugin as passed argument {0!r} is not an ' 'Session instance.'.format(session) ) return session.event_hub.subscribe( 'topic=studio.ftrack-connect.start and source.id != "{0}" and ' 'data.username = "{1}"'.format( session.event_hub.id, session._api_user ), callback ) session.event_hub.publish( ftrack_api.event.base.Event( topic='studio.ftrack-connect.start', data={ 'username': session._api_user, 'machine': socket.gethostname() } ), on_reply=handle_reply ) To use it create a folder detect-multi-instance/hook/ inside the ftrack connectp plugins folder, and add the code in a plugin.py (don't forget the hook/ folder). Restart Connect for the plugin to source. This simple example could be extended with the ability to "quit" other instances of ftrack Connect.
  44. 1 point
    Willem Zwarthoed

    Component 'duplicate entry'

    Ok, so the issue was with these lines: shot["custom_attributes"] = shot_data["custom_attributes"] shot["metadata"] = shot_data["metadata"] which doesn't work anymore, at least with ftrack 3.5.9 and API version 1.0.4. All credits to Eric Hermelin from ftrack support for figuring it out and providing the solution: for key, value in shot_data["custom_attributes"].items(): shot['custom_attributes'][key] = value for key, value in shot_data["metadata"].items(): shot['metadata'][key] = value Everything is working fine again now. Thanks Eric and Matthias for resolving this quickly!
  45. 1 point
    Mattias Lagergren

    Custom keyboard shortcuts

    I'm afraid it is not possible to change them but I can create a feature request for you!
  46. 1 point

    Time logging

    Being able to change the time log for other people as a supervisor or coordinator would be good.