import os PLUGIN_VERSION = "20140226" # subfolder for gimmicks GIMMICK_SUBDIR = "gimmicks" # gimmick file extension GIMMICK_EXT = ".gimmick" MENU_NAME = "Gimmick" SERVICE_GIMMICKS = "KellerGimmicksPlugin.gimmicks" #_MENU_TOKEN_SEPARATOR_ = "|" #_MENU_KNOB_NAME_ = "_kMenu" GIMMICK_BASEDIR = os.path.join(WORKGROUP_BASEDIR, GIMMICK_SUBDIR) GIMMICK_TEMPLATE_SUBDIR = "Templates" GIMMICK_GROUP_SUBDIR = "Gimmicks" class KellerGimmicksPlugin(KellerNukePlugin): def configurePlugin(self): # register menu entry self.menu = nuke.menu("Nuke") #m = menu.addMenu("&Edit") m = self.menu.addMenu(MENU_NAME) m.addCommand("Save from Node...", "kellerGimmicks.saveGimmick()") m.addCommand("Update Nodes", "kellerGimmicks.updateGimmicks()") #nuke.debug("basedir ist %s " % self.getBaseDir()) KellerPluginManager.setServiceData(SERVICE_GIMMICKS, dict()) registerGimmicks(GIMMICK_BASEDIR) def unconfigurePlugin(self): self.menu.removeItem(MENU_NAME) # remove gimmicks removeGimmicks(GIMMICK_BASEDIR) KellerPluginManager.removeServiceData(SERVICE_GIMMICKS) class KellerGimmick(): pass def __init__(self, file=None): self._initFile(file) self._gimmickData = dict() def _initFile(self, file): import re print ("created gimmick %s" % file) self.menuLocation = list() self.file = None if file is not None: # init menu location from filename if GIMMICK_BASEDIR is not None: # check if valid directory if not os.path.isdir(GIMMICK_BASEDIR): # TODO, raise specific exception raise Exception gimmickPath = os.path.dirname(file) #if gimmickPath == GIMMICK_BASEDIR: # relPath = "" #else: relPath = os.path.relpath(gimmickPath, GIMMICK_BASEDIR) #nuke.debug("RELPATH: %s" %relPath) relPath = relPath.replace("\\","/") menuEntries = relPath.split("/") # remove . element if "." in menuEntries: menuEntries.remove(".") self.setMenuLocation(menuEntries) self.file = os.path.normpath(file).replace("\\","/") # get name from file m = re.match("(.*)\..*", os.path.basename(file)) if m is not None: self.name = m.group(1) else: self.name=os.path.basename(file) else: # filename is none self.file = None self.name = "unknown" def getFile(self): return self.file def load(self, file): pass def setMenuLocation(self, menuLocation): self.menuLocation = menuLocation def addData(self,name, value): self._gimmickData[name] = value def _createDefaultGimmickData(self): import time self.addData("Creation Time", time.ctime()) def _saveAs(self, file): try: nuke.nodeCopy(file) except: nuke.message("Error saving node to %s" % file) self._initFile(file) # append gimmick data self._createDefaultGimmickData() self._saveGimmickData() def setName(self, name): self.name = name def getName(self): return self.name def addMenuLocation(self, menuString): print ("added %s" % menuString) self.menuLocation.append(menuString) def removeFromMenu(self): print (self.menuEntry) if self.menuEntry is not None: print ("remove from menu, entry=%s" % str(self.menuEntry)) (parent, commandName) = self.menuEntry parent.removeItem(commandName) def _registerMenu(self): #nuke.debug("register menulocation %s" % str(self.menuLocation)) self._registerMenuInternal(self.menuLocation, -1, len(self.menuLocation)) def _registerMenuInternal(self, entries, level, numLevels, parent=None): if level > numLevels: return if (level == -1): # # Root Menu # #nuke.debug( "creating root menu NODES ") parent = nuke.menu("Nodes") #print ("Menu %s" % entries[level]) elif (level >= 0 ) and (level < numLevels): # # Sub menues # #nuke.debug( "submenu %s" % entries[level] ) parent = parent.addMenu(entries[level],icon="gimmicks.png") elif (level == numLevels): # # register command # #nuke.debug( "register command ") parent.addCommand(self.name,"kellerGimmicks.createGimmick(\"%s\")" % self.file,icon="gimmicks.png") self.menuEntry = (parent, self.name) #else: # done # return # continue self._registerMenuInternal(entries, level+1, numLevels, parent) def getMenuLocation(self, menuString): self.menuLocation def pasteGimmick(self): pass def _saveGimmickData(self): #return with open(self.file, 'a+') as f: content = f.read() f.seek(0,0) print (self._gimmickData) for key in self._gimmickData.keys(): f.write("# %s=%s\n" % (key, self._gimmickData[key])) f.close() @staticmethod def loadFromFile(file): file = os.path.normpath(file) gimmick = KellerGimmick(file) #f = open(file,'r') #script = f.read() #f.close() #import re #for line in script.split("\n"): # tokens = line.strip().split() #if ( (len(tokens)>0) and (tokens[0].startswith(_MENU_KNOB_NAME_)) ): # gimmick.addMenuLocation(tokens[1]) #if ( (len(tokens)>0) and (tokens[0].startswith("name")) ): # gimmick.setName(tokens[1]) #gimmick.registerMenus() #match = re.findall("_kMenu\d*\s*(?P[a-zA-Z0-9_|]*)\s*", script) return gimmick #def createGimmick(file): # nuke.nodePaste(file) def updateGimmicks(): removeGimmicks(GIMMICK_BASEDIR) registerGimmicks(GIMMICK_BASEDIR) def saveGimmick(): selection = nuke.selectedNodes(); if len(selection) == 0: nuke.message("No node selected") return defaultName = "customTemplate" + GIMMICK_EXT folderProposal = GIMMICK_BASEDIR if len(selection) == 1: n = selection[0] if isinstance(n, nuke.Group): # use name of group by default defaultName = n.name() + GIMMICK_EXT #nuke.message("Node must be a group type") folderProposal = os.path.join(GIMMICK_BASEDIR, GIMMICK_GROUP_SUBDIR) else: folderProposal = os.path.join(GIMMICK_BASEDIR, GIMMICK_TEMPLATE_SUBDIR) saveFile = nuke.getFilename("Save...", pattern="*.gimmick", default=os.path.join(folderProposal, defaultName), type="save") if saveFile is None: return if not saveFile.endswith(".gimmick"): saveFile = saveFile + ".gimmick" if os.path.isdir(saveFile): # is already a dir, append the filename saveFile = os.path.join(saveFile, defaultName) else: saveFile = saveFile gimmick = KellerGimmick() creatorName = nuke.getInput("Enter your name:","") if creatorName: gimmick.addData("Creator", creatorName) if os.path.exists(saveFile): if not nuke.ask("File exists, overwrite?"): return backupFile(saveFile) gimmick._saveAs(saveFile) gimmick._registerMenu() # register new gimmick # TODO def backupFile(file): import shutil try: shutil.copy(file, file+".bak") except: nuke.debug("Cannot create backup of gimmick %s" % file) def removeGimmicks(folder): # TODO: retrieve list of gimmicks and remove from menu gimmicks = KellerPluginManager.getServiceData(SERVICE_GIMMICKS) for gimmick in gimmicks.values(): print ("removing %s" % gimmick) gimmick.removeFromMenu() KellerPluginManager.setServiceData(SERVICE_GIMMICKS, dict()) def createGimmick(file): nuke.nodePaste(file) def registerGimmicks(folder, menu=None): if (menu is None): menu = list() #menu = nuke.menu("Nodes") files = os.listdir(folder) for file in files: absfile = os.path.join(folder, file) if file.endswith(GIMMICK_EXT): # register command gimmick = KellerGimmick.loadFromFile(absfile) gimmick._registerMenu() gimmicks = KellerPluginManager.getServiceData(SERVICE_GIMMICKS) gimmicks[gimmick.getName()] = gimmick #menu.addCommand(gimmick.getName(),"kellerGimmicks.createGimmick(\"%s\")" % gimmick.getFile()) # create gimmick #kGimmick = KellerGimmick.parseFromFile(os.path.join(folder,file)) if os.path.isdir(absfile): # create menu #menu = menu.addMenu(file) menu.append(file) # recurse registerGimmicks(absfile, menu=menu,) if __name__ == "__main__": #print ("start") registerGimmicks("p:/env/nuke/_workgroup/_Projects/temp_schnelli/gimmicks")