Patching Your Pipeline

Recently, our studio’s file server started failing randomly. We lost Nuke scripts and we also lost the autosave files that Nuke creates in the same directory. Of course there are ways to deal with that on lower levels but I needed a quick fix that I could deploy without dealing with infrastructure and file system journals. Fortunately, Nuke provided the means to do that. I managed to redirect autosaves to each artist’s local drive without even accessing their machines. Here’s how:

Nuke has a bunch of callbacks that you can use. And it also has some that relate to autosaves:

  • AutoSaveFilter (called whenever Nuke wants to write to an autosave file)
  • AutoSaveRestoreFilter (called whenever it wants to check or read an autosave during startup)
  • AutoSaveDeleteFilter (called before an autosave gets deleted).

All of these functions receive the file name of the autosave that Nuke would use if you hadn’t installed any event handlers. The expected return value is a modified file name that it will actually use.

The whole idea is simple: diverting autosaves whose paths match a certain pattern (I only want to catch those that would have been saved on our file server) to a clone of the server’s folder structure on the artist’s local drive. We’re running Linux so I chose ~/Documents/NukeAutosaves as a location.

As an extra failsafe against data loss I made a copy of an autosave right before Nuke deletes it. This makes sure that each artist gets an automatic copy his .nk script on his local drive. This script may not be the same as the .nk file that is saved on the server, but since it is identical to the last autosave, it’s definitely a helpful backup.

Here’s the Python code that you need to paste into your or include it as a separate module (which I recommend):

import os, re, shutil
import nuke
def onAutoSave(filename):
  """Build local autosave file name for saving."""
  localfilename = os.path.expanduser(re.sub(r"/PATH/TO/SERVER/", r"~/Documents/NukeAutosave/", filename, re.IGNORECASE))
  localdir = os.path.dirname(localfilename)
  if not os.path.isdir(localdir):
  return localfilename
def onAutoSaveRestore(filename):
  """Build local autosave file name for restoration."""
  return os.path.expanduser(re.sub(r"/PATH/TO/SERVER/", r"~/Documents/NukeAutosave/", filename, re.IGNORECASE))
def onAutoSaveDelete(filename):
  """Create a backup copy before deleting an autosave."""
  # only delete untiled autosave
  if nuke.root().name() == 'Root':
    return filename
  # build local autosave file name
  localfilename = os.path.expanduser(re.sub(r"/PATH/TO/SERVER/", r"~/Documents/NukeAutosave/", filename, re.IGNORECASE))
  # before Nuke deletes it, make a backup copy (without the .autosave extension)
    if os.path.isfile(localfilename):
      shutil.copy2(localfilename, os.path.splitext(localfilename)[0])
  except Exception as e:
    print "Exception thrown in onAutoSaveDelete(): %s" % e
  return localfilename
def init():
  nuke.addAutoSaveFilter( onAutoSave )
  nuke.addAutoSaveRestoreFilter( onAutoSaveRestore )
  nuke.addAutoSaveDeleteFilter( onAutoSaveDelete )

Our file server was of course fixed soon after I had deployed this hotfix. But I have left it in our pipeline since then because it solves another autosave problem: bogus autosaves created by other users.

Whenever someone else opens your script without saving (maybe a supervisor or just another artist who needs to borrow part of your setup) he’ll leave behind an autosave. These files are potentially dangerous. Nuke will ask you to restore from this autosave but what if it contains changes that mess with your script or even break it? The guy who previously opened your comp didn’t mean any harm and he didn’t save his changes. But now you’ve restored his autosave and by subsequently hitting “save” you might have damaged your script permanently.

The hotfix I have shown above will divert all autosaves to local machines. So when you open a script, Nuke will never find an autosave that somebody else has created or left behind.

Tags: ,

Comments are closed.