Filesystem Interface

Filesystem Class

class musicdb.lib.filesystem.Filesystem(root='/')[source]

This class provides an interface to the filesystem. The whole class assumes that it is used with an Unicode capable UNIX-style filesystem.

Whenever I write about root director the path set in this class as root is meant. Otherwise I would call it system root directory.

The root path must exist and must be a directory.

Some naming conventions:

  • abspath: Absolute path. They always start with a "/".

  • relpath: Relative path - Relative to the root directory. They should not start with a "./". This leads to undefined behavior!

  • xpath: Can be absolute or relative.

Parameters

root (str/Path) – Path to the internal used root directory. It is allowed to start with “./”.

Raises
  • ValueError – If the root path does not exist

  • TypeError – If root is not of type str or Path.

AbsolutePath(xpath: Union[str, pathlib.Path]) pathlib.Path[source]

This method returns an absolute path by adding the root directory to the path. If the path is already absolute (starts with "/") it gets returned as it is.

If the path starts with a ~ the user home directories will be resolved.

If path is exact ".", the root path gets returned.

In all other cases the root path gets prepended.

Parameters

xpath (str/Path) – A relative or absolute path

Returns

An absolute path as Path object

Raises

TypeError – If xpath is None

Example

fs   = Filesystem()
home = fs.AbsolutePath("~")
# PosixPath('/home/ralf')
home = fs.ToString(home)
# '/home/ralf'
AssertDirectory(xpath: Union[str, pathlib.Path]) bool[source]

Raises an AssertionError if IsDirectory() fails.

AssertFile(xpath: Union[str, pathlib.Path])[source]

Raises an AssertionError if IsFile() fails.

CheckAccessPermissions(xpath: Union[str, pathlib.Path] = '.') str[source]

This method can be used to check if a file or directory can be accessed. It returns a string with 3 characters that represent the read, write and execute flags. The returned string is specified as follows:

  • 3 Characters wide string

  • [0]: "r" when read access is possible, otherwise "-"

  • [1]: "w" when write access is possible, otherwise "-"

  • [2]: "r" when the file can be executed or the directory can be entered. Otherwise "-"

The access is checked for the user ID and group ID of the process that calls this method.

Parameters

xpath (str/Path) – The file or directory that mode shall be changed. (Optional, default is ".")

Returns

A 3 character string representing the "rwx" access permissions.

Example

fs.CheckAccessPermissions("test.txt") # "rw-"
fs.CheckAccessPermissions("dir")      # "r-x"
fs.CheckAccessPermissions("mydir")    # "rwx"
fs.CheckAccessPermissions()           # "rwx"
CopyFile(xsrcpath: Union[str, pathlib.Path], xdstpath: Union[str, pathlib.Path]) bool[source]

This method copies a file. Handle with care!

If the source file does not exist, False gets returned. If the destination file exists, it gets overwritten! When the destination path is a directory, the file gets copied into the directory. All parent directories must exist, otherwise a FileNotFoundError exception gets raised.

The UNIX shell alternative would be like the following line:

cp $SRCPATH $DSTPATH
Parameters
  • xsrcpath (str/Path) – A relative or absolute path of the source

  • xdstpath (str/Path) – A relative or absolute path where the source file shall be copied to

Returns

False if the file does not exist.

Excpetions:

PermissionError: When there is no write access to the destination directory FileNotFoundError: When the destination directory does not exist

CreateSubdirectory(xnewpath: Union[str, pathlib.Path]) bool[source]

This method creates a subdirectory. The directories are made recursively. So xnewpath can address the last directory of a path that will be created.

Parameters

xnewpath (str/Path) – A path that addresses a new directory

Returns

True

Execute(commandline: list[str])[source]

Executes an external program. The command line is a list of arguments with the executable name as first element. So commandline[0] is the program name like "ls" and the next elements are a list of arguments to this program (like "-l", "-h"). All entries in this list must be representable as string.

