Fixed bug for multi-field templates and --xattr-template, #422

This commit is contained in:
Rhet Turnbull
2021-04-17 02:41:29 -07:00
parent 874ad2fa34
commit 6a288676a1
3 changed files with 76 additions and 14 deletions

View File

@@ -1,3 +1,3 @@
""" version info """ """ version info """
__version__ = "0.42.1" __version__ = "0.42.2"

View File

@@ -3307,7 +3307,7 @@ def write_finder_tags(
# filter out any template values that didn't match by looking for sentinel # filter out any template values that didn't match by looking for sentinel
rendered_tags = [ rendered_tags = [
tag for tag in rendered_tags if _OSXPHOTOS_NONE_SENTINEL not in tag value.replace(_OSXPHOTOS_NONE_SENTINEL, "") for value in rendered_tags
] ]
tags.extend(rendered_tags) tags.extend(rendered_tags)
@@ -3358,10 +3358,10 @@ def write_extended_attributes(photo, files, xattr_template, strip=False):
), ),
err=True, err=True,
) )
# filter out any template values that didn't match by looking for sentinel # filter out any template values that didn't match by looking for sentinel
rendered = [ rendered = [value.replace(_OSXPHOTOS_NONE_SENTINEL, "") for value in rendered]
value for value in rendered if _OSXPHOTOS_NONE_SENTINEL not in value
]
try: try:
attributes[xattr].extend(rendered) attributes[xattr].extend(rendered)
except KeyError: except KeyError:

View File

@@ -462,7 +462,17 @@ CLI_FINDER_TAGS = {
"XMP:Description": "Girl holding pumpkin", "XMP:Description": "Girl holding pumpkin",
"XMP:PersonInImage": "Katie", "XMP:PersonInImage": "Katie",
"XMP:Subject": "Kids", "XMP:Subject": "Kids",
} },
"E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51": {
"File:FileName": "wedding.jpg",
"IPTC:Keywords": ["Maria", "wedding"],
"XMP:TagsList": ["Maria", "wedding"],
"XMP:Title": None,
"EXIF:ImageDescription": "Bride Wedding day",
"XMP:Description": "Bride Wedding day",
"XMP:PersonInImage": "Maria",
"XMP:Subject": ["Maria", "wedding"],
},
} }
LABELS_JSON = { LABELS_JSON = {
@@ -5330,7 +5340,7 @@ def test_export_finder_tag_template_multiple():
keywords = [keywords] if type(keywords) != list else keywords keywords = [keywords] if type(keywords) != list else keywords
persons = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"] persons = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
persons = [persons] if type(persons) != list else persons persons = [persons] if type(persons) != list else persons
expected = [Tag(x) for x in keywords + persons] expected = [Tag(x) for x in set(keywords + persons)]
assert sorted(md.tags) == sorted(expected) assert sorted(md.tags) == sorted(expected)
@@ -5368,7 +5378,42 @@ def test_export_finder_tag_template_keywords():
keywords = [keywords] if type(keywords) != list else keywords keywords = [keywords] if type(keywords) != list else keywords
persons = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"] persons = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
persons = [persons] if type(persons) != list else persons persons = [persons] if type(persons) != list else persons
expected = [Tag(x) for x in keywords + persons] expected = [Tag(x) for x in set(keywords + persons)]
assert sorted(md.tags) == sorted(expected)
def test_export_finder_tag_template_multi_field():
""" test --finder-tag-template with multiple fields (issue #422) """
import glob
import os
import os.path
from osxmetadata import OSXMetaData, Tag
from osxphotos.cli import export
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
for uuid in CLI_FINDER_TAGS:
result = runner.invoke(
export,
[
os.path.join(cwd, PHOTOS_DB_15_7),
".",
"-V",
"--finder-tag-template",
"{title};{descr}",
"--uuid",
f"{uuid}",
],
)
assert result.exit_code == 0
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
title = CLI_FINDER_TAGS[uuid]["XMP:Title"] or ""
descr = CLI_FINDER_TAGS[uuid]["XMP:Description"] or ""
expected = [Tag(f"{title};{descr}")]
assert sorted(md.tags) == sorted(expected) assert sorted(md.tags) == sorted(expected)
@@ -5397,7 +5442,7 @@ def test_export_xattr_template():
"{person}", "{person}",
"--xattr-template", "--xattr-template",
"comment", "comment",
"{title}", "{title};{descr}",
"--uuid", "--uuid",
f"{uuid}", f"{uuid}",
], ],
@@ -5408,7 +5453,9 @@ def test_export_xattr_template():
expected = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"] expected = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
expected = [expected] if type(expected) != list else expected expected = [expected] if type(expected) != list else expected
assert sorted(md.keywords) == sorted(expected) assert sorted(md.keywords) == sorted(expected)
assert md.comment == CLI_FINDER_TAGS[uuid]["XMP:Title"] title = CLI_FINDER_TAGS[uuid]["XMP:Title"] or ""
descr = CLI_FINDER_TAGS[uuid]["XMP:Description"] or ""
assert md.comment == f"{title};{descr}"
# run again with --update, should skip writing extended attributes # run again with --update, should skip writing extended attributes
result = runner.invoke( result = runner.invoke(
@@ -5422,7 +5469,7 @@ def test_export_xattr_template():
"{person}", "{person}",
"--xattr-template", "--xattr-template",
"comment", "comment",
"{title}", "{title};{descr}",
"--uuid", "--uuid",
f"{uuid}", f"{uuid}",
"--update", "--update",
@@ -5768,6 +5815,7 @@ def test_export_name():
files = glob.glob("*") files = glob.glob("*")
assert len(files) == 1 assert len(files) == 1
def test_query_eval(): def test_query_eval():
""" test export --query-eval """ """ test export --query-eval """
import glob import glob
@@ -5778,7 +5826,14 @@ def test_query_eval():
# pylint: disable=not-context-manager # pylint: disable=not-context-manager
with runner.isolated_filesystem(): with runner.isolated_filesystem():
result = runner.invoke( result = runner.invoke(
export, [os.path.join(cwd, PHOTOS_DB_15_7), ".", "-V", "--query-eval", "'DSC03584' in photo.original_filename"] export,
[
os.path.join(cwd, PHOTOS_DB_15_7),
".",
"-V",
"--query-eval",
"'DSC03584' in photo.original_filename",
],
) )
assert result.exit_code == 0 assert result.exit_code == 0
files = glob.glob("*") files = glob.glob("*")
@@ -5795,7 +5850,14 @@ def test_bad_query_eval():
# pylint: disable=not-context-manager # pylint: disable=not-context-manager
with runner.isolated_filesystem(): with runner.isolated_filesystem():
result = runner.invoke( result = runner.invoke(
export, [os.path.join(cwd, PHOTOS_DB_15_7), ".", "-V", "--query-eval", "'DSC03584' in photo.originalfilename"] export,
[
os.path.join(cwd, PHOTOS_DB_15_7),
".",
"-V",
"--query-eval",
"'DSC03584' in photo.originalfilename",
],
) )
assert result.exit_code != 0 assert result.exit_code != 0
assert "Error: Invalid query-eval CRITERIA" in result.output assert "Error: Invalid query-eval CRITERIA" in result.output