Files
UnrealEngine/Engine/Source/ThirdParty/Alembic/alembic-1.8.7/lib/python/abcutils/Path.py
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

376 lines
11 KiB
Python

#!/usr/bin/env python2.5
#-*- mode: python -*-
##-*****************************************************************************
##
## Copyright (c) 2009-2011,
## Sony Pictures Imageworks Inc. and
## Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
##
## All rights reserved.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are
## met:
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following disclaimer
## in the documentation and/or other materials provided with the
## distribution.
## * Neither the name of Industrial Light & Magic nor the names of
## its contributors may be used to endorse or promote products derived
## from this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
##-*****************************************************************************
import os, sys
class Path( object ):
"""The Path class simplifies filesystem path manipulation. If you wish
to use a Path object as an argument to standard Python path functions
such as os.path.*, open(), etc., you must first cast it to a string like
"str( myPathObject )"."""
def __init__( self, path=None ):
if path != None:
path = str( path )
self._isabs = os.path.isabs( path )
self._orig = path
self._path = os.path.normpath( os.path.expanduser( path ) )
else:
self._isabs = False
self._path = ''
self._orig = ''
if self._isabs:
self._root = os.sep
else:
if self._orig == '':
self._root = None
else:
self._root = os.curdir
self._plist = filter( lambda x: x and x != os.curdir,
self._path.split( os.sep ))
self._len = len( self._plist )
self._isempty = self._root == None and self._len == 0
self._maxindex = self._len - 1
self._maxsliceindex = self._len
def __reinit__( self, new ):
self._len = len( new._plist )
self._plist = new._plist[:]
self._isempty = 0 == new._len
self._maxindex = new._len - 1
self._maxsliceindex = new._len
self._path = new._path
self._orig = new._orig
self._isabs = new._isabs
self._root = new._root
def __repr__( self ):
return self._path
def __str__( self ):
return self.__repr__()
def __contains__( self, other ):
return other in self._plist
def __len__( self ):
return self._len
def __add__( self, other ):
return Path( os.path.join( str( self ), str( other ) ) )
def __radd__( self, other ):
return Path( other ) + self
def __iter__( self ):
self._iterindex = 0
return self
def __eq__( self, other ):
return str( self ) == str( other )
def __ne__( self, other ):
return str( self ) != str( other )
def __cmp__( self, other ):
_, p1, p2 = self.common( other )
return len( p1 ) - len( p2 )
def __nonzero__( self ):
if not self.isabs() and len( self ) == 0:
return False
else:
return True
def __hash__( self ):
return hash( str( self ))
def __getitem__( self, n ):
if isinstance( n, slice ):
path = None
plist = self._plist[n.start:n.stop:n.step]
returnabs = self._isabs and n.start < 1
if len( plist ) > 0:
path = os.sep.join( plist )
else:
path = os.curdir
path = Path( path )
if returnabs:
path = self.root() + path
else:
pass
return path
else:
return self._plist[n]
def __setitem__( self, key, value ):
try:
key = int( key )
except ValueError:
raise ValueError("You must use an integer to refer to a path element.")
if key > abs( self._maxindex ):
raise IndexError("Maximum index is +/- %s." % self._maxindex)
self._plist[key] = value
self._path = str( self[:] )
def __delitem__( self, n ):
try:
n = int( n )
except ValueError:
raise ValueError("You must use an integer to refer to a path element.")
try:
del( self._plist[n] )
t = Path( self[:] )
self.__reinit__( t )
except IndexError:
raise IndexError("Maximum index is +/- %s" & self._maxindex)
def rindex( self, val ):
if val in self:
return len( self._plist ) - \
list( reversed( self._plist ) ).index( val ) - 1
else:
raise ValueError("%s is not in path." % val)
def index( self, val ):
if val in self:
return self._plist.index( val )
else:
raise ValueError("%s is not in path." % val)
def common( self, other, cmn=None ):
cmn = Path( cmn )
other = Path( str( other ) )
if self.isempty() or other.isempty():
return cmn, self, other
elif (self[0] != other[0]) or (self.root() != other.root()):
return cmn, self, other
else:
return self[1:].common( other[1:], self.root() + cmn + self[0] )
def relative( self, other ):
cmn, p1, p2 = self.common( other )
relhead = Path()
if len( p1 ) > 0:
relhead = Path( (os.pardir + os.sep) * len( p1 ))
return relhead + p2
def join( self, *others ):
t = self[:]
for o in others:
t = t + o
return t
def split( self ):
head = self[:-1]
tail = None
if not head.isempty():
tail = Path( self[-1] )
else:
tail = self
if not head.isabs() and head.isempty():
head = Path( None )
if head.isabs() and len( tail ) == 1:
tail = tail[-1]
return ( head, tail )
def splitext( self ):
head, tail = os.path.splitext( self._path )
return Path( head ), tail
def next( self ):
if self._iterindex > self._maxindex:
raise StopIteration
else:
i = self._iterindex
self._iterindex += 1
return self[i]
def subpaths( self ):
sliceind = 0
while sliceind < self._maxsliceindex:
sliceind += 1
yield self[:sliceind]
def append( self, *others ):
t = self[:]
for o in others:
t = t + o
self.__reinit__( t )
def root( self ):
return Path( self._root )
def elems( self ):
return self._plist
def path( self ):
return self._path
def exists( self ):
return os.path.exists( self._path )
def isempty( self ):
return self._isempty
def isabs( self ):
return self._isabs
def islink( self ):
return os.path.islink( self._path )
def isdir( self ):
return os.path.isdir( self._path )
def isfile( self ):
return os.path.isfile( self._path )
def readlink( self ):
if self.islink():
return Path( os.readlink( self._orig ) )
else:
return self
def dirname( self ):
return self[:-1]
def basename( self ):
return self.dirname()
def startswith( self, other ):
return self._path.startswith( other )
def makeabs( self ):
t = self[:]
t._root = os.sep
t._isabs = True
t._path = os.path.join( os.sep, self._path )
self.__reinit__( t )
def makerel( self ):
t = self[:]
t._root = os.curdir
t._isabs = False
t._path = os.sep.join( t._plist )
self.__reinit__( t )
def toabs( self ):
return Path( os.path.abspath( self._path ) )
def torel( self ):
t = self[:]
t.makerel()
return t
##-*****************************************************************************
def mapFSTree( root, path, dirs=set(), links={} ):
"""Create a sparse map of the filesystem graph from the root node to the path
node."""
root = Path( root )
path = Path( path )
for sp in path.subpaths():
if sp.isabs():
full = sp
else:
full = sp.toabs()
head = full.dirname()
if full.islink():
target = full.readlink()
if target.isabs():
newpath = target
else:
newpath = head + target
# make sure there are no cycles
if full in links:
continue
links[full] = newpath
_dirs, _links = mapFSTree( full, newpath, dirs, links )
dirs.update( _dirs )
links.update( _links )
elif full.isdir():
if full in dirs:
continue
else:
dirs.add( full )
elif full.isfile():
break
#pass
else:
print ("QOI??? %s" % full)
return dirs, links
##-*****************************************************************************
def main():
try:
arg = Path( sys.argv[1] )
except IndexError:
print ("Please supply a directory to analyze.")
return 1
dirs, links = mapFSTree( Path( os.getcwd() ), arg )
print
print ("Directories traversed to get to %s\n" % arg)
for d in sorted( list( dirs ) ): print (d)
print
print ("Symlinks in traversed directories for %s\n" % arg)
for k in links: print ("%s: %s" % ( k, links[k] ))
print
return 0
##-*****************************************************************************
if __name__ == "__main__":
sys.exit( main() )