def clean(self, pNetworkLoc=''):
        _pNetworkLoc = pNetworkLoc

        # clean pymel
        pymel102 = Path('%s/python/maya/pymel-1.0.2' % _pNetworkLoc)
        if pymel102.exists():
            print "Cleaning old: %s/." % _pNetworkLoc
            for _dir in pymel102.dirs():
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()

                if _dir.exists():
                    try:
                        _dir.rmtree()
                        print "Removing dir: %s" % _dir
                    except WindowsError:
                        print "Unable to delete dir: '%s'" % _dir
                        raise
            # remote top dir too
            pymel102.rmtree()

        pymel103 = Path('%s/python/maya/pymel-1.0.3' % _pNetworkLoc)

        for _dir in pymel103.dirs():
            if "pymel" not in _dir.basename() and "maya" not in _dir.basename(
            ):  #keep 'pymel' & 'maya'!
                print "Cleaning unneeded: %s/." % _dir
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()

                if _dir.exists():
                    try:
                        _dir.rmtree()
                        print "Removing dir: %s" % _dir
                    except WindowsError:
                        print "Unable to delete dir: '%s'" % _dir
                        raise

        # make writable
        for _file in pymel103.files():
            _file.makeWritable()
            _file.remove()


#		# clean
#		try:
#			Path('%s/.settings' % self.networkLoc).removedirs() # Fails. Read-Only?
#		except WindowsError:
#			print "Failed to remove %s/.settings'" % self.networkLoc

        print "**********************************"
        print "cleaning of '%s' complete." % _pNetworkLoc
        print "**********************************"
        logger.info("**********************************")
        logger.info("cleaning of '%s' complete." % _pNetworkLoc)
        logger.info("**********************************")
    def pipelineSourceLocation(self):
        ''' Property, do not use ()
			determine location of pipeline root as specified by .xml schema
			Params: none
			Returns: Path(fileLocation)
		'''

        # Parse Global XML
        globalPCSXMLPath = Path('%s/installData/PCSstudio.xml' %
                                self.networkLoc)
        globalPCSXML = ET.parse(globalPCSXMLPath)
        globalXMLCore = globalPCSXML.getiterator('teamA')[0]
        sourceLoc = globalXMLCore.get('P4_Mode')

        return Path(sourceLoc)
    def removePYfiles(self, pathToScrape='', optionalExt='.py'):
        ''' removes all .py files from directory
		NOTE: may need to make non-Read only
			Params:
				pathToScrape: directory to process
				optionalExt: can remove .pyc if needed
			Returns: True/False?
		'''
        completeSuccess = True
        logger.info("Removing %s files from : '%s'" %
                    (optionalExt, pathToScrape))

        if not pathToScrape:
            pathToScrape = self.networkLoc

        count = 0
        for pyFile in Path(pathToScrape).walkfiles('*%s' % optionalExt):
            # skip Mobu/Maya startup files
            if "pcsGlobalSetup.py" in pyFile or "gVarInit.py" in pyFile or "sysGlobalMenu.py" in pyFile:
                # make non-readOnly
                pyFile.makeWritable()
                continue
            # template files need to stay
            if not "mayaMenuBoot.py" in pyFile:
                if not "teamMenu.py" in pyFile and not "teamMenuBoot.py" in pyFile:
                    try:
                        if Path(pyFile).isReadOnly:
                            Path(pyFile).makeWritable()
                        os.remove(pyFile)
                        logger.debug("Removing: '%s'" % pyFile)
                        count += 1
                    except:
                        logger.info("Failed to remove: '%s'" % pyFile)
                        completeSuccess = False

        print "Removed %d %s files from : '%s'" % (count, optionalExt,
                                                   pathToScrape)
        logger.info("Removed %d %s files from : '%s'" %
                    (count, optionalExt, pathToScrape))

        print "**********************************"
        print "Remove %s complete." % optionalExt
        print "**********************************"
        logger.info("**********************************")
        logger.info("Remove %s complete." % optionalExt)
        logger.info("**********************************")

        return completeSuccess
    def clean(self, pNetworkLoc=""):
        _pNetworkLoc = pNetworkLoc

        # clean pymel
        pymel102 = Path("%s/python/maya/pymel-1.0.2" % _pNetworkLoc)
        if pymel102.exists():
            print "Cleaning old: %s/." % _pNetworkLoc
            for _dir in pymel102.dirs():
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()

                if _dir.exists():
                    try:
                        _dir.rmtree()
                        print "Removing dir: %s" % _dir
                    except WindowsError:
                        print "Unable to delete dir: '%s'" % _dir
                        raise
                        # remote top dir too
            pymel102.rmtree()

        pymel103 = Path("%s/python/maya/pymel-1.0.3" % _pNetworkLoc)

        for _dir in pymel103.dirs():
            if "pymel" not in _dir.basename() and "maya" not in _dir.basename():  # keep 'pymel' & 'maya'!
                print "Cleaning unneeded: %s/." % _dir
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()

                if _dir.exists():
                    try:
                        _dir.rmtree()
                        print "Removing dir: %s" % _dir
                    except WindowsError:
                        print "Unable to delete dir: '%s'" % _dir
                        raise

                        # make writable
        for _file in pymel103.files():
            _file.makeWritable()
            _file.remove()

        # 		# clean
        # 		try:
        # 			Path('%s/.settings' % self.networkLoc).removedirs() # Fails. Read-Only?
        # 		except WindowsError:
        # 			print "Failed to remove %s/.settings'" % self.networkLoc

        print "**********************************"
        print "cleaning of '%s' complete." % _pNetworkLoc
        print "**********************************"
        logger.info("**********************************")
        logger.info("cleaning of '%s' complete." % _pNetworkLoc)
        logger.info("**********************************")
    def getMenuDic(self):
        menuDict = {}
        ext = '.py'

        # Add tools procedurally from ../mobuMenu
        self.mobuMenuPath = Path('%s/python/moBu/menu/' % gv.toolsLocation)
        if self.mobuMenuPath[:2] == '//':
            # network, look for .pyc
            ext = '.pyc'
        for root, unused, unused in os.walk(os.path.abspath(
                self.mobuMenuPath)):
            if not Path(root).makePretty(lastSlash=False,
                                         backward=False) == self.mobuMenuPath:
                mFiles = []
                for fname in os.listdir(root):
                    fullPath = '%s/%s' % (root, fname)
                    if Path(fullPath).isfile() and fnmatch.fnmatch(
                            fname, '*%s' % ext):
                        mFiles.append(fname)
                menuDict[Path(root).makePretty(lastSlash=False,
                                               backward=False)] = mFiles
        return menuDict, ext
    def __init__(self, remoteBuild=True):
        """ PipelineBuild.__init__():  set initial parameters """
        ''' create class
		Params:
			remoteBuild: build for remote location delivery
		Returns: PipelineBuild object
		'''
        super(PipelineBuild, self).__init__()
        self.p4 = pcsP4.P4Lib(maya=0)
        self.networkLoc = gv.toolsLocation

        # create in location on network
        self.remoteBuild = remoteBuild
        self.buildDest = Path(
            gv.toolsLocation).parent + '/AMremoteBuild/ArtMonkey'
