diff --git a/setup.py b/setup.py index 18e805e..6af9841 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="way3", - version="0.0.29", + version="1.0.1", author="aboutmydreams", author_email="aboutmydreams@163.com", description="Simplified file path management for Python developers", diff --git a/tests/test_file_op.py b/tests/test_file_op.py index 5a022b4..d924412 100644 --- a/tests/test_file_op.py +++ b/tests/test_file_op.py @@ -1,4 +1,14 @@ -from way3 import create_file, delete_file +from way3 import ( + create_file, + delete_file, + read_file, + read_line, + insert_to_file, + modify_line, + replace_string_in_file, + replace_string_in_line, + delete_line, +) import unittest import os @@ -22,3 +32,67 @@ def test_delete_file(self): self.assertEqual( os.path.isfile("test.txt"), False, "result fail: expected False" ) + + def test_read_file(self): + file_content = "Hello\nWorld!" + create_file("./test.txt", file_content) + info = read_file("test.txt") + self.assertEqual(info.content, file_content) + self.assertEqual(info.length, len(file_content)) + self.assertEqual(info.lines, 2) + self.assertEqual(info.file_type, ".txt") + delete_file("test.txt") + + def test_read_line(self): + file_content = "Hello\nWorld!" + create_file("./test.txt", file_content) + line = read_line("test.txt", 1) + self.assertEqual(line, "Hello\n") + line = read_line("test.txt", 2) + self.assertEqual(line, "World!") + delete_file("test.txt") + + def test_insert_to_file(self): + file_content = "Hello\nWorld!" + create_file("./test.txt", file_content) + insert_to_file("./test.txt", "Python\n", 1) + with open("./test.txt", "r") as f: + lines = f.readlines() + self.assertEqual(lines[1], "Python\n") + delete_file("test.txt") + + def test_modify_line(self): + file_content = "Hello\nWorld!" + create_file("./test.txt", file_content) + modify_line("./test.txt", "Python\n", 0) + with open("./test.txt", "r") as f: + lines = f.readlines() + self.assertEqual(lines[0], "Python\n") + delete_file("test.txt") + + def test_replace_string_in_file(self): + file_content = "Hello, Python!" + create_file("./test.txt", file_content) + replace_string_in_file("./test.txt", "Python", "World") + with open("./test.txt", "r") as f: + file_content = f.read() + self.assertEqual(file_content, "Hello, World!") + delete_file("test.txt") + + def test_replace_string_in_line(self): + file_content = "Hello,\nPython!" + create_file("./test.txt", file_content) + replace_string_in_line("./test.txt", 1, "Python", "World") + with open("./test.txt", "r") as f: + lines = f.readlines() + self.assertEqual(lines[1], "World!") + delete_file("test.txt") + + def test_delete_line(self): + file_content = "Hello,\nPython!" + create_file("./test.txt", file_content) + delete_line("./test.txt", 1) + with open("./test.txt", "r") as f: + lines = f.readlines() + self.assertEqual(len(lines), 1) + delete_file("test.txt") diff --git a/way3/__init__.py b/way3/__init__.py index 68b196a..8510da3 100644 --- a/way3/__init__.py +++ b/way3/__init__.py @@ -4,6 +4,11 @@ from .file_op.create_file import create_file as create_file # noqa: E402 from .file_op.create_file import add_to_file_end as add_to_file_end # noqa: E402 from .file_op.create_file import delete_file as delete_file # noqa: E402 +from .file_op.edit import insert_to_file as insert_to_file # noqa: E402 +from .file_op.edit import modify_line as modify_line # noqa: E402 +from .file_op.edit import delete_line as delete_line # noqa: E402 +from .file_op.edit import replace_string_in_line as replace_string_in_line # noqa: E402 +from .file_op.edit import replace_string_in_file as replace_string_in_file # noqa: E402 # File Find @@ -27,3 +32,7 @@ from .folder_op.create_folder import create_directory as create_directory # noqa: E402 from .folder_op.create_folder import rename_directory as rename_directory # noqa: E402 from .folder_op.create_folder import delete_directory as delete_directory # noqa: E402 + +## read file +from .file_op.read import read_file as read_file # noqa: E402 +from .file_op.read import read_line as read_line # noqa: E402 diff --git a/way3/file_op/edit.py b/way3/file_op/edit.py new file mode 100644 index 0000000..88b2673 --- /dev/null +++ b/way3/file_op/edit.py @@ -0,0 +1,158 @@ +import os +import logging +from typing import Union + + +def insert_to_file( + file_name: str, + content: str, + line_number: int = 0, + file_path: Union[str, os.PathLike] = ".", + create_if_not_exist: bool = True, +) -> tuple[bool, str]: + if file_name.startswith(os.sep): + file_path = file_name + else: + file_path = os.path.join(file_path, file_name) + + if not create_if_not_exist and not os.path.exists(file_path): + logging.warning("File does not exist: " + file_path) + return False, f"Failure, File does not exist: {file_path}" + + with open(file_path, "r") as file: + lines = file.readlines() + + if line_number < 0: + line_number += len(lines) + 1 + + lines.insert(line_number, content + "\n") + + with open(file_path, "w") as file: + file.writelines(lines) + + return True, os.path.abspath(file_path) + + +def modify_line( + file_name: str, + content: str, + line_number: int, + file_path: Union[str, os.PathLike] = ".", +) -> tuple[bool, str]: + if file_name.startswith(os.sep): + file_path = file_name + else: + file_path = os.path.join(file_path, file_name) + + if not os.path.exists(file_path): + logging.warning("File does not exist: " + file_path) + return False, f"Failure, File does not exist: {file_path}" + + with open(file_path, "r") as file: + lines = file.readlines() + + if line_number < 0: + line_number += len(lines) + + if abs(line_number) > len(lines): + logging.warning("Line number exceeds the number of lines in the file.") + return False, "Failure, Line number exceeds the number of lines in the file." + + lines[line_number] = content + "\n" + + with open(file_path, "w") as file: + file.writelines(lines) + + return True, os.path.abspath(file_path) + + +def delete_line( + file_name: str, + line_number: int, + file_path: Union[str, os.PathLike] = ".", +) -> tuple[bool, str]: + if file_name.startswith(os.sep): + file_path = file_name + else: + file_path = os.path.join(file_path, file_name) + + if not os.path.exists(file_path): + logging.warning("File does not exist: " + file_path) + return False, f"Failure, File does not exist: {file_path}" + + with open(file_path, "r") as file: + lines = file.readlines() + + if line_number < 0: + line_number += len(lines) + + if abs(line_number) > len(lines): + logging.warning("Line number exceeds the number of lines in the file.") + return False, "Failure, Line number exceeds the number of lines in the file." + + del lines[line_number] + + with open(file_path, "w") as file: + file.writelines(lines) + + return True, os.path.abspath(file_path) + + +def replace_string_in_file( + file_name: str, + old_string: str, + new_string: str, + file_path: Union[str, os.PathLike] = ".", +) -> tuple[bool, str]: + if file_name.startswith(os.sep): + file_path = file_name + else: + file_path = os.path.join(file_path, file_name) + + if not os.path.exists(file_path): + logging.warning("File does not exist: " + file_path) + return False, f"Failure, File does not exist: {file_path}" + + with open(file_path, "r") as file: + file_content = file.read() + + file_content = file_content.replace(old_string, new_string) + + with open(file_path, "w") as file: + file.write(file_content) + + return True, os.path.abspath(file_path) + + +def replace_string_in_line( + file_name: str, + line_number: int, + old_string: str, + new_string: str, + file_path: Union[str, os.PathLike] = ".", +) -> tuple[bool, str]: + if file_name.startswith(os.sep): + file_path = file_name + else: + file_path = os.path.join(file_path, file_name) + + if not os.path.exists(file_path): + logging.warning("File does not exist: " + file_path) + return False, f"Failure, File does not exist: {file_path}" + + with open(file_path, "r") as file: + lines = file.readlines() + + if line_number < 0: + line_number += len(lines) + + if abs(line_number) > len(lines): + logging.warning("Line number exceeds the number of lines in the file.") + return False, "Failure, Line number exceeds the number of lines in the file." + + lines[line_number] = lines[line_number].replace(old_string, new_string) + + with open(file_path, "w") as file: + file.writelines(lines) + + return True, os.path.abspath(file_path) diff --git a/way3/file_op/read.py b/way3/file_op/read.py new file mode 100644 index 0000000..8cb1405 --- /dev/null +++ b/way3/file_op/read.py @@ -0,0 +1,47 @@ +from typing import Union, NamedTuple +import os +import logging + + +class FileInfo(NamedTuple): + content: str + length: int + lines: int + file_type: str + + +def read_file(file_name: str, file_path: Union[str, os.PathLike] = ".") -> FileInfo: + if file_name.startswith(os.sep): + file_path = file_name + else: + file_path = os.path.join(file_path, file_name) + + if not os.path.exists(file_path): + logging.warning("File does not exist: " + file_path) + return FileInfo(content="", length=0, lines=0, file_type="") + + with open(file_path, "r") as file: + content = file.read() + length = len(content) + lines = content.count("\n") + 1 + file_type = os.path.splitext(file_path)[1] + + return FileInfo(content=content, length=length, lines=lines, file_type=file_type) + + +def read_line( + file_name: str, line_number: int, file_path: Union[str, os.PathLike] = "." +) -> str: + if file_name.startswith(os.sep): + file_path = file_name + else: + file_path = os.path.join(file_path, file_name) + + if not os.path.exists(file_path): + logging.warning("File does not exist: " + file_path) + return "" + + with open(file_path, "r") as file: + for _ in range(line_number - 1): + file.readline() + return file.readline()