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  from PySide2 import QtWidgets, QtGui, QtCore 
 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(QtWidgets.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( QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed ) 125 self.setMinimumWidth(450) 126 127 layout = QtWidgets.QVBoxLayout() 128 layout.setSpacing(0) 129 130 filename = versionHelper.nextVersionString() 131 132 text = QtWidgets.QLabel("Unable to save script. Version:\n%s\nalready exists. \n\nWould you like to:" % filename) 133 layout.addWidget(text) 134 135 self._buttonGroup = QtWidgets.QButtonGroup(self) 136 137 overwriteButton = QtWidgets.QRadioButton("Overwrite existing version") 138 self._buttonGroup.addButton(overwriteButton) 139 self._buttonGroup.setId(overwriteButton, self._eButtonIds["overwrite"]) 140 overwriteButton.setChecked(True) 141 142 saveAsmaxVersionButton = QtWidgets.QRadioButton("Save as max version (%s)" % versionHelper._maxV) 143 self._buttonGroup.addButton(saveAsmaxVersionButton) 144 self._buttonGroup.setId(saveAsmaxVersionButton, self._eButtonIds["saveAsMax"]) 145 146 saveAsVersionButton = QtWidgets.QRadioButton("Save as version: ") 147 self._buttonGroup.addButton(saveAsVersionButton) 148 self._buttonGroup.setId(saveAsVersionButton, self._eButtonIds["saveAsVersion"]) 149 150 self._saveAsVersionSpin = QtWidgets.QSpinBox() 151 self._saveAsVersionSpin.setValue(versionHelper._maxV) 152 self._saveAsVersionSpin.setButtonSymbols(QtWidgets.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 = QtGui.QIntValidator() 158 versionValidator.setBottom(1) 159 self._saveAsVersionSpin.lineEdit().setValidator(versionValidator) 160 161 saveAsVerionLayout = QtWidgets.QHBoxLayout() 162 saveAsVerionLayout.setSpacing(0) 163 saveAsVerionLayout.setContentsMargins(0,0,0,0) 164 saveAsVerionLayout.setAlignment(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 = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.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 245 try: 246 versionHelper = VersionHelper(root_name) 247 except ValueError, e: 248 nuke.message("Unable to save new comp version:\n%s" % str(e)) 249 return 250 251 newFileName = versionHelper.nextVersionString() 252 newVersion = versionHelper.nextVersion() 253 254 # If the next version number already exists we need to ask the user how to proceed 255 newVersionExists = os.path.exists( newFileName ) 256 if newVersionExists: 257 versionDialog = VersionConflictDialog(versionHelper) 258 cancelVersionUp = not versionDialog.showDialog() 259 if cancelVersionUp: 260 return 261 else: 262 newFileName = versionDialog.getNewFilePath() 263 newVersion = versionDialog.getNewVersionNumber() 264 265 # Get the Studio write Node and version up before saving the script 266 try: 267 timeline_write_version_set(newVersion) 268 except Exception, e: 269 shouldContinue = nuke.ask("Unable to set Write node version:\n%s\nDo you want to continue saving new comp version?" % str(e)) 270 if not shouldContinue: 271 return 272 273 #Make the new directory if needed 274 dirName = os.path.dirname( newFileName ) 275 if not os.path.exists( dirName ): 276 os.makedirs( dirName ) 277 278 #Save the script and add to the bin 279 nuke.scriptSaveAs(newFileName) 280 if nuke.env['studio']: 281 from hiero.ui.nuke_bridge.nukestudio import addNewScriptVersionToBin 282 addNewScriptVersionToBin(root_name, newFileName)
283 284
285 -def script_and_write_nodes_version_up():
286 # Just calls script_version_up 287 script_version_up()
288 289
290 -def get_script_data():
291 activechans = nuke.Root.channels() 292 totchan = len(activechans) 293 294 root = nuke.toNode("root") 295 rez = root.knob("proxy").value() 296 297 numnodes = len(nuke.allNodes()) 298 299 chaninuse = totchan 300 chanleft = 1023-totchan 301 memusage = nuke.cacheUsage()/1024/1024 302 output = "Script : "+root.name()+"\n" 303 output = output+"Total nodes: "+str(numnodes)+"\n" 304 if rez: 305 output = output+"\nResolution : --PROXY--\n" 306 else: 307 output = output+"\nResolution : **FULL RES**\n" 308 output += "\nElements:\n"+nukescripts.get_reads("long") 309 310 output += "\nChannels in use: "+str(totchan)+"\n" 311 output += "Channels left: "+str(chanleft)+"\n" 312 output += "\nCache Usage: "+str(memusage)+" mb\n" 313 output += "\nChannel Data :\n" 314 315 layers = nuke.Root.layers() 316 for i in layers: 317 output += "\n"+i.name()+"\n" 318 channels = i.channels() 319 for j in channels: 320 if j in activechans: 321 output += "\t"+j+"\n" 322 323 return output
324 325
326 -def script_data():
327 nuke.display("nukescripts.get_script_data()", nuke.root())
328 329
330 -def script_directory():
331 return nuke.script_directory()
332