The I/O interfaces stderr, stdout and stdin are piped to /dev/null

After executing the command line, a sync command gets executed. In the past there were lots of problems because a second process wanted to process data preprocessed from the first one, but those data were not completely written to the disk.

Parameters

commandline (list) – command line split into the executable name and individual arguments

Returns

Nothing

Raises
  • TypeError – When one entry of the commandline list can not be converted to string

  • ChildProcessError – If the return value of the executed program is not 0

Example

The following python code results in the following command line

try:
    fs.Execute(["ls", "-l", "-h"])
except ChildProcessError as e:
    print(e)
ls -l -h 2> /dev/null > /dev/null < /dev/null
sync
Exists(xpath: Union[str, pathlib.Path]) bool[source]

This method checks if a path exist. It can be a file or a directory

Parameters

xpath (str) – A relative or absolute path

Returns

True if the path exists, otherwise False.

GetAccessPermissions(xpath: Union[str, pathlib.Path]) str[source]

This method returns the access mode (access permissions) of a file or a directory. The mode is represented as string as it is used to be when calling ls -l.

The returned string is defined as follows:

  • It consists of exact 9 characters.

  • 0…2: User access permissions (2: Set UID when "s")

  • 3…5: Group access permissions (5: Set GID when "s")

  • 6…8: Access permissions for others (8: Sticky when "t")

  • It uses the following set of characters: "rwxst-".

Parameters

xpath (str/Path) – Path to the file or directory

Returns

A string representing the files/directories access mode

Example

fs = Filesystem("/tmp")

# Files at /tmp:
# rw-rw-r-- test1.txt
# rwxr-xr-x directory1
# rwsr-x--t directory2
fs.GetAccessPermissions("test1.txt")    # "rw-rw-r--"
fs.GetAccessPermissions("directory1")   # "rwxr-xr-x"
fs.GetAccessPermissions("directory2")   # "rwsr-x--t"
GetDirectory(xpath: Union[str, pathlib.Path]) pathlib.Path[source]

This method returns the directory a file or folder is stored in. If is not required and not checked if the path exists.

Parameters

xpath (str/Path) – A path to a file or directory

Returns

The directory of that file

Example

directory = fs.GetDirectory("this/is/a/test.txt")
print(str(directory)) # "this/is/a"
GetDirectoryName(xpath: Union[str, pathlib.Path]) str[source]

See GetFileName(), but incldir is always False. So this method returns the last directory of a path.

GetFileExtension(xpath: Union[str, pathlib.Path]) str[source]

This method returns the file extension of the file addressed by xpath. It will not be checked if the file exists.

If xpath does not address a file or the file does not have an extension, None gets returned. Otherwise only the extension without the leading "." gets returned.

Parameters

xpath (str/Path) – A path or name of a file that extension shall be returned

Returns

The file extension without the leading dot, or None if the file does not have an extension.

Example

fs  = FileSystem("/tmp")
ext = fs.GetFileExtension("test.txt")
if ext:
    print("File Extension is: "%s""%(ext))    # in this example: "txt"
GetFileName(xpath: Union[str, pathlib.Path], incldir=True) str[source]

This method returns the file name of the file addressed by xpath. It is not required and not checked that the file exist. The name of a file does not include the file extension.

If incldir is True (default), the full path including the directories is returd. So the returned path is the argument without any suffix. When xpath addresses a directory and inclddir is True, the behavior is not defined!

If incldir is False only the file name is returned without suffix and without directories.

The return type is a string.

Parameters

xpath (str/Path) – A path or name of a file that name shall be returned

Returns

The name of the file including directories if incldir==True.

Example

name = fs.GetFileName("this/is/a/test.txt")
print(name) # "this/is/a/test"

name = fs.GetFileName("this/is/a/test.txt", incldir=False)
print(name) # "test"

name = fs.GetFileName("this/is/a", incldir=False)
print(name) # "a"
GetFiles(xparents: Optional[Union[str, pathlib.Path]] = None, ignore: Optional[list[str, pathlib.Path]] = None) list[pathlib.Path][source]

