def newProject(self, projectName, projectCode): """ Create new project :param projectName: Project name :type projectName: str :param projectCode: Project code :type projectCode: str """ self.log.info("#--- Create New Project ---#") self.log.info("Project Name: %s" % projectName) self.log.info("Project Code: %s" % projectCode) #--- Check New Project ---# if '%s--%s' % (projectName, projectCode) in self.projects: raise AttributeError("Project already exists: %s--%s" % (projectName, projectCode)) if projectName in self.projectNames: raise AttributeError("Project name already used: %s" % projectName) if projectCode in self.projectCodes: raise AttributeError("Project code already used: %s" % projectCode) #--- Create Project Folder ---# newProjectPath = pFile.conformPath(os.path.join(self._fdn.__projectsPath__, '%s--%s' % (projectName, projectCode))) pFile.createPath([newProjectPath], log=self.log) #--- Create Project File ---# projFile = pFile.conformPath(os.path.join(newProjectPath, '%s--%s.py' % (projectName, projectCode))) projDict = dict(project="%s--%s" % (projectName, projectCode), watchers=[self._fdn.__user__], _assets=None, _shots=None) try: pFile.writeDictFile(projFile, projDict) self.log.debug("---> Project file successfully written: %s" % projFile) except: raise IOError("!!! Can not write project file: %s !!!" % projFile)
def __init__(self, mainUi): super(LoadProject, self).__init__(mainUi) self.mainUi = mainUi #--- Core ---# self.log = self.mainUi.log self._fdn = self.mainUi._fdn self._users = self._fdn._users self._groups = self._fdn._groups self._project = self._fdn._project #--- Icons ---# self.iconStore = QtGui.QIcon( pFile.conformPath( os.path.join(self.mainUi.__iconPath__, 'png', 'pinGreen.png'))) self.iconRemove = QtGui.QIcon( pFile.conformPath( os.path.join(self.mainUi.__iconPath__, 'png', 'del.png'))) self.iconRefresh = QtGui.QIcon( pFile.conformPath( os.path.join(self.mainUi.__iconPath__, 'png', 'refresh.png'))) self.iconLoad = QtGui.QIcon( pFile.conformPath( os.path.join(self.mainUi.__iconPath__, 'png', 'apply.png'))) self.iconCancel = QtGui.QIcon( pFile.conformPath( os.path.join(self.mainUi.__iconPath__, 'png', 'cancel.png'))) #--- Setup ---# self._setupDial()
class Fondation(object): """ Fondation Class: Contains foundation datas, main core object :param logLvl : Log level ('critical', 'error', 'warning', 'info', 'debug', 'detail') :type logLvl: str """ __user__ = os.environ['USERNAME'] __rootPath__ = "E:/fondation" __projectsPath__ = pFile.conformPath(os.path.join(__rootPath__, "projects")) __settingsPath__ = pFile.conformPath(os.path.join(__rootPath__, "settings")) def __init__(self, logLvl='info'): self._setup(logLvl) self._groups = userGroups.Groups(self) self._users = users.Users(self) self._project = project.Project(self) def _setup(self, logLvl): """ Setup Foundation core object """ #--- Init Log ---# self.log = pFile.Logger(title=self.__class__.__name__, level=logLvl) self.log.info("########## %s ##########" % self.__class__.__name__, newLinesBefore=1) #--- Create Tool Paths ---# self.log.debug("#--- Check Paths ---#") paths = [self.__rootPath__, self.__projectsPath__, self.__settingsPath__] pFile.createPath(paths, log=self.log) @property def contextTypes(self): """ Get context types :return: Context types :rtype: list """ return ['asset', 'shot'] @property def typoExclusion(self): """ Typo results that must not be found :return: Typo exclusion :rtype: list """ return ['', ' ', 'None', None]
def projects(self): """ Get all projects :return: Project list :rtype: list """ projectList = [] for fld in os.listdir(self._fdn.__projectsPath__): if '--' in fld: fldPath = pFile.conformPath(os.path.join(self._fdn.__projectsPath__, fld)) if os.path.isdir(fldPath): if os.path.exists(pFile.conformPath(os.path.join(fldPath, '%s.py' % fld))): projectList.append(fld) return projectList
class ToolBox(QtGui.QMainWindow, toolBoxUI.Ui_mw_toolBox): """ ToolBox class: Cloth toolBox mainUi. Contains cloth dept cmds and tools :param logLvl : Log level ('critical', 'error', 'warning', 'info', 'debug', 'detail') :type logLvl: str :param parent: Maya main window :type parent: QtCore.QObject """ __iconPath__ = pFile.conformPath(env.iconsPath) def __init__(self, logLvl='info', parent=None): self.log = pFile.Logger(title=self.__class__.__name__, level=logLvl) self.log.info("########## Launching %s Ui ##########" % self.__class__.__name__, newLinesBefore=1) super(ToolBox, self).__init__(parent) self._setupUi() def _setupUi(self): """ Setup main ui """ self.log.debug("Setup %s ui ..." % self.__class__.__name__) self.setupUi(self) #-- Widgets --# self.wgModeBox = toolBoxWgts.ModeBox(self) self.vl_mode.addWidget(self.wgModeBox) self.wgRiggBox = toolBoxWgts.RiggBox(self) self.vl_setup.addWidget(self.wgRiggBox)
def loadProject(self, project): """ Load given project :param project: Project (name--code) :type project: str """ self.log.info("#--- Load Project: %r ---#" % project) #--- Check Project ---# projectFile = pFile.conformPath( os.path.join(self._fdn.__projectsPath__, project, '%s.py' % project)) if not os.path.exists(projectFile): raise ValueError("!!! Project %r not found !!!" % project) #--- Get Project ---# try: projectDict = pFile.readDictFile(projectFile) except: raise IOError("!!! Can not load project %r !!!" % project) #--- Load Project ---# if self._fdn.__user__ in projectDict['watchers']: self.update(**projectDict) self.log.info("---> Project %r successfully loaded" % project) else: raise ValueError("User %r is not set as projectUser in %s !" % (self._fdn.__user__, project))
def launchDisplayColorUi(): """ Launch DisplayColorUi """ from mayaTools.util import displayColor as toolModul tmFile = pFile.conformPath(os.path.join(os.path.dirname(toolModul.__file__), '__tm__.py')) execfile(tmFile)
def launchRiggerUi(): """ Launch RiggerUi """ from mayaTools.cloth import rigger as toolModul tmFile = pFile.conformPath(os.path.join(os.path.dirname(toolModul.__file__), '__tm__.py')) execfile(tmFile)
def parseUsers(self, userPrefix, userName): """ Parse disk users directory :param userPrefix: User prefix folder :type userPrefix: str :param userName: User name :type userName: str :return: Users list :rtype: list """ self.log.detail("Parse disk ...") #--- Get Index List ---# if userPrefix is not None: prefixList = [userPrefix] else: if userName is not None: prefixList = [userName[0].lower()] else: prefixList = os.listdir(self.usersPath) or [] #--- Collecte Index ---# userList = [] for prefix in prefixList: prefixPath = pFile.conformPath(os.path.join(self.usersPath, prefix)) if len(prefix) == 1 and os.path.isdir(prefixPath): #--- Get User List ---# if userName is not None: userList = [userName] else: userList.extend(os.listdir(prefixPath) or []) #--- Result ---# return userList
def buildTree(self, treeName): """ Refresh 'Projects' tree :param treeName: Tree widget name ('allProjects' or 'myProjects') :type treeName: str """ #--- Get Projects ---# if treeName == 'allProjects': self.log.detail("Build 'All Projects' tree ...") projects = self._project.projects treeWidget = self.tw_allProjects else: self.log.detail("Build 'My Projects' tree ...") projects = self._users._user.userPinedProjects treeWidget = self.tw_myProjects #--- Populate Tree ---# treeWidget.clear() for project in projects: projectFile = pFile.conformPath(os.path.join(self._fdn.__projectsPath__, project, '%s.py' % project)) data = pFile.readDictFile(projectFile) newItem = self.new_projectItem(project, data, treeWidget) treeWidget.addTopLevelItem(newItem) #--- Refresh ---# self.rf_treeColumns(treeWidget) treeWidget.sortItems(0, QtCore.Qt.AscendingOrder)
def buildEntities(self): """ Build all entities from disk """ self.entities = [] if self.contextPath is not None: if os.path.exists(self.contextPath): contents = os.listdir(self.contextPath) or [] for fld in contents: if not fld.startswith('_') and not fld.startswith('.'): path = pFile.conformPath(os.path.join(self.contextPath, fld)) entityFile = pFile.conformPath(os.path.join(path, '%s.py' % fld)) if os.path.exists(entityFile): self.log.detail(">>> Build entity from file %s ..." % entityFile) data = pFile.readDictFile(entityFile) self.addEntity(self.newEntity(**data))
def loadProject(self, project): """ Load given project :param project: Project (name--code) :type project: str """ self.log.info("#--- Load Project: %r ---#" % project) #--- Check Project ---# projectFile = pFile.conformPath(os.path.join(self._fdn.__projectsPath__, project, '%s.py' % project)) if not os.path.exists(projectFile): raise ValueError("!!! Project %r not found !!!" % project) #--- Get Project ---# try: projectDict = pFile.readDictFile(projectFile) except: raise IOError("!!! Can not load project %r !!!" % project) #--- Load Project ---# if self._fdn.__user__ in projectDict['watchers']: self.update(**projectDict) for ctxtObj in self.contexts: ctxtObj.buildEntities() self.log.info("---> Project %r successfully loaded" % project) else: raise ValueError("User %r is not set as projectUser in %s !" % (self._fdn.__user__, project))
def buildTree(self, treeName): """ Refresh 'Projects' tree :param treeName: Tree widget name ('allProjects' or 'myProjects') :type treeName: str """ #--- Get Projects ---# if treeName == 'allProjects': self.log.detail("Build 'All Projects' tree ...") projects = self._project.projects treeWidget = self.tw_allProjects else: self.log.detail("Build 'My Projects' tree ...") projects = self._users._user.userPinedProjects treeWidget = self.tw_myProjects #--- Populate Tree ---# treeWidget.clear() for project in projects: projectFile = pFile.conformPath( os.path.join(self._fdn.__projectsPath__, project, '%s.py' % project)) data = pFile.readDictFile(projectFile) newItem = self.new_projectItem(project, data, treeWidget) treeWidget.addTopLevelItem(newItem) #--- Refresh ---# self.rf_treeColumns(treeWidget) treeWidget.sortItems(0, QtCore.Qt.AscendingOrder)
def __init__(self, mainUi): super(LoadProject, self).__init__(mainUi) self.mainUi = mainUi #--- Core ---# self.log = self.mainUi.log self._fdn = self.mainUi._fdn self._users = self._fdn._users self._groups = self._fdn._groups self._project = self._fdn._project #--- Icons ---# self.iconStore = QtGui.QIcon(pFile.conformPath(os.path.join(self.mainUi.__iconPath__, 'png', 'pinGreen.png'))) self.iconRemove = QtGui.QIcon(pFile.conformPath(os.path.join(self.mainUi.__iconPath__, 'png', 'del.png'))) self.iconRefresh = QtGui.QIcon(pFile.conformPath(os.path.join(self.mainUi.__iconPath__, 'png', 'refresh.png'))) self.iconLoad = QtGui.QIcon(pFile.conformPath(os.path.join(self.mainUi.__iconPath__, 'png', 'apply.png'))) self.iconCancel = QtGui.QIcon(pFile.conformPath(os.path.join(self.mainUi.__iconPath__, 'png', 'cancel.png'))) #--- Setup ---# self._setupDial()
def settingsFile(self): """ Get settings file full path :return: Settings file full path :rtype: str """ return pFile.conformPath(os.path.join(self._fdn.__settingsPath__, 'userGroups.py'))
def archivePath(self): """ Get archive path :return: Archive path :rtype: str """ return pFile.conformPath(os.path.join(self.usersPath, self.__archiveDir__))
def usersPath(self): """ Get users path :return: Users path :rtype: str """ return pFile.conformPath(os.path.join(self._fdn.__rootPath__, self.__usersDir__))
def projectFile(self): """ Get project file full path :return: Project file path :rtype: str """ if self.project is not None: return pFile.conformPath(os.path.join(self.projectPath, '%s.py' % self.project))
def entityFile(self): """ Get entity file full path :return: Entity file :rtype: str """ if self.entityPath is not None: return pFile.conformPath(os.path.join(self.entityPath, '%s.py' % self.entityName))
def entityPath(self): """ Get entity path :return: Entity path :rtype: str """ if self.contextPath is not None and self.entityName is not None: return pFile.conformPath(os.path.join(self.contextPath, self.entityName))
def projectPath(self): """ Get project path :return: Project path :rtype: str """ if self.project is not None: return pFile.conformPath(os.path.join(self._fdn.__projectsPath__, self.project))
def userFile(self): """ Get user file full path :return: User file full path :rtype: str """ if self.userName is not None: return pFile.conformPath(os.path.join(self.userPath, '%s.py' % self.userName))
def contextPath(self): """ Get context path :return: Context path :rtype: str """ if self.contextFolder is not None: return pFile.conformPath(os.path.join(self._project.projectPath, self.contextFolder))
def contextPath(self): """ Get context entity path :return: Context entity path :rtype: str """ if self._parent.contextPath is not None and self.ctxtFolder is not None: return pFile.conformPath(os.path.join(self._parent.contextPath, self.ctxtFolder))
def userPath(self): """ Get user path :return: User path :rtype: str """ if self.userName is not None: return pFile.conformPath(os.path.join(self._parent.usersPath, self.userPrefix, self.userName))
def delUser(self, userName=None, userObj=None, archive=False): """ Delete given user :param userName: User name :type userName: str :param userObj: User object :type userObj: User :param archive: Archives datas (clean disk) :type archive: bool """ # --- Check User Object ---# if userObj is None: userObj = self.getChilds(userName=userName) if userObj is None: raise AttributeError("!!! User not found: %s !!!" % userName) # --- Archive User ---# if archive: self.log.info("Archive user %r" % userObj.userName) dateTime = "%s--%s" % (pFile.getDate(), pFile.getTime()) archivePath = pFile.conformPath( os.path.join(self.archivePath, userObj.userPrefix, userObj.userName, dateTime) ) pFile.createPath(archivePath, recursive=True, root=self.usersPath, log=self.log) archiveFullPath = pFile.conformPath(os.path.join(archivePath, userObj.userName)) # --- Create Archive ---# if os.path.exists(userObj.userPath): try: shutil.copytree(userObj.userPath, archiveFullPath) shutil.rmtree(userObj.userPath) self.log.debug("---> User %r archived in %s" % (userObj.userName, archivePath)) except: raise IOError("!!! Can not copy tree: %s !!!" % userObj.userPath) else: raise IOError("!!! User path not found: %s !!!" % userObj.userPath) # --- Delete User Object ---# if userObj in self.childs: self.log.info("Deleting user object %r ..." % userObj.userName) self.childs.remove(userObj) else: self.log.debug("User object %r already deleted. Skipp !!!" % userObj.userName) # --- Result ---# self.log.info("---> %r deleted." % userObj.userName)
def delUser(self, userName=None, userObj=None, archive=False): """ Delete given user :param userName: User name :type userName: str :param userObj: User object :type userObj: User :param archive: Archives datas (clean disk) :type archive: bool """ #--- Check User Object ---# if userObj is None: userObj = self.getChilds(userName=userName) if userObj is None: raise AttributeError("!!! User not found: %s !!!" % userName) #--- Archive User ---# if archive: self.log.info("Archive user %r" % userObj.userName) dateTime = '%s--%s' % (pFile.getDate(), pFile.getTime()) archivePath = pFile.conformPath(os.path.join(self.archivePath, userObj.userPrefix, userObj.userName, dateTime)) pFile.createPath(archivePath, recursive=True, root=self.usersPath, log=self.log) archiveFullPath = pFile.conformPath(os.path.join(archivePath, userObj.userName)) #--- Create Archive ---# if os.path.exists(userObj.userPath): try: shutil.copytree(userObj.userPath, archiveFullPath) shutil.rmtree(userObj.userPath) self.log.debug("---> User %r archived in %s" % (userObj.userName, archivePath)) except: raise IOError("!!! Can not copy tree: %s !!!" % userObj.userPath) else: raise IOError("!!! User path not found: %s !!!" % userObj.userPath) #--- Delete User Object ---# if userObj in self.childs: self.log.info("Deleting user object %r ..." % userObj.userName) self.childs.remove(userObj) else: self.log.debug("User object %r already deleted. Skipp !!!" % userObj.userName) #--- Result ---# self.log.info("---> %r deleted." % userObj.userName)
def toolIcon(self): """ Get icon file full path :return: Icon file :rtype: str """ if self.tmFile is not None: iconFile = pFile.conformPath(os.path.join(os.path.dirname(self.tmFile), '__ico__.png')) if os.path.exists(iconFile): return iconFile
def collecteUsers(self, userPrefix=None, userName=None, clear=False, checkStatus=False): """ Collecte Users from disk :param userPrefix: User prefix folder :type userPrefix: str :param userName: User name :type userName: str :param clear: Clear childs contents :type clear: bool :param checkStatus: Consider userStatus when collecting :type checkStatus: bool :return: Collected user objects :rtype: list """ self.log.debug("Collecting users ...") #--- Clear Users ---# if clear: self.log.detail("Clear users list") self.clearChilds() #--- Collecte Users ---# userObjects = [] userList = self.parseUsers(userPrefix, userName) for user in userList: userPath = pFile.conformPath(os.path.join(self.usersPath, user[0].lower(), user)) if not user.startswith('_') and os.path.isdir(userPath): #--- Remove Existing object ---# userCheck = self.getChilds(userName=user) if userCheck: self.log.debug("Remove user object: %s" % user) if len(userCheck) == 1: self.childs.remove(userCheck[0]) else: raise ValueError("!!! Several userObj with same userName value !!!") #--- Create User Object ---# userObj = self.newChild(userName=user) userObj.setDataFromUserFile() #--- Check Status ---# addUserObj = True if checkStatus: addUserObj = userObj.userStatus if addUserObj: #--- Store Current User ---# if user == self._fdn.__user__: self._user = userObj #--- Add User Object ---# self.addChild(userObj) userObjects.append(userObj) self.log.detail("---> User Object %r added" % user) else: #--- Reject Current User ---# self.log.detail("---> User Object skipped, %r status is False" % user) #--- Result ---# return userObjects
def toolIcon(self): """ Get icon file full path :return: Icon file :rtype: str """ if self.tmFile is not None: iconFile = pFile.conformPath( os.path.join(os.path.dirname(self.tmFile), '__ico__.png')) if os.path.exists(iconFile): return iconFile
class ToolManager(QtGui.QMainWindow, toolManagerUI.Ui_mw_toolManager): """ ToolManager class: Manage maya tools :param logLvl : Log level ('critical', 'error', 'warning', 'info', 'debug', 'detail') :type logLvl: str :param parent: Maya main window :type parent: QtCore.QObject """ __rootDir__ = 'mayaTools' __rootPath__ = '/'.join(pFile.conformPath(__file__).split('/')[:-4]) __iconPath__ = pFile.conformPath(os.path.join(env.iconsPath, 'png')) def __init__(self, logLvl='info', parent=None): self.log = pFile.Logger(title=self.__class__.__name__, level=logLvl) self.log.info("########## Launching %s Ui ##########" % self.__class__.__name__, newLinesBefore=1) super(ToolManager, self).__init__(parent) self.toolsDict = dict() self._setupUi() def _setupUi(self): """ Setup ToolManager ui """ self.log.debug("Setup %s ui ..." % self.__class__.__name__) self.setupUi(self) self.gridLayout.setSpacing(0) self.gridLayout.setMargin(0) self._setupMenu() #--- Refresh ---# self.buildTree() def _setupMenu(self): """ Setup toolManager menu """ #--- Log Level ---# for level in self.log.levels: menuItem = self.m_logLevel.addAction(level) menuItem.setCheckable(True) menuItem.triggered.connect(partial(self.on_miLogLevel, level)) self.on_miLogLevel(self.log.level) def collecteTools(self): """ Collecte tools from rootPath. Tool is detected if roolPackage contains '__tm__.py' file :return: Tools dict :rtype: dict """ self.log.info("Collecting tools ...") self.toolsDict = toolMngrCmds.collecteTools(self.__rootPath__) def buildTree(self): """ Build tools tree """ self.log.debug("Init tree ...") self.tw_tools.clear() self.collecteTools() #--- Add Category ---# self.log.debug("Building tree ...") for category in sorted(self.toolsDict.keys()): catItem = self.new_treeItem('category', category) self.tw_tools.addTopLevelItem(catItem) self.tw_tools.setItemWidget(catItem, 0, catItem._widget) #--- Add Tool ---# for tool in sorted(self.toolsDict[category].keys()): toolItem = self.new_treeItem( 'tool', tool, tmFile=self.toolsDict[category][tool]) catItem.addChild(toolItem) self.tw_tools.setItemWidget(toolItem, 0, toolItem._widget) #--- Refresh ---# self.tw_tools.collapseAll() def new_treeItem(self, itemType, itemName, tmFile=None): """ Create 'Tool' tree item :param itemType: 'Category' or 'tool' :type itemType: str :param itemName: Tool name :type itemName: str :param tmFile: __tm__.py file fullPath :type tmFile: str :return: Tool item :rtype: QtGui.QTreeWidgetItem """ newItem = QtGui.QTreeWidgetItem() newItem.itemType = itemType newItem.itemName = itemName newItem._widget = toolMngrWgts.TreeNode(self, newItem, tmFile=tmFile) return newItem def on_miLogLevel(self, logLevel): """ Command launched when 'Log Level' QMenuItem is triggered Set ui and core log level :param logLevel : Log level ('critical', 'error', 'warning', 'info', 'debug', 'detail') :type logLevel: str """ #--- Uncheck All ---# for menuItem in self.m_logLevel.children(): menuItem.setChecked(False) #--- Check Given LogLvl ---# for menuItem in self.m_logLevel.children(): if str(menuItem.text()) == logLevel: menuItem.setChecked(True) break #--- Set Log Level ---# self.log.level = logLevel
class Rigger(QtGui.QMainWindow, riggerUI.Ui_mw_rigger): """ Rigger class: Cloth rigger mainUi. Contains cloth setup cmds :param logLvl : Log level ('critical', 'error', 'warning', 'info', 'debug', 'detail') :type logLvl: str :param parent: Maya main window :type parent: QtCore.QObject """ __iconPath__ = pFile.conformPath(env.iconsPath) def __init__(self, logLvl='info', parent=None): self.log = pFile.Logger(title=self.__class__.__name__, level=logLvl) self.log.info("########## Launching %s Ui ##########" % self.__class__.__name__, newLinesBefore=1) super(Rigger, self).__init__(parent) self.iconCloth = QtGui.QIcon( os.path.join(self.__iconPath__, 'maya', 'nCloth.png')) self.iconRigid = QtGui.QIcon( os.path.join(self.__iconPath__, 'maya', 'nRigid.png')) self.iconConst = QtGui.QIcon( os.path.join(self.__iconPath__, 'maya', 'nConstraint.png')) self._setupUi() def _setupUi(self): """ Setup main ui """ self.log.debug("Setup %s ui ..." % self.__class__.__name__) self.setupUi(self) #--- Wraps ---# self.gb_initWraps.clicked.connect(self.rf_initWraps) self.pb_hiToDecoupe.setToolTip( "Select driver Hi mesh, then slave cutted loS mesh.") self.pb_losToDecoupe.setToolTip( "Select slave loS mesh component, then slave cutted loS mesh.") #--- nCloth ---# self.le_clothMesh.wgResult = self.le_clothResult self.pb_createCloth.setIcon(self.iconCloth) #--- nRigid ---# self.le_rigidMesh.wgResult = self.le_rigidResult self.pb_createRigid.setIcon(self.iconRigid) #--- nConstraint ---# self.le_constraint.wgResult = self.le_constResult self.pb_storeConst.setIcon(self.iconConst) #--- Refresh ---# self.rf_initWraps() @property def clothSolver(self): """ Get current cloth solver :return: Cloth solver :rtype: str """ return str(self.cb_clothSolver.currentText()) @property def rigidSolver(self): """ Get current rigid solver :return: Rigid solver :rtype: str """ return str(self.cb_rigidSolver.currentText()) @property def passiveMode(self): """ Get current passive mode :return: Passive mode ('collide', 'pushOut', 'passive') :rtype: str """ if self.rb_collide.isChecked(): return "collide" elif self.rb_pushOut.isChecked(): return "pushOut" elif self.rb_passive.isChecked(): return "passive" def rf_initWraps(self): """ Refresh 'Init Wraps' QGroupBox visibility """ if self.gb_initWraps.isChecked(): self.gb_initWraps.setMaximumHeight(55) else: self.gb_initWraps.setMaximumHeight(15)