diff --git a/README.md b/README.md index 11200dc1..707d6825 100644 --- a/README.md +++ b/README.md @@ -1730,7 +1730,7 @@ exiftool must be installed in the path for this to work. If exiftool cannot be `ExifTool` provides the following methods: -- `asdict()`: returns all EXIF metadata found in the file as a dictionary in following form (Note: this shows just a subset of available metadata). See [exiftool](https://exiftool.org/) documentation to understand which metadata keys are available. +- `asdict(tag_groups=True)`: returns all EXIF metadata found in the file as a dictionary in following form (Note: this shows just a subset of available metadata). See [exiftool](https://exiftool.org/) documentation to understand which metadata keys are available. If `tag_groups` is True (default) dict keys are in form "GROUP:TAG", e.g. "IPTC:Keywords". If `tag_groups` is False, dict keys do not have group names, e.g. "Keywords". ```python {'Composite:Aperture': 2.2, diff --git a/osxphotos/exiftool.py b/osxphotos/exiftool.py index 8f83eb4a..f0a3678c 100644 --- a/osxphotos/exiftool.py +++ b/osxphotos/exiftool.py @@ -9,11 +9,11 @@ import json import logging import os +import re import shutil import subprocess from functools import lru_cache # pylint: disable=syntax-error - # exiftool -stay_open commands outputs this EOF marker after command is run EXIFTOOL_STAYOPEN_EOF = "{ready}" EXIFTOOL_STAYOPEN_EOF_LEN = len(EXIFTOOL_STAYOPEN_EOF) @@ -300,17 +300,28 @@ class ExifTool: ver, _, _ = self.run_commands("-ver", no_file=True) return ver.decode("utf-8") - def asdict(self): + def asdict(self, tag_groups=True): """return dictionary of all EXIF tags and values from exiftool returns empty dict if no tags + + Args: + tag_groups: if True (default), dict keys have tag groups, e.g. "IPTC:Keywords"; if False, drops groups from keys, e.g. "Keywords" """ json_str, _, _ = self.run_commands("-json") - if json_str: - exifdict = json.loads(json_str) - return exifdict[0] - else: + if not json_str: return dict() + exifdict = json.loads(json_str) + exifdict = exifdict[0] + if not tag_groups: + # strip tag groups + exif_new = {} + for k, v in exifdict.items(): + k = re.sub(r".*:", "", k) + exif_new[k] = v + exifdict = exif_new + return exifdict + def json(self): """ returns JSON string containing all EXIF tags and values from exiftool """ json, _, _ = self.run_commands("-json") diff --git a/tests/test_exiftool.py b/tests/test_exiftool.py index 241c86c7..2897f5cf 100644 --- a/tests/test_exiftool.py +++ b/tests/test_exiftool.py @@ -57,6 +57,36 @@ EXIF_UUID = { "IPTC:DateCreated": "2019:04:15", }, } +EXIF_UUID_NO_GROUPS = { + "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4": { + "DateTimeOriginal": "2019:07:04 16:24:01", + "LensModel": "XF18-55mmF2.8-4 R LM OIS", + "Keywords": [ + "Digital Nomad", + "Indoor", + "Reiseblogger", + "Stock Photography", + "Top Shot", + "close up", + "colorful", + "design", + "display", + "fake", + "flower", + "outdoor", + "photography", + "plastic", + "stock photo", + "vibrant", + ], + "DocumentNotes": "https://flickr.com/e/l7FkSm4f2lQkSV3CG6xlv8Sde5uF3gVu4Hf0Qk11AnU%3D", + }, + "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51": { + "Make": "NIKON CORPORATION", + "Model": "NIKON D810", + "DateCreated": "2019:04:15", + }, +} EXIF_UUID_NONE = ["A1DD1F98-2ECD-431F-9AC9-5AFEFE2D3A5C"] try: @@ -319,6 +349,14 @@ def test_as_dict(): assert exifdata["XMP:TagsList"] == "wedding" +def test_as_dict_no_tag_groups(): + import osxphotos.exiftool + + exif1 = osxphotos.exiftool.ExifTool(TEST_FILE_ONE_KEYWORD) + exifdata = exif1.asdict(tag_groups=False) + assert exifdata["TagsList"] == "wedding" + + def test_json(): import osxphotos.exiftool import json @@ -349,6 +387,19 @@ def test_photoinfo_exiftool(): assert exif_dict[key] == val +def test_photoinfo_exiftool_no_groups(): + """ test PhotoInfo.exiftool which returns ExifTool object for photo without tag group names""" + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + for uuid in EXIF_UUID_NO_GROUPS: + photo = photosdb.photos(uuid=[uuid])[0] + exiftool = photo.exiftool + exif_dict = exiftool.asdict(tag_groups=False) + for key, val in EXIF_UUID_NO_GROUPS[uuid].items(): + assert exif_dict[key] == val + + def test_photoinfo_exiftool_none(): import osxphotos