Added tag_groups arg to ExifTool.asdict(), issue #324

This commit is contained in:
Rhet Turnbull
2021-01-03 10:28:44 -08:00
parent b1cab32ff4
commit 2480f2a325
3 changed files with 69 additions and 7 deletions

View File

@@ -1730,7 +1730,7 @@ exiftool must be installed in the path for this to work. If exiftool cannot be
`ExifTool` provides the following methods: `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 ```python
{'Composite:Aperture': 2.2, {'Composite:Aperture': 2.2,

View File

@@ -9,11 +9,11 @@
import json import json
import logging import logging
import os import os
import re
import shutil import shutil
import subprocess import subprocess
from functools import lru_cache # pylint: disable=syntax-error from functools import lru_cache # pylint: disable=syntax-error
# exiftool -stay_open commands outputs this EOF marker after command is run # exiftool -stay_open commands outputs this EOF marker after command is run
EXIFTOOL_STAYOPEN_EOF = "{ready}" EXIFTOOL_STAYOPEN_EOF = "{ready}"
EXIFTOOL_STAYOPEN_EOF_LEN = len(EXIFTOOL_STAYOPEN_EOF) EXIFTOOL_STAYOPEN_EOF_LEN = len(EXIFTOOL_STAYOPEN_EOF)
@@ -300,17 +300,28 @@ class ExifTool:
ver, _, _ = self.run_commands("-ver", no_file=True) ver, _, _ = self.run_commands("-ver", no_file=True)
return ver.decode("utf-8") return ver.decode("utf-8")
def asdict(self): def asdict(self, tag_groups=True):
"""return dictionary of all EXIF tags and values from exiftool """return dictionary of all EXIF tags and values from exiftool
returns empty dict if no tags 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") json_str, _, _ = self.run_commands("-json")
if json_str: if not json_str:
exifdict = json.loads(json_str)
return exifdict[0]
else:
return dict() 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): def json(self):
""" returns JSON string containing all EXIF tags and values from exiftool """ """ returns JSON string containing all EXIF tags and values from exiftool """
json, _, _ = self.run_commands("-json") json, _, _ = self.run_commands("-json")

View File

@@ -57,6 +57,36 @@ EXIF_UUID = {
"IPTC:DateCreated": "2019:04:15", "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"] EXIF_UUID_NONE = ["A1DD1F98-2ECD-431F-9AC9-5AFEFE2D3A5C"]
try: try:
@@ -319,6 +349,14 @@ def test_as_dict():
assert exifdata["XMP:TagsList"] == "wedding" 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(): def test_json():
import osxphotos.exiftool import osxphotos.exiftool
import json import json
@@ -349,6 +387,19 @@ def test_photoinfo_exiftool():
assert exif_dict[key] == val 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(): def test_photoinfo_exiftool_none():
import osxphotos import osxphotos