Q100158: Keeping multiple, incremental autosaves of your Nuke script

Follow

SUMMARY

This article explains how you can customise Nuke's autosave functionality to implement a rolling and incremental autosave system.

 

MORE INFORMATION

By default, Nuke will only keep one autosave for the current file you're working on.  The file will be called <scriptname>.nk.autosave and will be updated/overwritten at the frequency set in your Nuke Preferences.

You can customise Nuke's autosave behaviour by setting up your own autosave python functions.  The example below (from the Nuke Python Developer's Guide) will set up a rolling autosave to store multiple incremental backups of your work in progress script.

You can set this up by doing the following.

  1. Download the attached "autosave.py" file and place it in the .nuke directory in your $HOME area

  2. Add the following line to the "init.py" file in your $HOME/.nuke directory (if you do not already have an init.py file in your .nuke directory then you'll need to create one)

    import autosave

The next time you launch Nuke it will then create multiple, incremental autosave files like this:

<scriptname>.nk.autosave

<scriptname>.nk.autosave1

<scriptname>.nk.autosave2

<scriptname>.nk.autosave3

up to 

<scriptname>.nk.autosave9

If you encounter any problems with Nuke such as crashing or corrupted scripts then you can load each autosave (using File > Open) to find a script before the problem occurred.

 
FURTHER READING
 
The Nuke User Guide has more information about how to load custom python scripts and other customisations
 
The Nuke Python Developer's Guide has more information about how to use python callbacks like onAutoSave.
 

EXAMPLE CODE

Here is the contents of the "autosave.py" file.

import nuke
import glob
import time
import os

### Example that implements a rolling autosave using the autoSaveFilter callbacks
###
## autosaves roll from 0-9 eg myfile.autosave, myfile.autosave1, myfile.autosave2...
#
## To use just add 'import nukescripts.autosave' in your init.py


def onAutoSave(filename):

  ## ignore untiled autosave
  if nuke.root().name() == 'Root':
    return filename

  fileNo = 0
  files = getAutoSaveFiles(filename)

  if len(files) > 0 :
    lastFile = files[-1]
    # get the last file number

    if len(lastFile) > 0:
      try:
        fileNo = int(lastFile[-1:])
      except:
        pass

      fileNo = fileNo + 1

  if ( fileNo > 9 ):
    fileNo = 0

  if ( fileNo != 0 ):
    filename = filename + str(fileNo)

  return filename


def onAutoSaveRestore(filename):

  files = getAutoSaveFiles(filename)

  if len(files) > 0:
    filename = files[-1]

  return filename

def onAutoSaveDelete(filename):

  ## only delete untiled autosave
  if nuke.root().name() == 'Root':
    return filename

  # return None here to not delete auto save file
  return None

  
def getAutoSaveFiles(filename):
  date_file_list = []
  files = glob.glob(filename + '[1-9]')
  files.extend( glob.glob(filename) )

  for file in files:
      # retrieves the stats for the current file as a tuple
      # (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)
      # the tuple element mtime at index 8 is the last-modified-date
      stats = os.stat(file)
      # create tuple (year yyyy, month(1-12), day(1-31), hour(0-23), minute(0-59), second(0-59),
      # weekday(0-6, 0 is monday), Julian day(1-366), daylight flag(-1,0 or 1)) from seconds since epoch
      # note:  this tuple can be sorted properly by date and time
      lastmod_date = time.localtime(stats[8])
      #print image_file, lastmod_date   # test
      # create list of tuples ready for sorting by date
      date_file_tuple = lastmod_date, file
      date_file_list.append(date_file_tuple)
   
  date_file_list.sort()
  return [ filename for _, filename in date_file_list ]


nuke.addAutoSaveFilter( onAutoSave )
nuke.addAutoSaveRestoreFilter( onAutoSaveRestore )
nuke.addAutoSaveDeleteFilter( onAutoSaveDelete )

### As an example to remove the callbacks use this code
#nuke.removeAutoSaveFilter( onAutoSave )
#nuke.removeAutoSaveRestoreFilter( onAutoSaveRestore )
#nuke.removeAutoSaveDeleteFilter( onAutoSaveDelete )
 

 

Was this article helpful?
0 out of 0 found this helpful