V8 settings backup (Rhino for Windows only)

So, I’ve been toying around with a script to make a one-click backup of my entire settings folder as well as any .rui files I have. That way if anything goes south, I just have to close Rhino replace the settings folder and .rui files with the backup versions and I’m back to running again. Hopefully this will never be necessary, but…

A few caveats:

  • This is Windows V8 only, as I have no idea where settings and .rui files actually reside in Mac Rhino.
  • You will need to change the destination file paths to the location you want on your computer.
  • You will also need to substitute your own user name for <username>.
  • If you have any .rui files and they are not located in the default UI folder, you will need to change the path to find them too.
  • This really an expert procedure, so caution is advised, but in principle it only makes copies, so nothing can be damaged.
  • it should run in Py 2 or Py3
  • Every time you run the script a new backup is created. Older backups are not deleted.
import Rhino
import shutil
import os
from datetime import datetime

def WinRhinoV8SettingsBackup():
    #only Windows Rhino 8 and later
    if not Rhino.Runtime.HostUtils.RunningOnWindows:
        print "This script is for Windows Rhino only, sorry!"
        return
    if Rhino.RhinoApp.ExeVersion<8:
        print("This script is only for Rhino V8 and later")
        return
    
    #this is the path of the (existing) top folder in which backups are stored
    #if the folder does not already exist, it will be created
    top_dir=r"D:\Dropbox\Rhino8 Settings Backup"
    
    #this is the name of the folder which will be created for copy of settings
    name="Desktop Settings Backup-{}" ###change to what you like###
    
    #add a date/timestamp to name to insure uniqueness
    timestamp=datetime.now().strftime("%d-%m-%Y_%H%M%S")
    dest_dir=os.path.join(top_dir,name.format(timestamp))
    
    #create path for 'settings' folder inside destination folder
    sett_dest_dir=os.path.join(dest_dir,"settings")
    
    #get C:\Users\<username>\AppData\Roaming
    adr=os.environ['APPDATA'] 
    
    #this is the settings source directory
    source_dir=os.path.join(adr,"McNeel\Rhinoceros\8.0\settings")
    
    #do the copy - 'settings' folder inside backup is automatically created
    shutil.copytree(source_dir, sett_dest_dir)
    
    #this is the UI source directory - search for .rui files to back up
    ui_dir=os.path.join(adr,"McNeel\Rhinoceros\8.0\UI")
    
    #this is the destination directory path for .rui file backup if found
    ui_dest_dir=os.path.join(dest_dir,"rui_backup")
    
    found=0
    for filename in os.listdir(ui_dir):
        if filename.lower().endswith(".rui"):
            found+=1
            fullpath=os.path.join(ui_dir,filename).lower()
             #make an rui_backup folder inside the main backup folder(only once)
            if not os.path.isdir(ui_dest_dir): os.mkdir(ui_dest_dir)
            #copy the .rui files found into the UI folder in the backup directory
            shutil.copy2(fullpath,ui_dest_dir)
    msg="Backed up V8 settings folder to {}".format(dest_dir)
    if found:
        msg+="\n{} .rui files backed up to same destination".format(found)
    else:
        msg+="\nNo .rui files found to backup"
    print(msg)
WinRhinoV8SettingsBackup()

Anyway, FWIW if anyone is interested…

Edited to reflect @nathanletwory suggestion to get home directory

2 Likes

To make it easier for others to use you could get from os.environ %APPDATA% and use that to build the path to the Rhino 8 settings folder. Takes out the need to change script for each user.

1 Like

@nathanletwory Thanks for the suggestion - edited above.

The user will still most likely want to edit the script to change the backup destination folder location and possibly the folder names.

2 Likes

I’m unfamiliar with that Python API. How do I add more search directories? (I could always move the one or two rui files that aren’t in the default folder, but worth knowing how to customize that line.

thx

The script is looking for one single directory (folder) where .rui’s are stored. If you have .rui’s in multiple folders, you would need to add an entire outer loop to search all the directories in your list, one-by-one.

Pseudocode:

    for ui_dir in directory_list: #outer loop
        for filename in os.listdir(ui_dir):
            if filename.lower().endswith(".rui"):
                found+=1
                fullpath=os.path.join(ui_dir,filename).lower()
                 #make an rui_backup folder inside the main backup folder(only once)
                if not os.path.isdir(ui_dest_dir): os.mkdir(ui_dest_dir)
                #copy the .rui files found into the UI folder in the backup directory
                shutil.copy2(fullpath,ui_dest_dir)
1 Like

Thanks muchly. I’ll bring the one or two stragglers into the UI folder, but it’s good to see/have that snippet.

Getting this error in command line when running the customized version of the script:

(unicode error) 'unicodeescape' codec can't decode bytes in position 21-22: truncated \UXXXXXXXX escape (Error CPYC01) file:///C:/Users/alanf/AppData/Roaming/McNeel/Rhinoceros/Scripts_universalMaster/Settings_scriptsUniMaster/SettingsSafetyBackup_Helvetosaur_AFAR_280531.py:[39:1]

SettingsSafetyBackup_Helvetosaur_AFAR_280531.py (2.3 KB)

EDIT: Whoop - Standby, I missed a “” prompt on line 29

Thx
-Alan