From 8c431c7d81d1331b18ea887e9fb9ed7d0659b817 Mon Sep 17 00:00:00 2001 From: I-Al-Istannen Date: Mon, 20 Apr 2020 12:08:52 +0200 Subject: [PATCH] Add a simple temporary folder --- .gitignore | 2 ++ PFERD/__init__.py | 12 ++++++---- PFERD/temp_folder.py | 56 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 PFERD/temp_folder.py diff --git a/.gitignore b/.gitignore index 85b0ead..7e2a4e6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ __pycache__/ .venv/ .mypy_cache/ .tmp/ +.env +.vscode diff --git a/PFERD/__init__.py b/PFERD/__init__.py index b615088..18ec1c0 100644 --- a/PFERD/__init__.py +++ b/PFERD/__init__.py @@ -1,18 +1,20 @@ import logging -from .ilias import * -from .utils import * +# from .ilias import * +# from .utils import * +from .temp_folder import * STYLE = "{" FORMAT = "[{levelname:<7}] {message}" DATE_FORMAT = "%F %T" FORMATTER = logging.Formatter( - fmt=FORMAT, - datefmt=DATE_FORMAT, - style=STYLE, + fmt=FORMAT, + datefmt=DATE_FORMAT, + style=STYLE, ) + def enable_logging(name: str = "PFERD", level: int = logging.INFO) -> None: handler = logging.StreamHandler() handler.setFormatter(FORMATTER) diff --git a/PFERD/temp_folder.py b/PFERD/temp_folder.py new file mode 100644 index 0000000..ad4da67 --- /dev/null +++ b/PFERD/temp_folder.py @@ -0,0 +1,56 @@ +"""Helper functions and classes for temporary folders.""" + +from typing import Optional, Type +from types import TracebackType + +import pathlib +import shutil + + +class TempFolder(): + """A temporary folder that can create files or nested temp folders.""" + + def __init__(self, path: pathlib.Path): + """Create a new temporary folder for the given path.""" + self.counter = 0 + self.path = path + + def __str__(self) -> str: + """Format the folder as a string.""" + return f"Folder at {self.path}" + + def __enter__(self) -> 'TempFolder': + """Context manager entry function.""" + return self + + def __exit__(self, + type: Optional[Type[BaseException]], + value: Optional[BaseException], + traceback: Optional[TracebackType]) -> Optional[bool]: + """Context manager exit function. Calls cleanup().""" + self.cleanup() + return None + + def new_file(self) -> pathlib.Path: + """Return a unique path inside the folder, but don't create a file.""" + name = f"tmp-{self.__inc_and_get_counter():03}" + return self.path.joinpath(name) + + def new_folder(self, prefix: str = "") -> 'TempFolder': + """Create a new nested temporary folder and return its path.""" + name = f"{prefix if prefix else 'tmp'}-{self.__inc_and_get_counter():03}" + + sub_path = self.path.joinpath(name) + sub_path.mkdir(parents=True) + + return TempFolder(sub_path) + + def cleanup(self) -> None: + """Delete this folder and all contained files.""" + shutil.rmtree(self.path.absolute()) + + def __inc_and_get_counter(self) -> int: + """Get and increment the counter by one.""" + counter = self.counter + self.counter += 1 + return counter