import logging import os from functools import wraps from subprocess import run __all__ = [ "unmount", "rmdir", "subdirs", "subfiles" ] L = logging.getLogger(__name__) def log(func): """Simple decorator for logging function calls.""" @wraps(func) def _log(*args, **kwargs): args_repr = [repr(a) for a in args] kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()] params = ", ".join(args_repr + kwargs_repr) file_name = os.path.basename(func.__code__.co_filename) file_name = os.path.splitext(file_name)[0] func_name = func.__name__ if file_name == "__init__" \ else f"{file_name}.{func.__name__}" L.debug("%s called with %s", func_name, params) try: result = func(*args, **kwargs) L.debug("%s returned %s", func_name, result) return result except Exception as e: L.error("%s raised %r", func_name, e) raise e return _log @log def unmount(path): """Unmount a FUSE filesystem using fusermount. See also: https://manpages.debian.org/bullseye/fuse/fusermount.1.en.html Args: path (str): Path to the mounted FUSE filesystem. Returns: True if the command was successful, False otherwise. """ cmd = ["fusermount", "-u", path] try: p = run(cmd, capture_output=True, check=False, text=True) except Exception as e: L.error("failed to execute command %s: %r", cmd, e) return False return not p.returncode @log def rm(path): """Remove a file. Args: path (str): Path to file. Returns: True if the command was successful, False otherwise. """ try: os.remove(path) except OSError as e: L.error("failed to remove file %s: %r", path, e) return False return True @log def rmdir(path): """Remove a directory. Args: path (str): Path to directory. Returns: True if the command was successful, False otherwise. """ try: os.rmdir(path) except OSError as e: L.error("failed to remove directory %s: %r", path, e) return False return True def subdirs(path): """Yield directory names under given path using os.scandir. See also: https://docs.python.org/3/library/os.html#os.scandir """ with os.scandir(path) as it: for entry in it: if not entry.name.startswith(".") and entry.is_dir(): yield entry.name def subfiles(path): """Yield file names under given path using os.scandir. See also: https://docs.python.org/3/library/os.html#os.scandir """ with os.scandir(path) as it: for entry in it: if not entry.name.startswith(".") and entry.is_file(): yield entry.name