Spaces:
Running
Running
| import os | |
| import warnings | |
| from enum import Enum | |
| from pathlib import Path | |
| from typing import List, Union | |
| try: | |
| from typing import Literal | |
| except ImportError: | |
| from typing_extensions import Literal | |
| def check_path_suffix(path_str: str, | |
| allowed_suffix: Union[str, List[str]] = '') -> bool: | |
| """Check whether the suffix of the path is allowed. | |
| Args: | |
| path_str (str): | |
| Path to check. | |
| allowed_suffix (List[str], optional): | |
| What extension names are allowed. | |
| Offer a list like ['.jpg', ',jpeg']. | |
| When it's [], all will be received. | |
| Use [''] then directory is allowed. | |
| Defaults to []. | |
| Returns: | |
| bool: | |
| True: suffix test passed | |
| False: suffix test failed | |
| """ | |
| if isinstance(allowed_suffix, str): | |
| allowed_suffix = [allowed_suffix] | |
| pathinfo = Path(path_str) | |
| suffix = pathinfo.suffix.lower() | |
| if len(allowed_suffix) == 0: | |
| return True | |
| if pathinfo.is_dir(): | |
| if '' in allowed_suffix: | |
| return True | |
| else: | |
| return False | |
| else: | |
| for index, tmp_suffix in enumerate(allowed_suffix): | |
| if not tmp_suffix.startswith('.'): | |
| tmp_suffix = '.' + tmp_suffix | |
| allowed_suffix[index] = tmp_suffix.lower() | |
| if suffix in allowed_suffix: | |
| return True | |
| else: | |
| return False | |
| class Existence(Enum): | |
| """State of file existence.""" | |
| FileExist = 0 | |
| DirectoryExistEmpty = 1 | |
| DirectoryExistNotEmpty = 2 | |
| MissingParent = 3 | |
| DirectoryNotExist = 4 | |
| FileNotExist = 5 | |
| def check_path_existence( | |
| path_str: str, | |
| path_type: Literal['file', 'dir', 'auto'] = 'auto', | |
| ) -> Existence: | |
| """Check whether a file or a directory exists at the expected path. | |
| Args: | |
| path_str (str): | |
| Path to check. | |
| path_type (Literal[, optional): | |
| What kind of file do we expect at the path. | |
| Choose among `file`, `dir`, `auto`. | |
| Defaults to 'auto'. path_type = path_type.lower() | |
| Raises: | |
| KeyError: if `path_type` conflicts with `path_str` | |
| Returns: | |
| Existence: | |
| 0. FileExist: file at path_str exists. | |
| 1. DirectoryExistEmpty: folder at path exists and. | |
| 2. DirectoryExistNotEmpty: folder at path_str exists and not empty. | |
| 3. MissingParent: its parent doesn't exist. | |
| 4. DirectoryNotExist: expect a folder at path_str, but not found. | |
| 5. FileNotExist: expect a file at path_str, but not found. | |
| """ | |
| path_type = path_type.lower() | |
| assert path_type in {'file', 'dir', 'auto'} | |
| pathinfo = Path(path_str) | |
| if not pathinfo.parent.is_dir(): | |
| return Existence.MissingParent | |
| suffix = pathinfo.suffix.lower() | |
| if path_type == 'dir' or\ | |
| path_type == 'auto' and suffix == '': | |
| if pathinfo.is_dir(): | |
| if len(os.listdir(path_str)) == 0: | |
| return Existence.DirectoryExistEmpty | |
| else: | |
| return Existence.DirectoryExistNotEmpty | |
| else: | |
| return Existence.DirectoryNotExist | |
| elif path_type == 'file' or\ | |
| path_type == 'auto' and suffix != '': | |
| if pathinfo.is_file(): | |
| return Existence.FileExist | |
| elif pathinfo.is_dir(): | |
| if len(os.listdir(path_str)) == 0: | |
| return Existence.DirectoryExistEmpty | |
| else: | |
| return Existence.DirectoryExistNotEmpty | |
| if path_str.endswith('/'): | |
| return Existence.DirectoryNotExist | |
| else: | |
| return Existence.FileNotExist | |
| def prepare_output_path(output_path: str, | |
| allowed_suffix: List[str] = [], | |
| tag: str = 'output file', | |
| path_type: Literal['file', 'dir', 'auto'] = 'auto', | |
| overwrite: bool = True) -> None: | |
| """Check output folder or file. | |
| Args: | |
| output_path (str): could be folder or file. | |
| allowed_suffix (List[str], optional): | |
| Check the suffix of `output_path`. If folder, should be [] or ['']. | |
| If could both be folder or file, should be [suffixs..., '']. | |
| Defaults to []. | |
| tag (str, optional): The `string` tag to specify the output type. | |
| Defaults to 'output file'. | |
| path_type (Literal[, optional): | |
| Choose `file` for file and `dir` for folder. | |
| Choose `auto` if allowed to be both. | |
| Defaults to 'auto'. | |
| overwrite (bool, optional): | |
| Whether overwrite the existing file or folder. | |
| Defaults to True. | |
| Raises: | |
| FileNotFoundError: suffix does not match. | |
| FileExistsError: file or folder already exists and `overwrite` is | |
| False. | |
| Returns: | |
| None | |
| """ | |
| if path_type.lower() == 'dir': | |
| allowed_suffix = [] | |
| exist_result = check_path_existence(output_path, path_type=path_type) | |
| if exist_result == Existence.MissingParent: | |
| warnings.warn( | |
| f'The parent folder of {tag} does not exist: {output_path},' + | |
| f' will make dir {Path(output_path).parent.absolute().__str__()}') | |
| os.makedirs( | |
| Path(output_path).parent.absolute().__str__(), exist_ok=True) | |
| elif exist_result == Existence.DirectoryNotExist: | |
| os.mkdir(output_path) | |
| print(f'Making directory {output_path} for saving results.') | |
| elif exist_result == Existence.FileNotExist: | |
| suffix_matched = \ | |
| check_path_suffix(output_path, allowed_suffix=allowed_suffix) | |
| if not suffix_matched: | |
| raise FileNotFoundError( | |
| f'The {tag} should be {", ".join(allowed_suffix)}: ' | |
| f'{output_path}.') | |
| elif exist_result == Existence.FileExist: | |
| if not overwrite: | |
| raise FileExistsError( | |
| f'{output_path} exists (set overwrite = True to overwrite).') | |
| else: | |
| print(f'Overwriting {output_path}.') | |
| elif exist_result == Existence.DirectoryExistEmpty: | |
| pass | |
| elif exist_result == Existence.DirectoryExistNotEmpty: | |
| if not overwrite: | |
| raise FileExistsError( | |
| f'{output_path} is not empty (set overwrite = ' | |
| 'True to overwrite the files).') | |
| else: | |
| print(f'Overwriting {output_path} and its files.') | |
| else: | |
| raise FileNotFoundError(f'No Existence type for {output_path}.') | |
| def check_input_path( | |
| input_path: str, | |
| allowed_suffix: List[str] = [], | |
| tag: str = 'input file', | |
| path_type: Literal['file', 'dir', 'auto'] = 'auto', | |
| ): | |
| """Check input folder or file. | |
| Args: | |
| input_path (str): input folder or file path. | |
| allowed_suffix (List[str], optional): | |
| Check the suffix of `input_path`. If folder, should be [] or ['']. | |
| If could both be folder or file, should be [suffixs..., '']. | |
| Defaults to []. | |
| tag (str, optional): The `string` tag to specify the output type. | |
| Defaults to 'output file'. | |
| path_type (Literal[, optional): | |
| Choose `file` for file and `directory` for folder. | |
| Choose `auto` if allowed to be both. | |
| Defaults to 'auto'. | |
| Raises: | |
| FileNotFoundError: file does not exists or suffix does not match. | |
| Returns: | |
| None | |
| """ | |
| if path_type.lower() == 'dir': | |
| allowed_suffix = [] | |
| exist_result = check_path_existence(input_path, path_type=path_type) | |
| if exist_result in [ | |
| Existence.FileExist, Existence.DirectoryExistEmpty, | |
| Existence.DirectoryExistNotEmpty | |
| ]: | |
| suffix_matched = \ | |
| check_path_suffix(input_path, allowed_suffix=allowed_suffix) | |
| if not suffix_matched: | |
| raise FileNotFoundError( | |
| f'The {tag} should be {", ".join(allowed_suffix)}:' + | |
| f'{input_path}.') | |
| else: | |
| raise FileNotFoundError(f'The {tag} does not exist: {input_path}.') |