Added tests for Finder tags
This commit is contained in:
@@ -1479,7 +1479,7 @@ def query(
|
|||||||
metavar="TEMPLATE",
|
metavar="TEMPLATE",
|
||||||
multiple=True,
|
multiple=True,
|
||||||
default=None,
|
default=None,
|
||||||
help="Set Finder tags to TEMPLATE. These tags can be searched in the Finder or Spotlight with "
|
help="Set MacOS Finder tags to TEMPLATE. These tags can be searched in the Finder or Spotlight with "
|
||||||
"'tag:tagname' format. For example, '--finder-tag-template \"{label}\"' to set Finder tags to photo labels. "
|
"'tag:tagname' format. For example, '--finder-tag-template \"{label}\"' to set Finder tags to photo labels. "
|
||||||
"You may specify multiple TEMPLATE values by using '--finder-tag-template' multiple times. "
|
"You may specify multiple TEMPLATE values by using '--finder-tag-template' multiple times. "
|
||||||
"See also '--finder-tag-keywords and Extended Attributes below.'.",
|
"See also '--finder-tag-keywords and Extended Attributes below.'.",
|
||||||
@@ -1487,7 +1487,7 @@ def query(
|
|||||||
@click.option(
|
@click.option(
|
||||||
"--finder-tag-keywords",
|
"--finder-tag-keywords",
|
||||||
is_flag=True,
|
is_flag=True,
|
||||||
help="Set Finder tags to keywords; any keywords specified via '--keyword-template', '--person-keyword', etc. "
|
help="Set MacOS Finder tags to keywords; any keywords specified via '--keyword-template', '--person-keyword', etc. "
|
||||||
"will also be used as Finder tags. See also '--finder-tag-template and Extended Attributes below.'.",
|
"will also be used as Finder tags. See also '--finder-tag-template and Extended Attributes below.'.",
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
@@ -1724,7 +1724,7 @@ def export(
|
|||||||
)
|
)
|
||||||
raise click.Abort()
|
raise click.Abort()
|
||||||
|
|
||||||
# re-set the local function vars to the corresponding config value
|
# re-set the local vars to the corresponding config value
|
||||||
# this isn't elegant but avoids having to rewrite this function to use cfg.varname for every parameter
|
# this isn't elegant but avoids having to rewrite this function to use cfg.varname for every parameter
|
||||||
db = cfg.db
|
db = cfg.db
|
||||||
photos_library = cfg.photos_library
|
photos_library = cfg.photos_library
|
||||||
|
|||||||
@@ -439,6 +439,19 @@ CLI_EXIFTOOL_DUPLICATE_KEYWORDS = {
|
|||||||
"E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51": "wedding.jpg"
|
"E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51": "wedding.jpg"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLI_FINDER_TAGS = {
|
||||||
|
"D79B8D77-BFFC-460B-9312-034F2877D35B": {
|
||||||
|
"File:FileName": "Pumkins2.jpg",
|
||||||
|
"IPTC:Keywords": "Kids",
|
||||||
|
"XMP:TagsList": "Kids",
|
||||||
|
"XMP:Title": "I found one!",
|
||||||
|
"EXIF:ImageDescription": "Girl holding pumpkin",
|
||||||
|
"XMP:Description": "Girl holding pumpkin",
|
||||||
|
"XMP:PersonInImage": "Katie",
|
||||||
|
"XMP:Subject": "Kids",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LABELS_JSON = {
|
LABELS_JSON = {
|
||||||
"labels": {
|
"labels": {
|
||||||
"Plant": 7,
|
"Plant": 7,
|
||||||
@@ -4814,3 +4827,243 @@ def test_export_exportdb():
|
|||||||
"Error: --exportdb must be specified as filename not path" in result.output
|
"Error: --exportdb must be specified as filename not path" in result.output
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_export_finder_tag_keywords():
|
||||||
|
""" test --finder-tag-keywords """
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
from osxmetadata import OSXMetaData, Tag
|
||||||
|
from osxphotos.__main__ 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-keywords",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["IPTC:Keywords"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
expected = [Tag(x) for x in keywords]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
# run again with --update, should skip writing extended attributes
|
||||||
|
result = runner.invoke(
|
||||||
|
export,
|
||||||
|
[
|
||||||
|
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||||
|
".",
|
||||||
|
"-V",
|
||||||
|
"--finder-tag-keywords",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
"--update",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "Skipping Finder tags" in result.output
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["IPTC:Keywords"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
expected = [Tag(x) for x in keywords]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
# clear tags and run again, should update extended attributes
|
||||||
|
md.tags = None
|
||||||
|
|
||||||
|
result = runner.invoke(
|
||||||
|
export,
|
||||||
|
[
|
||||||
|
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||||
|
".",
|
||||||
|
"-V",
|
||||||
|
"--finder-tag-keywords",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
"--update",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "Writing Finder tags" in result.output
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["IPTC:Keywords"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
expected = [Tag(x) for x in keywords]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
|
||||||
|
def test_export_finder_tag_template():
|
||||||
|
""" test --finder-tag-template """
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
from osxmetadata import OSXMetaData, Tag
|
||||||
|
from osxphotos.__main__ 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",
|
||||||
|
"{person}",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
expected = [Tag(x) for x in keywords]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
# run again with --update, should skip writing extended attributes
|
||||||
|
result = runner.invoke(
|
||||||
|
export,
|
||||||
|
[
|
||||||
|
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||||
|
".",
|
||||||
|
"-V",
|
||||||
|
"--finder-tag-template",
|
||||||
|
"{person}",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
"--update",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "Skipping Finder tags" in result.output
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
expected = [Tag(x) for x in keywords]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
# clear tags and run again, should update extended attributes
|
||||||
|
md.tags = None
|
||||||
|
|
||||||
|
result = runner.invoke(
|
||||||
|
export,
|
||||||
|
[
|
||||||
|
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||||
|
".",
|
||||||
|
"-V",
|
||||||
|
"--finder-tag-template",
|
||||||
|
"{person}",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
"--update",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "Writing Finder tags" in result.output
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
expected = [Tag(x) for x in keywords]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
|
||||||
|
def test_export_finder_tag_template_multiple():
|
||||||
|
""" test --finder-tag-template used more than once """
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
from osxmetadata import OSXMetaData, Tag
|
||||||
|
from osxphotos.__main__ 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",
|
||||||
|
"{keyword}",
|
||||||
|
"--finder-tag-template",
|
||||||
|
"{person}",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["IPTC:Keywords"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
persons = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
|
||||||
|
persons = [persons] if type(persons) != list else persons
|
||||||
|
expected = [Tag(x) for x in keywords + persons]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
|
||||||
|
def test_export_finder_tag_template_keywords():
|
||||||
|
""" test --finder-tag-template with --finder-tag-keywords """
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
from osxmetadata import OSXMetaData, Tag
|
||||||
|
from osxphotos.__main__ 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-keywords",
|
||||||
|
"--finder-tag-template",
|
||||||
|
"{person}",
|
||||||
|
"--uuid",
|
||||||
|
f"{uuid}",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
md = OSXMetaData(CLI_FINDER_TAGS[uuid]["File:FileName"])
|
||||||
|
keywords = CLI_FINDER_TAGS[uuid]["IPTC:Keywords"]
|
||||||
|
keywords = [keywords] if type(keywords) != list else keywords
|
||||||
|
persons = CLI_FINDER_TAGS[uuid]["XMP:PersonInImage"]
|
||||||
|
persons = [persons] if type(persons) != list else persons
|
||||||
|
expected = [Tag(x) for x in keywords + persons]
|
||||||
|
assert sorted(md.tags) == sorted(expected)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user