parent
091f1d9bb4
commit
603dabb8f4
15
README.md
15
README.md
@ -1294,7 +1294,8 @@ 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:
|
||||||
|
|
||||||
- `as_dict()`: 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()`: 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.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
{'Composite:Aperture': 2.2,
|
{'Composite:Aperture': 2.2,
|
||||||
'Composite:GPSPosition': '-34.9188916666667 138.596861111111',
|
'Composite:GPSPosition': '-34.9188916666667 138.596861111111',
|
||||||
@ -1307,7 +1308,7 @@ exiftool must be installed in the path for this to work. If exiftool cannot be
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `json()`: returns same information as `as_dict()` but as a serialized JSON string.
|
- `json()`: returns same information as `asdict()` but as a serialized JSON string.
|
||||||
|
|
||||||
- `setvalue(tag, value)`: write to the EXIF data in the photo file. To delete a tag, use setvalue with value = `None`. For example:
|
- `setvalue(tag, value)`: write to the EXIF data in the photo file. To delete a tag, use setvalue with value = `None`. For example:
|
||||||
```python
|
```python
|
||||||
@ -1318,7 +1319,7 @@ photo.exiftool.setvalue("XMP:Title", "Title of photo")
|
|||||||
photo.exiftool.addvalues("IPTC:Keywords", "vacation", "beach")
|
photo.exiftool.addvalues("IPTC:Keywords", "vacation", "beach")
|
||||||
```
|
```
|
||||||
|
|
||||||
**Caution**: I caution against writing new EXIF data to photos in the Photos library because this will overwrite the original copy of the photo and could adversely affect how Photos behaves. `exiftool.as_dict()` is useful for getting access to all the photos information but if you want to write new EXIF data, I recommend you export the photo first then write the data. [PhotoInfo.export()](#export) does this if called with `exiftool=True`.
|
**Caution**: I caution against writing new EXIF data to photos in the Photos library because this will overwrite the original copy of the photo and could adversely affect how Photos behaves. `exiftool.asdict()` is useful for getting access to all the photos information but if you want to write new EXIF data, I recommend you export the photo first then write the data. [PhotoInfo.export()](#export) does this if called with `exiftool=True`.
|
||||||
|
|
||||||
#### `score`
|
#### `score`
|
||||||
Returns a [ScoreInfo](#scoreinfo) data class object which provides access to the computed aesthetic scores for each photo.
|
Returns a [ScoreInfo](#scoreinfo) data class object which provides access to the computed aesthetic scores for each photo.
|
||||||
@ -1326,7 +1327,10 @@ Returns a [ScoreInfo](#scoreinfo) data class object which provides access to the
|
|||||||
**Note**: Valid only for Photos 5; returns None for earlier Photos versions.
|
**Note**: Valid only for Photos 5; returns None for earlier Photos versions.
|
||||||
|
|
||||||
#### `json()`
|
#### `json()`
|
||||||
Returns a JSON representation of all photo info
|
Returns a JSON representation of all photo info.
|
||||||
|
|
||||||
|
#### `asdict()`
|
||||||
|
Returns a dictionary representation of all photo info.
|
||||||
|
|
||||||
#### `export()`
|
#### `export()`
|
||||||
`export(dest, *filename, edited=False, live_photo=False, export_as_hardlink=False, overwrite=False, increment=True, sidecar_json=False, sidecar_xmp=False, use_photos_export=False, timeout=120, exiftool=False, no_xattr=False, use_albums_as_keywords=False, use_persons_as_keywords=False)`
|
`export(dest, *filename, edited=False, live_photo=False, export_as_hardlink=False, overwrite=False, increment=True, sidecar_json=False, sidecar_xmp=False, use_photos_export=False, timeout=120, exiftool=False, no_xattr=False, use_albums_as_keywords=False, use_persons_as_keywords=False)`
|
||||||
@ -1674,6 +1678,9 @@ Returns a list of [FaceInfo](#faceinfo) objects associated with this person sort
|
|||||||
#### `json()`
|
#### `json()`
|
||||||
Returns a json string representation of the PersonInfo instance.
|
Returns a json string representation of the PersonInfo instance.
|
||||||
|
|
||||||
|
#### `asdict()`
|
||||||
|
Returns a dictionary representation of the PersonInfo instance.
|
||||||
|
|
||||||
### FaceInfo
|
### FaceInfo
|
||||||
[PhotoInfo.face_info](#photofaceinfo) return a list of FaceInfo objects representing detected faces in a photo. The FaceInfo class has the following properties and methods.
|
[PhotoInfo.face_info](#photofaceinfo) return a list of FaceInfo objects representing detected faces in a photo. The FaceInfo class has the following properties and methods.
|
||||||
|
|
||||||
|
|||||||
@ -228,7 +228,7 @@ 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 as_dict(self):
|
def asdict(self):
|
||||||
""" 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
|
||||||
"""
|
"""
|
||||||
@ -245,7 +245,7 @@ class ExifTool:
|
|||||||
|
|
||||||
def _read_exif(self):
|
def _read_exif(self):
|
||||||
""" read exif data from file """
|
""" read exif data from file """
|
||||||
data = self.as_dict()
|
data = self.asdict()
|
||||||
self.data = {k: v for k, v in data.items()}
|
self.data = {k: v for k, v in data.items()}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@ -66,10 +66,10 @@ class PersonInfo:
|
|||||||
# no faces
|
# no faces
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def json(self):
|
def asdict(self):
|
||||||
""" Returns JSON representation of class instance """
|
""" Returns dictionary representation of class instance """
|
||||||
keyphoto = self.keyphoto.uuid if self.keyphoto is not None else None
|
keyphoto = self.keyphoto.uuid if self.keyphoto is not None else None
|
||||||
person = {
|
return {
|
||||||
"uuid": self.uuid,
|
"uuid": self.uuid,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"displayname": self.display_name,
|
"displayname": self.display_name,
|
||||||
@ -77,7 +77,10 @@ class PersonInfo:
|
|||||||
"facecount": self.facecount,
|
"facecount": self.facecount,
|
||||||
"keyphoto": keyphoto,
|
"keyphoto": keyphoto,
|
||||||
}
|
}
|
||||||
return json.dumps(person)
|
|
||||||
|
def json(self):
|
||||||
|
""" Returns JSON representation of class instance """
|
||||||
|
return json.dumps(self.asdict())
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"PersonInfo(name={self.name}, display_name={self.display_name}, uuid={self.uuid}, facecount={self.facecount})"
|
return f"PersonInfo(name={self.name}, display_name={self.display_name}, uuid={self.uuid}, facecount={self.facecount})"
|
||||||
|
|||||||
@ -5,6 +5,7 @@ PhotosDB.photos() returns a list of PhotoInfo objects
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import datetime
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@ -950,22 +951,23 @@ class PhotoInfo:
|
|||||||
}
|
}
|
||||||
return yaml.dump(info, sort_keys=False)
|
return yaml.dump(info, sort_keys=False)
|
||||||
|
|
||||||
def json(self):
|
def asdict(self):
|
||||||
""" return JSON representation """
|
""" return dict representation """
|
||||||
|
|
||||||
date_modified_iso = (
|
|
||||||
self.date_modified.isoformat() if self.date_modified else None
|
|
||||||
)
|
|
||||||
folders = {album.title: album.folder_names for album in self.album_info}
|
folders = {album.title: album.folder_names for album in self.album_info}
|
||||||
exif = dataclasses.asdict(self.exif_info) if self.exif_info else {}
|
exif = dataclasses.asdict(self.exif_info) if self.exif_info else {}
|
||||||
place = self.place.as_dict() if self.place else {}
|
place = self.place.asdict() if self.place else {}
|
||||||
score = dataclasses.asdict(self.score) if self.score else {}
|
score = dataclasses.asdict(self.score) if self.score else {}
|
||||||
|
comments = [comment.asdict() for comment in self.comments]
|
||||||
|
likes = [like.asdict() for like in self.likes]
|
||||||
|
faces = [face.asdict() for face in self.face_info]
|
||||||
|
|
||||||
pic = {
|
return {
|
||||||
|
"library": self._db._library_path,
|
||||||
"uuid": self.uuid,
|
"uuid": self.uuid,
|
||||||
"filename": self.filename,
|
"filename": self.filename,
|
||||||
"original_filename": self.original_filename,
|
"original_filename": self.original_filename,
|
||||||
"date": self.date.isoformat(),
|
"date": self.date,
|
||||||
"description": self.description,
|
"description": self.description,
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
"keywords": self.keywords,
|
"keywords": self.keywords,
|
||||||
@ -974,6 +976,7 @@ class PhotoInfo:
|
|||||||
"albums": self.albums,
|
"albums": self.albums,
|
||||||
"folders": folders,
|
"folders": folders,
|
||||||
"persons": self.persons,
|
"persons": self.persons,
|
||||||
|
"faces": faces,
|
||||||
"path": self.path,
|
"path": self.path,
|
||||||
"ismissing": self.ismissing,
|
"ismissing": self.ismissing,
|
||||||
"hasadjustments": self.hasadjustments,
|
"hasadjustments": self.hasadjustments,
|
||||||
@ -987,12 +990,13 @@ class PhotoInfo:
|
|||||||
"isphoto": self.isphoto,
|
"isphoto": self.isphoto,
|
||||||
"ismovie": self.ismovie,
|
"ismovie": self.ismovie,
|
||||||
"uti": self.uti,
|
"uti": self.uti,
|
||||||
|
"uti_original": self.uti_original,
|
||||||
"burst": self.burst,
|
"burst": self.burst,
|
||||||
"live_photo": self.live_photo,
|
"live_photo": self.live_photo,
|
||||||
"path_live_photo": self.path_live_photo,
|
"path_live_photo": self.path_live_photo,
|
||||||
"iscloudasset": self.iscloudasset,
|
"iscloudasset": self.iscloudasset,
|
||||||
"incloud": self.incloud,
|
"incloud": self.incloud,
|
||||||
"date_modified": date_modified_iso,
|
"date_modified": self.date_modified,
|
||||||
"portrait": self.portrait,
|
"portrait": self.portrait,
|
||||||
"screenshot": self.screenshot,
|
"screenshot": self.screenshot,
|
||||||
"slow_mo": self.slow_mo,
|
"slow_mo": self.slow_mo,
|
||||||
@ -1001,6 +1005,8 @@ class PhotoInfo:
|
|||||||
"selfie": self.selfie,
|
"selfie": self.selfie,
|
||||||
"panorama": self.panorama,
|
"panorama": self.panorama,
|
||||||
"has_raw": self.has_raw,
|
"has_raw": self.has_raw,
|
||||||
|
"israw": self.israw,
|
||||||
|
"raw_original": self.raw_original,
|
||||||
"uti_raw": self.uti_raw,
|
"uti_raw": self.uti_raw,
|
||||||
"path_raw": self.path_raw,
|
"path_raw": self.path_raw,
|
||||||
"place": place,
|
"place": place,
|
||||||
@ -1014,8 +1020,17 @@ class PhotoInfo:
|
|||||||
"original_width": self.original_width,
|
"original_width": self.original_width,
|
||||||
"original_orientation": self.original_orientation,
|
"original_orientation": self.original_orientation,
|
||||||
"original_filesize": self.original_filesize,
|
"original_filesize": self.original_filesize,
|
||||||
|
"comments": comments,
|
||||||
|
"likes": likes,
|
||||||
}
|
}
|
||||||
return json.dumps(pic)
|
|
||||||
|
def json(self):
|
||||||
|
""" Return JSON representation """
|
||||||
|
def default(o):
|
||||||
|
if isinstance(o, (datetime.date, datetime.datetime)):
|
||||||
|
return o.isoformat()
|
||||||
|
|
||||||
|
return json.dumps(self.asdict(), sort_keys=True, default=default)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
""" Compare two PhotoInfo objects for equality """
|
""" Compare two PhotoInfo objects for equality """
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
""" PhotosDB method for processing comments and likes on shared photos.
|
""" PhotosDB method for processing comments and likes on shared photos.
|
||||||
Do not import this module directly """
|
Do not import this module directly """
|
||||||
|
|
||||||
|
import dataclasses
|
||||||
import datetime
|
import datetime
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
@ -30,6 +31,9 @@ class CommentInfo:
|
|||||||
ismine: bool
|
ismine: bool
|
||||||
text: str
|
text: str
|
||||||
|
|
||||||
|
def asdict(self):
|
||||||
|
return dataclasses.asdict(self)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class LikeInfo:
|
class LikeInfo:
|
||||||
@ -39,6 +43,9 @@ class LikeInfo:
|
|||||||
user: str
|
user: str
|
||||||
ismine: bool
|
ismine: bool
|
||||||
|
|
||||||
|
def asdict(self):
|
||||||
|
return dataclasses.asdict(self)
|
||||||
|
|
||||||
|
|
||||||
# The following methods do not get imported into PhotosDB
|
# The following methods do not get imported into PhotosDB
|
||||||
# but will get called by _process_comments
|
# but will get called by _process_comments
|
||||||
|
|||||||
@ -491,7 +491,7 @@ class PlaceInfo4(PlaceInfo):
|
|||||||
}
|
}
|
||||||
return "PlaceInfo(" + ", ".join([f"{k}='{v}'" for k, v in info.items()]) + ")"
|
return "PlaceInfo(" + ", ".join([f"{k}='{v}'" for k, v in info.items()]) + ")"
|
||||||
|
|
||||||
def as_dict(self):
|
def asdict(self):
|
||||||
return {
|
return {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"names": self.names._asdict(),
|
"names": self.names._asdict(),
|
||||||
@ -634,7 +634,7 @@ class PlaceInfo5(PlaceInfo):
|
|||||||
}
|
}
|
||||||
return "PlaceInfo(" + ", ".join([f"{k}='{v}'" for k, v in info.items()]) + ")"
|
return "PlaceInfo(" + ", ".join([f"{k}='{v}'" for k, v in info.items()]) + ")"
|
||||||
|
|
||||||
def as_dict(self):
|
def asdict(self):
|
||||||
return {
|
return {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"names": self.names._asdict(),
|
"names": self.names._asdict(),
|
||||||
|
|||||||
@ -133,6 +133,7 @@ RawInfo = namedtuple(
|
|||||||
"uti_raw",
|
"uti_raw",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
RAW_DICT = {
|
RAW_DICT = {
|
||||||
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068": RawInfo(
|
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068": RawInfo(
|
||||||
"raw image, no jpeg pair",
|
"raw image, no jpeg pair",
|
||||||
@ -181,6 +182,7 @@ RAW_DICT = {
|
|||||||
def photosdb():
|
def photosdb():
|
||||||
return osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
return osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
|
|
||||||
|
|
||||||
def test_init1():
|
def test_init1():
|
||||||
# test named argument
|
# test named argument
|
||||||
|
|
||||||
@ -922,7 +924,6 @@ def test_from_to_date(photosdb):
|
|||||||
os.environ["TZ"] = "US/Pacific"
|
os.environ["TZ"] = "US/Pacific"
|
||||||
time.tzset()
|
time.tzset()
|
||||||
|
|
||||||
|
|
||||||
photos = photosdb.photos(from_date=datetime.datetime(2018, 10, 28))
|
photos = photosdb.photos(from_date=datetime.datetime(2018, 10, 28))
|
||||||
assert len(photos) == 7
|
assert len(photos) == 7
|
||||||
|
|
||||||
@ -941,7 +942,6 @@ def test_from_to_date_tz(photosdb):
|
|||||||
os.environ["TZ"] = "US/Pacific"
|
os.environ["TZ"] = "US/Pacific"
|
||||||
time.tzset()
|
time.tzset()
|
||||||
|
|
||||||
|
|
||||||
photos = photosdb.photos(
|
photos = photosdb.photos(
|
||||||
from_date=datetime.datetime(2018, 9, 28, 13, 7, 0),
|
from_date=datetime.datetime(2018, 9, 28, 13, 7, 0),
|
||||||
to_date=datetime.datetime(2018, 9, 28, 13, 9, 0),
|
to_date=datetime.datetime(2018, 9, 28, 13, 9, 0),
|
||||||
@ -978,8 +978,7 @@ def test_date_invalid():
|
|||||||
# doesn't run correctly with the module-level fixture
|
# doesn't run correctly with the module-level fixture
|
||||||
from datetime import datetime, timedelta, timezone
|
from datetime import datetime, timedelta, timezone
|
||||||
import osxphotos
|
import osxphotos
|
||||||
|
|
||||||
|
|
||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["date_invalid"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["date_invalid"]])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
|
|||||||
@ -854,7 +854,7 @@ def test_export_exiftool():
|
|||||||
files = glob.glob("*")
|
files = glob.glob("*")
|
||||||
assert sorted(files) == sorted([CLI_EXIFTOOL[uuid]["File:FileName"]])
|
assert sorted(files) == sorted([CLI_EXIFTOOL[uuid]["File:FileName"]])
|
||||||
|
|
||||||
exif = ExifTool(CLI_EXIFTOOL[uuid]["File:FileName"]).as_dict()
|
exif = ExifTool(CLI_EXIFTOOL[uuid]["File:FileName"]).asdict()
|
||||||
for key in CLI_EXIFTOOL[uuid]:
|
for key in CLI_EXIFTOOL[uuid]:
|
||||||
assert exif[key] == CLI_EXIFTOOL[uuid][key]
|
assert exif[key] == CLI_EXIFTOOL[uuid][key]
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,23 @@ LIKE_UUID_DICT = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
COMMENT_UUID_ASDICT = {
|
||||||
|
"4E4944A0-3E5C-4028-9600-A8709F2FA1DB": {
|
||||||
|
"datetime": datetime.datetime(2020, 9, 19, 22, 54, 12, 947978),
|
||||||
|
"user": None,
|
||||||
|
"ismine": True,
|
||||||
|
"text": "Nice trophy",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LIKE_UUID_ASDICT = {
|
||||||
|
"65BADBD7-A50C-4956-96BA-1BB61155DA17": {
|
||||||
|
"datetime": datetime.datetime(2020, 9, 18, 10, 28, 52, 570000),
|
||||||
|
"user": None,
|
||||||
|
"ismine": False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def photosdb():
|
def photosdb():
|
||||||
@ -69,3 +86,15 @@ def test_likes(photosdb):
|
|||||||
for uuid in LIKE_UUID_DICT:
|
for uuid in LIKE_UUID_DICT:
|
||||||
photo = photosdb.get_photo(uuid)
|
photo = photosdb.get_photo(uuid)
|
||||||
assert photo.likes == LIKE_UUID_DICT[uuid]
|
assert photo.likes == LIKE_UUID_DICT[uuid]
|
||||||
|
|
||||||
|
|
||||||
|
def test_comments_as_dict(photosdb):
|
||||||
|
for uuid in COMMENT_UUID_ASDICT:
|
||||||
|
photo = photosdb.get_photo(uuid)
|
||||||
|
assert photo.comments[0].asdict() == COMMENT_UUID_ASDICT[uuid]
|
||||||
|
|
||||||
|
|
||||||
|
def test_likes_as_dict(photosdb):
|
||||||
|
for uuid in LIKE_UUID_ASDICT:
|
||||||
|
photo = photosdb.get_photo(uuid)
|
||||||
|
assert photo.likes[0].asdict() == LIKE_UUID_ASDICT[uuid]
|
||||||
|
|||||||
@ -198,7 +198,7 @@ def test_as_dict():
|
|||||||
import osxphotos.exiftool
|
import osxphotos.exiftool
|
||||||
|
|
||||||
exif1 = osxphotos.exiftool.ExifTool(TEST_FILE_ONE_KEYWORD)
|
exif1 = osxphotos.exiftool.ExifTool(TEST_FILE_ONE_KEYWORD)
|
||||||
exifdata = exif1.as_dict()
|
exifdata = exif1.asdict()
|
||||||
assert exifdata["XMP:TagsList"] == "wedding"
|
assert exifdata["XMP:TagsList"] == "wedding"
|
||||||
|
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ def test_photoinfo_exiftool():
|
|||||||
for uuid in EXIF_UUID:
|
for uuid in EXIF_UUID:
|
||||||
photo = photosdb.photos(uuid=[uuid])[0]
|
photo = photosdb.photos(uuid=[uuid])[0]
|
||||||
exiftool = photo.exiftool
|
exiftool = photo.exiftool
|
||||||
exif_dict = exiftool.as_dict()
|
exif_dict = exiftool.asdict()
|
||||||
for key, val in EXIF_UUID[uuid].items():
|
for key, val in EXIF_UUID[uuid].items():
|
||||||
assert exif_dict[key] == val
|
assert exif_dict[key] == val
|
||||||
|
|
||||||
|
|||||||
@ -130,15 +130,15 @@ def test_place_no_place_info():
|
|||||||
assert photo.place is None
|
assert photo.place is None
|
||||||
|
|
||||||
|
|
||||||
def test_place_place_info_as_dict():
|
def test_place_place_info_asdict():
|
||||||
# test PlaceInfo.as_dict()
|
# test PlaceInfo.asdict()
|
||||||
import osxphotos
|
import osxphotos
|
||||||
|
|
||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photo = photosdb.photos(uuid=[UUID_DICT["place_maui"]])[0]
|
photo = photosdb.photos(uuid=[UUID_DICT["place_maui"]])[0]
|
||||||
|
|
||||||
assert isinstance(photo.place, osxphotos.placeinfo.PlaceInfo)
|
assert isinstance(photo.place, osxphotos.placeinfo.PlaceInfo)
|
||||||
assert photo.place.as_dict() == MAUI_DICT
|
assert photo.place.asdict() == MAUI_DICT
|
||||||
|
|
||||||
|
|
||||||
# def test_place_str():
|
# def test_place_str():
|
||||||
|
|||||||
@ -89,11 +89,11 @@ def test_place_str():
|
|||||||
|
|
||||||
|
|
||||||
def test_place_as_dict():
|
def test_place_as_dict():
|
||||||
# test PlaceInfo.as_dict()
|
# test PlaceInfo.asdict()
|
||||||
import osxphotos
|
import osxphotos
|
||||||
|
|
||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photo = photosdb.photos(uuid=[UUID_DICT["place_uk"]])[0]
|
photo = photosdb.photos(uuid=[UUID_DICT["place_uk"]])[0]
|
||||||
assert photo.place is not None
|
assert photo.place is not None
|
||||||
assert isinstance(photo.place, osxphotos.placeinfo.PlaceInfo)
|
assert isinstance(photo.place, osxphotos.placeinfo.PlaceInfo)
|
||||||
assert photo.place.as_dict() == UK_DICT
|
assert photo.place.asdict() == UK_DICT
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user