From 5fbbb0f54a3d09138e03e3adca25edd42d0f5fe1 Mon Sep 17 00:00:00 2001 From: Nissy0409 Date: Tue, 11 Jun 2024 18:27:50 +0900 Subject: [PATCH] Add a mode to judge FileRename Class without distinguishing file extensions --- cliboa/scenario/transform/file.py | 66 +++++++++++------- cliboa/test/scenario/transform/test_file.py | 77 ++++++++++++++++++++- docs/modules/file_rename.md | 42 ++++++++--- 3 files changed, 147 insertions(+), 38 deletions(-) diff --git a/cliboa/scenario/transform/file.py b/cliboa/scenario/transform/file.py index af3d4e10..ed34cba4 100644 --- a/cliboa/scenario/transform/file.py +++ b/cliboa/scenario/transform/file.py @@ -509,6 +509,7 @@ def __init__(self): self._regex_pattern = None self._rep_str = None self._ext = "" + self._without_ext = True def prefix(self, prefix): self._prefix = prefix @@ -525,6 +526,9 @@ def rep_str(self, rep_str): def ext(self, ext): self._ext = ext + def without_ext(self, without_ext): + self._without_ext = without_ext + def execute(self, *args): # essential parameters check valid = EssentialParameters(self.__class__.__name__, [self._src_dir, self._src_pattern]) @@ -532,39 +536,51 @@ def execute(self, *args): files = super().get_target_files(self._src_dir, self._src_pattern) self.check_file_existence(files) + if self._rep_str is None and self._regex_pattern is not None: + raise InvalidParameter("Replace string is not defined in yaml file: rep_str") + if self._rep_str is not None and self._regex_pattern is None: + raise InvalidParameter( + "The conversion pattern is not defined in yaml file: regex_pattern" + ) for file in files: dirname = os.path.dirname(file) basename = os.path.basename(file) - px = "" - if basename.startswith("."): - basename = basename[1:] - px = "." - - if "." in basename: - nameonly, extension = basename.split(".", 1) - extension = "." + extension - else: - nameonly = basename - extension = "" - - if self._regex_pattern is not None and self._rep_str is not None: - nameonly = re.sub(self._regex_pattern, self._rep_str, nameonly) - elif self._regex_pattern is not None: - raise InvalidParameter("The converted string is not defined in yaml file: dest_str") - elif self._rep_str is not None: - raise InvalidParameter( - "The conversion pattern is not defined in yaml file: regex_pattern" + if self._without_ext is False: + if self._prefix != "" or self._suffix != "" or self._ext != "": + raise InvalidParameter("Cannot be specified in without_ext mode") + self._replace( + dirname, + file, + os.path.join(dirname, re.sub(self._regex_pattern, self._rep_str, basename)), ) + else: + px = "" + if basename.startswith("."): + basename = basename[1:] + px = "." + + if "." in basename: + nameonly, extension = basename.split(".", 1) + extension = "." + extension + else: + nameonly = basename + extension = "" + + if self._regex_pattern is not None and self._rep_str is not None: + nameonly = re.sub(self._regex_pattern, self._rep_str, nameonly) + + if self._ext: + extension = "." + self._ext - if self._ext: - extension = "." + self._ext + newfilename = self._prefix + px + nameonly + self._suffix + extension + self._replace(dirname, file, newfilename) - newfilename = self._prefix + px + nameonly + self._suffix + extension - newfilepath = os.path.join(dirname, newfilename) - os.rename(file, newfilepath) - self._logger.info("File name changed %s -> %s" % (file, newfilepath)) + def _replace(self, dirname, file, newfilename): + newfilepath = os.path.join(dirname, newfilename) + os.rename(file, newfilepath) + self._logger.info("File name changed %s -> %s" % (file, newfilepath)) class FileConvert(FileBaseTransform): diff --git a/cliboa/test/scenario/transform/test_file.py b/cliboa/test/scenario/transform/test_file.py index b24574e5..17d57889 100644 --- a/cliboa/test/scenario/transform/test_file.py +++ b/cliboa/test/scenario/transform/test_file.py @@ -811,6 +811,40 @@ def test_execute_ok_10(self): assert os.path.exists(os.path.join(self._data_dir, "ataeasata1a.txt")) assert os.path.exists(os.path.join(self._data_dir, "ataeasata2a.txt")) + def test_execute_ok_11(self): + self._create_files() + + instance = FileRename() + Helper.set_property(instance, "logger", LisboaLog.get_logger(__name__)) + Helper.set_property(instance, "src_dir", self._data_dir) + Helper.set_property(instance, "src_pattern", r"test.*\.txt") + Helper.set_property(instance, "regex_pattern", "test") + Helper.set_property(instance, "rep_str", "test_") + Helper.set_property(instance, "without_ext", False) + instance.execute() + + assert os.path.exists(os.path.join(self._data_dir, "test_1.txt")) + assert os.path.exists(os.path.join(self._data_dir, "test_2.txt")) + + def test_execute_ok_12(self): + self._create_files() + files = self._create_files() + for file in files: + root, name = os.path.split(file) + os.rename(file, os.path.join(root, name + ".12345")) + + instance = FileRename() + Helper.set_property(instance, "logger", LisboaLog.get_logger(__name__)) + Helper.set_property(instance, "src_dir", self._data_dir) + Helper.set_property(instance, "src_pattern", r"test.*\.txt\.12345") + Helper.set_property(instance, "regex_pattern", ".txt") + Helper.set_property(instance, "rep_str", "_txt") + Helper.set_property(instance, "without_ext", False) + instance.execute() + + assert os.path.exists(os.path.join(self._data_dir, "test1_txt.12345")) + assert os.path.exists(os.path.join(self._data_dir, "test2_txt.12345")) + def test_execute_ng_1(self): self._create_files() @@ -823,7 +857,7 @@ def test_execute_ng_1(self): Helper.set_property(instance, "regex_pattern", "test1") with pytest.raises(InvalidParameter) as execinfo: instance.execute() - assert "The converted string is not defined in yaml file: dest_str" == str(execinfo.value) + assert "Replace string is not defined in yaml file: rep_str" == str(execinfo.value) def test_execute_ng_2(self): self._create_files() @@ -853,7 +887,7 @@ def test_execute_ng_3(self): Helper.set_property(instance, "regex_pattern", "") with pytest.raises(InvalidParameter) as execinfo: instance.execute() - assert "The converted string is not defined in yaml file: dest_str" == str(execinfo.value) + assert "Replace string is not defined in yaml file: rep_str" == str(execinfo.value) def test_execute_ng_4(self): self._create_files() @@ -871,6 +905,45 @@ def test_execute_ng_4(self): execinfo.value ) + def test_execute_ng_5(self): + self._create_files() + + instance = FileRename() + Helper.set_property(instance, "logger", LisboaLog.get_logger(__name__)) + Helper.set_property(instance, "src_dir", self._data_dir) + Helper.set_property(instance, "src_pattern", r"test.*\.txt") + Helper.set_property(instance, "prefix", "PRE-") + Helper.set_property(instance, "without_ext", False) + with pytest.raises(InvalidParameter) as execinfo: + instance.execute() + assert "Cannot be specified in without_ext mode" == str(execinfo.value) + + def test_execute_ng_6(self): + self._create_files() + + instance = FileRename() + Helper.set_property(instance, "logger", LisboaLog.get_logger(__name__)) + Helper.set_property(instance, "src_dir", self._data_dir) + Helper.set_property(instance, "src_pattern", r"test.*\.txt") + Helper.set_property(instance, "suffix", "-SUF") + Helper.set_property(instance, "without_ext", False) + with pytest.raises(InvalidParameter) as execinfo: + instance.execute() + assert "Cannot be specified in without_ext mode" == str(execinfo.value) + + def test_execute_ng_7(self): + self._create_files() + + instance = FileRename() + Helper.set_property(instance, "logger", LisboaLog.get_logger(__name__)) + Helper.set_property(instance, "src_dir", self._data_dir) + Helper.set_property(instance, "src_pattern", r"test.*\.txt") + Helper.set_property(instance, "ext", "csv") + Helper.set_property(instance, "without_ext", False) + with pytest.raises(InvalidParameter) as execinfo: + instance.execute() + assert "Cannot be specified in without_ext mode" == str(execinfo.value) + class TestFileConvert(TestFileTransform): def test_execute(self): diff --git a/docs/modules/file_rename.md b/docs/modules/file_rename.md index 651f6c9c..5335bd82 100644 --- a/docs/modules/file_rename.md +++ b/docs/modules/file_rename.md @@ -2,18 +2,19 @@ Renaming files with adding either prefix or suffix. # Parameters -|Parameters|Explanation|Required|Default|Remarks| -|----------|-----------|--------|-------|-------| -|src_dir|Path of the directory which target files are placed.|Yes|None|| -|src_pattern|Regex which is to find target files.|Yes|None|| -|prefix|Prefix for new file name|No|`""`|| -|suffix|Suffix for new file name|No|`""`|| -|regex_pattern|Pattern when conversion.|No|None|Fails if both regex_pattern and dest_str are not defined.| -|rep_str|Converted string in the file name.|No|None|Fails if both regex_pattern and dest_str are not defined.| -|ext|Converted file extension.|No|`""`|Only change the extension, not the file format.| -|nonfile_error|Whether an error is thrown when files are not found in src_dir.|No|False|| +| Parameters | Explanation | Required | Default | Remarks | +|---------------|-------------------------------------------------------------------------------|----------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| src_dir | Path of the directory which target files are placed. | Yes | None | | +| src_pattern | Regex which is to find target files. | Yes | None | | +| prefix | Prefix for new file name | No | `""` | | +| suffix | Suffix for new file name | No | `""` | | +| regex_pattern | Pattern when conversion. | No | None | Fails if both regex_pattern and rep_str are not defined. | +| rep_str | Converted string in the file name. | No | None | Fails if both regex_pattern and rep_str are not defined. | +| ext | Converted file extension. | No | `""` | Only change the extension, not the file format. | +| nonfile_error | Whether an error is thrown when files are not found in src_dir. | No | False | | +| without_ext | Include the extension in the range when converting using regular expressions. | No | False | Fails if without_ext is True, only one of the regex_pattern or rep_str are specified. Fails if without_ext is False, both regex_pattern and rep_str are not defined, and specify prefix and suffix, ext. | -# Examples +# Example1 ``` scenario: - step: Rename file @@ -29,7 +30,10 @@ scenario: Input: /root/foo.txt Output: /root/PRE_hoo_SUF.csv +``` +# Example2 +``` scenario: - step: Rename file (deletion of character) class: FileRename @@ -42,3 +46,19 @@ scenario: Input: /root/foo_delete.txt Output: /root/foo.csv ``` + +# Example3 +``` +scenario: +- step: Rename file(without distinguishing extension) + class: FileRename + arguments: + src_dir: /root + src_pattern: foo\.1\.txt + regex_pattern: \.1\.txt + rep_str: _1.txt + without_ext: False + +Input: /root/foo.1.txt +Output: /root/foo_1.txt +```