Skip to content

Instantly share code, notes, and snippets.

@jfftck
Last active March 17, 2017 00:48
Show Gist options
  • Save jfftck/c0c7a8857fe82add027f to your computer and use it in GitHub Desktop.
Save jfftck/c0c7a8857fe82add027f to your computer and use it in GitHub Desktop.
This is a convinience object to make path/file opperations easier.
class Path(object):
def __init__(self, path=None):
self.__path = []
self.__drive = ''
self.__file = None
self.path(path)
def __add__(self, other):
if isinstance(other, Path):
if unicode(other).startswith('/') or unicode(other).startswith('\\'):
other = os.path.join(*other[1:])
obj = Path(os.path.join(unicode(self), unicode(other)))
else:
obj = unicode(self) + other
return obj
def __div__(self, other):
path = self.__add_path(other)
return Path(self.__build_path(path))
def __mul__(self, other):
if self.__file is None:
raise AttributeError('No file associated with path.')
return Path('{}{}'.format(os.path.splitext(str(self))[0], other))
def __eq__(self, other):
return self.__get_path() == other
def __contains__(self, item):
return len(glob(os.path.join(str(self), item))) > 0
def __getitem__(self, item):
return self.__path[item]
def __iter__(self):
path_parts = self.__path[:]
if self.__drive:
path_parts.insert(0, self.__drive)
return iter(path_parts)
def __repr__(self):
return repr(self.__get_path())
def __str__(self):
return str(self.__get_path())
def __unicode__(self):
return unicode(self.__get_path())
def __len__(self):
return len(unicode(self))
def endswith(self, text):
return str(self).endswith(text)
@staticmethod
def __build_path(path):
return os.path.normpath(os.path.join(*path))
def __get_path(self):
path = ''
if len(self.__path):
path = self.__build_path(self.__path)
else:
raise AttributeError('Path not set.')
if self.__file is not None:
path = os.path.join(path, self.__file)
return self.__drive + path
def __add_path(self, directory):
path = self.__path[:]
path.append(directory)
return path
def __set_path(self, path):
head, tail = os.path.split(path)
if tail:
self.__path.insert(0, tail)
elif head == os.sep:
self.__path.insert(0, head)
if head and tail:
self.__set_path(head)
def path(self, path):
if isinstance(path, Path):
path = str(path)
if isinstance(path, basestring):
path = os.path.expanduser(os.path.expandvars(path))
path = os.path.normpath(path)
if os.path.isfile(path):
path, self.__file = os.path.split(path)
self.__drive, path = os.path.splitdrive(path)
self.__path = []
self.__set_path(path)
def up(self, count=1):
path = self.__path[:]
while count:
if len(path) > 1:
path.pop()
count -= 1
path = os.path.join(*path)
if not os.path.exists(path):
raise IOError('Invalid path: {}'.format(path))
return Path(path)
def exists(self):
return os.path.exists(unicode(self))
def isdir(self):
return os.path.isdir(unicode(self))
def isfile(self):
return os.path.isfile(unicode(self))
def walk(self, path_limit=None, topdown=True, onerror=None, followlinks=False):
if not self.exists():
raise StopIteration
if not isinstance(path_limit, list) and not isinstance(path_limit, int):
path_limit = None
for path, dirs, files in iter(os.walk(unicode(self), topdown, onerror, followlinks)):
children = path.replace(unicode(self), '')
if path_limit:
if isinstance(path_limit, list) and len(set(dirs) & set(path_limit)):
for removal_dir in path_limit:
dirs.remove(removal_dir)
elif (len(children.split(os.sep)) if children else 0) > path_limit:
del dirs[:]
yield Path(path), dirs, files
def files(self, file_filter='*'):
return [x for x in glob(os.path.join(unicode(self), file_filter)) if os.path.isfile(x)]
def dirs(self, dir_filter='*'):
return [Path(x) for x in glob(os.path.join(unicode(self), dir_filter)) if os.path.isdir(x)]
def existing_path(self):
path = Path(input(self))
while not path.exists() and input(path):
path = path.up()
if not str(path):
raise IOError('Invalid path, no valid parent directories.')
return path
def file(self, filename):
if isinstance(filename, basestring):
self.__file = filename
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment