diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 58c9d624..ba5ac208 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.42.35" +__version__ = "0.42.36" diff --git a/osxphotos/path_utils.py b/osxphotos/path_utils.py index 075f14e2..b5a4a4c8 100644 --- a/osxphotos/path_utils.py +++ b/osxphotos/path_utils.py @@ -6,22 +6,22 @@ from ._constants import MAX_DIRNAME_LEN, MAX_FILENAME_LEN def sanitize_filepath(filepath): - """ sanitize a filepath """ + """sanitize a filepath""" return pathvalidate.sanitize_filepath(filepath, platform="macos") def is_valid_filepath(filepath): - """ returns True if a filepath is valid otherwise False """ + """returns True if a filepath is valid otherwise False""" return pathvalidate.is_valid_filepath(filepath, platform="macos") def sanitize_filename(filename, replacement=":"): - """ replace any illegal characters in a filename and truncate filename if needed + """replace any illegal characters in a filename and truncate filename if needed Args: filename: str, filename to sanitze replacement: str, value to replace any illegal characters with; default = ":" - + Returns: filename with any illegal characters replaced by replacement and truncated if necessary """ @@ -46,12 +46,12 @@ def sanitize_filename(filename, replacement=":"): def sanitize_dirname(dirname, replacement=":"): - """ replace any illegal characters in a directory name and truncate directory name if needed + """replace any illegal characters in a directory name and truncate directory name if needed Args: - dirname: str, directory name to sanitze - replacement: str, value to replace any illegal characters with; default = ":" - + dirname: str, directory name to sanitize + replacement: str, value to replace any illegal characters with; default = ":"; if None, no replacement occurs + Returns: dirname with any illegal characters replaced by replacement and truncated if necessary """ @@ -61,19 +61,20 @@ def sanitize_dirname(dirname, replacement=":"): def sanitize_pathpart(pathpart, replacement=":"): - """ replace any illegal characters in a path part (either directory or filename without extension) and truncate name if needed + """replace any illegal characters in a path part (either directory or filename without extension) and truncate name if needed Args: - pathpart: str, path part to sanitze - replacement: str, value to replace any illegal characters with; default = ":" - + pathpart: str, path part to sanitize + replacement: str, value to replace any illegal characters with; default = ":"; if None, no replacement occurs + Returns: pathpart with any illegal characters replaced by replacement and truncated if necessary """ if pathpart: - pathpart = pathpart.replace("/", replacement) + pathpart = ( + pathpart.replace("/", replacement) if replacement is not None else pathpart + ) if len(pathpart) > MAX_DIRNAME_LEN: drop = len(pathpart) - MAX_DIRNAME_LEN pathpart = pathpart[:-drop] return pathpart - diff --git a/osxphotos/phototemplate.py b/osxphotos/phototemplate.py index 929858ef..a6125d6c 100644 --- a/osxphotos/phototemplate.py +++ b/osxphotos/phototemplate.py @@ -1194,7 +1194,8 @@ class PhotoTemplate: if self.filename: values = [sanitize_pathpart(value) for value in values] elif self.dirname: - values = [sanitize_dirname(value) for value in values] + # sanitize but don't replace any "/" as user function may want to create sub directories + values = [sanitize_dirname(value, replacement=None) for value in values] return values diff --git a/tests/test_cli.py b/tests/test_cli.py index f6fa1f42..5e4c85ff 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -6443,3 +6443,33 @@ def test_export_post_command_bad_command(): ) assert result.exit_code == 0 assert 'Error running command "foobar' in result.output + + +def test_export_directory_template_function(): + """Test --directory with template function """ + import os.path + import pathlib + from osxphotos.cli import cli + + runner = CliRunner() + cwd = os.getcwd() + # pylint: disable=not-context-manager + with runner.isolated_filesystem(): + with open("foo.py", "w") as f: + f.writelines(["def foo(photo, **kwargs):\n"," return 'foo/bar'"]) + result = runner.invoke( + cli, + [ + "export", + "--db", + os.path.join(cwd, PHOTOS_DB_15_7), + ".", + "--uuid", + CLI_EXPORT_UUID, + "--directory", + "{function:foo.py::foo}" + ], + ) + assert result.exit_code == 0 + assert pathlib.Path(f"foo/bar/{CLI_EXPORT_UUID_FILENAME}").is_file() +