This method returns a filtered list with files for one or more parent directories. If xparents is None, the root directory will be used. If a parent path does not exist, an exception gets raised.

The ignore parameter is a list of names that will be ignored and won’t appear in the returned list of subdirectories.

All paths returned are relative to the root directory if possible. If not, the they are absolute.

This method works like GetSubdirectories() but with files

Parameters
  • xparents – A parent directory or a list of parent directories

  • ignore – A list of entries to ignore

Returns

A list of paths relative to the root directory, including the parent directory (“parent/filename”)

GetMode(xpath: Union[str, pathlib.Path]) int[source]

This method returns the mode of a file. The mode consists of the stat attributes as listed in SetAttributes().

Only the first four octal digits will be returned.

Parameters

xpath (str/Path) – Path to the file or directory

Returns

An integer with st_mode & 0o7777 of the addressed file or directory.

Example

fs = Filesystem("/tmp")
mode = fs.GetMode("testfile.txt")
GetModificationDate(xpath: Union[str, pathlib.Path]) int[source]

This method returns the date when a file or directory was modified the last time. (See os.path.getmtime)

Parameters

xpath (str/Path) – Path to the file or directory

Returns

The modification date of the file or directory as UNIX time value in seconds (integer)

Example

fs = Filesystem("/data/music/")
cdate = fs.GetModificationDate("Rammstein") # Possible creation date of /data/music/Rammstein directory
print(cdate)
GetOwner(xpath: Union[str, pathlib.Path]) tuple[str, str][source]

This method returns the owner of a file or directory. The owner is a tuple of a UNIX user and group as string

Parameters

xpath (str/Path) – Path to the file or directory

Returns

A tuple (user, group) to which the file belongs to

Example

fs = Filesystem("/tmp")
user,group = fs.GetOwner("testfile.txt")
print("User: " + user)      # "User: root"
print("Group: " + group)    # "Group: root"
GetRoot()[source]

Returns the root path. User name directories are resolved. The path is absolute.

Returns

Returns a pathlib.Path object with the root path

GetSubdirectories(xparents: Optional[list[typing.Union[str, pathlib.Path]]] = None, ignore: Optional[list[str, pathlib.Path]] = None) list[pathlib.Path][source]

This method returns a filtered list with sub-directories for one or more parent directories. If xparents is None, the root directory will be used.

This method returns relative Path objects. If a path is not relative to the root path, then an absolute path is returned.

The ignore parameter is a list of names that will be ignored and won’t appear in the returned list of subdirectories.

Parameters
  • xparents – A parent directory or a list of parent directories

  • ignore – A list of entries to ignore

Returns

A list of paths being the parent directory plus the child directory

Example

Get the subdirectories of the following file structure:

