Source code for shared.file_directory_ops

#! /usr/bin/env python3.10
import os
import shutil
import sys
from contextlib import contextmanager
from os import path

from shared.command_execution import execute_command
from shared.logging import setup_logger

logger = setup_logger(__name__.split('.')[-1])


[docs] @contextmanager def change_directory(new_directory): """Context manager to change the working directory temporarily.""" current_directory = os.getcwd() os.chdir(new_directory) try: yield finally: os.chdir(current_directory)
[docs] class change_directory_manager: def __init__(self, new_dir): self.new_dir = new_dir self.original_dir = os.getcwd() def __enter__(self): os.chdir(self.new_dir) def __exit__(self, type, value, traceback): os.chdir(self.original_dir)
[docs] def copy_to(input, output, include_directories=True): """ Copies a file to a new location. :param input: The path of the file to be copied. :param output: The path to copy the file to. :type input: str :type output: str """ cp_flags = '-r' if include_directories else '' try: logger.info(f"Copying: {input} to {output}") execute_command(f'cp {cp_flags} {input} {output}') except Exception as e: logger.info("Error copying file: " + str(e))
[docs] def delete_files_or_directories(*paths, ignore_errors=False): """ Deletes the files or directories specified by the given paths. :param paths: The paths of files or directories to be deleted. :type paths: str :raises FileNotFoundError: If the given path does not exist. Usage:: delete_files_or_directories('/path/to/file', '/path/to/directory') # Deletes specified file and directory """ for paths in paths: try: if os.path.isfile(paths): os.remove(paths) # Delete the file elif os.path.isdir(paths): shutil.rmtree(paths) # Delete the directory and its contents else: if not ignore_errors: raise FileNotFoundError(f"Path '{paths}' does not exist.") except Exception as e: if ignore_errors: logger.warning(f"Error deleting file or directory: {e}") else: logger.error(f"Error deleting file or directory: {e}") raise e
[docs] def find(filename, *args): """ Searches for a file in multiple directories. :param filename: The name of the file to search for. :param args: The directories to search in. :type filename: str :type args: str :return: The first directory where the file was found. :rtype: str """ directories = [*args] foundfile = False for searchdirectory in directories: if path.exists(searchdirectory + "/" + filename): if searchdirectory == ".": logger.info(f"Found {filename} inside the current directory") else: logger.info(f"Found {filename} inside {searchdirectory} directory") foundfile = True return searchdirectory # if not exited by now it means that the file was not found in any of the given directories thus rise error if foundfile != True: logger.info(f'{filename} not found inside {directories} directories') logger.info("exiting...") sys.exit()
[docs] def file_len(file_path): """ Returns the number of lines in a file. :param file_path: The path to the file. :type file_path: str :return: The number of lines in the file. :rtype: int """ with open(file_path) as f: for i, l in enumerate(f): pass return i + 1
[docs] def file_lenth(filename): """ Returns the number of lines in a file. :param filename: The path to the file. :type filename: str :return: The number of lines in the file. :rtype: int """ with open(filename) as fin: for i, l in enumerate(fin): pass return i + 1
[docs] def get_all_files_in_directory(directory): """ Returns all files in a directory. :param directory: The path to the directory. :type directory: str :return: All files in the directory. :rtype: list """ return [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
[docs] def get_folders_in_directory(directory): """ Returns the folders in a directory. :param directory: The path to the directory. :type directory: str :return: The folders in the directory. :rtype: list """ return [f for f in os.listdir(directory) if os.path.isdir(os.path.join(directory, f))]
[docs] def make_directory(output_dir: str, delete_if_exists: bool = False): """ Creates a directory at the specified path. If the directory already exists and 'delete_if_exists' is True, it deletes the existing directory before creating a new one. :param output_dir: The path where the directory is to be created. :type output_dir: str :param delete_if_exists: If True, deletes the directory at 'output_dir' if it exists. Default is False. :type delete_if_exists: bool Usage:: make_directory('/path/to/directory', delete_if_exists=True) # Creates directory, deleting existing one if necessary """ if delete_if_exists and os.path.exists(output_dir): delete_files_or_directories(output_dir) os.makedirs(output_dir, exist_ok=True) # Create the directory
[docs] def uniquify(filepath): """ Makes a file path unique by appending a counter to the file name. :param filepath: The initial file path. :type filepath: str :return: A unique file path. :rtype: str """ filename, extension = path.splitext(filepath) logger.info(filename, extension) counter = 1 while path.exists(filepath): filepath = f'{filename}_{counter}{extension}' logger.info(counter) counter += 1 return filepath
[docs] def validate_directory_and_get_full_path(path): path = path.strip() if not os.path.exists(path): raise ValueError(f'{path} does not exist.') if not os.path.isdir(path): raise ValueError(f'{path} is not a directory.') return os.path.abspath(path)