From 067efe8a88cc7a0c3cbb6d518de87e3ba74ee0c9 Mon Sep 17 00:00:00 2001 From: Adrian Epifanio Rodriguez Hernandez Date: Sat, 29 Mar 2025 09:15:06 +0000 Subject: [PATCH] FileManager Module --- modules/errors/error_handler.py | 13 +-- modules/files/__init__.py | 0 modules/files/file_manager.py | 180 ++++++++++++++++++++++++++++++++ modules/files/requirements.txt | 0 requirements.txt | 1 + tests/test_date.py | 4 +- tests/test_file_manager.py | 51 +++++++++ tests/tmp/sample.txt | 1 + 8 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 modules/files/__init__.py create mode 100644 modules/files/file_manager.py create mode 100644 modules/files/requirements.txt create mode 100644 tests/test_file_manager.py create mode 100644 tests/tmp/sample.txt diff --git a/modules/errors/error_handler.py b/modules/errors/error_handler.py index 587c0c1..6b37c65 100644 --- a/modules/errors/error_handler.py +++ b/modules/errors/error_handler.py @@ -7,7 +7,7 @@ # @Email: adrianepi@gmail.com # @GitHub: https://github.com/AdrianEpi # @Last Modified by: Adrian Epifanio -# @Last Modified time: 2025-03-28 17:13:33 +# @Last Modified time: 2025-03-29 08:25:00 # @Description: This file describes an ErrorHandler @@ -21,20 +21,21 @@ class ErrorHandler: error_str = '' @classmethod - def log_error(cls, error_message: str, exception: Exception): + def log_error(cls, error_message, exception: Exception): """ Logs an error. :param cls: The cls :type cls: ErrorHandler :param error_message: The error message - :type error_message: str + :type error_message: str / None :param exception: The exception :type exception: Exception """ - error_type = type(exception).__name__ - cls.error_str += f'\n\n{datetime.now()}: {error_message} - {error_type}\n' - cls.error_str += f'{traceback.format_exc()}\n' + if error_message != None and error_message != '': + error_type = type(exception).__name__ + cls.error_str += f'\n\n{datetime.now()}: {error_message} - {error_type}\n' + cls.error_str += f'{traceback.format_exc()}\n' @classmethod diff --git a/modules/files/__init__.py b/modules/files/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/modules/files/file_manager.py b/modules/files/file_manager.py new file mode 100644 index 0000000..b5fd0a4 --- /dev/null +++ b/modules/files/file_manager.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +# @Proyect: Personal +# @Author: Adrian Epifanio +# @File: file_manager.py +# @Author: Adrian Epifanio +# @Date: 2025-03-29 08:04:19 +# @Email: adrianepi@gmail.com +# @GitHub: https://github.com/AdrianEpi +# @Last Modified by: Adrian Epifanio +# @Last Modified time: 2025-03-29 09:12:34 +# @Description: This file describes a file manager. Contains all +# the necessary methods to work with files and directories. + + +import os +import shutil + + +class FileManager: + """ + This class describes a file manager, it cotains all the static methods + needed to work with files, folders and directories. + """ + + + @staticmethod + def file_exist(f_name: str) -> bool: + """ + Checks if a file exists + + :param f_name: The file name + :type f_name: str + + :returns: True if the file exists, false otherwise + :rtype: bool + """ + return os.path.isfile(f_name) + + + @staticmethod + def create_file(f_name: str, content = '', path = '', f_extension = ''): + """ + Creates a file. + + :param f_name: The file name + :type f_name: str + :param content: The file content + :type content: str + :param path: The path + :type path: str + :param f_extension: The file extension + :type f_extension: str + """ + f = path + f_name + f_extension + try: + with open(f, 'w') as file: + file.write(content) + except Exception as e: + return f"Error while creating '{f_name}': {e}" + + @staticmethod + def delete_file(file_path: str): + """ + Deletes a file if it exists + + :param file_path: The file path + :type file_path: str + """ + if os.path.isfile(file_path): + os.remove(file_path) + + + @staticmethod + def move_file(file_path: str, destination_path: str) -> str: + """ + Moves a file to another dir + + :param file_path: The file path + :type file_path: str + :param destination_path: The destination path + :type destination_path: str + + :returns: String with the status. + :rtype: str + """ + try: + os.rename(file_path, destination_path) + return f"File moved from '{file_path}' to '{destination_path}'." + except FileNotFoundError: + return f"Error: The file '{file_path}' does not exist." + except PermissionError: + return f"Error: Permission denied for moving '{file_path}' to '{destination_path}'." + except Exception as e: + return f"Error: {e}" + + + @staticmethod + def copy_file(source_file: str, destination: str) -> str: + """ + Copy a file into the new destination + + :param source_file: The source file + :type source_file: str + :param destination: The destination + :type destination: str + + :returns: New path with the file + :rtype: str + """ + try: + file_name = os.path.basename(source_file) + destination_file = os.path.join(destination, file_name) + shutil.copy(source_file, destination_file) + return destination_file + except Exception as e: + if not os.path.exists(source_file): + return f"Error, file '{source_file}' does not exist." + + if not os.path.exists(destination): + return f"Error, dir '{destination}' does not exist." + return f"Error: {e}" + + + @staticmethod + def read_file(file_path: str) -> str: + """ + Reads a file. + + :param file_path: The file name + :type file_path: str + + :returns: Data readed from the file + :rtype: str + """ + try: + with open(file_path, 'r', encoding='utf-8') as file: + content = file.read() + return content + except FileNotFoundError: + return f"Error 404, '{file_path}' not found." + except Exception as e: + return f"Unexpected error while attempting to read file '{file_path}', with error code: {e}" + + + @staticmethod + def read_lines(file_path: str) -> list: + """ + Reads the lines in a file and creates a list from them. + + :param file_path: The file name + :type file_path: str + + :returns: List with one readed line per item in the list + :rtype: list + """ + try: + with open(file_path, 'r', encoding='utf-8') as file: + content = [line.strip() for line in file.readlines() if line.strip()] + return content + except FileNotFoundError: + return f"Error 404, '{file_path}' not found." + except Exception as e: + return f"Unexpected error while attempting to read lines in file '{file_path}', with error code: {e}" + + + @staticmethod + def add_line_to_file(file_path: str, line: str): + """ + Adds a line to file. + + :param file_path: The file path + :type file_path: str + :param line: The line + :type line: str + """ + try: + with open(file_path, 'a', encoding='utf-8') as file: + file.write('\n' + line) + except Exception as e: + return f"Error while attepmting to add line to file.\nFile Path: '{file_path}'\nLine: {line}\nError: {e}" \ No newline at end of file diff --git a/modules/files/requirements.txt b/modules/files/requirements.txt new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index a3afcab..4f3d834 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ sphinx>=8.1.3 # Documentation sphinx-rtd-theme>=3.0.2 # Github Pages Documentation -r modules/datetime/requirements.txt +-r modules/files/requirements.txt -r modules/errors/requirements.txt \ No newline at end of file diff --git a/tests/test_date.py b/tests/test_date.py index 10d22cd..1fe23a7 100644 --- a/tests/test_date.py +++ b/tests/test_date.py @@ -7,8 +7,8 @@ # @Email: adrianepi@gmail.com # @GitHub: https://github.com/AdrianEpi # @Last Modified by: Adrian Epifanio -# @Last Modified time: 2025-03-28 17:24:09 -# @Description: ... +# @Last Modified time: 2025-03-29 08:14:24 +# @Description: Tests for modules/datetime/date.py diff --git a/tests/test_file_manager.py b/tests/test_file_manager.py new file mode 100644 index 0000000..f2f560f --- /dev/null +++ b/tests/test_file_manager.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# @Proyect: Personal +# @Author: Adrian Epifanio +# @File: test_file_manager.py +# @Author: Adrian Epifanio +# @Date: 2025-03-29 08:13:50 +# @Email: adrianepi@gmail.com +# @GitHub: https://github.com/AdrianEpi +# @Last Modified by: Adrian Epifanio +# @Last Modified time: 2025-03-29 09:12:42 +# @Description: Tests for modules/files/file_manager.py + + +from modules.files.file_manager import FileManager + +import pytest + +def test_file_exist(): + assert(FileManager.file_exist(f_name='tests/tmp/sample.txt') == True) + assert(FileManager.file_exist(f_name='tests/tmp/NonExistingFile.txt') == False) + +def test_create_file(): + FileManager.create_file(f_name='tmp_file', content='Lorem Ipsum\nIpsumLorem', path='tests/tmp/', f_extension='.py') + assert(FileManager.file_exist(f_name='tests/tmp/tmp_file.py') == True) + assert('Error while creating \'tmp_file\'' in FileManager.create_file(f_name='tmp_file', path='tests/NonExistingPath/')) + +def test_move_file(): + assert(FileManager.move_file(file_path='tests/tmp/sample.txt', destination_path='tests/sample.txt') == "File moved from 'tests/tmp/sample.txt' to 'tests/sample.txt'.") + assert(FileManager.move_file(file_path='tests/tmp/sample.txt', destination_path='tests/sample.txt') == "Error: The file 'tests/tmp/sample.txt' does not exist.") + assert(FileManager.move_file(file_path='tests/sample.txt', destination_path='tests/tmp/sample.txt') == "File moved from 'tests/sample.txt' to 'tests/tmp/sample.txt'.") + assert('Error: ' in FileManager.move_file(file_path='tests/NonExistingPath/sample.txt', destination_path='tests/sample.txt')) + +def test_copy_file(): + assert(FileManager.copy_file(source_file='tests/tmp/sample.txt', destination='tests/') == 'tests/sample.txt') + FileManager.delete_file(file_path='tests/sample.txt') + assert(FileManager.copy_file(source_file='tests/NonExistingPath/sample.txt', destination='tests/') == "Error, file 'tests/NonExistingPath/sample.txt' does not exist.") + assert(FileManager.copy_file(source_file='tests/tmp/sample.txt', destination='tests/NonExistingPath/') == "Error, dir 'tests/NonExistingPath/' does not exist.") + +def test_read_file(): + assert(FileManager.read_file(file_path='tests/tmp/tmp_file.py') == 'Lorem Ipsum\nIpsumLorem') + assert(FileManager.read_file(file_path='tests/tmp/NonExistingFile') == "Error 404, 'tests/tmp/NonExistingFile' not found.") + +def test_read_lines(): + assert(FileManager.read_lines(file_path='tests/tmp/tmp_file.py') == ['Lorem Ipsum', 'IpsumLorem']) + assert(FileManager.read_lines(file_path='tests/tmp/NonExistingFile') == "Error 404, 'tests/tmp/NonExistingFile' not found.") + +def test_add_line_to_file(): + FileManager.add_line_to_file(file_path='tests/tmp/tmp_file.py', line='NEW LINE') + assert(FileManager.read_lines(file_path='tests/tmp/tmp_file.py') == ['Lorem Ipsum', 'IpsumLorem', 'NEW LINE']) + # Delete tmp file + FileManager.delete_file(file_path='tests/tmp/tmp_file.py') \ No newline at end of file diff --git a/tests/tmp/sample.txt b/tests/tmp/sample.txt new file mode 100644 index 0000000..4ec3196 --- /dev/null +++ b/tests/tmp/sample.txt @@ -0,0 +1 @@ +DO NOT DELETE THIS FILE \ No newline at end of file