forked from LumaPictures/LumaNukeGizmos
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinit.py
177 lines (151 loc) · 7.09 KB
/
init.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# To use this file, copy it as 'init.py' to a directory on your plugin path.
# By default, the plugin path is (taken from the nuke manual):
#
# Linux:
# /users/login name/.nuke
# /usr/local/Nuke6.0v6/plugins
# Mac OS X:
# /Users/login name/.nuke
# /Applications/Nuke6.0v6/Nuke6.0v6.app/Contents/MacOS/plugins
# Windows:
# In the .nuke directory, which can be found under the directory pointed to
# by the HOME environment variable. If this variable is not set (which is
# common), the .nuke directory will be under the folder specified by the
# USERPROFILE environment variable - which is generally of the form:
# drive letter:\Documents and Settings\login name\ (Windows XP)
# or
# drive letter:\Users\login name\ (Windows Vista)
#
# If there is already a 'init.py' at that location, open it in your favorite
# text editor, and add the contents of this file to the end of it.
#
# Once installed, this script will add to the plugin path subfolders of the
# folder it resides in (or of directories pointed at by the NUKE_GIZMO_PATH
# environment variable, if it is defined... or you may provide a custom
# directory by editing the CUSTOM_GIZMO_LOCATION, below), and have gizmos within
# those subfolders automatically available in nuke
#
# If in GUI mode, menu items for these subfolders may also be automatically
# created - see 'menu.py' for details.
# Example custom gizmo locations:
# Linux:
# CUSTOM_GIZMO_LOCATION = r'/users/<login name>/.nuke/Gizmos'
# Mac OS X:
# CUSTOM_GIZMO_LOCATION = r'/Users/<login name>/.nuke/Gizmos'
# Windows:
# CUSTOM_GIZMO_LOCATION = r'C:\Users\<login name>\.nuke\Gizmos'
# WARNING: on windows, do NOT end with a trailing slash... ie this is BAD:
# CUSTOM_GIZMO_LOCATION = r'C:\Users\<login name>\.nuke\Gizmos\'
CUSTOM_GIZMO_LOCATION = r''
import os
import re
import nuke
class GizmoPathManager(object):
def __init__(self, exclude=r'^\.', searchPaths=None):
'''Used to add folders within the gizmo folder(s) to the gizmo path
exclude: a regular expression for folders / gizmos which should NOT be
added; by default, excludes files / folders that begin with a '.'
searchPaths: a list of paths to recursively search; if not given, it
will use the NUKE_GIZMO_PATH environment variable; if that is
not defined, it will use the directory in which this file resides;
and if it cannot detect that, it will use the pluginPath
'''
if isinstance(exclude, basestring):
exclude = re.compile(exclude)
self.exclude = exclude
if searchPaths is None:
searchPaths = os.environ.get('NUKE_GIZMO_PATH', '').split(os.pathsep)
if not searchPaths:
import inspect
thisFile = inspect.getsourcefile(lambda: None)
if thisFile:
searchPaths = [os.path.dirname(os.path.abspath(thisFile))]
else:
searchPaths = list(nuke.pluginPath())
self.searchPaths = searchPaths
self.reset()
@classmethod
def canonical_path(cls, path):
return os.path.normcase(os.path.normpath(os.path.realpath(os.path.abspath(path))))
def reset(self):
self._crawlData = {}
def addGizmoPaths(self):
'''Recursively search searchPaths for folders to add to the nuke
pluginPath.
'''
self.reset()
self._visited = set()
for gizPath in self.searchPaths:
self._recursiveAddGizmoPaths(gizPath, self._crawlData,
foldersOnly=True)
def _recursiveAddGizmoPaths(self, folder, crawlData, foldersOnly=False):
# If we're in GUI mode, also store away data in _crawlDatato to be used
# later by addGizmoMenuItems
if not os.path.isdir(folder):
return
if nuke.GUI:
if 'files' not in crawlData:
crawlData['gizmos'] = []
if 'dirs' not in crawlData:
crawlData['dirs'] = {}
# avoid an infinite loop due to symlinks...
canonical_path = self.canonical_path(folder)
if canonical_path in self._visited:
return
self._visited.add(canonical_path)
for subItem in sorted(os.listdir(canonical_path)):
if self.exclude and self.exclude.search(subItem):
continue
subPath = os.path.join(canonical_path, subItem)
if os.path.isdir(subPath):
nuke.pluginAppendPath(subPath)
subData = {}
if nuke.GUI:
crawlData['dirs'][subItem] = subData
self._recursiveAddGizmoPaths(subPath, subData)
elif nuke.GUI and (not foldersOnly) and os.path.isfile(subPath):
name, ext = os.path.splitext(subItem)
if ext == '.gizmo':
crawlData['gizmos'].append(name)
def addGizmoMenuItems(self, toolbar=None, defaultTopMenu=None):
'''Recursively create menu items for gizmos found on the searchPaths.
Only call this if you're in nuke GUI mode! (ie, from inside menu.py)
toolbar - the toolbar to which to add the menus; defaults to 'Nodes'
defaultTopMenu - if you do not wish to create new 'top level' menu items,
then top-level directories for which there is not already a top-level
menu will be added to this menu instead (which must already exist)
'''
if not self._crawlData:
self.addGizmoPaths()
if toolbar is None:
toolbar = nuke.menu("Nodes")
elif isinstance(toolbar, basestring):
toolbar = nuke.menu(toolbar)
self._recursiveAddGizmoMenuItems(toolbar, self._crawlData,
defaultSubMenu=defaultTopMenu,
topLevel=True)
def _recursiveAddGizmoMenuItems(self, toolbar, crawlData,
defaultSubMenu=None, topLevel=False):
for name in crawlData.get('gizmos', ()):
niceName = name
if niceName.find('_v')==len(name) - 4:
niceName = name[:-4]
toolbar.addCommand(niceName,"nuke.createNode('%s')" % name)
for folder, data in crawlData.get('dirs', {}).iteritems():
import sys
subMenu = toolbar.findItem(folder)
if subMenu is None:
if defaultSubMenu:
subMenu = toolbar.findItem(defaultSubMenu)
else:
subMenu = toolbar.addMenu(folder)
self._recursiveAddGizmoMenuItems(subMenu, data)
if __name__ == '__main__':
if CUSTOM_GIZMO_LOCATION and os.path.isdir(CUSTOM_GIZMO_LOCATION):
gizManager = GizmoPathManager(searchPaths=[CUSTOM_GIZMO_LOCATION])
else:
gizManager = GizmoPathManager()
gizManager.addGizmoPaths()
if not nuke.GUI:
# We're not gonna need it anymore, cleanup...
del gizManager