diff --git a/osxphotos/_version.py b/osxphotos/_version.py index ba85f77b..575ae7b1 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,5 +1,5 @@ """ version info """ -__version__ = "0.38.12" +__version__ = "0.38.13" diff --git a/osxphotos/photoinfo/_photoinfo_export.py b/osxphotos/photoinfo/_photoinfo_export.py index 1a47c858..b2fd1f63 100644 --- a/osxphotos/photoinfo/_photoinfo_export.py +++ b/osxphotos/photoinfo/_photoinfo_export.py @@ -1390,18 +1390,14 @@ def _exiftool_dict( if keyword_list: # remove duplicates keyword_list = sorted(list(set(keyword_list))) - exif["XMP:TagsList"] = keyword_list.copy() exif["IPTC:Keywords"] = keyword_list.copy() + exif["XMP:Subject"] = keyword_list.copy() + exif["XMP:TagsList"] = keyword_list.copy() if person_list: person_list = sorted(list(set(person_list))) exif["XMP:PersonInImage"] = person_list.copy() - if self.keywords or person_list: - # Photos puts both keywords and persons in Subject when using "Export IPTC as XMP" - # only use Photos' keywords for subject (e.g. don't include template values) - exif["XMP:Subject"] = sorted(list(set(self.keywords + person_list))) - # if self.favorite(): # exif["Rating"] = 5 @@ -1607,20 +1603,15 @@ def _xmp_sidecar( keyword_list.extend(rendered_keywords) - subject_list = [] - if self.keywords or person_list: - # Photos puts both keywords and persons in Subject when using "Export IPTC as XMP" - subject_list = list(self.keywords) + person_list - # remove duplicates # sorted mainly to make testing the XMP file easier if keyword_list: keyword_list = sorted(list(set(keyword_list))) - if subject_list: - subject_list = sorted(list(set(subject_list))) if person_list: person_list = sorted(list(set(person_list))) + subject_list = keyword_list + xmp_str = xmp_template.render( photo=self, description=description, diff --git a/osxphotos/templates/xmp_sidecar.mako b/osxphotos/templates/xmp_sidecar.mako index add2663d..12bd2080 100644 --- a/osxphotos/templates/xmp_sidecar.mako +++ b/osxphotos/templates/xmp_sidecar.mako @@ -26,7 +26,6 @@ <%def name="dc_subject(subject)"> % if subject: - % for subj in subject: diff --git a/tests/search_info_test_data_10_15_7.json b/tests/search_info_test_data_10_15_7.json index a39a6167..633ea061 100644 --- a/tests/search_info_test_data_10_15_7.json +++ b/tests/search_info_test_data_10_15_7.json @@ -1 +1 @@ -{"UUID_SEARCH_INFO": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["Butter", "Food"], "place_names": ["Durham Bulls Athletic Park"], "streets": ["Blackwell St"], "neighborhoods": ["American Tobacco District", "Downtown Durham"], "city": "Durham", "locality_names": ["Durham"], "state": "North Carolina", "state_abbreviation": "NC", "country": "United States", "bodies_of_water": [], "month": "October", "year": "2018", "holidays": [], "activities": ["Dinner", "Travel", "Entertainment", "Dining", "Trip"], "season": "Fall", "venues": ["Luna Rotisserie and Empanadas", "Pie Pusher's", "Copa", "The Pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Desert", "Land", "Outdoor", "Sky", "Sunset Sunrise"], "place_names": ["Royal Palms State Beach"], "streets": [], "neighborhoods": ["San Pedro"], "city": "Los Angeles", "locality_names": [], "state": "California", "state_abbreviation": "", "country": "United States", "bodies_of_water": ["Catalina Channel"], "month": "November", "year": "2017", "holidays": [], "activities": ["Beach Activity", "Activity"], "season": "Fall", "venues": [], "venue_types": [], "media_types": ["Live Photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["Bench", "People", "Water Body", "Land", "Water", "Furniture", "Plant", "Outdoor", "Vegetation", "Forest"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "December", "year": "2014", "holidays": ["Christmas Day"], "activities": ["Celebration", "Holiday"], "season": "Winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["butter", "food"], "place_names": ["durham bulls athletic park"], "streets": ["blackwell st"], "neighborhoods": ["american tobacco district", "downtown durham"], "city": "durham", "locality_names": ["durham"], "state": "north carolina", "state_abbreviation": "nc", "country": "united states", "bodies_of_water": [], "month": "october", "year": "2018", "holidays": [], "activities": ["dinner", "travel", "entertainment", "dining", "trip"], "season": "fall", "venues": ["luna rotisserie and empanadas", "pie pusher's", "copa", "the pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["desert", "land", "outdoor", "sky", "sunset sunrise"], "place_names": ["royal palms state beach"], "streets": [], "neighborhoods": ["san pedro"], "city": "los angeles", "locality_names": [], "state": "california", "state_abbreviation": "", "country": "united states", "bodies_of_water": ["catalina channel"], "month": "november", "year": "2017", "holidays": [], "activities": ["beach activity", "activity"], "season": "fall", "venues": [], "venue_types": [], "media_types": ["live photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["bench", "people", "water body", "land", "water", "furniture", "plant", "outdoor", "vegetation", "forest"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "december", "year": "2014", "holidays": ["christmas day"], "activities": ["celebration", "holiday"], "season": "winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_ALL": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["Butter", "Food", "Durham Bulls Athletic Park", "Blackwell St", "American Tobacco District", "Downtown Durham", "Durham", "Dinner", "Travel", "Entertainment", "Dining", "Trip", "Luna Rotisserie and Empanadas", "Pie Pusher's", "Copa", "The Pinhook", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Desert", "Land", "Outdoor", "Sky", "Sunset Sunrise", "Royal Palms State Beach", "San Pedro", "Catalina Channel", "Beach Activity", "Activity", "Live Photos", "Los Angeles", "California", "United States", "November", "2017", "Fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["Bench", "People", "Water Body", "Land", "Water", "Furniture", "Plant", "Outdoor", "Vegetation", "Forest", "Christmas Day", "Celebration", "Holiday", "December", "2014", "Winter"]}, "UUID_SEARCH_INFO_ALL_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["butter", "food", "durham bulls athletic park", "blackwell st", "american tobacco district", "downtown durham", "durham", "dinner", "travel", "entertainment", "dining", "trip", "luna rotisserie and empanadas", "pie pusher's", "copa", "the pinhook", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["desert", "land", "outdoor", "sky", "sunset sunrise", "royal palms state beach", "san pedro", "catalina channel", "beach activity", "activity", "live photos", "los angeles", "california", "united states", "november", "2017", "fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["bench", "people", "water body", "land", "water", "furniture", "plant", "outdoor", "vegetation", "forest", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} +{"UUID_SEARCH_INFO": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["Food", "Butter"], "place_names": ["Durham Bulls Athletic Park"], "streets": ["Blackwell St"], "neighborhoods": ["American Tobacco District", "Downtown Durham"], "city": "Durham", "locality_names": ["Durham"], "state": "North Carolina", "state_abbreviation": "NC", "country": "United States", "bodies_of_water": [], "month": "October", "year": "2018", "holidays": [], "activities": ["Dinner", "Travel", "Entertainment", "Dining", "Trip"], "season": "Fall", "venues": ["Luna Rotisserie and Empanadas", "Copa", "Pie Pusher's", "The Pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Land", "Desert", "Outdoor", "Sky", "Sunset Sunrise"], "place_names": ["Royal Palms State Beach"], "streets": [], "neighborhoods": ["San Pedro"], "city": "Los Angeles", "locality_names": [], "state": "California", "state_abbreviation": "", "country": "United States", "bodies_of_water": ["Catalina Channel"], "month": "November", "year": "2017", "holidays": [], "activities": ["Beach Activity", "Activity"], "season": "Fall", "venues": [], "venue_types": [], "media_types": ["Live Photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["Furniture", "Bench", "Vegetation", "Forest", "People", "Outdoor", "Land", "Water", "Water Body"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "December", "year": "2014", "holidays": ["Christmas Day"], "activities": ["Celebration", "Holiday"], "season": "Winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["food", "butter"], "place_names": ["durham bulls athletic park"], "streets": ["blackwell st"], "neighborhoods": ["american tobacco district", "downtown durham"], "city": "durham", "locality_names": ["durham"], "state": "north carolina", "state_abbreviation": "nc", "country": "united states", "bodies_of_water": [], "month": "october", "year": "2018", "holidays": [], "activities": ["dinner", "travel", "entertainment", "dining", "trip"], "season": "fall", "venues": ["luna rotisserie and empanadas", "copa", "pie pusher's", "the pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["land", "desert", "outdoor", "sky", "sunset sunrise"], "place_names": ["royal palms state beach"], "streets": [], "neighborhoods": ["san pedro"], "city": "los angeles", "locality_names": [], "state": "california", "state_abbreviation": "", "country": "united states", "bodies_of_water": ["catalina channel"], "month": "november", "year": "2017", "holidays": [], "activities": ["beach activity", "activity"], "season": "fall", "venues": [], "venue_types": [], "media_types": ["live photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["furniture", "bench", "vegetation", "forest", "people", "outdoor", "land", "water", "water body"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "december", "year": "2014", "holidays": ["christmas day"], "activities": ["celebration", "holiday"], "season": "winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_ALL": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["Food", "Butter", "Durham Bulls Athletic Park", "Blackwell St", "American Tobacco District", "Downtown Durham", "Durham", "Dinner", "Travel", "Entertainment", "Dining", "Trip", "Luna Rotisserie and Empanadas", "Copa", "Pie Pusher's", "The Pinhook", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Land", "Desert", "Outdoor", "Sky", "Sunset Sunrise", "Royal Palms State Beach", "San Pedro", "Catalina Channel", "Beach Activity", "Activity", "Live Photos", "Los Angeles", "California", "United States", "November", "2017", "Fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["Furniture", "Bench", "Vegetation", "Forest", "People", "Outdoor", "Land", "Water", "Water Body", "Christmas Day", "Celebration", "Holiday", "December", "2014", "Winter"]}, "UUID_SEARCH_INFO_ALL_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["food", "butter", "durham bulls athletic park", "blackwell st", "american tobacco district", "downtown durham", "durham", "dinner", "travel", "entertainment", "dining", "trip", "luna rotisserie and empanadas", "copa", "pie pusher's", "the pinhook", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["land", "desert", "outdoor", "sky", "sunset sunrise", "royal palms state beach", "san pedro", "catalina channel", "beach activity", "activity", "live photos", "los angeles", "california", "united states", "november", "2017", "fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["furniture", "bench", "vegetation", "forest", "people", "outdoor", "land", "water", "water body", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} diff --git a/tests/test_cli.py b/tests/test_cli.py index 74c659e1..96e67a35 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,4 +1,4 @@ -""" Test the command line interface (CLI) """ +r""" Test the command line interface (CLI) """ import os @@ -354,7 +354,7 @@ CLI_EXIFTOOL = { "EXIF:ImageDescription": "Girl holding pumpkin", "XMP:Description": "Girl holding pumpkin", "XMP:PersonInImage": "Katie", - "XMP:Subject": ["Kids", "Katie"], + "XMP:Subject": "Kids", "EXIF:GPSLatitudeRef": "N", "EXIF:GPSLongitudeRef": "W", "EXIF:GPSLatitude": 41.256566, @@ -395,7 +395,7 @@ CLI_EXIFTOOL_IGNORE_DATE_MODIFIED = { "XMP:TagsList": "wedding", "IPTC:Keywords": "wedding", "XMP:PersonInImage": "Maria", - "XMP:Subject": ["wedding", "Maria"], + "XMP:Subject": "wedding", "EXIF:DateTimeOriginal": "2019:04:15 14:40:24", "EXIF:CreateDate": "2019:04:15 14:40:24", "EXIF:OffsetTimeOriginal": "-04:00", @@ -3135,7 +3135,7 @@ def test_export_sidecar_keyword_template(): "XMP:TagsList": ["Kids", "Multi Keyword", "Pumpkin Farm", "Test Album"], "IPTC:Keywords": ["Kids", "Multi Keyword", "Pumpkin Farm", "Test Album"], "XMP:PersonInImage": ["Katie"], - "XMP:Subject": ["Kids", "Katie"], + "XMP:Subject": ["Kids", "Multi Keyword", "Pumpkin Farm", "Test Album"], "EXIF:DateTimeOriginal": "2018:09:28 16:07:07", "EXIF:CreateDate": "2018:09:28 16:07:07", "EXIF:OffsetTimeOriginal": "-04:00", diff --git a/tests/test_export_catalina_10_15_7.py b/tests/test_export_catalina_10_15_7.py index 708678e4..b24d3610 100644 --- a/tests/test_export_catalina_10_15_7.py +++ b/tests/test_export_catalina_10_15_7.py @@ -1,5 +1,6 @@ import pytest +import osxphotos from osxphotos._constants import _UNKNOWN_PERSON from osxphotos.exiftool import get_exiftool_path from osxphotos.utils import dd_to_dms_str @@ -12,6 +13,12 @@ except: PHOTOS_DB = "./tests/Test-10.15.7.photoslibrary/database/photos.db" + +@pytest.fixture(scope="module") +def photosdb(): + return osxphotos.PhotosDB(dbfile=PHOTOS_DB) + + KEYWORDS = [ "Kids", "wedding", @@ -22,7 +29,7 @@ KEYWORDS = [ "St. James's Park", "UK", "United Kingdom", - "Maria" + "Maria", ] # Photos 5 includes blank person for detected face PERSONS = ["Katie", "Suzy", "Maria", _UNKNOWN_PERSON] @@ -100,18 +107,15 @@ EXIF_JSON_EXPECTED_IGNORE_DATE_MODIFIED = """ """ -def test_export_1(): +def test_export_1(photosdb): # test basic export # get an unedited image and export it using default filename import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -122,18 +126,15 @@ def test_export_1(): assert os.path.isfile(got_dest) -def test_export_2(): +def test_export_2(photosdb): # test export with user provided filename import os import os.path import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) timestamp = time.time() @@ -145,18 +146,15 @@ def test_export_2(): assert os.path.isfile(got_dest) -def test_export_3(): +def test_export_3(photosdb): # test file already exists and test increment=True (default) import os import os.path import pathlib import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -172,7 +170,7 @@ def test_export_3(): assert os.path.isfile(got_dest_2) -def test_export_4(): +def test_export_4(photosdb): # test user supplied file already exists and test increment=True (default) import os import os.path @@ -180,11 +178,8 @@ def test_export_4(): import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) timestamp = time.time() @@ -200,18 +195,15 @@ def test_export_4(): assert os.path.isfile(got_dest_2) -def test_export_5(): +def test_export_5(photosdb): # test file already exists and test increment=True (default) # and overwrite = True import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -225,7 +217,7 @@ def test_export_5(): assert os.path.isfile(got_dest_2) -def test_export_6(): +def test_export_6(photosdb): # test user supplied file already exists and test increment=True (default) # and overwrite = True import os @@ -234,11 +226,8 @@ def test_export_6(): import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) timestamp = time.time() @@ -253,18 +242,15 @@ def test_export_6(): assert os.path.isfile(got_dest_2) -def test_export_7(): +def test_export_7(photosdb): # test file already exists and test increment=False (not default), overwrite=False (default) # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -277,18 +263,15 @@ def test_export_7(): assert e.type == type(FileExistsError()) -def test_export_8(): +def test_export_8(photosdb): # try to export missing file # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["missing"]]) filename = photos[0].filename @@ -299,18 +282,15 @@ def test_export_8(): assert e.type == type(FileNotFoundError()) -def test_export_9(): +def test_export_9(photosdb): # try to export edited file that's not edited # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]]) with pytest.raises(Exception) as e: @@ -318,7 +298,7 @@ def test_export_9(): assert e.type == ValueError -def test_export_10(): +def test_export_10(photosdb): # try to export edited file that's not edited and name provided # should raise exception import os @@ -326,11 +306,8 @@ def test_export_10(): import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]]) timestamp = time.time() @@ -342,18 +319,15 @@ def test_export_10(): assert e.type == ValueError -def test_export_11(): +def test_export_11(photosdb): # export edited file with name provided import os import os.path import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]]) timestamp = time.time() @@ -364,18 +338,15 @@ def test_export_11(): assert got_dest == expected_dest -def test_export_12(): +def test_export_12(photosdb): # export edited file with default name import os import os.path import pathlib import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]]) edited_name = pathlib.Path(photos[0].path_edited).name @@ -387,15 +358,13 @@ def test_export_12(): assert got_dest == expected_dest -def test_export_13(): +def test_export_13(photosdb): # export to invalid destination # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name @@ -405,7 +374,6 @@ def test_export_13(): dest = os.path.join(dest, str(i)) i += 1 - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -417,7 +385,6 @@ def test_export_13(): def test_dd_to_dms_str_1(): - import osxphotos lat_str, lon_str = dd_to_dms_str( 34.559331096, 69.206499174 @@ -428,7 +395,6 @@ def test_dd_to_dms_str_1(): def test_dd_to_dms_str_2(): - import osxphotos lat_str, lon_str = dd_to_dms_str( -34.601997592, -58.375665164 @@ -439,7 +405,6 @@ def test_dd_to_dms_str_2(): def test_dd_to_dms_str_3(): - import osxphotos lat_str, lon_str = dd_to_dms_str( -1.2666656, 36.7999968 @@ -450,7 +415,6 @@ def test_dd_to_dms_str_3(): def test_dd_to_dms_str_4(): - import osxphotos lat_str, lon_str = dd_to_dms_str( 38.889248, -77.050636 @@ -460,11 +424,9 @@ def test_dd_to_dms_str_4(): assert lon_str == "77 deg 3' 2.29\" W" -def test_exiftool_json_sidecar(): - import osxphotos +def test_exiftool_json_sidecar(photosdb): import json - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[EXIF_JSON_UUID]) json_expected = json.loads(EXIF_JSON_EXPECTED)[0] @@ -486,11 +448,9 @@ def test_exiftool_json_sidecar(): assert json_got[k] == v -def test_exiftool_json_sidecar_ignore_date_modified(): - import osxphotos +def test_exiftool_json_sidecar_ignore_date_modified(photosdb): import json - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[EXIF_JSON_UUID]) json_expected = json.loads(EXIF_JSON_EXPECTED_IGNORE_DATE_MODIFIED)[0] @@ -512,12 +472,10 @@ def test_exiftool_json_sidecar_ignore_date_modified(): assert json_got[k] == v -def test_exiftool_json_sidecar_keyword_template_long(caplog): - import osxphotos +def test_exiftool_json_sidecar_keyword_template_long(caplog, photosdb): from osxphotos._constants import _MAX_IPTC_KEYWORD_LEN import json - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[EXIF_JSON_UUID]) json_expected = json.loads( @@ -526,8 +484,8 @@ def test_exiftool_json_sidecar_keyword_template_long(caplog): "XMP:Description": "Bride Wedding day", "XMP:TagsList": ["Maria", "wedding", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"], "IPTC:Keywords": ["Maria", "wedding", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"], + "XMP:Subject": ["Maria", "wedding", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"], "XMP:PersonInImage": ["Maria"], - "XMP:Subject": ["wedding", "Maria"], "EXIF:DateTimeOriginal": "2019:04:15 14:40:24", "EXIF:CreateDate": "2019:04:15 14:40:24", "EXIF:OffsetTimeOriginal": "-04:00", @@ -562,11 +520,9 @@ def test_exiftool_json_sidecar_keyword_template_long(caplog): assert json_got[k] == v -def test_exiftool_json_sidecar_keyword_template(): - import osxphotos +def test_exiftool_json_sidecar_keyword_template(photosdb): import json - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[EXIF_JSON_UUID]) json_expected = json.loads( @@ -575,8 +531,8 @@ def test_exiftool_json_sidecar_keyword_template(): "XMP:Description": "Bride Wedding day", "XMP:TagsList": ["Maria", "wedding", "Folder1/SubFolder2/AlbumInFolder", "I have a deleted twin"], "IPTC:Keywords": ["Maria", "wedding", "Folder1/SubFolder2/AlbumInFolder", "I have a deleted twin"], + "XMP:Subject": ["Maria", "wedding", "Folder1/SubFolder2/AlbumInFolder", "I have a deleted twin"], "XMP:PersonInImage": ["Maria"], - "XMP:Subject": ["wedding", "Maria"], "EXIF:DateTimeOriginal": "2019:04:15 14:40:24", "EXIF:CreateDate": "2019:04:15 14:40:24", "EXIF:OffsetTimeOriginal": "-04:00", @@ -622,11 +578,9 @@ def test_exiftool_json_sidecar_keyword_template(): assert json_got[k] == v -def test_exiftool_json_sidecar_use_persons_keyword(): - import osxphotos +def test_exiftool_json_sidecar_use_persons_keyword(photosdb): import json - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) json_expected = json.loads( @@ -664,11 +618,9 @@ def test_exiftool_json_sidecar_use_persons_keyword(): assert json_got[k] == v -def test_exiftool_json_sidecar_use_albums_keyword(): - import osxphotos +def test_exiftool_json_sidecar_use_albums_keyword(photosdb): import json - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) json_expected = json.loads( @@ -679,7 +631,7 @@ def test_exiftool_json_sidecar_use_albums_keyword(): "XMP:TagsList": ["Kids", "Pumpkin Farm", "Test Album"], "IPTC:Keywords": ["Kids", "Pumpkin Farm", "Test Album"], "XMP:PersonInImage": ["Suzy", "Katie"], - "XMP:Subject": ["Kids", "Suzy", "Katie"], + "XMP:Subject": ["Kids", "Pumpkin Farm", "Test Album"], "EXIF:DateTimeOriginal": "2018:09:28 15:35:49", "EXIF:CreateDate": "2018:09:28 15:35:49", "EXIF:OffsetTimeOriginal": "-04:00", @@ -707,12 +659,10 @@ def test_exiftool_json_sidecar_use_albums_keyword(): @pytest.mark.skipif(exiftool is None, reason="exiftool not installed") -def test_xmp_sidecar_is_valid(tmp_path): +def test_xmp_sidecar_is_valid(tmp_path, photosdb): """ validate XMP sidecar file with exiftool """ - import osxphotos from osxphotos.exiftool import ExifTool - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) photos[0].export(str(tmp_path), XMP_JPG_FILENAME, sidecar_xmp=True) xmp_file = tmp_path / XMP_FILENAME @@ -722,10 +672,8 @@ def test_xmp_sidecar_is_valid(tmp_path): assert output == b"[ExifTool] Validate : 0 0 0" -def test_xmp_sidecar(): - import osxphotos +def test_xmp_sidecar(photosdb): - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) xmp_expected = """ @@ -738,12 +686,9 @@ def test_xmp_sidecar(): jpg Girls with pumpkins Can we carry this? - Kids - Suzy - Katie 2018-09-28T15:35:49.063000-04:00 @@ -787,11 +732,9 @@ def test_xmp_sidecar(): assert line_expected == line_got -def test_xmp_sidecar_extension(): +def test_xmp_sidecar_extension(photosdb): """ test XMP sidecar when no extension is passed """ - import osxphotos - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) xmp_expected = """ @@ -804,12 +747,9 @@ def test_xmp_sidecar_extension(): jpg Girls with pumpkins Can we carry this? - Kids - Suzy - Katie 2018-09-28T15:35:49.063000-04:00 @@ -853,10 +793,8 @@ def test_xmp_sidecar_extension(): assert line_expected == line_got -def test_xmp_sidecar_use_persons_keyword(): - import osxphotos +def test_xmp_sidecar_use_persons_keyword(photosdb): - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) xmp_expected = """ @@ -869,7 +807,6 @@ def test_xmp_sidecar_use_persons_keyword(): jpg Girls with pumpkins Can we carry this? - Kids @@ -920,10 +857,8 @@ def test_xmp_sidecar_use_persons_keyword(): assert line_expected == line_got -def test_xmp_sidecar_use_albums_keyword(): - import osxphotos +def test_xmp_sidecar_use_albums_keyword(photosdb): - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) xmp_expected = """ @@ -936,12 +871,11 @@ def test_xmp_sidecar_use_albums_keyword(): jpg Girls with pumpkins Can we carry this? - Kids - Suzy - Katie + Pumpkin Farm + Test Album 2018-09-28T15:35:49.063000-04:00 @@ -987,11 +921,9 @@ def test_xmp_sidecar_use_albums_keyword(): assert line_expected == line_got -def test_xmp_sidecar_gps(): +def test_xmp_sidecar_gps(photosdb): """ Test export XMP sidecar with GPS info """ - import osxphotos - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["location"]]) xmp_expected = """ @@ -1004,7 +936,6 @@ def test_xmp_sidecar_gps(): jpg St. James's Park - UK @@ -1057,10 +988,8 @@ def test_xmp_sidecar_gps(): assert line_expected == line_got -def test_xmp_sidecar_keyword_template(): - import osxphotos +def test_xmp_sidecar_keyword_template(photosdb): - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) xmp_expected = """ @@ -1073,12 +1002,12 @@ def test_xmp_sidecar_keyword_template(): jpg Girls with pumpkins Can we carry this? - Kids - Suzy - Katie + Pumpkin Farm + Test Album + 2018 2018-09-28T15:35:49.063000-04:00 diff --git a/tests/test_export_mojave_10_14_6.py b/tests/test_export_mojave_10_14_6.py index 24e93011..5fbab61b 100644 --- a/tests/test_export_mojave_10_14_6.py +++ b/tests/test_export_mojave_10_14_6.py @@ -1,9 +1,8 @@ import pytest +import osxphotos from osxphotos._constants import _UNKNOWN_PERSON -# TODO: put some of this code into a pre-function - PHOTOS_DB = "./tests/Test-10.14.6.photoslibrary/database/photos.db" PHOTOS_DB_PATH = "/Test-10.14.6.photoslibrary/database/photos.db" @@ -63,18 +62,20 @@ EXIF_JSON_EXPECTED = """ """ -def test_export_1(): +@pytest.fixture(scope="module") +def photosdb(): + return osxphotos.PhotosDB(dbfile=PHOTOS_DB) + + +def test_export_1(photosdb): # test basic export # get an unedited image and export it using default filename import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -85,18 +86,15 @@ def test_export_1(): assert os.path.isfile(got_dest) -def test_export_2(): +def test_export_2(photosdb): # test export with user provided filename import os import os.path import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) timestamp = time.time() @@ -108,18 +106,15 @@ def test_export_2(): assert os.path.isfile(got_dest) -def test_export_3(): +def test_export_3(photosdb): # test file already exists and test increment=True (default) import os import os.path import pathlib import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -135,7 +130,7 @@ def test_export_3(): assert os.path.isfile(got_dest_2) -def test_export_4(): +def test_export_4(photosdb): # test user supplied file already exists and test increment=True (default) import os import os.path @@ -143,11 +138,8 @@ def test_export_4(): import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) timestamp = time.time() @@ -163,18 +155,15 @@ def test_export_4(): assert os.path.isfile(got_dest_2) -def test_export_5(): +def test_export_5(photosdb): # test file already exists and test increment=True (default) # and overwrite = True import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -188,7 +177,7 @@ def test_export_5(): assert os.path.isfile(got_dest_2) -def test_export_6(): +def test_export_6(photosdb): # test user supplied file already exists and test increment=True (default) # and overwrite = True import os @@ -197,11 +186,8 @@ def test_export_6(): import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) timestamp = time.time() @@ -216,18 +202,15 @@ def test_export_6(): assert os.path.isfile(got_dest_2) -def test_export_7(): +def test_export_7(photosdb): # test file already exists and test increment=False (not default), overwrite=False (default) # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -240,18 +223,15 @@ def test_export_7(): assert e.type == type(FileExistsError()) -def test_export_8(): +def test_export_8(photosdb): # try to export missing file # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["missing"]]) filename = photos[0].filename @@ -262,18 +242,15 @@ def test_export_8(): assert e.type == type(FileNotFoundError()) -def test_export_9(): +def test_export_9(photosdb): # try to export edited file that's not edited # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]]) filename = photos[0].filename @@ -284,7 +261,7 @@ def test_export_9(): assert e.type == ValueError -def test_export_10(): +def test_export_10(photosdb): # try to export edited file that's not edited and name provided # should raise exception import os @@ -292,11 +269,8 @@ def test_export_10(): import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]]) timestamp = time.time() @@ -308,18 +282,15 @@ def test_export_10(): assert e.type == ValueError -def test_export_11(): +def test_export_11(photosdb): # export edited file with name provided import os import os.path import tempfile import time - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]]) timestamp = time.time() @@ -330,18 +301,15 @@ def test_export_11(): assert got_dest == expected_dest -def test_export_12(): +def test_export_12(photosdb): # export edited file with default name import os import os.path import pathlib import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]]) edited_name = pathlib.Path(photos[0].path_edited).name @@ -353,15 +321,13 @@ def test_export_12(): assert got_dest == expected_dest -def test_export_13(): +def test_export_13(photosdb): # export to invalid destination # should raise exception import os import os.path import tempfile - import osxphotos - tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_") dest = tempdir.name @@ -371,7 +337,6 @@ def test_export_13(): dest = os.path.join(dest, str(i)) i += 1 - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["export"]]) filename = photos[0].filename @@ -382,11 +347,9 @@ def test_export_13(): assert e.type == type(FileNotFoundError()) -def test_exiftool_json_sidecar(): - import osxphotos +def test_exiftool_json_sidecar(photosdb): import json - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["location"]]) json_expected = json.loads(EXIF_JSON_EXPECTED)[0] @@ -408,10 +371,8 @@ def test_exiftool_json_sidecar(): assert json_got[k] == v -def test_xmp_sidecar(): - import osxphotos +def test_xmp_sidecar(photosdb): - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) xmp_expected = """ @@ -424,12 +385,9 @@ def test_xmp_sidecar(): jpg Girls with pumpkins Can we carry this? - - Katie Kids - Suzy 2018-09-28T15:35:49.063000-04:00 @@ -471,10 +429,8 @@ def test_xmp_sidecar(): assert line_expected == line_got -def test_xmp_sidecar_keyword_template(): - import osxphotos +def test_xmp_sidecar_keyword_template(photosdb): - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) xmp_expected = """ @@ -487,12 +443,12 @@ def test_xmp_sidecar_keyword_template(): jpg Girls with pumpkins Can we carry this? - Kids - Suzy - Katie + Test Album + Pumpkin Farm + 2018 2018-09-28T15:35:49.063000-04:00 diff --git a/tests/test_search_info_10_15_7.py b/tests/test_search_info_10_15_7.py index 6eaea160..4215b463 100644 --- a/tests/test_search_info_10_15_7.py +++ b/tests/test_search_info_10_15_7.py @@ -32,15 +32,23 @@ def photosdb(): def test_search_info(photosdb): for uuid in UUID_SEARCH_INFO: photo = photosdb.get_photo(uuid) - assert photo.search_info.asdict() == UUID_SEARCH_INFO[uuid] + search_dict = photo.search_info.asdict() + for k, v in search_dict.items(): + if type(v) == list: + assert sorted(v) == sorted(UUID_SEARCH_INFO[uuid][k]) + else: + assert v == UUID_SEARCH_INFO[uuid][k] def test_search_info_normalized(photosdb): for uuid in UUID_SEARCH_INFO_NORMALIZED: photo = photosdb.get_photo(uuid) - assert ( - photo.search_info_normalized.asdict() == UUID_SEARCH_INFO_NORMALIZED[uuid] - ) + search_dict = photo.search_info_normalized.asdict() + for k, v in search_dict.items(): + if type(v) == list: + assert sorted(v) == sorted(UUID_SEARCH_INFO_NORMALIZED[uuid][k]) + else: + assert v == UUID_SEARCH_INFO_NORMALIZED[uuid][k] def test_search_info_all(photosdb):