####################################################################################################
#
# PySpice - A Spice Package for Python
# Copyright (C) 2014 Fabrice Salvaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
####################################################################################################
####################################################################################################
import os
import subprocess
####################################################################################################
[docs]def file_name_has_extension(file_name, extension):
return file_name.endswith(extension)
####################################################################################################
[docs]def file_extension(filename):
# index = filename.rfind(os.path.extsep)
# if index == -1:
# return None
# else:
# return filename[index:]
return os.path.splitext(filename)[1]
####################################################################################################
[docs]def run_shasum(filename, algorithm=1, text=False, binary=False, portable=False):
if algorithm not in (1, 224, 256, 384, 512, 512224, 512256):
raise ValueError
args = ['shasum', '--algorithm=' + str(algorithm)]
if text:
args.append('--text')
elif binary:
args.append('--binary')
elif portable:
args.append('--portable')
args.append(filename)
output = subprocess.check_output(args)
shasum = output[:output.find(' ')]
return shasum
####################################################################################################
[docs]class Path:
##############################################
def __init__(self, path):
self._path = str(path)
##############################################
def __bool__(self):
return os.path.exists(self._path)
##############################################
def __str__(self):
return self._path
##############################################
@property
def path(self):
return self._path
##############################################
[docs] def is_absolut(self):
return os.path.isabs(self._path)
##############################################
[docs] def absolut(self):
return self.clone_for_path(os.path.abspath(self._path))
##############################################
[docs] def normalise(self):
return self.clone_for_path(os.path.normpath(self._path))
##############################################
[docs] def normalise_case(self):
return self.clone_for_path(os.path.normcase(self._path))
##############################################
[docs] def expand_vars_and_user(self):
return self.clone_for_path(os.path.expandvars(os.path.expanduser(self._path)))
##############################################
[docs] def real_path(self):
return self.clone_for_path(os.path.realpath(self._path))
##############################################
[docs] def relative_to(self, directory):
return self.clone_for_path(os.path.relpath(self._path, str(directory)))
##############################################
[docs] def clone_for_path(self, path):
return self.__class__(path)
##############################################
[docs] def split(self):
return self._path.split(os.path.sep)
##############################################
[docs] def directory_part(self):
return Directory(os.path.dirname(self._path))
##############################################
[docs] def filename_part(self):
return os.path.basename(self._path)
##############################################
[docs] def is_directory(self):
return os.path.isdir(self._path)
##############################################
[docs] def is_file(self):
return os.path.isfile(self._path)
##############################################
@property
def inode(self):
return os.stat(self._path).st_ino
##############################################
@property
def creation_time(self):
return os.stat(self._path).st_ctime
####################################################################################################
[docs]class Directory(Path):
##############################################
def __bool__(self):
return super().__nonzero__() and self.is_directory()
##############################################
[docs] def join_directory(self, directory):
return self.__class__(os.path.join(self._path, str(directory)))
##############################################
[docs] def join_filename(self, filename):
return File(filename, self._path)
##############################################
[docs] def iter_file(self, followlinks=False):
for root, directories, files in os.walk(self._path, followlinks=followlinks):
for filename in files:
yield File(filename, root)
##############################################
[docs] def iter_directories(self, followlinks=False):
for root, directories, files in os.walk(self._path, followlinks=followlinks):
for directory in directories:
yield Path(os.path.join(root, directory))
####################################################################################################
[docs]class File(Path):
default_shasum_algorithm = 256
##############################################
def __init__(self, filename, path=''):
super().__init__(os.path.join(str(path), str(filename)))
self._filename = self.filename_part()
if not self._filename:
raise ValueError
self._directory = self.directory_part()
self._shasum = None # lazy computation
##############################################
def __bool__(self):
return super().__nonzero__() and os.path.isfile(self._path)
##############################################
@property
def directory(self):
return self._directory
##############################################
@property
def filename(self):
return self._filename
##############################################
@property
def extension(self):
return file_extension(self._filename)
##############################################
@property
def shasum(self):
if self._shasum is None:
return self.compute_shasum()
else:
return self._shasum
##############################################
[docs] def compute_shasum(self, algorithm=None):
if algorithm is None:
algorithm = self.default_shasum_algorithm
self._shasum = run_shasum(self._path, algorithm, portable=True)
return self._shasum