From 11459d1da4d7d13e36e9db4bdc940b74baad9d11 Mon Sep 17 00:00:00 2001 From: Rhet Turnbull Date: Sat, 31 Oct 2020 22:11:00 -0700 Subject: [PATCH] Updated --exiftool to set dates/times as Photos does, issue #247 --- osxphotos/_version.py | 2 +- osxphotos/photoinfo/_photoinfo_export.py | 21 +++++++++- tests/test_cli.py | 25 ++++++----- tests/test_export_catalina_10_15_7.py | 53 ++++++++++++++++-------- tests/test_export_mojave_10_14_6.py | 28 ++++++++----- 5 files changed, 88 insertions(+), 41 deletions(-) diff --git a/osxphotos/_version.py b/osxphotos/_version.py index e7388534..2b937502 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,4 +1,4 @@ """ version info """ -__version__ = "0.36.3" +__version__ = "0.36.4" diff --git a/osxphotos/photoinfo/_photoinfo_export.py b/osxphotos/photoinfo/_photoinfo_export.py index 92f6b48f..555f6da8 100644 --- a/osxphotos/photoinfo/_photoinfo_export.py +++ b/osxphotos/photoinfo/_photoinfo_export.py @@ -1137,19 +1137,38 @@ def _exiftool_json_sidecar( exif["EXIF:GPSLongitudeRef"] = lon_ref # process date/time and timezone offset + # Photos exports the following fields and sets modify date to creation date + # [EXIF] Modify Date : 2020:10:30 00:00:00 + # [EXIF] Date/Time Original : 2020:10:30 00:00:00 + # [EXIF] Create Date : 2020:10:30 00:00:00 + # [IPTC] Digital Creation Date : 2020:10:30 + # [IPTC] Date Created : 2020:10:30 + # + # This code deviates from Photos in one regard: + # if photo has modification date, use it otherwise use creation date date = self.date + # exiftool expects format to "2015:01:18 12:00:00" datetimeoriginal = date.strftime("%Y:%m:%d %H:%M:%S") + exif["EXIF:DateTimeOriginal"] = datetimeoriginal + exif["EXIF:CreateDate"] = datetimeoriginal + offsettime = date.strftime("%z") # find timezone offset in format "-04:00" offset = re.findall(r"([+-]?)([\d]{2})([\d]{2})", offsettime) offset = offset[0] # findall returns list of tuples offsettime = f"{offset[0]}{offset[1]}:{offset[2]}" - exif["EXIF:DateTimeOriginal"] = datetimeoriginal exif["EXIF:OffsetTimeOriginal"] = offsettime + dateoriginal = date.strftime("%Y:%m:%d") + exif["IPTC:DigitalCreationDate"] = dateoriginal + exif["IPTC:DateCreated"] = dateoriginal + if self.date_modified is not None: exif["EXIF:ModifyDate"] = self.date_modified.strftime("%Y:%m:%d %H:%M:%S") + else: + exif["EXIF:ModifyDate"] = self.date.strftime("%Y:%m:%d %H:%M:%S") + json_str = json.dumps([exif]) return json_str diff --git a/tests/test_cli.py b/tests/test_cli.py index 1105ff7a..09f44f64 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2632,16 +2632,21 @@ def test_export_sidecar_keyword_template(): json_expected = json.loads( """ - [{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", - "EXIF:ImageDescription": "Girl holding pumpkin", - "XMP:Description": "Girl holding pumpkin", - "XMP:Title": "I found one!", - "XMP:TagsList": ["Kids", "Multi Keyword", "Test Album", "Pumpkin Farm"], - "IPTC:Keywords": ["Kids", "Multi Keyword", "Test Album", "Pumpkin Farm"], - "XMP:PersonInImage": ["Katie"], - "XMP:Subject": ["Kids", "Katie"], - "EXIF:DateTimeOriginal": "2018:09:28 16:07:07", - "EXIF:OffsetTimeOriginal": "-04:00"}]""" + [{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", + "EXIF:ImageDescription": "Girl holding pumpkin", + "XMP:Description": "Girl holding pumpkin", + "XMP:Title": "I found one!", + "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"], + "EXIF:DateTimeOriginal": "2018:09:28 16:07:07", + "EXIF:CreateDate": "2018:09:28 16:07:07", + "EXIF:OffsetTimeOriginal": "-04:00", + "IPTC:DigitalCreationDate": "2018:09:28", + "IPTC:DateCreated": "2018:09:28", + "EXIF:ModifyDate": "2018:09:28 16:07:07"}] + """ )[0] with open("Pumkins2.jpg.json", "r") as json_file: diff --git a/tests/test_export_catalina_10_15_7.py b/tests/test_export_catalina_10_15_7.py index 90dc3243..e285cee0 100644 --- a/tests/test_export_catalina_10_15_7.py +++ b/tests/test_export_catalina_10_15_7.py @@ -67,18 +67,21 @@ XMP_FILENAME = "Pumkins1.jpg.xmp" XMP_JPG_FILENAME = "Pumkins1.jpg" EXIF_JSON_UUID = UUID_DICT["has_adjustments"] -EXIF_JSON_EXPECTED = ( - '[{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", ' - '"EXIF:ImageDescription": "Bride Wedding day", ' - '"XMP:Description": "Bride Wedding day", ' - '"XMP:TagsList": ["wedding"], ' - '"IPTC:Keywords": ["wedding"], ' - '"XMP:PersonInImage": ["Maria"], ' - '"XMP:Subject": ["wedding", "Maria"], ' - '"EXIF:DateTimeOriginal": "2019:04:15 14:40:24", ' - '"EXIF:OffsetTimeOriginal": "-04:00", ' - '"EXIF:ModifyDate": "2019:07:27 17:33:28"}]' -) +EXIF_JSON_EXPECTED = """ + [{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", + "EXIF:ImageDescription": "Bride Wedding day", + "XMP:Description": "Bride Wedding day", + "XMP:TagsList": ["wedding"], + "IPTC:Keywords": ["wedding"], + "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", + "IPTC:DigitalCreationDate": "2019:04:15", + "IPTC:DateCreated": "2019:04:15", + "EXIF:ModifyDate": "2019:07:27 17:33:28"}] + """ def test_export_1(): @@ -507,7 +510,10 @@ def test_exiftool_json_sidecar_keyword_template_long(caplog): "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", + "IPTC:DigitalCreationDate": "2019:04:15", + "IPTC:DateCreated": "2019:04:15", "EXIF:ModifyDate": "2019:07:27 17:33:28"}] """ )[0] @@ -552,9 +558,12 @@ def test_exiftool_json_sidecar_keyword_template(): "XMP:TagsList": ["wedding", "Folder1/SubFolder2/AlbumInFolder", "I have a deleted twin"], "IPTC:Keywords": ["wedding", "Folder1/SubFolder2/AlbumInFolder", "I have a deleted twin"], "XMP:PersonInImage": ["Maria"], - "XMP:Subject": ["wedding", "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", + "IPTC:DigitalCreationDate": "2019:04:15", + "IPTC:DateCreated": "2019:04:15", "EXIF:ModifyDate": "2019:07:27 17:33:28"}] """ )[0] @@ -609,11 +618,15 @@ def test_exiftool_json_sidecar_use_persons_keyword(): "XMP:Description": "Girls with pumpkins", "XMP:Title": "Can we carry this?", "XMP:TagsList": ["Kids", "Suzy", "Katie"], - "IPTC:Keywords": ["Kids", "Suzy", "Katie"], - "XMP:PersonInImage": ["Suzy", "Katie"], - "XMP:Subject": ["Kids", "Suzy", "Katie"], + "IPTC:Keywords": ["Kids", "Suzy", "Katie"], + "XMP:PersonInImage": ["Suzy", "Katie"], + "XMP:Subject": ["Kids", "Suzy", "Katie"], "EXIF:DateTimeOriginal": "2018:09:28 15:35:49", - "EXIF:OffsetTimeOriginal": "-04:00"}] + "EXIF:CreateDate": "2018:09:28 15:35:49", + "EXIF:OffsetTimeOriginal": "-04:00", + "IPTC:DigitalCreationDate": "2018:09:28", + "IPTC:DateCreated": "2018:09:28", + "EXIF:ModifyDate": "2018:09:28 15:35:49"}] """ )[0] @@ -652,7 +665,11 @@ def test_exiftool_json_sidecar_use_albums_keyword(): "XMP:PersonInImage": ["Suzy", "Katie"], "XMP:Subject": ["Kids", "Suzy", "Katie"], "EXIF:DateTimeOriginal": "2018:09:28 15:35:49", - "EXIF:OffsetTimeOriginal": "-04:00"}] + "EXIF:CreateDate": "2018:09:28 15:35:49", + "EXIF:OffsetTimeOriginal": "-04:00", + "IPTC:DigitalCreationDate": "2018:09:28", + "IPTC:DateCreated": "2018:09:28", + "EXIF:ModifyDate": "2018:09:28 15:35:49"}] """ )[0] diff --git a/tests/test_export_mojave_10_14_6.py b/tests/test_export_mojave_10_14_6.py index a9350b75..9354d6bf 100644 --- a/tests/test_export_mojave_10_14_6.py +++ b/tests/test_export_mojave_10_14_6.py @@ -45,17 +45,23 @@ UUID_DICT = { "xmp": "8SOE9s0XQVGsuq4ONohTng", } -EXIF_JSON_EXPECTED = ( - '[{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", ' - '"XMP:Title": "St. James\'s Park", "XMP:TagsList": ["UK", "England", ' - '"London", "United Kingdom", "London 2018", "St. James\'s Park"], ' - '"IPTC:Keywords": ["UK", "England", "London", "United Kingdom", "London 2018", ' - '"St. James\'s Park"], "XMP:Subject": ["UK", "England", "London", "United Kingdom", ' - '"London 2018", "St. James\'s Park"], "EXIF:GPSLatitude": 51.50357167, ' - '"EXIF:GPSLongitude": -0.1318055, "EXIF:GPSLatitudeRef": "N", ' - '"EXIF:GPSLongitudeRef": "W", "EXIF:DateTimeOriginal": "2018:10:13 09:18:12", ' - '"EXIF:OffsetTimeOriginal": "-04:00", "EXIF:ModifyDate": "2019:12:01 11:43:45"}]' -) +EXIF_JSON_EXPECTED = """ + [{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", + "XMP:Title": "St. James\'s Park", + "XMP:TagsList": ["UK", "England", "London", "United Kingdom", "London 2018", "St. James\'s Park"], + "IPTC:Keywords": ["UK", "England", "London", "United Kingdom", "London 2018", "St. James\'s Park"], + "XMP:Subject": ["UK", "England", "London", "United Kingdom", "London 2018", "St. James\'s Park"], + "EXIF:GPSLatitude": 51.50357167, + "EXIF:GPSLongitude": -0.1318055, + "EXIF:GPSLatitudeRef": "N", + "EXIF:GPSLongitudeRef": "W", + "EXIF:DateTimeOriginal": "2018:10:13 09:18:12", + "EXIF:CreateDate": "2018:10:13 09:18:12", + "EXIF:OffsetTimeOriginal": "-04:00", + "IPTC:DigitalCreationDate": "2018:10:13", + "IPTC:DateCreated": "2018:10:13", + "EXIF:ModifyDate": "2019:12:01 11:43:45"}] + """ def test_export_1():