Begin work on libufps
This commit is contained in:
parent
d6e5f99f1f
commit
cce5a8b5b9
3
libufps/__init__.py
Normal file
3
libufps/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
#import ufps
|
||||
|
||||
#ufps = ufps.UFPS
|
147
libufps/ufps.py
Normal file
147
libufps/ufps.py
Normal file
|
@ -0,0 +1,147 @@
|
|||
import os
|
||||
import stat
|
||||
import pwd
|
||||
import grp
|
||||
|
||||
class ufps:
|
||||
"""
|
||||
Primary class for libufps
|
||||
"""
|
||||
|
||||
def __init__(self, basedir):
|
||||
"""
|
||||
Constructor method.
|
||||
:param basedir: The input base directory from the user/program. Gets normalized later.
|
||||
:type basedir: str
|
||||
"""
|
||||
|
||||
# Normalize the directory prior to setting it.
|
||||
self.basedir = self.normalizeInputDir(basedir)
|
||||
|
||||
# Now we check if the path exists and is a directory.
|
||||
self.checkPathValidity(self.basedir)
|
||||
|
||||
print ("Init ufps with base dir: " + self.basedir)
|
||||
|
||||
def normalizeInputDir(self, dir):
|
||||
"""
|
||||
This function normalizes the input directory.
|
||||
In short, it makes sure the input ends with /, as we expect that to be the case in the rest of the code.
|
||||
:param dir: The input directory from the user/program.
|
||||
:type dir: str
|
||||
:return: A string representing a directory that has been normalized as described above.
|
||||
:rtype: str
|
||||
"""
|
||||
|
||||
if(dir[-1] != '/'):
|
||||
dir=dir+'/'
|
||||
return dir
|
||||
|
||||
def checkPathValidity(self, dir):
|
||||
"""
|
||||
This function checks the validity of an input path.
|
||||
Path validity means that it (1) exists and (2) is a directory.
|
||||
:raises FileNotFoundError: The path doesn't exist at all.
|
||||
:raises NotADirectoryError: The path is a file.
|
||||
:param dir: Input directory.
|
||||
:type dir: str
|
||||
:return: `True` if path is valid, `False` if not.
|
||||
:rtype: bool
|
||||
"""
|
||||
|
||||
exist = os.path.exists(dir)
|
||||
isdir = os.path.isdir(dir)
|
||||
|
||||
# For the purposes of verbosity, we check if a file with the same name
|
||||
# exists by removing the / at the end of the directory.
|
||||
vDir = dir[len(dir)-1]
|
||||
vExist = os.path.exists(vDir)
|
||||
|
||||
# If vExist is False and exist is False, the user input a nothing burger.
|
||||
# This results in FileNotFoundError being thrown.
|
||||
|
||||
# If that doesn't occur, and isdir is false, they input a file.
|
||||
# This results in NotADirectoryError being thrown.
|
||||
|
||||
# If none of the above occurs, the path is valid.
|
||||
|
||||
if(not exist and not vExist):
|
||||
raise FileNotFoundError("The path " + dir + " does not exist.")
|
||||
|
||||
if(not isdir):
|
||||
raise NotADirectoryError("The path must be a directory.")
|
||||
|
||||
return isdir
|
||||
|
||||
def parsePerms(self, path):
|
||||
"""
|
||||
Parses octal permissions stats into a string. Also determines other characteristics of the path: if it's a directory, and if it's a link (and where it goes). Returns this information as well.
|
||||
:param oct_perm: Permissions of path in octal form (i.e. 0o0100644)
|
||||
:return pPerms: Path permissions
|
||||
:rtype pPerms: str
|
||||
|
||||
:return pIsDir: Whether or not the path is a directory
|
||||
:rtype pIsDir: bool
|
||||
|
||||
:return pIsLink: Whether or not the path is a link
|
||||
:rtype pIsLink: bool
|
||||
|
||||
:return pLinkTarget: Where the link points to (if applicable)
|
||||
:rtype pLinkTarget: str
|
||||
"""
|
||||
|
||||
# Get stats of the file/directory
|
||||
stats = os.stat(self.basedir+path)
|
||||
|
||||
# Invoke a magic spell
|
||||
# Magic number -3 is used as for this we only need the last 3 digits.
|
||||
# Directory and link detection is handled later.
|
||||
pPerms = oct(stats.st_mode)[-3:]
|
||||
|
||||
# Get whether or not the path is a dir
|
||||
pIsDir = os.path.isdir(path)
|
||||
|
||||
# Get whether or not the path is a link.
|
||||
pIsLink = os.path.islink(path)
|
||||
|
||||
pLinkTarget = None
|
||||
if pIsLink:
|
||||
pLinkTarget = os.readlink(path)
|
||||
|
||||
return pPerms, pIsDir, pIsLink, pLinkTarget
|
||||
|
||||
def getFilePermissions(self, path):
|
||||
"""
|
||||
Gets Unix file permissions of a directory or file.
|
||||
:param path: Path to directory or file
|
||||
:type path: str
|
||||
"""
|
||||
# Parse oct_perm
|
||||
permStr, isDir, isLink, linkTarget = self.parsePerms(path)
|
||||
|
||||
# If it's a directory, we also want to figure out if it's a link.
|
||||
#isDirectoryLink
|
||||
|
||||
D_userFriendlyString = permStr + " | " + str(isDir) + " | " + str(isLink) + " | " + str(linkTarget)
|
||||
return D_userFriendlyString
|
||||
|
||||
def getFileOwner(self, path):
|
||||
"""
|
||||
Gets file owner and group of a directory or file.
|
||||
:param path: Path to directory or file
|
||||
:type path: str
|
||||
|
||||
:return ownername: Owner name
|
||||
:rtype ownername: str
|
||||
|
||||
:return groupname: Group name
|
||||
:rtype groupname: str
|
||||
"""
|
||||
stats = os.stat(path)
|
||||
uid = stats.st_uid
|
||||
gid = stats.st_gid
|
||||
|
||||
ownername = pwd.getpwuid(stats.st_uid).pw_name
|
||||
groupname = grp.getgrgid(stats.st_gid).gr_name
|
||||
|
||||
return ownername, groupname
|
5
requirements-lib.txt
Normal file
5
requirements-lib.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
wheel
|
||||
setuptools
|
||||
twine
|
||||
pytest==4.4.1
|
||||
pytest-runner==4.4
|
Loading…
Reference in a new issue