This script is slightly flawed, but due to the way the Foundry handles certain naming structures, there isn’t a perfect solution just yet, but watch this space.
The script allows you to have two user preset files, one local, and one on a server (or any other location). The two have distinct differences, in that the ‘server’ files presets do not have the [User] tag that the local ones do. They also cannot be deleted without manually deleting the lines from the ‘server’ file, useful for preventing someone accidentally erasing all your hard work. Finally, the ‘server’ file will have a comment line for each preset stating when it was added to the file and by which user, so you can keep track of who’s been changing what. So, let’s look at how it works.
Download from here.
- Put uploadPresets.py into your plugin path
- Create a user_presets.py file, and place it in your desired directory. Make sure it only has the following two lines it:
import nuke def nodePresetsStartup():
- On line 8 of the uploadPresets.py, change the serverPath string to the path for the new file (including filename).
- Add the following into your menu.py file:
# Adds a right click option to a nodes properties bin to upload the nodes presets to the server file nuke.menu('Properties').addCommand( 'Upload Node Presets', uploadPresets.uploadPresets )
- Add a preset to any node using the spanner icon on the nodes properties bin.
- Right click the node and select ‘Upload Node Presets’.
Note: Deleting a ‘server’ preset through the spanner icon will not remove it from the file, and it will still be accessible to other users. To remove it entirely, you will have to manually remove the line from the user_presets.py file.
The code is quite simple for this one, we’re simply going to open both files, go through the local one line by line and if the line has presets for our current node, we move it across. So firstly, we need to access both files. Seeing as these are likely to be permanent locations, they need to be set in the script before the function.
Next up, we open both files (read only for the local file, and appending to the server) and read in their lines.
To check what presets we’re looking for, we gather both types of presets for the current node (User and non-user), and store them in the one list with:
node = nuke.selectedNode() user_presets = nuke.getUserPresets(node) presets = nuke.getPresets(node) all_presets = presets + user_presets
Now we iterate over every preset. Note, in the script I just start reading from line 3 onwards. This is because the user_presets.py file has two opening lines, importing nuke and declaring the function. If for whatever reason someone wanted to add another line in here (Although I can’t fathom a reason why they’d want, please do let me know if you can think of one!) then we would need to begin reading at the start and only begin our checks after we’ve found the function declaration.
For each line, we split it up to get the name of the preset. Now if you’re thinking about this, that’s a bad way to do it. We really want to be checking against the name of the node, so why don’t we? The reason for this is custom gizmos. Nuke uses some form of name mangling when handling custom gizmos, defining each as a group with a 20-digit number. I spent quite a long time digging through the nukescripts looking for where this naming structure comes from, but hit a dead end when the source code I was following stopped being public. I’ve been in contact with the support team and hope to have a solution for this shortly, but until then, we can only do the next best thing and check by preset name. This does of course mean, that if we upload presets from one node, but another node has a preset with an identical name, then both presets will be uploaded. For now, if you’re using this script, just be careful to name your presets accordingly.
new_line = line.replace('setUserPreset', 'setPreset') if new_line not in server_lines[2:]: if newLines: newLines = False #Ensure comment line is only added once. server_f.write(' #Preset added by %s at %s' % (getpass.getuser(), time.strftime("%c")) + '\n') server_f.write(new_line + '\n') remove_lines.append(line)
So, to compare we simply check if the name is one of the presets we collected from the current node. When we find a match, we replace the ‘setUserPreset’ with ‘setPreset’. This allows us to get rid of the [User] tag that is attached to presets, meaning our server ones will be quickly identifiable. If this line hasn’t already been added to the server file, then we add it in and store the line in a list to be removed later. DO NOT try to delete the line now. For one thing, we’re in read only mode. For another, we’re currently iterating over each line, and deleting one would cause things to go askew.
To help manage presets being added, we also add in a line saying when it was added and by who. This is quite easily done using two modules, getpass and time. There’s a myriad ways to display time, but I prefer a clean, thorough format and so am using time.strftime(“%c”)). To prevent this being added every time for each preset on the current node, I do a quick check that will stop itself after the first run using a boolean. This just saves the server file from getting too long.
for line in local_lines: if line not in remove_lines: local_f.write(line)
Now we can close back up the files. To prevent clashing presets between local and server files, which would cause our [User] tags to remain, we want to remove any of the lines we copied over from our local file. This is why we stored them earlier on. Now we can simply open the file back up, in write mode this time, and rewrite the file, omitting any of our saved lines.
And that, as they say, is that. There are other options out there to do something similar, but having the right click option feels a bit more comfortable to me, and because it handles the tagging as well as prevents deletion of server presets while still allowing users to hide them, it works quite well.