From 159d1102aabd56def2caf6754747f7a4caa7d374 Mon Sep 17 00:00:00 2001 From: Rhet Turnbull Date: Sat, 28 Aug 2021 08:14:26 -0700 Subject: [PATCH] Added {strip} template --- README.md | 7 +++++-- osxphotos/_version.py | 2 +- osxphotos/phototemplate.py | 3 +++ tests/test_template.py | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5ec54ccc..26625a3f 100644 --- a/README.md +++ b/README.md @@ -1702,7 +1702,7 @@ Substitution Description {lf} A line feed: '\n', alias for {newline} {cr} A carriage return: '\r' {crlf} a carriage return + line feed: '\r\n' -{osxphotos_version} The osxphotos version, e.g. '0.42.74' +{osxphotos_version} The osxphotos version, e.g. '0.42.77' {osxphotos_cmd_line} The full command line used to run osxphotos The following substitutions may result in multiple values. Thus if specified for @@ -1779,6 +1779,8 @@ Substitution Description rendered TEMPLATE value(s) for safe usage in the shell, e.g. My file.jpeg => 'My file.jpeg'; only adds quotes if needed. +{strip} Use in form '{strip,TEMPLATE}'; strips whitespace + from begining and end of rendered TEMPLATE value(s). {function} Execute a python function from an external file and use return value as template substitution. Use in format: {function:file.py::function_name} where @@ -3559,7 +3561,7 @@ The following template field substitutions are availabe for use the templating s |{lf}|A line feed: '\n', alias for {newline}| |{cr}|A carriage return: '\r'| |{crlf}|a carriage return + line feed: '\r\n'| -|{osxphotos_version}|The osxphotos version, e.g. '0.42.74'| +|{osxphotos_version}|The osxphotos version, e.g. '0.42.77'| |{osxphotos_cmd_line}|The full command line used to run osxphotos| |{album}|Album(s) photo is contained in| |{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder| @@ -3576,6 +3578,7 @@ The following template field substitutions are availabe for use the templating s |{photo}|Provides direct access to the PhotoInfo object for the photo. Must be used in format '{photo.property}' where 'property' represents a PhotoInfo property. For example: '{photo.favorite}' is the same as '{favorite}' and '{photo.place.name}' is the same as '{place.name}'. '{photo}' provides access to properties that are not available as separate template fields but it assumes some knowledge of the underlying PhotoInfo class. See https://rhettbull.github.io/osxphotos/ for additional documentation on the PhotoInfo class.| |{detected_text}|List of text strings found in the image after performing text detection. Using '{detected_text}' will cause osxphotos to perform text detection on your photos using the built-in macOS text detection algorithms which will slow down your export. The results for each photo will be cached in the export database so that future exports with '--update' do not need to reprocess each photo. You may pass a confidence threshold value between 0.0 and 1.0 after a colon as in '{detected_text:0.5}'; The default confidence threshold is 0.75. '{detected_text}' works only on macOS Catalina (10.15) or later. Note: this feature is not the same thing as Live Text in macOS Monterey, which osxphotos does not yet support.| |{shell_quote}|Use in form '{shell_quote,TEMPLATE}'; quotes the rendered TEMPLATE value(s) for safe usage in the shell, e.g. My file.jpeg => 'My file.jpeg'; only adds quotes if needed.| +|{strip}|Use in form '{strip,TEMPLATE}'; strips whitespace from begining and end of rendered TEMPLATE value(s).| |{function}|Execute a python function from an external file and use return value as template substitution. Use in format: {function:file.py::function_name} where 'file.py' is the name of the python file and 'function_name' is the name of the function to call. The function will be passed the PhotoInfo object for the photo. See https://github.com/RhetTbull/osxphotos/blob/master/examples/template_function.py for an example of how to implement a template function.| diff --git a/osxphotos/_version.py b/osxphotos/_version.py index ceb077a8..c2978847 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.42.76" +__version__ = "0.42.77" diff --git a/osxphotos/phototemplate.py b/osxphotos/phototemplate.py index f7d2491c..51fd56de 100644 --- a/osxphotos/phototemplate.py +++ b/osxphotos/phototemplate.py @@ -209,6 +209,7 @@ TEMPLATE_SUBSTITUTIONS_MULTI_VALUED = { + "'{detected_text}' works only on macOS Catalina (10.15) or later. " + "Note: this feature is not the same thing as Live Text in macOS Monterey, which osxphotos does not yet support.", "{shell_quote}": "Use in form '{shell_quote,TEMPLATE}'; quotes the rendered TEMPLATE value(s) for safe usage in the shell, e.g. My file.jpeg => 'My file.jpeg'; only adds quotes if needed.", + "{strip}": "Use in form '{strip,TEMPLATE}'; strips whitespace from begining and end of rendered TEMPLATE value(s).", "{function}": "Execute a python function from an external file and use return value as template substitution. " + "Use in format: {function:file.py::function_name} where 'file.py' is the name of the python file and 'function_name' is the name of the function to call. " + "The function will be passed the PhotoInfo object for the photo. " @@ -1162,6 +1163,8 @@ class PhotoTemplate: ) elif field == "shell_quote": values = [shlex.quote(v) for v in default if v] + elif field == "strip": + values = [v.strip() for v in default] elif field.startswith("photo"): # provide access to PhotoInfo object properties = field.split(".") diff --git a/tests/test_template.py b/tests/test_template.py index b3d4266f..cd4ed599 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -394,12 +394,18 @@ UUID_ALBUM_SEQ = { } UUID_EMPTY_TITLE = "7783E8E6-9CAC-40F3-BE22-81FB7051C266" # IMG_3092.heic +UUID_EMPTY_TITLE_HAS_DESCRIPTION = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51" # wedding.jpg TEMPLATE_VALUES_EMPTY_TITLE = { "{title,No Title} and {descr,No Descr}": "No Title and No Descr", "{title?true,false}": "false", } +TEMPLATE_VALUES_EMPTY_TITLE_HAS_DESCRIPTION = { + "{title,} {descr} ": " Bride Wedding day ", + "{strip,{title,} {descr} }": "Bride Wedding day", +} + @pytest.fixture(scope="module") def photosdb_places(): @@ -1194,3 +1200,11 @@ def test_empty_title(photosdb): for template, value in TEMPLATE_VALUES_EMPTY_TITLE.items(): rendered, _ = photo.render_template(template) assert value in "".join(rendered) + + +def test_strip(photosdb): + """Test {strip} template""" + photo = photosdb.get_photo(UUID_EMPTY_TITLE_HAS_DESCRIPTION) + for template, value in TEMPLATE_VALUES_EMPTY_TITLE_HAS_DESCRIPTION.items(): + rendered, _ = photo.render_template(template) + assert value in "".join(rendered)