Example #7
0
    def getExport(self, wFile=0):
        """ Method that returns folder for exporting meshes, animations (Character & Environment) """
        #assert(self.exportSourceFolder), ""
        if not self.filePath or not self.exportSourceFolder:
            return

        if self.team == gv.teamA:
            self.exportKey = int(self.exportKey)
            if wFile:
                self.exportPath = (
                    '%s%s' %
                    (self.exportSourceFolder.rsplit('/',
                                                    (self.exportKey + 1))[0] +
                     '/', self.filePath[self.filePath.rfind('/') + 1:])
                ).replace(".ma", ".gr2").replace(".mb", "gr2")
            else:
                self.exportPath = self.exportSourceFolder.rsplit(
                    '/', (self.exportKey + 1))[0] + '/'
                #print 'printStatement: ' + self.exportSourceFolder
                logger.debug('Export folder: %s' % self.exportSourceFolder)

            return self.exportPath

        elif self.team == gv.teamB:
            if re.search('Animations', self.filePath):
                self.exportFileName = self.filePath.basename().replace(
                    ".ma", ".xmd").replace(".mb",
                                           ".xmd").replace(".fbx", ".xmd")
                rigPath = self.filePath[:self.filePath.rfind('MoBu')]
                weapon = self.exportFileName.split('_')[1]
                self.exportPath = Path('%s/Morpheme/Animations/%s/%s' %
                                       (rigPath, weapon, self.exportFileName))
            else:
                self.exportPath = Path(
                    self.filePath.replace(".ma", ".gr2").replace(".mb", "gr2"))
            if not wFile:
                self.exportPath = self.exportPath.parent
            return self.exportPath.makePretty()

        elif self.team == gv.teamD:
            strFrom = self.exportKey[self.exportKey.find(':', 2) +
                                     1:self.exportKey.rfind(':', 1)]
            #print strFrom
            strTo = self.exportKey[self.exportKey.rfind(':', 1) + 1:]
            #print strTo
            self.exportPath = self.exportSourceFolder.replace(strFrom, strTo)
            if wFile:
                self.exportPath = '%s%s' % (
                    self.exportPath,
                    self.filePath[self.filePath.rfind('/') + 1:])
            return self.exportPath

        elif self.team == gv.teamD:
            # If the asset is an environment asset
            if re.match(self.environmentRoot, self.exportSourceFolder):
                envMeshKey = self.exportList.get('environmentMeshExportKey')
                envMeshKeySource = envMeshKey[envMeshKey.find(':', 2) +
                                              1:envMeshKey.rfind(':', 1)]
                envMeshKeyTarget = envMeshKey[envMeshKey.rfind(':', 1) + 1:]
                envAnimKey = self.exportList.get('environmentAnimExportKey')
                envAnimKeySource = envAnimKey[envAnimKey.find(':', 2) +
                                              1:envAnimKey.rfind(':', 1) - 3]
                envAnimKeyTarget = envAnimKey[envAnimKey.rfind(':', 1) + 1:]

                # If the environment asset is an animation
                if re.search(envAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(
                        envAnimKeySource)[0] + envAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(
                        envMeshKeySource, envMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

            # If the asset is a character asset
            if re.match(self.characterRoot, self.exportSourceFolder):
                charMeshKey = self.exportList.get('characterMeshExportKey')
                charMeshKeySource = charMeshKey[charMeshKey.find(':', 2) +
                                                1:charMeshKey.rfind(':', 1)]
                charMeshKeyTarget = charMeshKey[charMeshKey.rfind(':', 1) + 1:]
                charAnimKey = self.exportList.get('characterAnimExportKey')
                charAnimKeySource = charAnimKey[charAnimKey.find(':', 2) +
                                                1:charAnimKey.rfind(':', 1) -
                                                3]
                charAnimKeyTarget = charAnimKey[charAnimKey.rfind(':', 1) + 1:]

                # If the character asset is an animation
                if re.search(charAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(
                        charAnimKeySource)[0] + charAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath
                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(
                        charMeshKeySource, charMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath
Example #8
0
class ExportParse(ParseSchema):
    """ Class to solve for the export tools """
    def __init__(self, filePath='', team=''):
        super(ExportParse, self).__init__()

        # Solve needed attributes from the xml
        self.runTimeArtRoot = eval(self.exportList.get("runTimeArtRoot"))
        self.exportKey = self.exportList.get("exportKey")

        # Set needed variables
        if self.filePath:
            if os.path.isdir(self.filePath):
                self.exportSourceFolder = self.filePath + '/'
            else:
                self.exportSourceFolder = os.path.dirname(self.filePath) + '/'
        else:
            logger.warning('No scene selected')
        #self.exportSourceFolder = '/'

    def getExport(self, wFile=0):
        """ Method that returns folder for exporting meshes, animations (Character & Environment) """
        #assert(self.exportSourceFolder), ""
        if not self.filePath or not self.exportSourceFolder:
            return

        if self.team == gv.teamA:
            self.exportKey = int(self.exportKey)
            if wFile:
                self.exportPath = (
                    '%s%s' %
                    (self.exportSourceFolder.rsplit('/',
                                                    (self.exportKey + 1))[0] +
                     '/', self.filePath[self.filePath.rfind('/') + 1:])
                ).replace(".ma", ".gr2").replace(".mb", "gr2")
            else:
                self.exportPath = self.exportSourceFolder.rsplit(
                    '/', (self.exportKey + 1))[0] + '/'
                #print 'printStatement: ' + self.exportSourceFolder
                logger.debug('Export folder: %s' % self.exportSourceFolder)

            return self.exportPath

        elif self.team == gv.teamB:
            if re.search('Animations', self.filePath):
                self.exportFileName = self.filePath.basename().replace(
                    ".ma", ".xmd").replace(".mb",
                                           ".xmd").replace(".fbx", ".xmd")
                rigPath = self.filePath[:self.filePath.rfind('MoBu')]
                weapon = self.exportFileName.split('_')[1]
                self.exportPath = Path('%s/Morpheme/Animations/%s/%s' %
                                       (rigPath, weapon, self.exportFileName))
            else:
                self.exportPath = Path(
                    self.filePath.replace(".ma", ".gr2").replace(".mb", "gr2"))
            if not wFile:
                self.exportPath = self.exportPath.parent
            return self.exportPath.makePretty()

        elif self.team == gv.teamD:
            strFrom = self.exportKey[self.exportKey.find(':', 2) +
                                     1:self.exportKey.rfind(':', 1)]
            #print strFrom
            strTo = self.exportKey[self.exportKey.rfind(':', 1) + 1:]
            #print strTo
            self.exportPath = self.exportSourceFolder.replace(strFrom, strTo)
            if wFile:
                self.exportPath = '%s%s' % (
                    self.exportPath,
                    self.filePath[self.filePath.rfind('/') + 1:])
            return self.exportPath

        elif self.team == gv.teamD:
            # If the asset is an environment asset
            if re.match(self.environmentRoot, self.exportSourceFolder):
                envMeshKey = self.exportList.get('environmentMeshExportKey')
                envMeshKeySource = envMeshKey[envMeshKey.find(':', 2) +
                                              1:envMeshKey.rfind(':', 1)]
                envMeshKeyTarget = envMeshKey[envMeshKey.rfind(':', 1) + 1:]
                envAnimKey = self.exportList.get('environmentAnimExportKey')
                envAnimKeySource = envAnimKey[envAnimKey.find(':', 2) +
                                              1:envAnimKey.rfind(':', 1) - 3]
                envAnimKeyTarget = envAnimKey[envAnimKey.rfind(':', 1) + 1:]

                # If the environment asset is an animation
                if re.search(envAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(
                        envAnimKeySource)[0] + envAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(
                        envMeshKeySource, envMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

            # If the asset is a character asset
            if re.match(self.characterRoot, self.exportSourceFolder):
                charMeshKey = self.exportList.get('characterMeshExportKey')
                charMeshKeySource = charMeshKey[charMeshKey.find(':', 2) +
                                                1:charMeshKey.rfind(':', 1)]
                charMeshKeyTarget = charMeshKey[charMeshKey.rfind(':', 1) + 1:]
                charAnimKey = self.exportList.get('characterAnimExportKey')
                charAnimKeySource = charAnimKey[charAnimKey.find(':', 2) +
                                                1:charAnimKey.rfind(':', 1) -
                                                3]
                charAnimKeyTarget = charAnimKey[charAnimKey.rfind(':', 1) + 1:]

                # If the character asset is an animation
                if re.search(charAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(
                        charAnimKeySource)[0] + charAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath
                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(
                        charMeshKeySource, charMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (
                            self.exportPath,
                            self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

    def getRunTimeArt(self, wFile=0):
        """ method to return the folder (or w/ file) for the run time copy """
        fileLoc = self.getExport(wFile)
        runTimeFilePath = fileLoc.replace(self.characterRoot,
                                          self.runTimeArtRoot)
        return runTimeFilePath

    def getRunTime(self):
        return self.runTimeArtRoot[:self.runTimeArtRoot.rfind('Runtime') + 8]
Example #9
0
    def __init__(self, filePath='', team='', mobu=0, **kwargs):
        super(ParseSchema, self).__init__()
        self.filePath = filePath

        if not filePath:
            if mobu:
                # get sceneName
                from pyfbsdk import FBApplication  # @UnresolvedImport

                self.filePath = Path(FBApplication().FBXFileName.replace(
                    '\\', '/'))
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == '':
                    self.filePath = None
            else:
                try:
                    from pymel.core import sceneName
                except ImportError:
                    sceneName = None
                    logger.errorDialog(
                        "ParseSchema thinks it is in Maya mode, forgot to pass 'mobu=1' arg?"
                    )
                self.filePath = Path(sceneName())
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == 'untitled.ma':
                    self.filePath = None

        # if no team passed, use first team listed in globalVariables.py
        if not team:
            team = gv.teamA

        #Parse the schema file
        relPath = (os.path.dirname(__file__).replace('\\', '/').replace(
            'python/common/fileIO', 'schemas/'))
        self.xmlContent = ET.parse(relPath + team + '.xml')

        #Gather all global headers
        self.coreList = self.xmlContent.getiterator('Core')[0]
        self.characterList = self.xmlContent.getiterator('Character')[0]
        self.environmentList = self.xmlContent.getiterator('Environment')[0]
        self.exportList = self.xmlContent.getiterator('Export')[0]
        self.areaList = self.xmlContent.getiterator('Areas')[0]
        self.mayaList = self.xmlContent.getiterator('Maya')[0]
        self.mobuList = self.xmlContent.getiterator('MoBu')[0]
        self.team = team

        # Read in the asset hub xml section
        if self.team == gv.teamA:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]
            self.assetHubList = self.xmlContent.getiterator('AssetHubUi')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamB:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamC:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")
Example #10
0
class ParseSchema(object):
    """ Super class that parses all necessary content that can be parsed on a global level """
    def __init__(self, filePath='', team='', mobu=0, **kwargs):
        super(ParseSchema, self).__init__()
        self.filePath = filePath

        if not filePath:
            if mobu:
                # get sceneName
                from pyfbsdk import FBApplication  # @UnresolvedImport

                self.filePath = Path(FBApplication().FBXFileName.replace(
                    '\\', '/'))
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == '':
                    self.filePath = None
            else:
                try:
                    from pymel.core import sceneName
                except ImportError:
                    sceneName = None
                    logger.errorDialog(
                        "ParseSchema thinks it is in Maya mode, forgot to pass 'mobu=1' arg?"
                    )
                self.filePath = Path(sceneName())
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == 'untitled.ma':
                    self.filePath = None

        # if no team passed, use first team listed in globalVariables.py
        if not team:
            team = gv.teamA

        #Parse the schema file
        relPath = (os.path.dirname(__file__).replace('\\', '/').replace(
            'python/common/fileIO', 'schemas/'))
        self.xmlContent = ET.parse(relPath + team + '.xml')

        #Gather all global headers
        self.coreList = self.xmlContent.getiterator('Core')[0]
        self.characterList = self.xmlContent.getiterator('Character')[0]
        self.environmentList = self.xmlContent.getiterator('Environment')[0]
        self.exportList = self.xmlContent.getiterator('Export')[0]
        self.areaList = self.xmlContent.getiterator('Areas')[0]
        self.mayaList = self.xmlContent.getiterator('Maya')[0]
        self.mobuList = self.xmlContent.getiterator('MoBu')[0]
        self.team = team

        # Read in the asset hub xml section
        if self.team == gv.teamA:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]
            self.assetHubList = self.xmlContent.getiterator('AssetHubUi')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamB:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamC:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(
                self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(
                self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

    def getMayaDir(self, attr):
        return eval(self.mayaList.get(attr))

    def getMoBuDir(self, attr):
        return eval(self.mobuList.get(attr))

    @property
    def artRoot(self):
        return self.getMayaDir('artRoot')

    @property
    def animationsRoot(self):
        return self.getMoBuDir('animationsRoot')

    @property
    def environmentRoot(self):
        return self.getMayaDir('environmentRoot')

    @property
    def characterRoot(self):
        return self.getMayaDir('characterRoot')

    def getUnitTestSource(self):
        return '%s/python/tests/source/' % gv.toolsLocation

    def getWellFormed(self, varName='', listName='Rigging'):

        if not listName.__class__ == str and listName.__module__ == 'xml.etree.ElementTree':
            self.list = listName
        else:
            self.list = self.xmlContent.getiterator(listName)
            if not self.list:
                logger.error(
                    'Failed to find list named "%s" in xml file: %s, wrong team? "%s"'
                    % (listName, self.xmlContent, self.team))
                return
            #assert(len(self.list) > 0), logger.error('Failed to find list named "%s" in xml file: %s, wrong team? "%s"' % (listName, self.xmlContent, self.team))
            self.list = self.list[0]

        for under in self.list.getiterator():
            if under.get('name') == varName:
                result = under.get('value')
                if re.search('\.', result):
                    result = float(result)
                return result

    def setFilePath(self, filePath):
        self.filePath = Path(filePath)

    def setTeam(self, team):
        self.team = team

    def findAnimationFolder(self, team):
        self.replace(self.characterList.get("AnimationFolderKey"), '')
Example #11
0
 def setFilePath(self, filePath):
     self.filePath = Path(filePath)
    def createTool(self):
        moBuLogger.info('----------------------------------------')
        moBuLogger.info('|     Running Art Monkey v:%s     |' % _VERSION)
        moBuLogger.info('|     Build #:%s     |' % self.buildNumber)
        moBuLogger.info('----------------------------------------')

        pcsGlobalToolName = "Art Monkey"
        tool = FBCreateUniqueTool(pcsGlobalToolName)
        tool.StartSizeX = 610
        tool.StartSizeY = 185

        # Layout for the controls
        x = FBAddRegionParam(5, FBAttachType.kFBAttachLeft, "")
        y = FBAddRegionParam(0, FBAttachType.kFBAttachNone, "")
        w = FBAddRegionParam(50, FBAttachType.kFBAttachRight, "")
        h = FBAddRegionParam(85, FBAttachType.kFBAttachNone, "")
        tool.AddRegion("main", "main", x, y, w, h)

        # Add grid layout
        grid = FBGridLayout()
        tool.SetControl("main", grid)

        col = 0

        logo = FBButton()
        logo.SetImageFileNames('%s/logo_small.jpg' % self.pcsImagePath)
        logo.Caption = "yeah"
        logo.OnClick.Add(self.openToolDocs)
        grid.AddRange(logo, 0, 1, col, col)
        grid.SetColWidth(col, 70)

        v = FBLabel()
        v.Caption = 'v:%s' % _VERSION
        v.Style = FBTextStyle.kFBTextStyleItalic
        v.Justify = FBTextJustify.kFBTextJustifyCenter
        grid.Add(v, 2, col)
        col += 1

        # create load button
        loadB = FBButton()
        loadB.Caption = "Load"
        loadB.Look = FBButtonLook.kFBLookColorChange
        loadB.OnClick.Add(self.KToolsCallback)

        # create save button
        saveB = FBButton()
        saveB.Caption = "Save"
        saveB.Look = FBButtonLook.kFBLookColorChange
        saveB.OnClick.Add(self.KToolsCallback)

        # create saveAs button
        saveAsB = FBButton()
        saveAsB.Caption = "SaveAs"
        saveAsB.Look = FBButtonLook.kFBLookColorChange
        saveAsB.OnClick.Add(self.KToolsCallback)

        # add buttons to row 1,2,3 column 1
        grid.Add(loadB, 0, col)
        grid.Add(saveB, 1, col)
        grid.Add(saveAsB, 2, col)

        # want to fix the width of column 1 and 2 so the buttons are of a normal size
        grid.SetColWidth(col, 40)

        col += 1

        # create tab
        tab = FBTabControl()
        # we want the tab to span from row 0 to row 3 and from column 2 to column 2
        grid.AddRange(tab, 0, 3, col, col)

        # set the spacing between col0 and col1
        grid.SetColSpacing(col, 20)

        # now assign the rows and columns attributes
        # Fixed the height of row 0 and row 2 so the label and the buttons have a normal height
        grid.SetRowHeight(0, 20)
        grid.SetRowHeight(1, 20)
        grid.SetRowHeight(2, 20)
        grid.SetRowHeight(3, 70)

        # 1. Build a construction dictionary with {folder=[files]}
        self.menuDict, ext = self.getMenuDic()

        # 1.5 add top menu path for Load, Save, SaveAs
        #		menuTop = self.menuDict.keys()[0]
        if not Path.modulePath(self.mobuMenuPath):
            sys.path.append(self.mobuMenuPath)

        # 2. Sorted Keys list
        sKeys = []
        for dr in self.menuDict.iterkeys():
            sKeys.append(dr)
        sKeys.sort()

        for menu in sKeys:

            menuName = str(Path(menu).basename())
            # skip root and 'old'
            if not menuName == 'old' and not menuName == 'menu':
                tabLayout = FBGridLayout()
                #				lyt.default_space = 5
                tabLayout.SetRegionTitle("My Title", "Title")

                x = FBAddRegionParam(10, FBAttachType.kFBAttachLeft, "")
                y = FBAddRegionParam(20, FBAttachType.kFBAttachTop, "")
                w = FBAddRegionParam(140, FBAttachType.kFBAttachRight, "")
                h = FBAddRegionParam(75, FBAttachType.kFBAttachBottom, "")
                tabLayout.AddRegion(menuName, menuName, x, y, w, h)

                # must add dir to sys.path so imp can find it
                if not Path.modulePath(menu):
                    sys.path.append(menu)

                row = 0
                column = 0
                colWidth = 0
                colMax = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
                for script in self.menuDict[menu]:
                    if not script == '__init__%s' % ext:
                        toolName = str(Path(script).namebase)
                        lTool = FBButton()
                        lTool.Caption = toolName
                        lTool.Justify = FBTextJustify.kFBTextJustifyCenter

                        # Make "Fix this!" red
                        if toolName == 'Fix this!':
                            lTool.Look = FBButtonLook.kFBLookColorChange
                            lTool.SetStateColor(FBButtonState.kFBButtonState0,
                                                mbCore.Red)
                            lTool.SetStateColor(FBButtonState.kFBButtonState1,
                                                mbCore.Red)

                        # this callBack is active and all buttons will run this "last" menuModule.run()
                        lTool.OnClick.Add(self.KToolsCallback)
                        tabLayout.Add(lTool, row, column)

                        # make column maximum of all rows
                        colWidth = len(toolName) * 7 + 2
                        if colWidth > colMax[column]:
                            colMax[column] = colWidth

                        tabLayout.SetColWidth(column, colMax[column])
                        tabLayout.SetRowHeight(row, 30)
                        # add button to tabbed sub-layout
                        tabLayout.Add(lTool, row, column)

                        # increment columns, rows
                        column += 1
                        if column > 3:
                            row += 1
                            column = 0

                # add layouts to tabControl with name of dir
                tab.Add(menuName, tabLayout)

        # finish up tab
        tab.SetContent(0)
        tab.TabPanel.TabStyle = 0  # normal tabs
class ParseSchema(object):
    """ Super class that parses all necessary content that can be parsed on a global level """

    def __init__(self, filePath='', team='', mobu=0, **kwargs):
        super(ParseSchema, self).__init__()
        self.filePath = filePath

        if not filePath:
            if mobu:
                # get sceneName
                from pyfbsdk import FBApplication  # @UnresolvedImport

                self.filePath = Path(FBApplication().FBXFileName.replace('\\', '/'))
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == '':
                    self.filePath = None
            else:
                try:
                    from pymel.core import sceneName
                except ImportError:
                    sceneName = None
                    logger.errorDialog("ParseSchema thinks it is in Maya mode, forgot to pass 'mobu=1' arg?")
                self.filePath = Path(sceneName())
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == 'untitled.ma':
                    self.filePath = None

        # if no team passed, use first team listed in globalVariables.py
        if not team:
            team = gv.teamA

        #Parse the schema file
        relPath = (os.path.dirname(__file__)
                   .replace('\\', '/')
                   .replace('python/common/fileIO', 'schemas/'))
        self.xmlContent = ET.parse(relPath + team + '.xml')

        #Gather all global headers
        self.coreList = self.xmlContent.getiterator('Core')[0]
        self.characterList = self.xmlContent.getiterator('Character')[0]
        self.environmentList = self.xmlContent.getiterator('Environment')[0]
        self.exportList = self.xmlContent.getiterator('Export')[0]
        self.areaList = self.xmlContent.getiterator('Areas')[0]
        self.mayaList = self.xmlContent.getiterator('Maya')[0]
        self.mobuList = self.xmlContent.getiterator('MoBu')[0]
        self.team = team


        # Read in the asset hub xml section
        if self.team == gv.teamA:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]
            self.assetHubList = self.xmlContent.getiterator('AssetHubUi')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamB:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamC:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

    def getMayaDir(self, attr):
        return eval(self.mayaList.get(attr))

    def getMoBuDir(self, attr):
        return eval(self.mobuList.get(attr))

    @property
    def artRoot(self):
        return self.getMayaDir('artRoot')

    @property
    def animationsRoot(self):
        return self.getMoBuDir('animationsRoot')

    @property
    def environmentRoot(self):
        return self.getMayaDir('environmentRoot')

    @property
    def characterRoot(self):
        return self.getMayaDir('characterRoot')

    def getUnitTestSource(self):
        return '%s/python/tests/source/' % gv.toolsLocation

    def getWellFormed(self, varName='', listName='Rigging'):

        if not listName.__class__ == str and listName.__module__ == 'xml.etree.ElementTree':
            self.list = listName
        else:
            self.list = self.xmlContent.getiterator(listName)
            if not self.list:
                logger.error('Failed to find list named "%s" in xml file: %s, wrong team? "%s"' % (
                    listName, self.xmlContent, self.team))
                return
            #assert(len(self.list) > 0), logger.error('Failed to find list named "%s" in xml file: %s, wrong team? "%s"' % (listName, self.xmlContent, self.team))
            self.list = self.list[0]

        for under in self.list.getiterator():
            if under.get('name') == varName:
                result = under.get('value')
                if re.search('\.', result):
                    result = float(result)
                return result

    def setFilePath(self, filePath):
        self.filePath = Path(filePath)

    def setTeam(self, team):
        self.team = team

    def findAnimationFolder(self, team):
        self.replace(self.characterList.get("AnimationFolderKey"), '')
    def pushToNetwork(self, networkLoc=gv.toolsLocation, remote=True):
        """ copies all files from depot to desired
			network test location
			Params:
				networkLoc: destination location
			Returns: True/False?
		"""

        _pNetworkLoc = Path(networkLoc)
        result = True

        # copy to remote build location, straight-up delete and copy all
        if remote:

            # try whole loop 5 times?
            for unused in range(4):
                if _pNetworkLoc.exists():
                    # nuke current folders
                    print "Cleaning old: %s/." % _pNetworkLoc
                    for _dir in _pNetworkLoc.dirs():
                        # make writable
                        for _file in _dir.walk():
                            _file.makeWritable()

                            # try /python twice
                        if "python" in _dir:
                            try:
                                _dir.rmtree()
                                print "Removing dir: %s" % _dir
                            except WindowsError:
                                print "Failed once on '%s', trying again . . ." % _dir

                        if _dir.exists():
                            try:
                                _dir.rmtree()
                                print "Removing dir: %s" % _dir
                            except WindowsError:
                                print "Unable to delete dir: '%s'" % _dir
                                raise
                                # remote top dir too
                    _pNetworkLoc.rmtree()

                    # copy to network
            print "Copying '%s' dir to '%s'" % (self.pipelineSourceLocation, _pNetworkLoc)
            try:
                Path(self.pipelineSourceLocation).copytree(_pNetworkLoc)
            except WindowsError:
                print "Process locked trying to copy to: '%s'. Please just run again." % _pNetworkLoc
                raise
            except shutil.Error as e:
                print "Permission denied for file/folder: '%s'" % e[0]

                # success?
            if not _pNetworkLoc.exists():
                logger.error("Failed to copy to remote location build: '%s'" % _pNetworkLoc)

                # copy/move dataResources sub-folder
            for _dir in Path("%s/dataResources" % _pNetworkLoc).dirs():
                if _dir.namebase == "installData":
                    Path(_dir).move(_pNetworkLoc)

                    # have to dance around data and installData dirs
        else:
            if _pNetworkLoc.exists():
                # nuke current folders
                print "Cleaning old: %s/." % _pNetworkLoc
                for _dir in _pNetworkLoc.dirs():
                    if "data" not in _dir:  # keep 'data' & 'installData'!
                        # make writable
                        for _file in _dir.walk():
                            _file.makeWritable()

                            # try /python twice
                        if "python" in _dir:
                            try:
                                _dir.rmtree()
                            except WindowsError:
                                print "Failed once on '%s', trying again . . ." % _dir

                        if _dir.exists():
                            try:
                                _dir.rmtree()
                                print "Removing dir: %s" % _dir
                            except WindowsError:
                                print "Unable to delete dir: '%s'" % _dir
                                raise

                                # clean dataResources
                    elif _dir == "dataResources":
                        # make writable
                        for _file in _dir.walk():
                            _file.makeWritable()
                        print "Removing dir: %s" % _dir
                        _dir.rmtree()

                        # copy to network
            tempNetworkLoc = Path("%s/temp" % _pNetworkLoc)

            # copy
            print "Copying '%s' dir to '%s'" % (self.pipelineSourceLocation, tempNetworkLoc)
            try:
                Path(self.pipelineSourceLocation).copytree(tempNetworkLoc)
            except WindowsError:
                print "Process locked trying to copy to: '%s'. Please just run again." % tempNetworkLoc
            except shutil.Error as e:
                print "Permission denied for file/folder: '%s'" % e[0]

                # move first-layer sub-dirs from '/temp' up to parent
            for _dir in tempNetworkLoc.dirs():
                try:
                    if "data" not in _dir:  # skip 'data' & 'installData'!
                        Path(_dir).move(_pNetworkLoc)
                except WindowsError:
                    print "failed on: " + _dir
                except shutil.Error:
                    print "failed to copy from dir: '%s', already exists?" % _dir
                    raise

                    # nuke tempNetworkLoc
            if tempNetworkLoc.exists():
                print "Cleaning old: %s" % tempNetworkLoc
                # make writable
                for _file in tempNetworkLoc.walk():
                    _file.makeWritable()
                print "Removing tree: %s" % tempNetworkLoc
                tempNetworkLoc.rmtree()

                ############# start cleaning ##############

                # clean un-needed root folders
        unNeededRoot = ["dataResources", "docs", "logs"]
        for unNeeded in unNeededRoot:
            print "Cleaning un-needed: %s/%s" % (_pNetworkLoc, unNeeded)
            for _dir in Path(_pNetworkLoc).dirs():
                if _dir.namebase == unNeeded:
                    # make writable
                    for _file in _dir.walk():
                        _file.makeWritable()
                    print "Removing dir: %s" % _dir
                    _dir.rmtree()

                    # clean unitTests
        print "Cleaning un-needed: %s/python/unitTests" % _pNetworkLoc
        for _dir in Path("%s/python" % _pNetworkLoc).dirs():
            if _dir.namebase == "unitTests":
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()
                print "Removing dir: %s" % _dir
                _dir.rmtree()

                # clean non-maya/pymel dirs from pymels
        print "Cleaning un-needed: %s/python/maya/pymel" % _pNetworkLoc
        pyMelDirs = ["pymel-1.0.2", "pymel-1.0.3"]
        for pyMelDir in pyMelDirs:
            if not Path("%s/python/maya/%s" % (_pNetworkLoc, pyMelDir)).exists():
                logger.error("No pymel dir found, probably failed copy earlier.")
                if not _dir.namebase == "maya" and not _dir.namebase == "pymel":
                    # make writable
                    for _file in _dir.walk():
                        _file.makeWritable()
                    print "Removing dir: %s" % _dir
                    _dir.rmtree()
                for _file in Path("%s/python/maya/%s" % (_pNetworkLoc, pyMelDir)).files():
                    _file.makeWritable()
                    print "Removing file: %s" % _file
                    _file.remove()

                    # clean apps
        print "Cleaning un-needed: %s/python/apps" % _pNetworkLoc
        for _dir in Path("%s/python/apps" % _pNetworkLoc).dirs():
            if not _dir.namebase == "APE":
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()
                print "Removing dir: %s" % _dir
                _dir.rmtree()

                # clean misc
        print "Cleaning un-needed project files in : %s" % _pNetworkLoc
        unNeededRoot = [".project", ".pydevproject", "artMonkey.wpr", "artMonkey.wpu"]
        for unNeeded in unNeededRoot:
            for _file in _pNetworkLoc.files():
                if _file.basename() == unNeeded:
                    # make writable
                    _file.makeWritable()
                    print "Removing file: %s" % _file
                    _file.remove()

        print "**********************************"
        print "Push To Network complete."
        print "**********************************"
        logger.info("**********************************")
        logger.info("Push To Network complete.")
        logger.info("**********************************")

        return result
	def createTool(self):
		moBuLogger.info('----------------------------------------')
		moBuLogger.info('|     Running Art Monkey v:%s     |' % _VERSION)
		moBuLogger.info('|     Build #:%s     |' % self.buildNumber)
		moBuLogger.info('----------------------------------------')
		
		pcsGlobalToolName = "Art Monkey"
		tool = FBCreateUniqueTool(pcsGlobalToolName)
		tool.StartSizeX = 610
		tool.StartSizeY = 185
		
		# Layout for the controls
		x = FBAddRegionParam(5, FBAttachType.kFBAttachLeft, "")
		y = FBAddRegionParam(0, FBAttachType.kFBAttachNone, "")
		w = FBAddRegionParam(50, FBAttachType.kFBAttachRight, "")
		h = FBAddRegionParam(85, FBAttachType.kFBAttachNone, "")
		tool.AddRegion("main", "main", x, y, w, h)
		
		# Add grid layout
		grid = FBGridLayout()
		tool.SetControl("main", grid)
		
		col = 0
		
		logo = FBButton()
		logo.SetImageFileNames('%s/logo_small.jpg' % self.pcsImagePath)
		logo.Caption = "yeah"
		logo.OnClick.Add(self.openToolDocs)
		grid.AddRange(logo, 0, 1, col, col)
		grid.SetColWidth( col, 70 )
		
		v = FBLabel()
		v.Caption = 'v:%s' % _VERSION
		v.Style = FBTextStyle.kFBTextStyleItalic
		v.Justify = FBTextJustify.kFBTextJustifyCenter
		grid.Add(v, 2, col)
		col +=1
		
		# create load button
		loadB = FBButton()
		loadB.Caption = "Load"
		loadB.Look = FBButtonLook.kFBLookColorChange
		loadB.OnClick.Add(self.KToolsCallback)
		
		# create save button
		saveB = FBButton()
		saveB.Caption = "Save"
		saveB.Look = FBButtonLook.kFBLookColorChange
		saveB.OnClick.Add(self.KToolsCallback)
		
		# create saveAs button
		saveAsB = FBButton()
		saveAsB.Caption = "SaveAs"
		saveAsB.Look = FBButtonLook.kFBLookColorChange
		saveAsB.OnClick.Add(self.KToolsCallback)
		
		# add buttons to row 1,2,3 column 1
		grid.Add(loadB, 0, col)
		grid.Add(saveB, 1, col)
		grid.Add(saveAsB, 2, col)
		
		# want to fix the width of column 1 and 2 so the buttons are of a normal size
		grid.SetColWidth( col, 40 )

		col +=1
				
		# create tab
		tab = FBTabControl()
		# we want the tab to span from row 0 to row 3 and from column 2 to column 2
		grid.AddRange(tab, 0, 3, col, col)
		
		# set the spacing between col0 and col1
		grid.SetColSpacing(col, 20)
		
		# now assign the rows and columns attributes
		# Fixed the height of row 0 and row 2 so the label and the buttons have a normal height
		grid.SetRowHeight(0, 20)
		grid.SetRowHeight(1, 20)
		grid.SetRowHeight(2, 20)
		grid.SetRowHeight(3, 70)
		
		# 1. Build a construction dictionary with {folder=[files]}
		self.menuDict, ext = self.getMenuDic()
		
		# 1.5 add top menu path for Load, Save, SaveAs
#		menuTop = self.menuDict.keys()[0]
		if not Path.modulePath(self.mobuMenuPath):
			sys.path.append(self.mobuMenuPath)
		
		# 2. Sorted Keys list
		sKeys = []
		for dr in self.menuDict.iterkeys():
			sKeys.append(dr)
		sKeys.sort()
		
		for menu in sKeys:
			
			menuName = str(Path(menu).basename())
			# skip root and 'old'
			if not menuName == 'old' and not menuName == 'menu':
				tabLayout = FBGridLayout()
#				lyt.default_space = 5
				tabLayout.SetRegionTitle("My Title", "Title")
				
				x = FBAddRegionParam(10, FBAttachType.kFBAttachLeft, "")
				y = FBAddRegionParam(20, FBAttachType.kFBAttachTop, "")
				w = FBAddRegionParam(140, FBAttachType.kFBAttachRight, "")
				h = FBAddRegionParam(75, FBAttachType.kFBAttachBottom, "")
				tabLayout.AddRegion(menuName, menuName, x, y, w, h)
		
				# must add dir to sys.path so imp can find it
				if not Path.modulePath(menu):
					sys.path.append(menu)
				
				row = 0
				column = 0
				colWidth = 0
				colMax = {0:0, 1:0, 2:0, 3:0, 4:0}
				for script in self.menuDict[menu]:
					if not script == '__init__%s' % ext:
						toolName = str(Path(script).namebase)
						lTool = FBButton()
						lTool.Caption = toolName
						lTool.Justify = FBTextJustify.kFBTextJustifyCenter
						
						# Make "Fix this!" red
						if toolName == 'Fix this!':
							lTool.Look = FBButtonLook.kFBLookColorChange
							lTool.SetStateColor(FBButtonState.kFBButtonState0, mbCore.Red)
							lTool.SetStateColor(FBButtonState.kFBButtonState1, mbCore.Red)
		
						# this callBack is active and all buttons will run this "last" menuModule.run()
						lTool.OnClick.Add(self.KToolsCallback)
						tabLayout.Add(lTool, row, column)
						
						# make column maximum of all rows
						colWidth = len(toolName) * 7 + 2
						if colWidth > colMax[column]:
							colMax[column] = colWidth
						
						tabLayout.SetColWidth(column, colMax[column])
						tabLayout.SetRowHeight(row, 30)
						# add button to tabbed sub-layout
						tabLayout.Add(lTool, row, column)
						
						# increment columns, rows
						column += 1
						if column > 3:
							row += 1
							column = 0
			
				# add layouts to tabControl with name of dir
				tab.Add(menuName, tabLayout)
		
		# finish up tab
		tab.SetContent(0)
		tab.TabPanel.TabStyle = 0 # normal tabs
    def pushToNetwork(self, networkLoc=gv.toolsLocation, remote=True):
        ''' copies all files from depot to desired
			network test location
			Params:
				networkLoc: destination location
			Returns: True/False?
		'''

        _pNetworkLoc = Path(networkLoc)
        result = True

        # copy to remote build location, straight-up delete and copy all
        if remote:

            # try whole loop 5 times?
            for unused in range(4):
                if _pNetworkLoc.exists():
                    # nuke current folders
                    print "Cleaning old: %s/." % _pNetworkLoc
                    for _dir in _pNetworkLoc.dirs():
                        # make writable
                        for _file in _dir.walk():
                            _file.makeWritable()

                        # try /python twice
                        if 'python' in _dir:
                            try:
                                _dir.rmtree()
                                print "Removing dir: %s" % _dir
                            except WindowsError:
                                print "Failed once on '%s', trying again . . ." % _dir

                        if _dir.exists():
                            try:
                                _dir.rmtree()
                                print "Removing dir: %s" % _dir
                            except WindowsError:
                                print "Unable to delete dir: '%s'" % _dir
                                raise
                    # remote top dir too
                    _pNetworkLoc.rmtree()

            # copy to network
            print "Copying '%s' dir to '%s'" % (self.pipelineSourceLocation,
                                                _pNetworkLoc)
            try:
                Path(self.pipelineSourceLocation).copytree(_pNetworkLoc)
            except WindowsError:
                print "Process locked trying to copy to: '%s'. Please just run again." % _pNetworkLoc
                raise
            except shutil.Error as e:
                print "Permission denied for file/folder: '%s'" % e[0]

            # success?
            if not _pNetworkLoc.exists():
                logger.error("Failed to copy to remote location build: '%s'" %
                             _pNetworkLoc)

            # copy/move dataResources sub-folder
            for _dir in Path('%s/dataResources' % _pNetworkLoc).dirs():
                if _dir.namebase == 'installData':
                    Path(_dir).move(_pNetworkLoc)

        # have to dance around data and installData dirs
        else:
            if _pNetworkLoc.exists():
                # nuke current folders
                print "Cleaning old: %s/." % _pNetworkLoc
                for _dir in _pNetworkLoc.dirs():
                    if "data" not in _dir:  #keep 'data' & 'installData'!
                        # make writable
                        for _file in _dir.walk():
                            _file.makeWritable()

                        # try /python twice
                        if 'python' in _dir:
                            try:
                                _dir.rmtree()
                            except WindowsError:
                                print "Failed once on '%s', trying again . . ." % _dir

                        if _dir.exists():
                            try:
                                _dir.rmtree()
                                print "Removing dir: %s" % _dir
                            except WindowsError:
                                print "Unable to delete dir: '%s'" % _dir
                                raise

                    # clean dataResources
                    elif _dir == 'dataResources':
                        # make writable
                        for _file in _dir.walk():
                            _file.makeWritable()
                        print "Removing dir: %s" % _dir
                        _dir.rmtree()

            # copy to network
            tempNetworkLoc = Path('%s/temp' % _pNetworkLoc)

            # copy
            print "Copying '%s' dir to '%s'" % (self.pipelineSourceLocation,
                                                tempNetworkLoc)
            try:
                Path(self.pipelineSourceLocation).copytree(tempNetworkLoc)
            except WindowsError:
                print "Process locked trying to copy to: '%s'. Please just run again." % tempNetworkLoc
            except shutil.Error as e:
                print "Permission denied for file/folder: '%s'" % e[0]

            # move first-layer sub-dirs from '/temp' up to parent
            for _dir in tempNetworkLoc.dirs():
                try:
                    if "data" not in _dir:  #skip 'data' & 'installData'!
                        Path(_dir).move(_pNetworkLoc)
                except WindowsError:
                    print "failed on: " + _dir
                except shutil.Error:
                    print "failed to copy from dir: '%s', already exists?" % _dir
                    raise

            # nuke tempNetworkLoc
            if tempNetworkLoc.exists():
                print "Cleaning old: %s" % tempNetworkLoc
                # make writable
                for _file in tempNetworkLoc.walk():
                    _file.makeWritable()
                print "Removing tree: %s" % tempNetworkLoc
                tempNetworkLoc.rmtree()

        ############# start cleaning ##############

        # clean un-needed root folders
        unNeededRoot = ['dataResources', 'docs', 'logs']
        for unNeeded in unNeededRoot:
            print "Cleaning un-needed: %s/%s" % (_pNetworkLoc, unNeeded)
            for _dir in Path(_pNetworkLoc).dirs():
                if _dir.namebase == unNeeded:
                    # make writable
                    for _file in _dir.walk():
                        _file.makeWritable()
                    print "Removing dir: %s" % _dir
                    _dir.rmtree()

        # clean unitTests
        print "Cleaning un-needed: %s/python/unitTests" % _pNetworkLoc
        for _dir in Path('%s/python' % _pNetworkLoc).dirs():
            if _dir.namebase == 'unitTests':
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()
                print "Removing dir: %s" % _dir
                _dir.rmtree()

        # clean non-maya/pymel dirs from pymels
        print "Cleaning un-needed: %s/python/maya/pymel" % _pNetworkLoc
        pyMelDirs = ['pymel-1.0.2', 'pymel-1.0.3']
        for pyMelDir in pyMelDirs:
            if not Path('%s/python/maya/%s' %
                        (_pNetworkLoc, pyMelDir)).exists():
                logger.error(
                    "No pymel dir found, probably failed copy earlier.")
                if not _dir.namebase == 'maya' and not _dir.namebase == 'pymel':
                    # make writable
                    for _file in _dir.walk():
                        _file.makeWritable()
                    print "Removing dir: %s" % _dir
                    _dir.rmtree()
                for _file in Path('%s/python/maya/%s' %
                                  (_pNetworkLoc, pyMelDir)).files():
                    _file.makeWritable()
                    print "Removing file: %s" % _file
                    _file.remove()

        # clean apps
        print "Cleaning un-needed: %s/python/apps" % _pNetworkLoc
        for _dir in Path('%s/python/apps' % _pNetworkLoc).dirs():
            if not _dir.namebase == 'APE':
                # make writable
                for _file in _dir.walk():
                    _file.makeWritable()
                print "Removing dir: %s" % _dir
                _dir.rmtree()

        # clean misc
        print "Cleaning un-needed project files in : %s" % _pNetworkLoc
        unNeededRoot = [
            '.project', '.pydevproject', 'artMonkey.wpr', 'artMonkey.wpu'
        ]
        for unNeeded in unNeededRoot:
            for _file in _pNetworkLoc.files():
                if _file.basename() == unNeeded:
                    # make writable
                    _file.makeWritable()
                    print "Removing file: %s" % _file
                    _file.remove()

        print "**********************************"
        print "Push To Network complete."
        print "**********************************"
        logger.info("**********************************")
        logger.info("Push To Network complete.")
        logger.info("**********************************")

        return result
    def __init__(self, filePath='', team='', mobu=0, **kwargs):
        super(ParseSchema, self).__init__()
        self.filePath = filePath

        if not filePath:
            if mobu:
                # get sceneName
                from pyfbsdk import FBApplication  # @UnresolvedImport

                self.filePath = Path(FBApplication().FBXFileName.replace('\\', '/'))
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == '':
                    self.filePath = None
            else:
                try:
                    from pymel.core import sceneName
                except ImportError:
                    sceneName = None
                    logger.errorDialog("ParseSchema thinks it is in Maya mode, forgot to pass 'mobu=1' arg?")
                self.filePath = Path(sceneName())
                if not self.filePath:
                    self.filePath = None
                elif self.filePath.basename() == 'untitled.ma':
                    self.filePath = None

        # if no team passed, use first team listed in globalVariables.py
        if not team:
            team = gv.teamA

        #Parse the schema file
        relPath = (os.path.dirname(__file__)
                   .replace('\\', '/')
                   .replace('python/common/fileIO', 'schemas/'))
        self.xmlContent = ET.parse(relPath + team + '.xml')

        #Gather all global headers
        self.coreList = self.xmlContent.getiterator('Core')[0]
        self.characterList = self.xmlContent.getiterator('Character')[0]
        self.environmentList = self.xmlContent.getiterator('Environment')[0]
        self.exportList = self.xmlContent.getiterator('Export')[0]
        self.areaList = self.xmlContent.getiterator('Areas')[0]
        self.mayaList = self.xmlContent.getiterator('Maya')[0]
        self.mobuList = self.xmlContent.getiterator('MoBu')[0]
        self.team = team


        # Read in the asset hub xml section
        if self.team == gv.teamA:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]
            self.assetHubList = self.xmlContent.getiterator('AssetHubUi')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamB:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")

        if self.team == gv.teamC:
            # Added headers
            self.riggingList = self.xmlContent.getiterator('Rigging')[0]

            # Self attributes
            self.fbxModels = eval(self.mobuList.get("FBXmodels"))
            self.retargetProcessing = eval(self.mobuList.get("retargetProcessing"))
            self.targetChar = eval(self.mobuList.get("targetCharacter"))
            self.sourceRetargetChar = eval(self.mobuList.get("sourceRetargetCharacters"))
            self.targetCharNode = self.mobuList.get("targetCharacterNode")
class ExportParse(ParseSchema):
    """ Class to solve for the export tools """

    def __init__(self, filePath='', team=''):
        super(ExportParse, self).__init__()

        # Solve needed attributes from the xml
        self.runTimeArtRoot = eval(self.exportList.get("runTimeArtRoot"))
        self.exportKey = self.exportList.get("exportKey")

        # Set needed variables
        if self.filePath:
            if os.path.isdir(self.filePath):
                self.exportSourceFolder = self.filePath + '/'
            else:
                self.exportSourceFolder = os.path.dirname(self.filePath) + '/'
        else:
            logger.warning('No scene selected')
        #self.exportSourceFolder = '/'

    def getExport(self, wFile=0):
        """ Method that returns folder for exporting meshes, animations (Character & Environment) """
        #assert(self.exportSourceFolder), ""
        if not self.filePath or not self.exportSourceFolder:
            return

        if self.team == gv.teamA:
            self.exportKey = int(self.exportKey)
            if wFile:
                self.exportPath = ('%s%s' % (self.exportSourceFolder.rsplit('/', (self.exportKey + 1))[0] + '/',
                                             self.filePath[self.filePath.rfind('/') + 1:])).replace(".ma",
                                                                                                    ".gr2").replace(
                    ".mb", "gr2")
            else:
                self.exportPath = self.exportSourceFolder.rsplit('/', (self.exportKey + 1))[0] + '/'
                #print 'printStatement: ' + self.exportSourceFolder
                logger.debug('Export folder: %s' % self.exportSourceFolder)

            return self.exportPath

        elif self.team == gv.teamB:
            if re.search('Animations', self.filePath):
                self.exportFileName = self.filePath.basename().replace(".ma", ".xmd").replace(".mb", ".xmd").replace(
                    ".fbx", ".xmd")
                rigPath = self.filePath[:self.filePath.rfind('MoBu')]
                weapon = self.exportFileName.split('_')[1]
                self.exportPath = Path('%s/Morpheme/Animations/%s/%s' % (rigPath, weapon, self.exportFileName))
            else:
                self.exportPath = Path(self.filePath.replace(".ma", ".gr2").replace(".mb", "gr2"))
            if not wFile:
                self.exportPath = self.exportPath.parent
            return self.exportPath.makePretty()

        elif self.team == gv.teamD:
            strFrom = self.exportKey[self.exportKey.find(':', 2) + 1:self.exportKey.rfind(':', 1)]
            #print strFrom
            strTo = self.exportKey[self.exportKey.rfind(':', 1) + 1:]
            #print strTo
            self.exportPath = self.exportSourceFolder.replace(strFrom, strTo)
            if wFile:
                self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
            return self.exportPath

        elif self.team == gv.teamD:
            # If the asset is an environment asset
            if re.match(self.environmentRoot, self.exportSourceFolder):
                envMeshKey = self.exportList.get('environmentMeshExportKey')
                envMeshKeySource = envMeshKey[envMeshKey.find(':', 2) + 1:envMeshKey.rfind(':', 1)]
                envMeshKeyTarget = envMeshKey[envMeshKey.rfind(':', 1) + 1:]
                envAnimKey = self.exportList.get('environmentAnimExportKey')
                envAnimKeySource = envAnimKey[envAnimKey.find(':', 2) + 1:envAnimKey.rfind(':', 1) - 3]
                envAnimKeyTarget = envAnimKey[envAnimKey.rfind(':', 1) + 1:]

                # If the environment asset is an animation
                if re.search(envAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(envAnimKeySource)[0] + envAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(envMeshKeySource, envMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

            # If the asset is a character asset
            if re.match(self.characterRoot, self.exportSourceFolder):
                charMeshKey = self.exportList.get('characterMeshExportKey')
                charMeshKeySource = charMeshKey[charMeshKey.find(':', 2) + 1:charMeshKey.rfind(':', 1)]
                charMeshKeyTarget = charMeshKey[charMeshKey.rfind(':', 1) + 1:]
                charAnimKey = self.exportList.get('characterAnimExportKey')
                charAnimKeySource = charAnimKey[charAnimKey.find(':', 2) + 1:charAnimKey.rfind(':', 1) - 3]
                charAnimKeyTarget = charAnimKey[charAnimKey.rfind(':', 1) + 1:]

                # If the character asset is an animation
                if re.search(charAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(charAnimKeySource)[0] + charAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath
                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(charMeshKeySource, charMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

    def getRunTimeArt(self, wFile=0):
        """ method to return the folder (or w/ file) for the run time copy """
        fileLoc = self.getExport(wFile)
        runTimeFilePath = fileLoc.replace(self.characterRoot, self.runTimeArtRoot)
        return runTimeFilePath

    def getRunTime(self):
        return self.runTimeArtRoot[:self.runTimeArtRoot.rfind('Runtime') + 8]
    def getExport(self, wFile=0):
        """ Method that returns folder for exporting meshes, animations (Character & Environment) """
        #assert(self.exportSourceFolder), ""
        if not self.filePath or not self.exportSourceFolder:
            return

        if self.team == gv.teamA:
            self.exportKey = int(self.exportKey)
            if wFile:
                self.exportPath = ('%s%s' % (self.exportSourceFolder.rsplit('/', (self.exportKey + 1))[0] + '/',
                                             self.filePath[self.filePath.rfind('/') + 1:])).replace(".ma",
                                                                                                    ".gr2").replace(
                    ".mb", "gr2")
            else:
                self.exportPath = self.exportSourceFolder.rsplit('/', (self.exportKey + 1))[0] + '/'
                #print 'printStatement: ' + self.exportSourceFolder
                logger.debug('Export folder: %s' % self.exportSourceFolder)

            return self.exportPath

        elif self.team == gv.teamB:
            if re.search('Animations', self.filePath):
                self.exportFileName = self.filePath.basename().replace(".ma", ".xmd").replace(".mb", ".xmd").replace(
                    ".fbx", ".xmd")
                rigPath = self.filePath[:self.filePath.rfind('MoBu')]
                weapon = self.exportFileName.split('_')[1]
                self.exportPath = Path('%s/Morpheme/Animations/%s/%s' % (rigPath, weapon, self.exportFileName))
            else:
                self.exportPath = Path(self.filePath.replace(".ma", ".gr2").replace(".mb", "gr2"))
            if not wFile:
                self.exportPath = self.exportPath.parent
            return self.exportPath.makePretty()

        elif self.team == gv.teamD:
            strFrom = self.exportKey[self.exportKey.find(':', 2) + 1:self.exportKey.rfind(':', 1)]
            #print strFrom
            strTo = self.exportKey[self.exportKey.rfind(':', 1) + 1:]
            #print strTo
            self.exportPath = self.exportSourceFolder.replace(strFrom, strTo)
            if wFile:
                self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
            return self.exportPath

        elif self.team == gv.teamD:
            # If the asset is an environment asset
            if re.match(self.environmentRoot, self.exportSourceFolder):
                envMeshKey = self.exportList.get('environmentMeshExportKey')
                envMeshKeySource = envMeshKey[envMeshKey.find(':', 2) + 1:envMeshKey.rfind(':', 1)]
                envMeshKeyTarget = envMeshKey[envMeshKey.rfind(':', 1) + 1:]
                envAnimKey = self.exportList.get('environmentAnimExportKey')
                envAnimKeySource = envAnimKey[envAnimKey.find(':', 2) + 1:envAnimKey.rfind(':', 1) - 3]
                envAnimKeyTarget = envAnimKey[envAnimKey.rfind(':', 1) + 1:]

                # If the environment asset is an animation
                if re.search(envAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(envAnimKeySource)[0] + envAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(envMeshKeySource, envMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath

            # If the asset is a character asset
            if re.match(self.characterRoot, self.exportSourceFolder):
                charMeshKey = self.exportList.get('characterMeshExportKey')
                charMeshKeySource = charMeshKey[charMeshKey.find(':', 2) + 1:charMeshKey.rfind(':', 1)]
                charMeshKeyTarget = charMeshKey[charMeshKey.rfind(':', 1) + 1:]
                charAnimKey = self.exportList.get('characterAnimExportKey')
                charAnimKeySource = charAnimKey[charAnimKey.find(':', 2) + 1:charAnimKey.rfind(':', 1) - 3]
                charAnimKeyTarget = charAnimKey[charAnimKey.rfind(':', 1) + 1:]

                # If the character asset is an animation
                if re.search(charAnimKeySource, self.exportSourceFolder):
                    self.exportPath = self.exportSourceFolder.split(charAnimKeySource)[0] + charAnimKeyTarget
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath
                # If the asset is not an animation
                else:
                    self.exportPath = self.exportSourceFolder.replace(charMeshKeySource, charMeshKeyTarget)
                    if wFile:
                        self.exportPath = '%s%s' % (self.exportPath, self.filePath[self.filePath.rfind('/') + 1:])
                    if self.exportPath:
                        return self.exportPath
    def buildPCSPipeline(self,
                         compileInstaller=False,
                         pyc=True,
                         removePY=True,
                         removePYC=True):
        ''' main pipeline build and push process
			Params: 
				compileInstaller: try to compile APEinstaller.exe
				pyc: create .pyc files in source first
				removePY: remove .py files on network build location
				removePYC: remove local .pyc files in source
			Returns: True/False
		'''
        completeSuccess = True

        #TODO: run unitTself.pipeBuildself.pipeBuildself.pipeBuildests

        #		# hack gVarInit
        #		self.swapGVarInit(direction='REMOTE')
        #
        #		#TODO: Compile APE
        #		self.compileAPE()
        #
        #		# swap back
        #		self.p4.p4RevertFile()
        ##		self.swapGVarInit(direction='PCS')

        # create pyc
        if pyc:
            if not self.createPYCfiles(self.pipelineSourceLocation):
                completeSuccess = False

        # copy to network
        if self.remoteBuild:
            # build for remote delivery
            if not self.pushToNetwork(self.buildDest, remote=True):
                completeSuccess = False
            if removePY:
                if not _KEEP_NETWORK_PY:
                    if not self.removePYfiles(pathToScrape=self.buildDest):
                        completeSuccess = False

            # make Mobu/Maya startup files writable
            for pyFile in Path(self.buildDest).walkfiles('*py'):
                if "pcsGlobalSetup.py" in pyFile or "gVarInit.py" in pyFile or "sysGlobalMenu.py" in pyFile:
                    # make non-readOnly
                    pyFile.makeWritable()

            # make PCSstudio.xml writable too
            pcsStudioXML = Path('%s/installData/PCSstudio.xml' %
                                self.buildDest)
            if pcsStudioXML.exists():
                pcsStudioXML.makeWritable(_dir=False)

            # clean
            self.clean(self.buildDest)

        else:
            # push to local network
            if not self.pushToNetwork(self.networkLoc, remote=False):
                completeSuccess = False

            if removePY:
                if not _KEEP_NETWORK_PY:
                    if not self.removePYfiles(pathToScrape=self.networkLoc):
                        completeSuccess = False

        if removePYC:
            if not self.removePYfiles(pathToScrape=self.pipelineSourceLocation,
                                      optionalExt='.pyc'):
                completeSuccess = False

        # provide reminder
        print "Remember to remove unneeded:\n./schemas/.\n\nand change:\n./installData/PCSstudio.xml\n./python/maya/maya/sysGlobalMenu.py\n./python/moBu/startup/pcsGlobalSetup.py\n./python/common/core/gVarInit.py"

        #TODO: email T.A.

        print "********************************************"
        print "*** Build complete."
        print "********************************************"
        logger.info("********************************************")
        logger.info("*** Build complete.")
        logger.info("********************************************")

        return completeSuccess
    # Docs menu item first
    docMenuItem = menu.InsertFirst("Documentation", 0)
    menu.OnMenuActivate.Add(KToolsCallbackMenu)

    menuDict, ext = MoBuToolsMenu().getMenuDic()

    # 2. Sorted Keys list
    sKeys = []
    for dr in menuDict.iterkeys():
        sKeys.append(dr)
    sKeys.sort()

    count = 0
    for menuNamePath in sKeys:
        menuName = str(Path(menuNamePath).basename())
        # skip root and 'old'
        if not menuName == 'old' and not menuName == 'mobuMenu':
            subMenu = FBGenericMenu()
            i = 0
            for script in menuDict[menuNamePath]:
                if not script == '__init__%s' % ext:
                    toolName = str(Path(script).namebase)
                    subMenu.InsertFirst(toolName, i)
                    i += 1

            subMenu.OnMenuActivate.Add(KToolsCallbackSubMenu)
            menu.InsertLast(menuName, 101 + count, subMenu)
            count += 1
else:
    moBuLogger.info("ArtMonkey menu already found.")
    def buildPCSPipeline(self, compileInstaller=False, pyc=True, removePY=True, removePYC=True):
        """ main pipeline build and push process
			Params: 
				compileInstaller: try to compile APEinstaller.exe
				pyc: create .pyc files in source first
				removePY: remove .py files on network build location
				removePYC: remove local .pyc files in source
			Returns: True/False
		"""
        completeSuccess = True

        # TODO: run unitTself.pipeBuildself.pipeBuildself.pipeBuildests

        # 		# hack gVarInit
        # 		self.swapGVarInit(direction='REMOTE')
        #
        # 		#TODO: Compile APE
        # 		self.compileAPE()
        #
        # 		# swap back
        # 		self.p4.p4RevertFile()
        ##		self.swapGVarInit(direction='PCS')

        # create pyc
        if pyc:
            if not self.createPYCfiles(self.pipelineSourceLocation):
                completeSuccess = False

                # copy to network
        if self.remoteBuild:
            # build for remote delivery
            if not self.pushToNetwork(self.buildDest, remote=True):
                completeSuccess = False
            if removePY:
                if not _KEEP_NETWORK_PY:
                    if not self.removePYfiles(pathToScrape=self.buildDest):
                        completeSuccess = False

                        # make Mobu/Maya startup files writable
            for pyFile in Path(self.buildDest).walkfiles("*py"):
                if "pcsGlobalSetup.py" in pyFile or "gVarInit.py" in pyFile or "sysGlobalMenu.py" in pyFile:
                    # make non-readOnly
                    pyFile.makeWritable()

                    # make PCSstudio.xml writable too
            pcsStudioXML = Path("%s/installData/PCSstudio.xml" % self.buildDest)
            if pcsStudioXML.exists():
                pcsStudioXML.makeWritable(_dir=False)

                # clean
            self.clean(self.buildDest)

        else:
            # push to local network
            if not self.pushToNetwork(self.networkLoc, remote=False):
                completeSuccess = False

            if removePY:
                if not _KEEP_NETWORK_PY:
                    if not self.removePYfiles(pathToScrape=self.networkLoc):
                        completeSuccess = False

        if removePYC:
            if not self.removePYfiles(pathToScrape=self.pipelineSourceLocation, optionalExt=".pyc"):
                completeSuccess = False

                # provide reminder
        print "Remember to remove unneeded:\n./schemas/.\n\nand change:\n./installData/PCSstudio.xml\n./python/maya/maya/sysGlobalMenu.py\n./python/moBu/startup/pcsGlobalSetup.py\n./python/common/core/gVarInit.py"

        # TODO: email T.A.

        print "********************************************"
        print "*** Build complete."
        print "********************************************"
        logger.info("********************************************")
        logger.info("*** Build complete.")
        logger.info("********************************************")

        return completeSuccess
 def setFilePath(self, filePath):
     self.filePath = Path(filePath)