123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- from pathlib import Path
- import re
- class OverwriteError(Exception):
- pass
- def overwrite_protection(path: Path) -> None:
- if path.is_file():
- raise OverwriteError(f'File {path} already exists and should not be overwritten.')
- if path.is_dir():
- raise OverwriteError(f'Directory {path} already exists and should not be overwritten.')
- def rm_directory(path: Path) -> None:
- """Removes a directory with its entire content."""
- for child in path.iterdir():
- if child.is_file():
- child.unlink()
- else:
- rm_directory(child)
- path.rmdir()
- def recursive_dir_empty(path: Path, ignore_top_level_files=False) -> bool:
- """Check if the directory is empty."""
- if not path.exists():
- return True
- # Check if path is empty
- has_next = next(path.iterdir(), None)
- if has_next is None:
- return True
- # Iterate over items in dir_path
- for item in path.iterdir():
- if item.is_dir():
- # Recursively check if subdirectory is empty or contains only empty subdirectories
- if not recursive_dir_empty(item, ignore_top_level_files=False): # files in subdirectories are never allowed
- return False
- if item.is_file() and not ignore_top_level_files:
- return False
- return True
- def split_base_and_num(name: str, sep: str, no_num_return=0):
- separated = str(name).split(sep)
- try:
- num = int(separated[-1])
- return sep.join(separated[:-1]), num
- except ValueError:
- return sep.join(separated), no_num_return
- def get_unique_filename(file_path: Path) -> Path:
- # Get the base name and the extension
- ext = file_path.suffix # Get the file extension (e.g., .dat)
- base_name, current_suffix = split_base_and_num(file_path.stem, '_', no_num_return=0)
- directory = file_path.parent
- existing_files = list(directory.glob(f"{base_name}_*{ext}"))
- # Extract all existing suffixes (numbers) and find the highest one
- suffixes = []
- for file in existing_files:
- suffix_part = file.stem[len(base_name) + 1:] # Skip base name and underscore
- if suffix_part.isdigit():
- suffixes.append(int(suffix_part))
- # Find the next available suffix
- if suffixes:
- new_suffix = max(suffixes) + 1
- else:
- new_suffix = 1 # Start with _1 if no suffixes are found
- new_file_name = f"{base_name}_{new_suffix}{ext}"
- return directory / new_file_name
- def new_folder(folder_name: Path, sep='_', mkdir: bool = True) -> Path:
- """Create a new folder based on the given folder_name with unique (sequential) number added in the end."""
- folder_name = folder_name.resolve()
- if folder_name.is_file():
- raise NameError(f'{folder_name} is not a directory.')
- parent = folder_name.parent
- base_str, num = split_base_and_num(folder_name.name, sep=sep, no_num_return=0)
- pattern = re.compile(rf"^{base_str}{sep}\d+$")
- all_directory_nums = []
- for folder in parent.glob(f'{base_str}*'):
- if folder.is_dir() and pattern.match(folder.name):
- _, dir_num = split_base_and_num(folder.name, sep=sep, no_num_return=0)
- all_directory_nums.append(dir_num)
- try:
- max_num = max(all_directory_nums)
- except ValueError: # if all_directory_nums is empty (i.e. no file with such name exists)
- max_num = num
- new_folder_name = parent.joinpath(base_str + sep + str(max_num))
- if new_folder_name.exists(): # and not recursive_dir_empty(new_folder_name, ignore_top_level_files=ignore_files):
- new_folder_name = parent.joinpath(base_str + sep + str(max_num + 1))
- if mkdir:
- new_folder_name.mkdir(parents=True, exist_ok=True)
- return new_folder_name
- def new_folder_with_number(folder_name: Path, number: int, sep='_') -> Path:
- folder_name = folder_name.resolve()
- if folder_name.is_file():
- raise NameError(f'{folder_name} is not a directory.')
- parent = folder_name.parent
- base_str, num = split_base_and_num(folder_name.name, sep=sep, no_num_return=0)
- new_folder_name = parent.joinpath(base_str + sep + str(number))
- new_folder_name.mkdir(parents=True, exist_ok=True)
- return new_folder_name
|