Source code for wtforglib.dirs

"""Top-level module for wtforglib Library."""

import os
from datetime import datetime
from pathlib import Path
from tempfile import TemporaryFile
from typing import Optional, Tuple

from wtforglib.kinds import Fspec


[docs] def ensure_directory(target: Fspec, perm: int = 0o755) -> bool: """Creates a directory if it doesn't exist. Parameters ---------- target : Fspec The path to the target directory perm : int Optional The mode to use if creation needed Returns ------- bool True if directory exists Raises ------ NotADirectoryError if target exists, but not a directory """ dp = Path(target) if dp.is_dir(): return True if dp.exists(): raise NotADirectoryError( 'Pathname "{0}" is not a directory.'.format(str(target)), ) dp.mkdir(mode=perm, parents=True) return True
def _verify_directory_write(dpath: Fspec) -> Optional[Exception]: """Verify that the given directory is writable. Parameters ---------- dpath : Fspec Pathlike object specifying the directory Returns ------- Optional[Exception] The exception when caught """ error: Optional[Exception] = None try: temp_file = TemporaryFile(dir=dpath) temp_file.close() except Exception as ex: error = ex return error
[docs] def verify_directory(dspec: Fspec, ex: bool = False) -> Tuple[bool, str]: """Verify that a directory exits and is writable. Parameters ---------- dspec : Fspec Pathlike object specifying the directory ex : bool, optional When True exceptions are raised, by default False Returns ------- Tuple[bool, str] When ex is False the status is returned Raises ------ error NotADirectoryError, FileNotFoundError or other exception is raised on failure when ex is True """ dpath = Path(dspec) target_path_str = str(dpath) error: Optional[Exception] if dpath.exists(): if dpath.is_dir(): error = _verify_directory_write(dpath) else: error = NotADirectoryError( "'{0}' is not a directory".format(target_path_str), ) else: error = FileNotFoundError("Directory not found: {0}".format(dpath)) if error: if ex: raise error return error is None, str(error)
[docs] def delete_empty_dirs(path: Fspec) -> int: # noqa: WPS210 """Delete empty directories in the given path recursively. Parameters ---------- path : Fspec The given path to walk through Returns ------- int Number of directories deleted """ removed = 0 for root, dirs, _files in os.walk(path, topdown=False): for directory in dirs: dirpath = os.path.join(root, directory) if not os.listdir(dirpath): os.rmdir(dirpath) removed += 1 return removed
# function to perform delete operation based on condition
[docs] def prune_older_files(path: Fspec, max_days: int) -> int: # noqa: WPS210 """Delete files recursively in path if they are older than days. Parameters ---------- path : Fspec Path to the folder to prune max_days : int Number of days to keep Returns ------- int Number of files pruned """ removed = 0 # loop to check all files one by one # os.walk returns 3 things: # - current path, # - files in the current path, and # - folders in the current path for root, _dirs, files in os.walk(path, topdown=True): for fn in files: # temp variable to store path of the file file_path = os.path.join(root, fn) # get the timestamp, when the file was modified timestamp_of_file_modified = os.path.getmtime(file_path) # convert timestamp to datetime modification_date = datetime.fromtimestamp(timestamp_of_file_modified) # find the number of days when the file was modified number_of_days = (datetime.now() - modification_date).days if number_of_days > max_days: # remove file os.remove(file_path) removed += 1 return removed
[docs] def prune_older_files_empty_dir(path: Fspec, max_days: int) -> int: """Delete files recursively in path if they are older than days, delete empty dirs. Parameters ---------- path : Fspec Path to the folder to prune max_days : int Number of days to keep Returns ------- int Number of items removed """ removed = prune_older_files(path, max_days) removed += delete_empty_dirs(path) return removed