Package nukescripts :: Module script
[hide private]
[frames] | no frames]

Source Code for Module nukescripts.script

  1  # Copyright (c) 2016 The Foundry Visionmongers Ltd.  All Rights Reserved. 
  2   
  3  import os.path 
  4   
  5  import nuke 
  6  import nukescripts 
  7   
  8  import re 
  9  import PySide.QtGui 
 10   
 11  kCommandField = 'Command:' 
 12  last_cmd = '' 
 13   
 14   
15 -def script_command(default_cmd):
16 global last_cmd 17 p = nuke.Panel("Nuke") 18 if (default_cmd != None and len(default_cmd) != 0): 19 use_cmd = default_cmd 20 else: 21 use_cmd = last_cmd 22 p.addScriptCommand(kCommandField, use_cmd) 23 p.addButton("Cancel") 24 p.addButton("OK") 25 result = p.show() 26 if result == 1: 27 last_cmd = p.value(kCommandField) 28 p.execute(kCommandField)
29 30
31 -def findMaxVersionForFileName(filename):
32 """Helper function for finding the max version of a paticular 33 script in it's current directory. 34 Note that a file in the current directory will count towards the 35 current version set if the string before the v number for that file 36 is the same as the string before the v numebr of the current version.""" 37 38 # Get the maximum version number based in the current files on disk 39 (basePath, fileNameCurrent) = os.path.split(filename) 40 (prefixCurrent, vCurrent) = nukescripts.version_get(fileNameCurrent, "v") 41 # Set maxV to the current version + 1 42 maxV = int(vCurrent) + 1 43 44 # Get the base name for the current file version. 45 # i.e. the bit of the filename before the version number. 46 baseNameRegex = "(.*)" + str(prefixCurrent) 47 baseMatch = re.match(baseNameRegex, fileNameCurrent, re.IGNORECASE) 48 49 if not baseMatch: 50 return maxV 51 52 baseNameCurrent = baseMatch.group(1) 53 54 # Iterate the files in the current directory 55 for fileName in os.listdir(basePath): 56 # get the base name of each file. 57 match = re.match(baseNameRegex, fileName, re.IGNORECASE) 58 if not match: 59 continue 60 61 baseNameFile = match.group(1) 62 63 # Check whether the base name is the same as the current file 64 if baseNameFile == baseNameCurrent: 65 # Compare the v number and update maxV if needed. 66 (prefix, version) = nukescripts.version_get(fileName, "v") 67 if version > maxV: 68 maxV = int(version) + 1 69 70 return maxV
71 72
73 -class VersionHelper(object):
74 """Helper class for storing the new version information""" 75 """Intended to be created per rootname."""
76 - def __init__(self, rootname):
77 (prefix, v) = nukescripts.version_get(rootname, "v") 78 self._rootname = rootname 79 self._prefix = prefix 80 self._currentV = int(v) 81 self._maxV = findMaxVersionForFileName(rootname)
82 83
84 - def hasVersion(self):
85 return self._currentV is not None
86
87 - def nextVersion(self):
88 return self._currentV + 1
89
90 - def maxVersion(self):
91 return self._maxV
92
93 - def currentVersionString(self):
94 return self._rootname
95
96 - def nextVersionString(self):
97 return self.versionString(self.nextVersion())
98
99 - def maxVersionString(self):
100 return self.versionString(self.maxVersion())
101
102 - def versionString(self, version):
103 return nukescripts.version_set(self._rootname, self._prefix, self._currentV, version)
104 #End VersionHelper 105 106
107 -class VersionConflictDialog(PySide.QtGui.QDialog):
108 """Dialog which gives the user options for resolving version conflicts"""
109 - def __init__(self,versionHelper,parent=None):
110 super(VersionConflictDialog, self).__init__(parent) 111 112 self._newPath = None 113 self._newVersion = None 114 115 self._eButtonIds = { 116 "overwrite": 0, 117 "saveAsMax": 1, 118 "saveAsVersion": 2, 119 } 120 121 self._versionHelper = versionHelper 122 123 self.setWindowTitle("Version Conflict") 124 self.setSizePolicy( PySide.QtGui.QSizePolicy.Expanding, PySide.QtGui.QSizePolicy.Fixed ) 125 self.setMinimumWidth(450) 126 127 layout = PySide.QtGui.QVBoxLayout() 128 layout.setSpacing(0) 129 130 filename = versionHelper.nextVersionString() 131 132 text = PySide.QtGui.QLabel("Unable to save script. Version:\n%s\nalready exists. \n\nWould you like to:" % filename) 133 layout.addWidget(text) 134 135 self._buttonGroup = PySide.QtGui.QButtonGroup(self) 136 137 overwriteButton = PySide.QtGui.QRadioButton("Overwrite existing version") 138 self._buttonGroup.addButton(overwriteButton) 139 self._buttonGroup.setId(overwriteButton, self._eButtonIds["overwrite"]) 140 overwriteButton.setChecked(True) 141 142 saveAsmaxVersionButton = PySide.QtGui.QRadioButton("Save as max version (%s)" % versionHelper._maxV) 143 self._buttonGroup.addButton(saveAsmaxVersionButton) 144 self._buttonGroup.setId(saveAsmaxVersionButton, self._eButtonIds["saveAsMax"]) 145 146 saveAsVersionButton = PySide.QtGui.QRadioButton("Save as version: ") 147 self._buttonGroup.addButton(saveAsVersionButton) 148 self._buttonGroup.setId(saveAsVersionButton, self._eButtonIds["saveAsVersion"]) 149 150 self._saveAsVersionSpin = PySide.QtGui.QSpinBox() 151 self._saveAsVersionSpin.setValue(versionHelper._maxV) 152 self._saveAsVersionSpin.setButtonSymbols(PySide.QtGui.QAbstractSpinBox.NoButtons) 153 self._saveAsVersionSpin.setFixedWidth(30) 154 self._saveAsVersionSpin.setContentsMargins(0,0,0,0) 155 156 # Negative versions are not allowed, so set min valid version to 1 157 versionValidator = PySide.QtGui.QIntValidator() 158 versionValidator.setBottom(1) 159 self._saveAsVersionSpin.lineEdit().setValidator(versionValidator) 160 161 saveAsVerionLayout = PySide.QtGui.QHBoxLayout() 162 saveAsVerionLayout.setSpacing(0) 163 saveAsVerionLayout.setContentsMargins(0,0,0,0) 164 saveAsVerionLayout.setAlignment(PySide.QtCore.Qt.AlignLeft) 165 saveAsVerionLayout.addWidget(saveAsVersionButton) 166 saveAsVerionLayout.addWidget(self._saveAsVersionSpin) 167 168 layout.addWidget(overwriteButton) 169 layout.addWidget(saveAsmaxVersionButton) 170 layout.addLayout(saveAsVerionLayout) 171 172 # Standard buttons for Add/Cancel 173 buttonbox = PySide.QtGui.QDialogButtonBox(PySide.QtGui.QDialogButtonBox.Ok | PySide.QtGui.QDialogButtonBox.Cancel) 174 buttonbox.accepted.connect(self.accept) 175 buttonbox.rejected.connect(self.reject) 176 layout.addWidget(buttonbox) 177 178 self.setLayout(layout)
179
180 - def showDialog(self):
181 result = self.exec_() 182 183 if result: 184 buttonId = self._buttonGroup.checkedId() 185 186 if(buttonId < 0 ): 187 return None 188 189 #Get the correct path for that button ID 190 if buttonId is self._eButtonIds["overwrite"]: 191 self._newPath = self._versionHelper.nextVersionString() 192 self._newVersion = self._versionHelper.nextVersion() 193 elif buttonId is self._eButtonIds["saveAsMax"]: 194 self._newPath = self._versionHelper.maxVersionString() 195 self._newVersion = self._versionHelper.maxVersion() 196 elif buttonId is self._eButtonIds["saveAsVersion"]: 197 self._newVersion = self._saveAsVersionSpin.value() 198 self._newPath = self._versionHelper.versionString(self._newVersion ) 199 200 return result
201
202 - def getNewFilePath(self):
203 # Get the checked button id from the button group 204 return self._newPath
205
206 - def getNewVersionNumber(self):
207 return self._newVersion
208 #End VersionDialog 209 210
211 -def set_fileknob_version(knob, version):
212 """Sets version of the filename knob to the passed in version. 213 Throws with ValueError if fileKnob has no version.""" 214 currentPath = knob.value() 215 if currentPath: 216 (prefix, v) = nukescripts.version_get(currentPath, "v") 217 newPath = nukescripts.version_set(currentPath, prefix, int(v), version) 218 knob.setValue(newPath)
219 220
221 -def timeline_write_version_set(version):
222 """Sets the version number in the file path of the 'timeline' write node""" 223 kTimelineWriteNodeKnobName = "timeline_write_node" 224 225 timelineWriteNodeKnob = nuke.root().knob(kTimelineWriteNodeKnobName) 226 if timelineWriteNodeKnob is not None: 227 timelineWriteNodeName = timelineWriteNodeKnob.getText() 228 writeNode = nuke.toNode(timelineWriteNodeName) 229 if writeNode is not None: 230 # Set file knob 231 fileKnob = writeNode['file'] 232 set_fileknob_version(fileKnob, version) 233 234 # Set proxy knob 235 proxyKnob = writeNode['proxy'] 236 set_fileknob_version(proxyKnob, version)
237 238
239 -def script_version_up():
240 """ Increments the versioning in the script name and the path of the timeline 241 write nodes, then saves the new version. """ 242 # Set up the version helper 243 root_name = nuke.toNode("root").name() 244 versionHelper = VersionHelper(root_name) 245 246 if not versionHelper.hasVersion(): 247 print "Version: Cannot version up as version string not found in filename. %s" % root_name 248 return 249 250 newFileName = versionHelper.nextVersionString() 251 newVersion = versionHelper.nextVersion() 252 253 # If the next version number already exists we need to ask the user how to proceed 254 newVersionExists = os.path.exists( newFileName ) 255 if newVersionExists: 256 versionDialog = VersionConflictDialog(versionHelper) 257 cancelVersionUp = not versionDialog.showDialog() 258 if cancelVersionUp: 259 return 260 else: 261 newFileName = versionDialog.getNewFilePath() 262 newVersion = versionDialog.getNewVersionNumber() 263 264 # Get the Studio write Node and version up before saving the script 265 timeline_write_version_set(newVersion) 266 267 #Make the new directory if needed 268 dirName = os.path.dirname( newFileName ) 269 if not os.path.exists( dirName ): 270 os.makedirs( dirName ) 271 272 #Save the script and add to the bin 273 nuke.scriptSaveAs(newFileName) 274 if nuke.env['studio']: 275 from hiero.ui.nuke_bridge.nukestudio import addNewScriptVersionToBin 276 addNewScriptVersionToBin(root_name, newFileName)
277 278
279 -def script_and_write_nodes_version_up():
280 # Just calls script_version_up 281 script_version_up()
282 283
284 -def get_script_data():
285 activechans = nuke.Root.channels() 286 totchan = len(activechans) 287 288 root = nuke.toNode("root") 289 rez = root.knob("proxy").value() 290 291 numnodes = len(nuke.allNodes()) 292 293 chaninuse = totchan 294 chanleft = 1023-totchan 295 memusage = nuke.cacheUsage()/1024/1024 296 output = "Script : "+root.name()+"\n" 297 output = output+"Total nodes: "+str(numnodes)+"\n" 298 if rez: 299 output = output+"\nResolution : --PROXY--\n" 300 else: 301 output = output+"\nResolution : **FULL RES**\n" 302 output += "\nElements:\n"+nukescripts.get_reads("long") 303 304 output += "\nChannels in use: "+str(totchan)+"\n" 305 output += "Channels left: "+str(chanleft)+"\n" 306 output += "\nCache Usage: "+str(memusage)+" mb\n" 307 output += "\nChannel Data :\n" 308 309 layers = nuke.Root.layers() 310 for i in layers: 311 output += "\n"+i.name()+"\n" 312 channels = i.channels() 313 for j in channels: 314 if j in activechans: 315 output += "\t"+j+"\n" 316 317 return output
318 319
320 -def script_data():
321 nuke.display("nukescripts.get_script_data()", nuke.root())
322 323
324 -def script_directory():
325 return nuke.script_directory()
326