From 1212fad4adde0b4c6b2887392eed829d8d96d61d Mon Sep 17 00:00:00 2001 From: Rhet Turnbull Date: Sat, 20 Jun 2020 08:36:03 -0700 Subject: [PATCH] Fixed PhotoInfo.albums, album_info for issue #169 --- osxphotos/_version.py | 2 +- osxphotos/photoinfo/photoinfo.py | 58 ++++++++++++++----- tests/test_albums_folders_catalina_10_15_4.py | 16 ++++- tests/test_albums_folders_mojave_10_14_6.py | 2 +- tests/test_catalina_10_15_5.py | 25 +++++++- 5 files changed, 83 insertions(+), 20 deletions(-) diff --git a/osxphotos/_version.py b/osxphotos/_version.py index a321e013..aa8b1492 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.29.22" +__version__ = "0.29.23" diff --git a/osxphotos/photoinfo/photoinfo.py b/osxphotos/photoinfo/photoinfo.py index f962a9c6..d620c299 100644 --- a/osxphotos/photoinfo/photoinfo.py +++ b/osxphotos/photoinfo/photoinfo.py @@ -21,12 +21,15 @@ import yaml from .._constants import ( _MOVIE_TYPE, _PHOTO_TYPE, + _PHOTOS_4_ALBUM_KIND, _PHOTOS_4_VERSION, + _PHOTOS_5_ALBUM_KIND, + _PHOTOS_5_SHARED_ALBUM_KIND, _PHOTOS_5_SHARED_PHOTO_PATH, ) from ..albuminfo import AlbumInfo -from ..placeinfo import PlaceInfo4, PlaceInfo5 from ..phototemplate import PhotoTemplate +from ..placeinfo import PlaceInfo4, PlaceInfo5 from ..utils import _debug, _get_resource_loc, findfiles, get_preferred_uti_extension @@ -341,21 +344,42 @@ class PhotoInfo: @property def albums(self): """ list of albums picture is contained in """ - albums = [] - for album in self._info["albums"]: - if not self._db._dbalbum_details[album]["intrash"]: - albums.append(self._db._dbalbum_details[album]["title"]) - return albums + try: + return self._albums + except AttributeError: + self._albums = [] + if self._db._db_version <= _PHOTOS_4_VERSION: + album_kinds = [_PHOTOS_4_ALBUM_KIND] + kind_field = "albumSubclass" + else: + album_kinds = [_PHOTOS_5_ALBUM_KIND, _PHOTOS_5_SHARED_ALBUM_KIND] + kind_field = "kind" + + for album in self._info["albums"]: + detail = self._db._dbalbum_details[album] + if detail[kind_field] in album_kinds and not detail["intrash"]: + self._albums.append(detail["title"]) + return self._albums @property def album_info(self): """ list of AlbumInfo objects representing albums the photos is contained in """ - albums = [] - for album in self._info["albums"]: - if not self._db._dbalbum_details[album]["intrash"]: - albums.append(AlbumInfo(db=self._db, uuid=album)) + try: + return self._album_info + except AttributeError: + self._album_info = [] + if self._db._db_version <= _PHOTOS_4_VERSION: + album_kinds = [_PHOTOS_4_ALBUM_KIND] + kind_field = "albumSubclass" + else: + album_kinds = [_PHOTOS_5_ALBUM_KIND, _PHOTOS_5_SHARED_ALBUM_KIND] + kind_field = "kind" - return albums + for album in self._info["albums"]: + detail = self._db._dbalbum_details[album] + if detail[kind_field] in album_kinds and not detail["intrash"]: + self._album_info.append(AlbumInfo(db=self._db, uuid=album)) + return self._album_info @property def keywords(self): @@ -772,12 +796,18 @@ class PhotoInfo: } return json.dumps(pic) - # compare two PhotoInfo objects for equality def __eq__(self, other): + """ Compare two PhotoInfo objects for equality """ + # Can't just compare the two __dicts__ because some methods (like albums) + # memoize their value once called in an instance variable (e.g. self._albums) if isinstance(other, self.__class__): - return self.__dict__ == other.__dict__ - + return ( + self._db.db_path == other._db.db_path + and self.uuid == other.uuid + and self._info == other._info + ) return False def __ne__(self, other): + """ Compare two PhotoInfo objects for inequality """ return not self.__eq__(other) diff --git a/tests/test_albums_folders_catalina_10_15_4.py b/tests/test_albums_folders_catalina_10_15_4.py index e9660a44..cf0e732f 100644 --- a/tests/test_albums_folders_catalina_10_15_4.py +++ b/tests/test_albums_folders_catalina_10_15_4.py @@ -229,6 +229,7 @@ def test_albums_photos(): def test_photoinfo_albums(): + """ Test PhotoInfo.albums """ import osxphotos photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) @@ -238,7 +239,20 @@ def test_photoinfo_albums(): assert "Pumpkin Farm" in albums +def test_photoinfo_albums_2(): + """ Test that PhotoInfo.albums returns only number albums expected """ + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + photos = photosdb.photos(uuid=[UUID_DICT["two_albums"]]) + + albums = photos[0].albums + assert len(albums) == 2 + + def test_photoinfo_album_info(): + """ test PhotoInfo.album_info """ + import osxphotos photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) @@ -249,4 +263,4 @@ def test_photoinfo_album_info(): assert album_info[0].title in ["Pumpkin Farm", "Test Album"] assert album_info[1].title in ["Pumpkin Farm", "Test Album"] - assert photos[0] in album_info[0].photos + assert photos[0].uuid in [photo.uuid for photo in album_info[0].photos] diff --git a/tests/test_albums_folders_mojave_10_14_6.py b/tests/test_albums_folders_mojave_10_14_6.py index 91bbc44f..6f243620 100644 --- a/tests/test_albums_folders_mojave_10_14_6.py +++ b/tests/test_albums_folders_mojave_10_14_6.py @@ -244,4 +244,4 @@ def test_photoinfo_album_info(): assert album_info[0].title in ["Pumpkin Farm", "Test Album"] assert album_info[1].title in ["Pumpkin Farm", "Test Album"] - assert photos[0] in album_info[0].photos + assert photos[0].uuid in [photo.uuid for photo in album_info[0].photos] diff --git a/tests/test_catalina_10_15_5.py b/tests/test_catalina_10_15_5.py index d31350f5..0f474bb3 100644 --- a/tests/test_catalina_10_15_5.py +++ b/tests/test_catalina_10_15_5.py @@ -63,6 +63,7 @@ UUID_DICT = { "no_external_edit": "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51", "export": "D79B8D77-BFFC-460B-9312-034F2877D35B", # "Pumkins2.jpg" "export_tif": "8846E3E6-8AC8-4857-8448-E3D025784410", + "in_album": "D79B8D77-BFFC-460B-9312-034F2877D35B", # "Pumkins2.jpg" } UUID_PUMPKIN_FARM = [ @@ -797,11 +798,29 @@ def test_export_14(caplog): def test_eq(): + """ Test equality of two PhotoInfo objects """ import osxphotos - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) - photos1 = photosdb.photos(uuid=[UUID_DICT["export"]]) - photos2 = photosdb.photos(uuid=[UUID_DICT["export"]]) + photosdb1 = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + photosdb2 = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + photos1 = photosdb1.photos(uuid=[UUID_DICT["export"]]) + photos2 = photosdb2.photos(uuid=[UUID_DICT["export"]]) + assert photos1[0] == photos2[0] + + +def test_eq_2(): + """ Test equality of two PhotoInfo objects when one has memoized property """ + import osxphotos + + photosdb1 = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + photosdb2 = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + photos1 = photosdb1.photos(uuid=[UUID_DICT["in_album"]]) + photos2 = photosdb2.photos(uuid=[UUID_DICT["in_album"]]) + + # memoize a value + albums = photos1[0].albums + assert albums + assert photos1[0] == photos2[0]