def test_IsPackageRelativePath(self): self.assertFalse(Ar.IsPackageRelativePath("")) self.assertFalse(Ar.IsPackageRelativePath("/tmp/foo.pack")) self.assertFalse(Ar.IsPackageRelativePath("foo[0].pack")) self.assertTrue(Ar.IsPackageRelativePath("foo.pack[bar.file]")) self.assertTrue( Ar.IsPackageRelativePath("foo.pack[bar.pack[baz.file]]"))
def _CheckPackage(self, packagePath): self._Msg("Checking package <%s>." % packagePath) # XXX: Should we open the package on a stage to ensure that it is valid # and entirely self-contained. from pxr import Usd pkgExt = Ar.GetResolver().GetExtension(packagePath) if pkgExt != "usdz": self._AddError("Package at path %s has an invalid extension." % packagePath) return # Check the parent package first. if Ar.IsPackageRelativePath(packagePath): parentPackagePath = Ar.SplitPackageRelativePathInner(packagePath)[0] self._CheckPackage(parentPackagePath) # Avoid checking the same parent package multiple times. if packagePath in self._checkedPackages: return self._checkedPackages.add(packagePath) resolvedPath = Ar.GetResolver().Resolve(packagePath) if len(resolvedPath) == 0: self._AddError("Failed to resolve package path '%s'." % packagePath) return zipFile = Usd.ZipFile.Open(resolvedPath) if not zipFile: self._AddError("Could not open package at path '%s'." % resolvedPath) return for rule in self._rules: rule.CheckZipFile(zipFile, packagePath)
def RunCommand(self): if not self._item: return # Get layer path from item layerPath = getattr(self._item, "layerPath") if not layerPath: print("Error: Could not find layer file.") return if Ar.IsPackageRelativePath(layerPath): layerName = os.path.basename( Ar.SplitPackageRelativePathInner(layerPath)[1]) else: layerName = os.path.basename(layerPath) layerName += ".tmp" usdeditExe = self._FindUsdEdit() if not usdeditExe: print( "Warning: Could not find 'usdedit', expected it to be in PATH." ) return print("Opening file: %s" % layerPath) command = [usdeditExe, '-n', layerPath, '-p', layerName] subprocess.Popen(command, close_fds=True)
def _CheckPackage(self, packagePath): self._Msg("Checking package <%s>." % packagePath) # XXX: Should we open the package on a stage to ensure that it is valid # and entirely self-contained. from pxr import Ar, Usd pkgExt = Ar.GetResolver().GetExtension(packagePath) if self._arkit and pkgExt != "usdz": self._AddFailedCheck( "Package at path %s has an invalid extension." % packagePath, ruleNum=5) return # Check the parent package first. if Ar.IsPackageRelativePath(packagePath): parentPackagePath = Ar.SplitPackageRelativePathInner( packagePath)[0] self._CheckPackage(parentPackagePath) # Avoid checking the same parent package multiple times. if packagePath in self._checkedPackages: return self._checkedPackages.add(packagePath) resolvedPath = Ar.GetResolver().Resolve(packagePath) if len(resolvedPath) == 0: self._AddError("Failed to resolve package path '%s'." % packagePath) return zipFile = Usd.ZipFile.Open(resolvedPath) if not zipFile: self._AddError("Could not open package at path '%s'." % resolvedPath) return fileNames = zipFile.GetFileNames() for fileName in fileNames: fileExt = Ar.GetResolver().GetExtension(fileName) if fileExt not in ComplianceChecker._allowedFileExtensions: self._AddFailedCheck( "File '%s' in package '%s' has unknown or " "unsupported extension '%s'." % (fileName, packagePath, fileExt), ruleNum=[4, 5]) fileInfo = zipFile.GetFileInfo(fileName) offset = fileInfo.dataOffset if offset % 64 != 0: self._AddFailedCheck( "File '%s' in package '%s' has an invalid " "offset %s." % (fileName, packagePath, offset), ruleNum=1) if fileInfo.compressionMethod != 0: self._AddFailedCheck( "File '%s' in package '%s' has " "compression. Compression method is '%s', actual size is " "%s. Uncompressed size is %s." % (fileName, packagePath, fileInfo.compressionMethod, fileInfo.size, fileInfo.uncompressedSize), ruleNum=2)
def _CheckDependencies(self, usdStage, layerDeps, assetDeps, unresolvedPaths): from pxr import Ar def _IsPackageOrPackagedLayer(layer): return layer.GetFileFormat().IsPackage() or \ Ar.IsPackageRelativePath(layer.identifier) # Process every package just once by storing them all in a set. packages = set() for layer in layerDeps: if _IsPackageOrPackagedLayer(layer): packagePath = Ar.SplitPackageRelativePathInner( layer.identifier)[0] packages.add(packagePath) self._CheckLayer(layer) for package in packages: self._CheckPackage(package) # If the root layer is a package, validate that all the loaded layers # belong to the package. rootLayer = usdStage.GetRootLayer() if self._arkit and _IsPackageOrPackagedLayer(rootLayer): packagePath = usdStage.GetRootLayer().realPath if packagePath: if Ar.IsPackageRelativePath(packagePath): packagePath = Ar.SplitPackageRelativePathOuter( packagePath)[0] for layer in layerDeps: # In-memoery layers that session layers won't have a real # path. We can skip them. if layer.realPath: if not layer.realPath.startswith(packagePath): self._AddFailedCheck( "Found loaded layer '%s' that " "does not belong to the package '%s'." % (layer.identifier, packagePath), ruleNum=4) for asset in assetDeps: if not asset.startswith(packagePath): self._AddFailedCheck( "Found asset reference '%s' that " "does not belong to the package '%s'." % (asset, packagePath), ruleNum=4) for unresolvedPath in unresolvedPaths: self._AddFailedCheck( "Found unresolvable external dependency '%s'." % unresolvedPath, ruleNum=4)
def GetAssetCreationTime(primStack, assetIdentifier): """Finds the weakest layer in which assetInfo.identifier is set to 'assetIdentifier', and considers that an "asset-defining layer". We then retrieve the creation time for the asset by stat'ing the layer's real path. Returns a triple of strings: (fileDisplayName, creationTime, owner)""" definingLayer = None for spec in reversed(primStack): if spec.HasInfo('assetInfo'): identifier = spec.GetInfo('assetInfo')['identifier'] if identifier == assetIdentifier: definingLayer = spec.layer break if definingLayer: definingFile = definingLayer.realPath else: definingFile = primStack[-1].layer.realPath print "Warning: Could not find expected asset-defining layer for %s" %\ assetIdentifier if Ar.IsPackageRelativePath(definingFile): definingFile = Ar.SplitPackageRelativePathOuter(definingFile)[0] if not definingFile: displayName = (definingLayer.GetDisplayName() if definingLayer and definingLayer.anonymous else "<in-memory layer>") creationTime = "<unknown>" owner = "<unknown>" else: displayName = definingFile.split('/')[-1] try: creationTime = time.ctime(os.stat(definingFile).st_ctime) except: creationTime = "<unknown>" owner = GetFileOwner(definingFile) return (displayName, creationTime, owner)
def CheckDependencies(self, usdStage, layerDeps, assetDeps): rootLayer = usdStage.GetRootLayer() if not _IsPackageOrPackagedLayer(rootLayer): return packagePath = usdStage.GetRootLayer().realPath if packagePath: if Ar.IsPackageRelativePath(packagePath): packagePath = Ar.SplitPackageRelativePathOuter( packagePath)[0] for layer in layerDeps: # In-memory layers like session layers (which we must skip when # doing this check) won't have a real path. if layer.realPath: if not layer.realPath.startswith(packagePath): self._AddFailedCheck("Found loaded layer '%s' that " "does not belong to the package '%s'." % (layer.identifier, packagePath)) for asset in assetDeps: if not asset.startswith(packagePath): self._AddFailedCheck("Found asset reference '%s' that " "does not belong to the package '%s'." % (asset, packagePath))
def _IsPackageOrPackagedLayer(layer): return layer.GetFileFormat().IsPackage() or \ Ar.IsPackageRelativePath(layer.identifier)