def authenticate(self, user=None, password=None, relog=False): if user and password: logInFunc = partial(self.logIn, writeCookie=False) userData = {} else: logInFunc = self.logIn userData = self.loggedUser() if (not relog) and userData and user and userData["login"] != user: relog = True if relog: self.logOut() userData = {} if not userData: if user and password: userData = logInFunc(user, password) elif qtGuiApp(): userData = loginDialog(loginFunc=logInFunc) else: for _ in xrange(5): sUser = raw_input("login:") sPwd = getpass() try: userData = logInFunc(sUser, sPwd) except Exception, e: print toStr(e) else: if userData: break
def assertChars(sWord, sRegexp): sErrorMsg = "" sInvalidChars = re.sub(sRegexp, "", sWord) if sInvalidChars: sInvalidChars = ", ".join("'{0}'".format(toStr(c)) for c in set(sInvalidChars)) sErrorMsg += ('\t- contains invalid characters: {0}\n\n' .format(sInvalidChars.replace("' '", "'space'"))) if sErrorMsg: sErrorMsg = 'Invalid string: "{0}"\n'.format(toStr(sWord)) + sErrorMsg raise ValueError(sErrorMsg)
def assertChars(sWord, sRegexp): sErrorMsg = "" sInvalidChars = re.sub(sRegexp, "", sWord) if sInvalidChars: sInvalidChars = ", ".join("'{0}'".format(toStr(c)) for c in set(sInvalidChars)) sErrorMsg += ('\t- contains invalid characters: {0}\n\n'.format( sInvalidChars.replace("' '", "'space'"))) if sErrorMsg: sErrorMsg = 'Invalid string: "{0}"\n'.format(toStr(sWord)) + sErrorMsg raise ValueError(sErrorMsg)
def setPrpty(self, sProperty, value, write=True, **kwargs): bUseSetter = kwargs.pop("useSetter", True) bWarn = kwargs.get("warn", True) sMsg = "" setter = None if bUseSetter: sSetter = self.metaProperty(sProperty).getParam("setter", "") setter = getattr(self, sSetter) if sSetter else None sMsg = "Setting {0}.{1} to {2}( {3} ) using {4}".format( self, sProperty, type(value).__name__, toStr(value), setter if setter else "_setPrpty") logMsg(sMsg, log="debug") bSuccess = False if setter: if bWarn: logMsg("{}.{}() can be used to set '{}' property !".format( self, sSetter, sProperty), warning=True) bSuccess = setter(value, write=write, **kwargs) else: bSuccess = self._setPrpty(sProperty, value, write=write) if (not bSuccess) and sMsg: logMsg("Failed " + lowerFirst(sMsg), warning=True) return bSuccess
def setData(self, value, role=Qt.EditRole): if role == Qt.EditRole: metaobj = self._metaobj if not metaobj: return bSuccess = False try: value = self._metaprpty.castFromUi(value) bSuccess = metaobj.setPrpty(self.propertyName, value, warn=False, prompt=True) except Exception, err: sMsg = u"Could not set {}.{}:\n\n".format( metaobj, self.propertyName) confirmDialog(title='SORRY !', message=sMsg + toStr(err), button=["OK"], defaultButton="OK", cancelButton="OK", dismissString="OK", icon="critical") raise if bSuccess: metaobj.refresh() self.emitDataChanged()
def setProject(self, *args, **kwargs): try: return self.browserWidget.setProject(*args, **kwargs) except Exception, err: confirmDialog(title='SORRY !' , message=toStr(err) , button=["OK"] , defaultButton="OK" , cancelButton="OK" , dismissString="OK" , icon="critical") if not hostApp(): os.environ["PYTHONINSPECT"] = "1" self.close() raise # def __del__(self): # print "__del__", self.objectName() # def closeEvent(self, event): # print self, "closeEvent" # return QtGui.QMainWindow.closeEvent(self, event)
def __initDamas(self): sDamasServerAddr = self.getVar("project", "damas_server_addr", "") from .dbtypes import DummyDbCon dummydb = DummyDbCon(sDamasServerAddr) if not sDamasServerAddr: self._damasdb = dummydb return if inDevMode(): print "connecting to damas server:", sDamasServerAddr else: print "connecting to damas..." import damas damasdb = damas.http_connection(sDamasServerAddr) try: damasdb.verify() except IOError as e: logMsg(toStr(e), warning=True) self._damasdb = dummydb else: self._damasdb = damasdb
def dataRepr(self, *fields): bFilter = True if fields else False dataItems = [("id_", self.id_)] dataItems.extend(sorted(self._data.iteritems(), key=lambda x:x[0])) s = '{' for k, v in dataItems: if bFilter and (k not in fields): continue sTypeName = type(v).__name__ if k in ("time", "ino_write") or k.startswith("synced_"): try: v = datetime.fromtimestamp(int(v) / 1000).strftime("%Y-%m-%d %H:%M:%S") except Exception as e: logMsg(toStr(e)) elif isinstance(v, unicode): v = str_(v) s += "\n<{}> {}: {}".format(sTypeName, k, v) return (s + '\n}')
def _search(self, query, authOnFail=True, **kwargs): logMsg(query, log='all') dbconn = self._dbconn if isinstance(query, basestring): ids = dbconn.search(query) elif isinstance(query, dict): ids = dbconn.search_mongo(query, **kwargs) else: raise TypeError("Invalid query: '{}'".format(query)) if ids is None: if not authOnFail: raise DbSearchError('Failed to search: "{}"'.format(query)) bAuthOk = dbconn.verify() if not bAuthOk: try: bAuthOk = self.project.authenticate() except Exception, e: logMsg(toStr(e), warning=True) return self._search(query, authOnFail=False, **kwargs)
def iterSyncedResource(proj, sEntityType, sgEntityList): if sEntityType == "asset": EntityCls = DamAsset elif sEntityType == "shot": EntityCls = DamShot else: raise ValueError("Invalid entity type: '{}'.".format(sEntityType)) #library = proj.getLibrary("public", EntityCls.libraryName) numEntity = len(sgEntityList) for i, sgEntity in enumerate(sgEntityList): sEntityName = sgEntity["code"] print "{}/{} - {}".format(i + 1, numEntity, sEntityName) try: damEntity = EntityCls(proj, name=sEntityName) except Exception as e: logMsg(toStr(e), warning=True) continue sSection = damEntity.confSection pathIter = proj.iterRcPaths("public", sSection, tokens=vars(damEntity)) for sRcName, sAbsPath in pathIter: sSyncRuleList = proj.getRcParam(sSection, sRcName, "default_sync_rules", None) if sSyncRuleList:# and osp.exists(sAbsPath): #print damEntity, sRcName, sSyncRuleList yield damEntity, sAbsPath, sorted(sSyncRuleList)
def iterMissingPathItems(proj, sEntityType, sgEntityList): if sEntityType == "asset": entityCls = DamAsset elif sEntityType == "shot": entityCls = DamShot else: raise ValueError("Invalid entity type: '{}'.".format(sEntityType)) for sgEntity in sgEntityList: sEntityName = sgEntity["code"] damEntity = None sMissingPathList = [] try: damEntity = entityCls(proj, name=sEntityName) sMissingPathList = damEntity.createDirsAndFiles(dryRun=True, log=False) except Exception, e: sError = toStr(e) print "{:<60}: {}".format(sEntityName, sError) yield sEntityName, sError else: if sMissingPathList: yield damEntity, sMissingPathList
def doPublish(self, *itemList): item = itemList[-1] pubEntry = item._metaobj proj = self.model()._metamodel if isinstance(pubEntry, DrcFile): try: pubEntry.assertFreeToPublish() except EnvironmentError as e: confirmDialog(title='SORRY !', message="Publishing not allowed:\n\n" + toStr(e), button=["OK"], icon="critical") return sAbsPath = pubEntry.absPath() if proj.isEditableResource(sAbsPath): if hostApp() == "maya": sExt = osp.splitext(sAbsPath)[-1] if sExt in (".ma", ".mb"): raise EnvironmentError("Please, publish from integrated 'Davos' menu.") self.__publishEditedVersion(pubEntry) else: self.__publishRegularVersion(pubEntry) else: self.__publishFiles(pubEntry)
def importFiles(self, *itemList): proj = self.model()._metamodel try: if not hostApp(): raise AssertionError("You can only import from inside another application.") drcFileList = tuple(item._metaobj for item in itemList) if len(drcFileList) > 1: for drcFile in drcFileList: try: drcFile.importIt() except Exception as e: sResult = confirmDialog(title='SORRY !', message=toStr(e), button=["Continue", "Abort"], defaultButton="Continue", cancelButton="Abort", dismissString="Abort", icon="critical") if sResult == "Abort": break else: continue else: drcFileList[0].importIt() finally: proj.mayaLoadReferences = True
def _writeTokenData(self, tokenData): try: self.__writeTokenData(tokenData) except Exception, e: msg = (u"Could not write cookie file: '{}'!\n {}" .format(self.cookieFilePath, toStr(e))) logMsg(msg, warning=True)
def setPrpty(self, sProperty, value, write=True, **kwargs): bUseSetter = kwargs.pop("useSetter", True) bWarn = kwargs.get("warn", True) sMsg = "" setter = None if bUseSetter: sSetter = self.metaProperty(sProperty).getParam("setter", "") setter = getattr(self, sSetter) if sSetter else None sMsg = "Setting {0}.{1} to {2}( {3} ) using {4}".format( self, sProperty, type(value).__name__, toStr(value), setter if setter else "_setPrpty") logMsg(sMsg, log="debug") bSuccess = False if setter: if bWarn: logMsg("{}.{}() can be used to set '{}' property !" .format(self, sSetter, sProperty), warning=True) bSuccess = setter(value, write=write, **kwargs) else: bSuccess = self._setPrpty(sProperty, value, write=write) if (not bSuccess) and sMsg: logMsg("Failed " + lowerFirst(sMsg), warning=True) return bSuccess
def setData(self, value, role=Qt.EditRole): if role == Qt.EditRole: metaobj = self._metaobj if not metaobj: return bSuccess = False try: value = self._metaprpty.castFromUi(value) bSuccess = metaobj.setPrpty(self.propertyName, value, warn=False, prompt=True) except Exception, err: sMsg = u"Could not set {}.{}:\n\n".format(metaobj, self.propertyName) confirmDialog(title='SORRY !', message=sMsg + toStr(err), button=["OK"], defaultButton="OK", cancelButton="OK", dismissString="OK", icon="critical") raise if bSuccess: metaobj.refresh() self.emitDataChanged()
def doIt(*args, **kwargs): try: ret = func(*args, **kwargs) except Exception as e: pm.displayError(toStr(e)) traceback.print_exc() return returns return ret
def report(foundList, errorList, sDbPath=""): def _u(v): return unicode_(v) if isinstance(v, basestring) else v numNodes = len(foundList) foundList = sorted((e for e in foundList if e), key=lambda e:e.dbMtime) table = [] for rcEntry in foundList: try: dbnode = rcEntry._dbnode sOnlineTime = strftime(long(dbnode.synced_online) / 1000) if dbnode.synced_online else "" texts = map(_u, (rcEntry.dbPath(), rcEntry.author, rcEntry.origin, strftime(toTimestamp(rcEntry.dbMtime)), cmpStr(rcEntry.dbMtime, rcEntry.fsMtime), strftime(toTimestamp(rcEntry.fsMtime)), repr(rcEntry.fileSize), cmpStr(rcEntry.fileSize, rcEntry.sourceSize), repr(rcEntry.sourceSize), sOnlineTime, )) except Exception as e: print toStr(e), ":", rcEntry.absPath() continue table.append(texts) headers = ["file", "author", "site", "published", "", "modified", "current size", "", "source size", "synced online"] print tabulate(table, headers, tablefmt="simple") print len(foundList), "bad on", numNodes, "files - scan errors:", len(errorList) sFileName = sDbPath.strip("/").replace("/", "_") + "_report.html" sHtmlPath = pathResolve("%USERPROFILE%/Documents/{}".format(sFileName)) sCharset = '<head>\n<meta charset="UTF-8">\n</head>\n' with codecs.open(sHtmlPath, "w", "utf_8") as fo: fo.writelines(sCharset + tabulate(table, headers, tablefmt="html")) for rcEntry, e in errorList: print rcEntry.dbPath(), type(e), e.message, toDisplayText(rcEntry.dbMtime)
def __repr__(self): cls = self.__class__ try: sClsName = upperFirst(cls.classLabel) if hasattr(cls, "classLabel") else cls.__name__ sRepr = ("{0}('{1}')".format(sClsName, toStr(getattr(self, cls.classReprAttr)))) except AttributeError: sRepr = cls.__name__ return sRepr
def authenticate(self, user=None, password=None, relog=False): if relog: self.logOut() userData = self.loggedUser() if not userData: if user and password: userData = self.logIn(user, password) elif qtGuiApp(): userData = loginDialog(loginFunc=self.logIn) else: for _ in xrange(5): sUser = raw_input("login:") sPwd = getpass() try: userData = self.logIn(sUser, sPwd) except Exception, e: print toStr(e) else: if userData: break
def __repr__(self): cls = self.__class__ try: sClsName = upperFirst(cls.classLabel) if hasattr( cls, "classLabel") else cls.__name__ sRepr = ("{0}('{1}')".format( sClsName, toStr(getattr(self, cls.classReprAttr)))) except AttributeError: sRepr = cls.__name__ return sRepr
def _writeAllValues(self, propertyNames=None): logMsg(self.__class__.__name__, log='all') sPropertyIter = self.__class__._iterPropertyArg(propertyNames) for sProperty in sPropertyIter: value = getattr(self, sProperty) try: self.setPrpty(sProperty, value, write=True, useSetter=False) except Exception, msg: logMsg(toStr(msg), warning=True)
def openScene(sScenePath, **kwargs): bAddToRecent = kwargs.pop("addToRecent", False) if kwargs.pop("noFileCheck", True): pmu.putEnv("DAVOS_FILE_CHECK", "") bFail = kwargs.pop("fail", True) res = None try: res = pm.openFile(sScenePath, **kwargs) except RuntimeError, e: if bFail: raise else: pm.displayError(toStr(e.message))
def _search(self, sQuery, authOnFail=True): logMsg(sQuery, log='all') dbconn = self._dbconn ids = dbconn.search(sQuery) if ids is None: if not authOnFail: raise DbSearchError('Failed to search: "{}"'.format(sQuery)) bAuthOk = dbconn.verify() if not bAuthOk: try: bAuthOk = self.project.authenticate() except Exception, e: logMsg(toStr(e), warning=True) return self._search(sQuery, authOnFail=False)
def setProject(self, *args, **kwargs): try: return self.browserWidget.setProject(*args, **kwargs) except Exception, err: confirmDialog(title='SORRY !' , message=toStr(err) , button=["OK"] , defaultButton="OK" , cancelButton="OK" , dismissString="OK" , icon="critical") if not hostApp(): os.environ["PYTHONINSPECT"] = "1" self.close() raise
def afterBuildingMenu(self): sMuteModList = [ "requests.packages.urllib3.connectionpool", "pytd.util.external.parse", "PIL.Image", ] for sModule in sMuteModList: if not sModule: continue try: logger = logging.getLogger(sModule) if logger: logger.disabled = True except Exception as e: pm.displayWarning(toStr(e))
def afterBuildingMenu(self): self.startScriptJobs() sMuteModList = ["requests.packages.urllib3.connectionpool", "pytd.util.external.parse", "PIL.Image", ] for sModule in sMuteModList: if not sModule: continue try: logger = logging.getLogger(sModule) if logger: logger.disabled = True except Exception as e: pm.displayWarning(toStr(e))
def submitLogin(self): sUser, sPwd = (self.getUsername(), self.getPassword()) res = None if self.submitSlot: try: res = self.submitSlot(sUser, sPwd) except Exception, err: confirmDialog(title='SORRY !', message=toStr(err), button=["OK"], defaultButton="OK", cancelButton="OK", dismissString="OK", icon="critical") if inDevMode(): raise return
def submitLogin(self): sUser, sPwd = (self.getUsername(), self.getPassword()) res = None if self.submitSlot: try: res = self.submitSlot(sUser, sPwd) except Exception, err: confirmDialog(title='SORRY !' , message=toStr(err) , button=["OK"] , defaultButton="OK" , cancelButton="OK" , dismissString="OK" , icon="critical") if inDevMode(): raise return
def entryFromPath(self, sEntryPath, space="", library=None, fail=False, **kwargs): bWarn = kwargs.pop("warn", True) bFile = kwargs.pop("isFile", False) bWeak = kwargs.pop("weak", False) if library: drcLib = library else: drcLib = self.libraryFromPath(sEntryPath, space=space) if not drcLib: sLibType = space.upper() if space else "KNOWN" sMsg = "Path NOT from {} library: '{}'".format(sLibType, sEntryPath) if fail: raise ValueError(sMsg) else: if bWarn: logMsg(sMsg, warning=True) return None try: if bFile: rcFile = drcLib._weakFile(sEntryPath, **kwargs) if bWeak: return rcFile return rcFile if rcFile.isFile() else None return drcLib.getEntry(sEntryPath, **kwargs) except Exception as e: if fail: raise else: if bWarn: logMsg(toStr(e), warning=True) return None
def removeItems(self, *itemList): entryList = tuple(item._metaobj for item in itemList) sEntryList = "\n " .join(entry.name for entry in entryList) sMsg = u'Are you sure you want to DELETE these resources: \n\n ' + sEntryList sConfirm = confirmDialog(title='WARNING !', message=sMsg, button=['OK', 'Cancel'], defaultButton='Cancel', cancelButton='Cancel', dismissString='Cancel', icon="warning") if sConfirm == 'Cancel': logMsg("Cancelled !", warning=True) return if len(entryList) > 1: for entry in entryList: try: entry.sendToTrash() except Exception, e: sResult = confirmDialog(title='SORRY !', message=toStr(e), button=["Continue", "Abort"], defaultButton="Continue", cancelButton="Abort", dismissString="Abort", icon="critical") if sResult == "Abort": return else: continue
def importFiles(self, *itemList): if not hostApp(): raise AssertionError("You can only import from inside another application.") drcFileList = tuple(item._metaobj for item in itemList) if len(drcFileList) > 1: for drcFile in drcFileList: try: drcFile.importIt() except Exception, e: sResult = confirmDialog(title='SORRY !', message=toStr(e), button=["Continue", "Abort"], defaultButton="Continue", cancelButton="Abort", dismissString="Abort", icon="critical") if sResult == "Abort": return else: continue
def createFromCsv(sEntityType, sCsvFilePath, project="", **kwargs): if sEntityType == "asset": sEntityFields = ("Asset Name", "asset name") entityCls = DamAsset elif sEntityType == "shot": sEntityFields = ("Shot Code", "shot code") entityCls = DamShot else: raise ValueError("Invalid entity type: '{}'".format(sEntityType)) sProject = os.environ["DAVOS_INIT_PROJECT"] if not project else project proj = DamProject(sProject) print sProject.center(80, "-") iMaxCount = kwargs.get("maxCount", -1) with open(sCsvFilePath, 'rb') as csvFile: dialect = csv.Sniffer().sniff(csvFile.read(4096)) csvFile.seek(0) reader = csv.reader(csvFile, dialect) iNameColumn = -1 iHeaderRow = 0 for row in reader: bFound = False for sField in sEntityFields: try: iNameColumn = row.index(sField) except ValueError: pass else: bFound = True break if bFound: break iHeaderRow += 1 assert iNameColumn != -1, 'Asset names missing from "{}" !'.format(sCsvFilePath) csvFile.seek(0) for _ in xrange(iHeaderRow + 1): reader.next() sEntityList = [] damEntityList = [] sErrorList = [] for row in reader: sEntityName = row[iNameColumn] if sEntityName in sEntityList: continue sEntityList.append(sEntityName) try: assertChars(sEntityName, r'[\w]') except ValueError as e1: sErrorList.append(toStr(e1)) continue try: damEntity = entityCls(proj, name=sEntityName) except Exception as e2: sErrorList.append(toStr(e2)) continue print sEntityName damEntityList.append(damEntity) if sErrorList: raise RuntimeError("\n".join(sErrorList)) count = 0 for damEntity in damEntityList: if count == iMaxCount: break if damEntity.createDirsAndFiles(**kwargs): count += 1 sCreated = "will create" if kwargs.get("dryRun") else "created" print "{} asset directories {}.".format(count, sCreated)
def iterMissingPathItems(proj, sEntityType, sgEntityList, parentDirs=None, update=False): if sEntityType == "asset": EntityCls = DamAsset elif sEntityType == "shot": EntityCls = DamShot else: raise ValueError("Invalid entity type: '{}'.".format(sEntityType)) bLoadDbNodes = True if parentDirs: for rcDir in parentDirs: rcDir.loadChildDbNodes(recursive=True, noVersions=True) bLoadDbNodes = False damEntityList = [] numEntity = len(sgEntityList) for i, sgEntity in enumerate(sgEntityList): sEntityName = sgEntity["code"] damEntity = None print "{}/{} - loading {}".format(i + 1, numEntity, sEntityName) try: damEntity = EntityCls(proj, name=sEntityName) sDirPath = damEntity.getPath("public", "entity_dir") bExists = osp.exists(sDirPath) if update: if (not bExists): continue elif bExists: continue except Exception as e: sErrorMsg = toStr(e) print "{}: {}".format(sEntityName, sErrorMsg) yield sEntityName, sErrorMsg else: damEntityList.append(damEntity) numEntity = len(damEntityList) for i, damEntity in enumerate(damEntityList): sMissingPathList = [] sEntityName = damEntity.name print "{}/{} - scanning {}".format(i + 1, numEntity, sEntityName) try: sMissingPathList = damEntity.createDirsAndFiles(dryRun=True, log=False, checkDb=True, loadDbNodes=bLoadDbNodes) except Exception as e: sErrorMsg = toStr(e) print "{}: {}".format(sEntityName, sErrorMsg) yield sEntityName, sErrorMsg else: if sMissingPathList: yield damEntity, sMissingPathList
def importAtomFile(sFilePath, **kwargs): if not osp.isfile(sFilePath): raise EnvironmentError("No such file: '{}'".format(sFilePath)) sBaseName = osp.basename(osp.splitext(sFilePath)[0]) sNamespace = kwargs.pop("namespace", kwargs.pop("ns", sBaseName)) sValidKwargs = ATOM_IMPORT_KWARGS.keys() sOptList = [] for k, v in kwargs.iteritems(): if k not in sValidKwargs: raise TypeError("Unexpected keyword argument: '{}'. \n Are valid: {}" .format(k, ", ".join(sValidKwargs))) valueCast = ATOM_IMPORT_KWARGS[k] if isinstance(valueCast, dict): try: value = valueCast[v] except KeyError: raise ValueError("Invalid '{}' value: '{}'. Are valid: {}." .format(k, v, valueCast.keys())) elif isinstance(valueCast, list): if v in valueCast: value = v else: raise ValueError("Invalid '{}' value: '{}'. Are valid: {}." .format(k, v, valueCast)) else: try: value = valueCast(v) except Exception as e: raise ValueError("Invalid '{}' value: {}. {}." .format(k, v, toStr(e))) sOpt = "{}={}".format(k, value) sOptList.append(sOpt) sSelected = kwargs.get("selected", "selectedOnly") if sSelected == "selectedOnly": sXfmList = mc.ls(sl=True, tr=True) elif sSelected == "childrenToo": sXfmList = mc.ls(sl=True, dag=True, tr=True) def listAttr_(sNode): return listForNone(mc.listAttr(sNode, k=True, ud=True)) sPreAttrSet = set() for sXfm in sXfmList: sPreAttrSet.update(sXfm + "." + attr for attr in listAttr_(sXfm)) print "Importing atom file:", sFilePath print ";".join(sOptList) res = pm.importFile(sFilePath, type="atomImport", renameAll=True, namespace=sNamespace, options=";".join(sOptList)) sPostAttrSet = set() for sXfm in sXfmList: sPostAttrSet.update(sXfm + "." + attr for attr in listAttr_(sXfm)) keyFunc = lambda s: s.split(".", 1)[0] sNewAttrList = sorted((sPostAttrSet - sPreAttrSet), key=keyFunc) if sNewAttrList: for sXfm, attrs in itr.groupby(sNewAttrList, keyFunc): oXfm = pm.PyNode(sXfm) oShape = oXfm.getShape() if not oShape: continue sAttrSet = set(a.split(".", 1)[1] for a in attrs) sAttrList = list(sAttrSet & set(pm.listAttr(oShape, k=True))) if not sAttrList: continue sSep = "\n -" print (("transfering imported attrs from '{}' to '{}':" + sSep + "{}") .format(oXfm, oShape, sSep.join(sAttrList))) pm.copyAttr(oXfm, oShape, attribute=sAttrList, inConnections=True, keepSourceConnections=True) for sAttr in sAttrList: #print "deleting imported attr:", oXfm.name() + "." + sAttr oXfm.deleteAttr(sAttr) return res
def __repr__(self): sClsName = self.__class__.__name__ sRepr = ("{}('{}')".format(sClsName, toStr(self.text()))) return sRepr
import itertools as itr import pymel.core as pm import pymel.util as pmu import maya.cmds as mc from pytd.util.logutils import logMsg from pytd.util.fsutils import pathResolve from pytd.util.sysutils import listForNone, argToTuple, toStr from pytd.util.strutils import upperFirst from pytaya.core.general import iterAttrsUsedAsFilename try: pm.mel.source("exportAnimSharedOptions") except pm.MelError as e: pm.displayError(toStr(e)) try: pm.mel.source("importAnimSharedOptions") except pm.MelError as e: pm.displayError(toStr(e)) def importFile(sFilePath, **kwargs): if not isinstance(sFilePath, basestring): raise TypeError, 'Wrong type passed to file path argument: {0}'.format(type(sFilePath)) if ("%" in sFilePath) or ("$" in sFilePath): sResolvedPath = pathResolve(sFilePath) else: sResolvedPath = sFilePath
def copyFile(sSrcPath, sDstPath, preserve_mode=True, preserve_times=True, in_place=False, update=False, link="", verbose=1, dry_run=False, buffer_size=512 * 1024, showProgress=True): """Copy a file 'sSrcPath' to 'sDstPath'. (Stolen and customized from distutils.file_util.copy_file) If 'sDstPath' is a directory, then 'sSrcPath' is copied there with the same name; otherwise, it must be a filename. (If the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' is true (the default), the file's mode (type and permission bits, or whatever is analogous on the current platform) is copied. If 'preserve_times' is true (the default), the last-modified and last-access times are copied as well. If 'update' is true, 'sSrcPath' will only be copied if 'sDstPath' does not exist, or if 'sDstPath' does exist but is older than 'sSrcPath'. 'link' allows you to make hard links (os.link) or symbolic links (os.symlink) instead of copying: set it to "hard" or "sym"; if it is None (the default), files are copied. Don't set 'link' on systems that don't support it: 'copy_file()' doesn't check if hard or symbolic linking is available. Under Mac OS, uses the native file copy function in macostools; on other systems, uses '_copy_file_contents()' to copy file contents. Return a tuple (dest_name, copied): 'dest_name' is the actual name of the output file, and 'copied' is true if the file was copied (or would have been copied, if 'dry_run' true). """ # XXX if the destination file already exists, we clobber it if # copying, but blow up if linking. Hmmm. And I don't know what # macostools.copyfile() does. Should definitely be consistent, and # should probably blow up if destination exists and we would be # changing it (ie. it's not already a hard/soft link to sSrcPath OR # (not update) and (sSrcPath newer than sDstPath). sSrcPath = toStr(sSrcPath) sDstPath = toStr(sDstPath) # try: # sAction = _copy_action[link].capitalize() # except KeyError: # raise ValueError("Invalid value for 'link' argument: '{}'. Expected one of {}." # .format(link, _copy_action.keys())) sAction = "Copying" srcStat = os.stat(sSrcPath) if not S_ISREG(srcStat.st_mode): raise EnvironmentError("Source file NOT found: '{}'.".format(sSrcPath)) if osp.isdir(sDstPath): sDirPath = sDstPath sDstPath = osp.join(sDstPath, osp.basename(sSrcPath)) else: sDirPath = osp.dirname(sDstPath) if update and (not pathNewer(sSrcPath, sDstPath)): if verbose >= 1: logMsg("Not copying (output up-to-date): '{}'".format(sSrcPath), log="debug") return sDstPath, False if verbose >= 1: if osp.normcase(osp.basename(sDstPath)) == osp.normcase(osp.basename(sSrcPath)): logMsg("{} {}\n to {}".format(sAction, sSrcPath, sDirPath)) else: logMsg("{} {}\n as {}".format(sAction, sSrcPath, sDstPath)) if dry_run: return (sDstPath, True) # # If linking (hard or symbolic), use the appropriate system call # # (Unix only, of course, but that's the caller's responsibility) # if link == 'hard': # if not (osp.exists(sDstPath) and osp.samefile(sSrcPath, sDstPath)): # os.link(sSrcPath, sDstPath) # elif link == 'symb': # if not (osp.exists(sDstPath) and osp.samefile(sSrcPath, sDstPath)): # os.symlink(sSrcPath, sDstPath) # # # Otherwise (non-Mac, not linking), copy the file contents and # # (optionally) copy the times and mode. # else: if sameFile(sSrcPath, sDstPath): sMsg = "Source and destination files are the same:" sMsg += "\n source: ", sSrcPath sMsg += "\n destination: ", sDstPath raise EnvironmentError(sMsg) sTmpPath = "" try: dstStat = os.stat(sDstPath) except OSError: pass else:# destination path exists if not S_ISREG(dstStat.st_mode): raise EnvironmentError("Path already exists but NOT a regular file: '{}'." .format(sDstPath)) if not in_place: #pathRename(sDstPath, sDstPath) sTmpPath = sDstPath + ".tmpcopy" sCopyPath = sTmpPath if sTmpPath else sDstPath try: copyFileData(sSrcPath, sCopyPath, preserve_mode=preserve_mode, preserve_times=preserve_times, buffer_size=buffer_size, sourceStat=srcStat, showProgress=showProgress) if sTmpPath: if os.name == "nt": # on nt platform, destination must be removed first os.remove(sDstPath) pathRename(sTmpPath, sDstPath) finally: if sTmpPath and osp.exists(sTmpPath): os.remove(sTmpPath) return (sDstPath, True)
import itertools as itr import pymel.core as pm import pymel.util as pmu import maya.cmds as mc from pytd.util.logutils import logMsg from pytd.util.fsutils import pathResolve from pytd.util.sysutils import listForNone, argToTuple, toStr from pytd.util.strutils import upperFirst from pytaya.core.general import iterAttrsUsedAsFilename try: pm.mel.source("exportAnimSharedOptions") except pm.MelError as e: pm.displayError(toStr(e)) try: pm.mel.source("importAnimSharedOptions") except pm.MelError as e: pm.displayError(toStr(e)) def importFile(sFilePath, **kwargs): if not isinstance(sFilePath, basestring): raise TypeError, 'Wrong type passed to file path argument: {0}'.format( type(sFilePath)) if ("%" in sFilePath) or ("$" in sFilePath): sResolvedPath = pathResolve(sFilePath)
def importAtomFile(sFilePath, **kwargs): if not osp.isfile(sFilePath): raise EnvironmentError("No such file: '{}'".format(sFilePath)) sBaseName = osp.basename(osp.splitext(sFilePath)[0]) sNamespace = kwargs.pop("namespace", kwargs.pop("ns", sBaseName)) sValidKwargs = ATOM_IMPORT_KWARGS.keys() sOptList = [] for k, v in kwargs.iteritems(): if k not in sValidKwargs: raise TypeError( "Unexpected keyword argument: '{}'. \n Are valid: {}". format(k, ", ".join(sValidKwargs))) valueCast = ATOM_IMPORT_KWARGS[k] if isinstance(valueCast, dict): try: value = valueCast[v] except KeyError: raise ValueError( "Invalid '{}' value: '{}'. Are valid: {}.".format( k, v, valueCast.keys())) elif isinstance(valueCast, list): if v in valueCast: value = v else: raise ValueError( "Invalid '{}' value: '{}'. Are valid: {}.".format( k, v, valueCast)) else: try: value = valueCast(v) except Exception as e: raise ValueError("Invalid '{}' value: {}. {}.".format( k, v, toStr(e))) sOpt = "{}={}".format(k, value) sOptList.append(sOpt) sSelected = kwargs.get("selected", "selectedOnly") if sSelected == "selectedOnly": sXfmList = mc.ls(sl=True, tr=True) elif sSelected == "childrenToo": sXfmList = mc.ls(sl=True, dag=True, tr=True) def listAttr_(sNode): return listForNone(mc.listAttr(sNode, k=True, ud=True)) sPreAttrSet = set() for sXfm in sXfmList: sPreAttrSet.update(sXfm + "." + attr for attr in listAttr_(sXfm)) print "Importing atom file:", sFilePath print ";".join(sOptList) res = pm.importFile(sFilePath, type="atomImport", renameAll=True, namespace=sNamespace, options=";".join(sOptList)) sPostAttrSet = set() for sXfm in sXfmList: sPostAttrSet.update(sXfm + "." + attr for attr in listAttr_(sXfm)) keyFunc = lambda s: s.split(".", 1)[0] sNewAttrList = sorted((sPostAttrSet - sPreAttrSet), key=keyFunc) if sNewAttrList: for sXfm, attrs in itr.groupby(sNewAttrList, keyFunc): oXfm = pm.PyNode(sXfm) oShape = oXfm.getShape() if not oShape: continue sAttrSet = set(a.split(".", 1)[1] for a in attrs) sAttrList = list(sAttrSet & set(pm.listAttr(oShape, k=True))) if not sAttrList: continue sSep = "\n -" print(("transfering imported attrs from '{}' to '{}':" + sSep + "{}").format(oXfm, oShape, sSep.join(sAttrList))) pm.copyAttr(oXfm, oShape, attribute=sAttrList, inConnections=True, keepSourceConnections=True) for sAttr in sAttrList: #print "deleting imported attr:", oXfm.name() + "." + sAttr oXfm.deleteAttr(sAttr) return res
class BaseContextMenu(QtGui.QMenu): beforeActionLaunched = QtCore.Signal(dict, bool) afterActionLaunched = QtCore.Signal(dict, bool) def __init__(self, parentView): super(BaseContextMenu, self).__init__(parentView) self.view = parentView self.actionTargets = [] self.actionTargetsLoaded = False self.createActions() self.buildSubmenus() self.installEventFilter(parentView) def model(self): model = self.view.model() if isinstance(model, QtGui.QSortFilterProxyModel): return model.sourceModel() return model def getActionTargets(self): view = self.view model = view.model() selectModel = view.selectionModel() selBhv = view.selectionBehavior() if selBhv == SelectionBehavior.SelectRows: selIndexes = selectModel.selectedRows(0) elif selBhv == SelectionBehavior.SelectColumns: selIndexes = selectModel.selectedColumns(0) else: selIndexes = selectModel.selectedIndexes() if len(selIndexes) > 1: curIndex = selectModel.currentIndex() if selBhv == SelectionBehavior.SelectRows: curIndex = curIndex.sibling(curIndex.row(), 0) elif selBhv == SelectionBehavior.SelectColumns: curIndex = curIndex.sibling(0, curIndex.column()) if curIndex.isValid() and curIndex != selIndexes[-1]: try: selIndexes.remove(curIndex) except ValueError: pass selIndexes.append(curIndex) itemFromIndex = model.itemFromIndex return [itemFromIndex(idx) for idx in selIndexes] def loadActionTargets(self): self.actionTargets = self.getActionTargets() self.actionTargetsLoaded = True def assertActionTargets(self): if not self.actionTargetsLoaded: raise RuntimeError("Action Selection not loaded.") else: self.actionTargetsLoaded = False def launchAction(self, actionDct, checked): bCheckable = actionDct.get("checkable", False) self.beforeActionLaunched.emit(actionDct, checked) if not bCheckable: self.assertActionTargets() if not bCheckable: sActionMsg = u"Action: {} > {}".format(actionDct["menu"], actionDct["label"]) try: logMsg(u'# Action: {} #'.format(sActionMsg)) except Exception, e: logMsg(e, warning=True) args = actionDct.get("args", []) + self.actionTargets kwargs = actionDct.get("kwargs", {}) if bCheckable: kwargs.update(checked=checked) func = actionDct["fnc"] try: return func(*args, **kwargs) except Warning: raise except Exception as err: sMsg = u"{}\n\n".format(sActionMsg) confirmDialog(title='SORRY !', message=(toStr(sMsg) + toStr(err)), button=["OK"], defaultButton="OK", cancelButton="OK", dismissString="OK", icon="critical") raise self.afterActionLaunched.emit(actionDct, checked)
def cmpStr(v1, v2): try: return _CMPS.get(cmp(v1, v2), "") except Exception as e: print toStr(e) return ""