dir1/subdir/*
dir1/testdir/*
dir1/files
dir2/test/*
dir2/tmp/*
fs = Filesystem("/tmp")

subdirs = fs.GetSubdirectories(["dir1", "dir2"], ["tmp"])

print(subdirs)  # > ['dir1/subdir', 'dir1/testdir', 'dir2/test']
GuessMimeType(xpath: Union[str, pathlib.Path]) str[source]

Derives the mime type based on the file extension.

Parameters

xpath (str/Path) – A path or name of a file

Returns

The mime type as "type/subtype", or None if the mime type cannot be determined.

Example

fs   = FileSystem("/tmp")

type = fs.GuessMimeType("test.txt")
print("MIME type is: "%s""%(type))    # in this example: "text/plain"

type = fs.GuessMimeType("README")
print("MIME type is: "%s""%(type))    # in this example: "None"
IsDirectory(xpath: Union[str, pathlib.Path]) bool[source]

This method checks if a directory exists.

Parameters

xpath (str/Path) – A relative or absolute path to a directory

Returns

True if the directory exists, otherwise False.

IsFile(xpath: Union[str, pathlib.Path]) bool[source]

This method checks if a file exists.

Parameters

xpath (str/Path) – A relative or absolute path to a directory

Returns

True if the file exists, otherwise False.

ListDirectory(xpath: Optional[Union[str, pathlib.Path]] = None) list[pathlib.Path][source]

This method returns a list of entries in the directory addressed by xpath. The list can contain files and directories. If xpath is not a directory, an empty list will be returned. If xpath is None, the root directory will be used.

The list contains only the names (relative to root directory) including hidden files that starts with a ".". The special directories "." and ".." are not included.

Parameters

xpath (str/Path) – Path to a directory. If None the root directory will be used

Returns

A list of entries (files and directories) in the directory.

MoveDirectory(xsrcpath: Union[str, pathlib.Path], xdstpath: Union[str, pathlib.Path]) bool[source]

This method moves a directory in the filesystem. Handle with care!

If the source directory does not exist, False gets returned. To move files, see MoveFile(). The directory in that the directory shall be moved in must exist.

Parameters
  • xsrcpath (str/Path) – A relative or absolute path of the source

  • xdstpath (str/Path) – A relative or absolute path where the source file shall be moves to

Returns

False if the source directory does not exist.

Example

# Tree:
# dira/subdira/fa1.txt
# dirb/

fs.MoveDirectory(“dira/subdira”, “dirb”)

# Tree: # dira/ # dirb/subdira/fa1.txt

MoveFile(xsrcpath: Union[str, pathlib.Path], xdstpath: Union[str, pathlib.Path]) bool[source]

This method moves a file in the filesystem. Handle with care!

If the source file does not exist, False gets returned. To move directories, see MoveDirectory(). The directory in that the file shall be moved must exist.

Parameters
  • xsrcpath (str/Path) – A relative or absolute path of the source

  • xdstpath (str/Path) – A relative or absolute path where the source file shall be moves to

Returns

False if the file or the destination directory does not exist

RemoveDirectory(xpath: Union[str, pathlib.Path]) bool[source]

This method removes a directory from the filesystem.

Warning

Handle with care!

If the file does not exist, False gets returned

Parameters

xpath (str/Path) – A relative or absolute path to a directory

Returns

False if the directory does not exist

RemoveFile(xpath: Union[str, pathlib.Path]) bool[source]

This method removes a file from the filesystem.

Warning

Handle with care!

If the file does not exist, False gets returned

Parameters

xpath (str/Path) – A relative or absolute path to a file

Returns

False if the file does not exist.

RemoveRoot(path: Union[str, pathlib.Path]) pathlib.Path[source]

This method makes a path relative to the root path. The existence of the path gets not checked!

It is assumed that path is an absolute path. Anyway it will be processed by AbsolutePath() to resolve a user directory ~.

Parameters

abspath (str, Path) – A path that shall be made relative

Returns

A relative path to the root directory

Raises

ValueError – If the path is not inside the root path

Example

fs = Filesystem("/data/music")

abspath = "/data/music/Artist/Album"
relpath = fs.RemoveRoot(abspath)
print(relpath)  # > Artist/Album

_ = fs.RemoveRoot("/data/backup/Artist/Album")
# -> ValueError-Excpetion
Rename(xsrcpath: Union[str, pathlib.Path], xdstpath: Union[str, pathlib.Path]) bool[source]

Renames a file or a directory. If the destination path name exists, the method returns False. Only the last part of a path is allowed to be different, otherwise the renaming fails.

If the source file or directory does not exist, False gets returned. To move a file or directory to different places see MoveFile() or MoveDirectory().

Parameters
  • xsrcpath (str/Path) – A relative or absolute path of the source

  • xdstpath (str/Path) – A relative or absolute path where the source file shall be moves to

Returns

False if the source file or directory does not exist.

Exception:

OSError: When renaming is not possible

Example

# Tree:
# dira/fa1.txt
# dira/fa2.txt
# dirb/fb1.txt
# dirb/fb2.txt

fs.Rename(“dira”, “dirb”) # -> Returns False, does nothing fs.Rename(“dira”, “dirc”) # -> Returns True, renames dira to dirc fs.Rename(“dira/fa1.txt”, “dira/fa3.txt”) # -> Returns True, renames fa1.txt to fa3.txt fs.Rename(“dira/fa1.txt”, “dirb/fa3.txt”) # -> Returns False, does nothing

SetAccessPermissions(xpath: Union[str, pathlib.Path], mode: str) bool[source]

This method sets the access mode (access permissions) of a file or directory. The mode is represented as string as it is used to be when calling ls -l.

The access mode string must fulfill the following specification:

  • It consists of exact 9 characters.

  • 0…2: User access permissions (2: Set UID when "s")

  • 3…5: Group access permissions (5: Set GID when "s")

  • 6…8: Access permissions for others (8: Sticky when "t")

  • It uses the following set of characters: "rwxst-".

Unknown characters will be ignored as well as characters at unexpected positions.

Parameters
  • xpath (str/Path) – The file or directory that mode shall be changed

  • mode (str) – The new permissions to set

Returns

True on success, otherwise False

Raises
  • ValueError – When mode does not have exact 9 characters.

  • PermissionError – When setting mode is not allowed

Example

fs.SetAccessPermissions("test.txt", "rwxr-x---")
fs.SetAccessPermissions("test",     "rwxr-s--t")
SetAttributes(xpath: Union[str, pathlib.Path], owner: Optional[str] = None, group: Optional[str] = None, mode: Optional[int] = None) bool[source]

This method sets attributes for a file or directory. The mode is the access permissions as defined in the stats module.

When mode is None, the permissions will not be changed. When owner or group are None, the ownership will not be changed.

Mode-attributes can be an bitwise-OR combination of the following flags:

  • stat.S_ISUID

  • stat.S_ISGID

  • stat.S_ENFMT

  • stat.S_ISVTX

  • stat.S_IREAD

  • stat.S_IWRITE

  • stat.S_IEXEC

  • stat.S_IRWXU

  • stat.S_IRUSR

  • stat.S_IWUSR

  • stat.S_IXUSR

  • stat.S_IRWXG

  • stat.S_IRGRP

  • stat.S_IWGRP

  • stat.S_IXGRP

  • stat.S_IRWXO

  • stat.S_IROTH

  • stat.S_IWOTH

  • stat.S_IXOTH

Parameters
  • xpath (str/Path) – Path to the file or directory

  • owner (str) – Name of the owner of the file or directory

  • group (str) – Name of the group

  • mode – Access permissions

Returns

False when updating the mode or ownership fails

Example

import stat
fs = Filesystem("/tmp")

# -rw-rw-r--
permissions = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH
fs.SetAttributes("test.txt", "user", "group", permissions)

# drwxrwxr-x
mode = stat.S_IRWXU | stat.S_IRWXG | stat.S_IROTH | stat.S_IXOTH
fs.SetAttributes("testdirectory", None, None, mode) # make directory writeable for group members
SetOwner(xpath: Union[str, pathlib.Path], user: str, group: str) bool[source]

This method changes the ownership of a file or directory.

Parameters
  • xpath (str/Path) – Path to the file or directory

  • user (str) – Name of a valid UNIX user

  • group (str) – Name of a valid UNIX group

Returns

True on success, otherwise False

ToString(paths: Union[str, pathlib.Path, list[typing.Union[str, pathlib.Path]]]) Union[str, list[str]][source]

Converts a Path object or a list of path objects into a string or a list of strings

Parameters

paths (str,Path,list) – A single path or a list of paths

Returns

A single string or a list of strings

TryRemoveRoot(path: Union[str, pathlib.Path]) pathlib.Path[source]

Like RemoveRoot() just that exceptions are suppressed. If an exception occurs, path gets returned as it is.