From 538bac7adefa4034f7a475e554470a39bf3c32fb Mon Sep 17 00:00:00 2001 From: Rhet Turnbull Date: Sun, 21 Jun 2020 08:18:11 -0700 Subject: [PATCH] More PhotoInfo.albums refactoring, closes #169 --- osxphotos/_version.py | 2 +- osxphotos/photoinfo/photoinfo.py | 60 +++++++++++++++++++++----------- osxphotos/photosdb/photosdb.py | 6 ++-- tests/test_10_12_6.py | 2 +- tests/test_catalina_10_15_1.py | 4 +-- tests/test_catalina_10_15_4.py | 2 +- tests/test_catalina_10_15_5.py | 2 +- tests/test_cli.py | 5 ++- 8 files changed, 52 insertions(+), 31 deletions(-) diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 1569cee2..333bb322 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.29.24" +__version__ = "0.29.25" diff --git a/osxphotos/photoinfo/photoinfo.py b/osxphotos/photoinfo/photoinfo.py index 17aad738..61e5f114 100644 --- a/osxphotos/photoinfo/photoinfo.py +++ b/osxphotos/photoinfo/photoinfo.py @@ -22,6 +22,7 @@ from .._constants import ( _MOVIE_TYPE, _PHOTO_TYPE, _PHOTOS_4_ALBUM_KIND, + _PHOTOS_4_ROOT_FOLDER, _PHOTOS_4_VERSION, _PHOTOS_5_ALBUM_KIND, _PHOTOS_5_SHARED_ALBUM_KIND, @@ -347,17 +348,10 @@ class PhotoInfo: try: return self._albums except AttributeError: - self._albums = [] - album_kinds = ( - [_PHOTOS_4_ALBUM_KIND] - if self._db._db_version <= _PHOTOS_4_VERSION - else [_PHOTOS_5_ALBUM_KIND, _PHOTOS_5_SHARED_ALBUM_KIND] + album_uuids = self._get_album_uuids() + self._albums = list( + {self._db._dbalbum_details[album]["title"] for album in album_uuids} ) - - for album in self._info["albums"]: - detail = self._db._dbalbum_details[album] - if detail["kind"] in album_kinds and not detail["intrash"]: - self._albums.append(detail["title"]) return self._albums @property @@ -366,17 +360,10 @@ class PhotoInfo: try: return self._album_info except AttributeError: - self._album_info = [] - album_kinds = ( - [_PHOTOS_4_ALBUM_KIND] - if self._db._db_version <= _PHOTOS_4_VERSION - else [_PHOTOS_5_ALBUM_KIND, _PHOTOS_5_SHARED_ALBUM_KIND] - ) - - for album in self._info["albums"]: - detail = self._db._dbalbum_details[album] - if detail["kind"] in album_kinds and not detail["intrash"]: - self._album_info.append(AlbumInfo(db=self._db, uuid=album)) + album_uuids = self._get_album_uuids() + self._album_info = [ + AlbumInfo(db=self._db, uuid=album) for album in album_uuids + ] return self._album_info @property @@ -677,6 +664,37 @@ class PhotoInfo: """ Returns latitude, in degrees """ return self._info["latitude"] + def _get_album_uuids(self): + """ Return list of album UUIDs this photo is found in + + Filters out albums in the trash and any special album types + + Returns: list of album UUIDs + """ + if self._db._db_version <= _PHOTOS_4_VERSION: + version4 = True + album_kind = [_PHOTOS_4_ALBUM_KIND] + else: + version4 = False + album_kind = [_PHOTOS_5_SHARED_ALBUM_KIND, _PHOTOS_5_ALBUM_KIND] + + album_list = [] + for album in self._info["albums"]: + detail = self._db._dbalbum_details[album] + if ( + detail["kind"] in album_kind + and not detail["intrash"] + and ( + not version4 + # in Photos <= 4, special albums like "printAlbum" have kind _PHOTOS_4_ALBUM_KIND + # but should not be listed here; they can be distinguished by looking + # for folderUuid of _PHOTOS_4_ROOT_FOLDER as opposed to _PHOTOS_4_TOP_LEVEL_ALBUM + or (version4 and detail["folderUuid"] != _PHOTOS_4_ROOT_FOLDER) + ) + ): + album_list.append(album) + return album_list + def __repr__(self): return f"osxphotos.{self.__class__.__name__}(db={self._db}, uuid='{self._uuid}', info={self._info})" diff --git a/osxphotos/photosdb/photosdb.py b/osxphotos/photosdb/photosdb.py index b5a70d69..96d35a14 100644 --- a/osxphotos/photosdb/photosdb.py +++ b/osxphotos/photosdb/photosdb.py @@ -2084,7 +2084,7 @@ class PhotosDB: Args: shared: boolean; if True, returns shared albums, else normal albums - Returns: list of album names + Returns: list of album UUIDs """ if self._db_version <= _PHOTOS_4_VERSION: version4 = True @@ -2110,11 +2110,11 @@ class PhotosDB: or (not shared and detail["cloudownerhashedpersonid"] is None) ) and ( + not version4 # in Photos 4, special albums like "printAlbum" have kind _PHOTOS_4_ALBUM_KIND # but should not be listed here; they can be distinguished by looking # for folderUuid of _PHOTOS_4_ROOT_FOLDER as opposed to _PHOTOS_4_TOP_LEVEL_ALBUM - (version4 and detail["folderUuid"] != _PHOTOS_4_ROOT_FOLDER) - or not version4 + or (version4 and detail["folderUuid"] != _PHOTOS_4_ROOT_FOLDER) ) ): album_list.append(album) diff --git a/tests/test_10_12_6.py b/tests/test_10_12_6.py index 6d0d51a0..f0dda984 100644 --- a/tests/test_10_12_6.py +++ b/tests/test_10_12_6.py @@ -124,7 +124,7 @@ def test_attributes(): ) assert p.description == "Girl holding pumpkin" assert p.title == "I found one!" - assert p.albums == ["Pumpkin Farm", "AlbumInFolder"] + assert sorted(p.albums) == ["AlbumInFolder", "Pumpkin Farm"] assert p.persons == ["Katie"] assert p.path.endswith( "/tests/Test-10.12.6.photoslibrary/Masters/2019/08/24/20190824-030824/Pumkins2.jpg" diff --git a/tests/test_catalina_10_15_1.py b/tests/test_catalina_10_15_1.py index fd287a9c..641e76d9 100644 --- a/tests/test_catalina_10_15_1.py +++ b/tests/test_catalina_10_15_1.py @@ -106,6 +106,7 @@ def test_init4(): except: pass + def test_init5(mocker): # test failed get_last_library_path import osxphotos @@ -116,7 +117,6 @@ def test_init5(mocker): # get_last_library actually in utils but need to patch it in photosdb because it's imported into photosdb # because of the layout of photosdb/ need to patch it this way...don't really understand why, but it works mocker.patch("osxphotos.photosdb.photosdb.get_last_library_path", new=bad_library) - with pytest.raises(Exception): assert osxphotos.PhotosDB() @@ -207,7 +207,7 @@ def test_attributes(): ) assert p.description == "Girl holding pumpkin" assert p.title == "I found one!" - assert p.albums == ["Pumpkin Farm", "Test Album", "Multi Keyword"] + assert sorted(p.albums) == ["Multi Keyword", "Pumpkin Farm", "Test Album"] assert p.persons == ["Katie"] assert p.path.endswith( "tests/Test-10.15.1.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg" diff --git a/tests/test_catalina_10_15_4.py b/tests/test_catalina_10_15_4.py index ef9891e8..5e935e45 100644 --- a/tests/test_catalina_10_15_4.py +++ b/tests/test_catalina_10_15_4.py @@ -215,7 +215,7 @@ def test_attributes(): ) assert p.description == "Girl holding pumpkin" assert p.title == "I found one!" - assert p.albums == ["Pumpkin Farm", "Test Album"] + assert sorted(p.albums) == ["Pumpkin Farm", "Test Album"] assert p.persons == ["Katie"] assert p.path.endswith( "tests/Test-10.15.4.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg" diff --git a/tests/test_catalina_10_15_5.py b/tests/test_catalina_10_15_5.py index 176d185e..ef8e84dc 100644 --- a/tests/test_catalina_10_15_5.py +++ b/tests/test_catalina_10_15_5.py @@ -228,7 +228,7 @@ def test_attributes(): ) assert p.description == "Girl holding pumpkin" assert p.title == "I found one!" - assert p.albums == ["Pumpkin Farm", "Test Album"] + assert sorted(p.albums) == ["Pumpkin Farm", "Test Album"] assert p.persons == ["Katie"] assert p.path.endswith( "tests/Test-10.15.5.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg" diff --git a/tests/test_cli.py b/tests/test_cli.py index 068fbcb4..26efec52 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -355,7 +355,10 @@ def test_query_uuid(): for key_ in json_expected: assert key_ in json_got if key_ != "path": - assert json_expected[key_] == json_got[key_] + if isinstance(json_expected[key_], list): + assert sorted(json_expected[key_]) == sorted(json_got[key_]) + else: + assert json_expected[key_] == json_got[key_] else: assert json_expected[key_] in json_got[key_]