Fixed bug related to issue #119

This commit is contained in:
Rhet Turnbull 2020-04-30 21:38:24 -07:00
parent 1b6f661e6b
commit 7af1ccd4ed
19 changed files with 263 additions and 20 deletions

View File

@ -1,3 +1,3 @@
""" version info """ """ version info """
__version__ = "0.28.10" __version__ = "0.28.11"

View File

@ -20,6 +20,7 @@ from ._constants import (
_PHOTO_TYPE, _PHOTO_TYPE,
_PHOTOS_3_VERSION, _PHOTOS_3_VERSION,
_PHOTOS_4_ALBUM_KIND, _PHOTOS_4_ALBUM_KIND,
_PHOTOS_4_ROOT_FOLDER,
_PHOTOS_4_TOP_LEVEL_ALBUM, _PHOTOS_4_TOP_LEVEL_ALBUM,
_PHOTOS_4_VERSION, _PHOTOS_4_VERSION,
_PHOTOS_5_ALBUM_KIND, _PHOTOS_5_ALBUM_KIND,
@ -661,10 +662,11 @@ class PhotosDB:
# build folder hierarchy # build folder hierarchy
for album, details in self._dbalbum_details.items(): for album, details in self._dbalbum_details.items():
parent_folder = details["folderUuid"] parent_folder = details["folderUuid"]
if ( if details[
details["albumSubclass"] == _PHOTOS_4_ALBUM_KIND "albumSubclass"
and parent_folder != _PHOTOS_4_TOP_LEVEL_ALBUM ] == _PHOTOS_4_ALBUM_KIND and parent_folder not in [
): _PHOTOS_4_TOP_LEVEL_ALBUM
]:
folder_hierarchy = self._build_album_folder_hierarchy_4(parent_folder) folder_hierarchy = self._build_album_folder_hierarchy_4(parent_folder)
self._dbalbum_folders[album] = folder_hierarchy self._dbalbum_folders[album] = folder_hierarchy
else: else:
@ -1222,17 +1224,24 @@ class PhotosDB:
def _build_album_folder_hierarchy_4(self, uuid, folders=None): def _build_album_folder_hierarchy_4(self, uuid, folders=None):
""" recursively build folder/album hierarchy """ recursively build folder/album hierarchy
uuid: uuid of the album/folder being processed uuid: parent uuid of the album being processed
folders: dict holding the folder hierarchy """ (parent uuid is a folder in RKFolders)
folders: dict holding the folder hierarchy
NOTE: This implementation is different than _build_album_folder_hierarchy_5
which takes the uuid of the album being processed. Here uuid is the parent uuid
of the parent folder album because in Photos <=4, folders are in RKFolders and
albums in RKAlbums. In Photos 5, folders are just special albums
with kind = _PHOTOS_5_FOLDER_KIND """
parent_uuid = self._dbfolder_details[uuid]["parentFolderUuid"] parent_uuid = self._dbfolder_details[uuid]["parentFolderUuid"]
# logging.warning(f"uuid = {uuid}, parent = {parent_uuid}, folders = {folders}")
if parent_uuid is None: if parent_uuid is None:
return folders return folders
if parent_uuid == _PHOTOS_4_TOP_LEVEL_ALBUM: if parent_uuid == _PHOTOS_4_TOP_LEVEL_ALBUM:
if not folders:
# this is a top-level folder with no sub-folders
folders = {uuid: None}
# at top of hierarchy, we're done # at top of hierarchy, we're done
return folders return folders

View File

@ -8,6 +8,7 @@
<array/> <array/>
<key>ExpandedSidebarItemIdentifiers</key> <key>ExpandedSidebarItemIdentifiers</key>
<array> <array>
<string>obfeGcvoT1auxoh2Tu86OQ</string>
<string>TopLevelAlbums</string> <string>TopLevelAlbums</string>
<string>TopLevelSlideshows</string> <string>TopLevelSlideshows</string>
<string>MBS8+gBrQCWQxmcav+C8HQ</string> <string>MBS8+gBrQCWQxmcav+C8HQ</string>
@ -25,11 +26,11 @@
<key>key</key> <key>key</key>
<integer>1</integer> <integer>1</integer>
<key>lastKnownDisplayName</key> <key>lastKnownDisplayName</key>
<string>September 28, 2018</string> <string>Pumpkin Farm (1)</string>
<key>type</key> <key>type</key>
<string>album</string> <string>album</string>
<key>uuid</key> <key>uuid</key>
<string>si9dXIayQI2Tb2vrWgpddA</string> <string>AU8Gp8bwRlOvngZFgwXBdg</string>
</dict> </dict>
<key>lastKnownItemCounts</key> <key>lastKnownItemCounts</key>
<dict> <dict>

View File

@ -3,8 +3,8 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate</key> <key>PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate</key>
<date>2019-07-28T01:23:52Z</date> <date>2020-04-30T14:09:38Z</date>
<key>PhotoAnalysisGraphLastBackgroundMemoryGenerationJobDate</key> <key>PhotoAnalysisGraphLastBackgroundMemoryGenerationJobDate</key>
<date>2020-04-30T12:51:35Z</date> <date>2020-05-01T04:27:48Z</date>
</dict> </dict>
</plist> </plist>

View File

@ -2,7 +2,11 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>ProcessedInQuiescentState</key>
<true/>
<key>SuggestedMeIdentifier</key> <key>SuggestedMeIdentifier</key>
<string></string> <string></string>
<key>Version</key>
<integer>3</integer>
</dict> </dict>
</plist> </plist>

View File

@ -5,7 +5,7 @@
<key>LithiumMessageTracer</key> <key>LithiumMessageTracer</key>
<dict> <dict>
<key>LastReportedDate</key> <key>LastReportedDate</key>
<date>2019-07-27T12:01:15Z</date> <date>2020-05-01T03:34:50Z</date>
</dict> </dict>
</dict> </dict>
</plist> </plist>

View File

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>LastHistoryRowId</key> <key>LastHistoryRowId</key>
<integer>657</integer> <integer>670</integer>
<key>LibraryBuildTag</key> <key>LibraryBuildTag</key>
<string>BEA5F0E8-BA6B-4462-8F73-3E53BBE4C943</string> <string>BEA5F0E8-BA6B-4462-8F73-3E53BBE4C943</string>
<key>LibrarySchemaVersion</key> <key>LibrarySchemaVersion</key>

View File

@ -9,7 +9,7 @@
<key>HistoricalMarker</key> <key>HistoricalMarker</key>
<dict> <dict>
<key>LastHistoryRowId</key> <key>LastHistoryRowId</key>
<integer>657</integer> <integer>670</integer>
<key>LibraryBuildTag</key> <key>LibraryBuildTag</key>
<string>BEA5F0E8-BA6B-4462-8F73-3E53BBE4C943</string> <string>BEA5F0E8-BA6B-4462-8F73-3E53BBE4C943</string>
<key>LibrarySchemaVersion</key> <key>LibrarySchemaVersion</key>
@ -24,7 +24,7 @@
<key>SnapshotCompletedDate</key> <key>SnapshotCompletedDate</key>
<date>2019-07-26T20:15:17Z</date> <date>2019-07-26T20:15:17Z</date>
<key>SnapshotLastValidated</key> <key>SnapshotLastValidated</key>
<date>2020-04-30T12:51:32Z</date> <date>2020-05-01T03:34:50Z</date>
<key>SnapshotTables</key> <key>SnapshotTables</key>
<dict/> <dict/>
</dict> </dict>

View File

@ -0,0 +1,229 @@
import pytest
from osxphotos._constants import _UNKNOWN_PERSON
PHOTOS_DB = "./tests/Test-10.13.6.photoslibrary/database/photos.db"
TOP_LEVEL_FOLDERS = ["Folder1", "TestFolder"]
TOP_LEVEL_CHILDREN = ["SubFolder1", "SubFolder2"]
FOLDER_ALBUM_DICT = {
"Folder1": [],
"SubFolder1": [],
"SubFolder2": ["AlbumInFolder"],
"TestFolder": ["TestAlbum"],
}
ALBUM_NAMES = ["Pumpkin Farm", "AlbumInFolder", "TestAlbum"]
ALBUM_PARENT_DICT = {
"Pumpkin Farm": None,
"AlbumInFolder": "SubFolder2",
"TestAlbum": "TestFolder",
}
ALBUM_FOLDER_NAMES_DICT = {
"Pumpkin Farm": [],
"AlbumInFolder": ["Folder1", "SubFolder2"],
"TestAlbum": ["TestFolder"],
}
ALBUM_LEN_DICT = {"Pumpkin Farm": 3, "AlbumInFolder": 1, "TestAlbum": 1}
ALBUM_PHOTO_UUID_DICT = {
"Pumpkin Farm": [
"vAZGdUK1QdGfWPgC+KsJag",
"NlY8CklESxGpaKsTVHB3HQ",
"RWmFYiDjSyKjeK8Pfna0Eg",
],
"AlbumInFolder": ["RWmFYiDjSyKjeK8Pfna0Eg"],
"TestAlbum": ["NlY8CklESxGpaKsTVHB3HQ"],
}
######### Test FolderInfo ##########
def test_folders_1():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
folders = photosdb.folders
# top level folders
folders = photosdb.folder_info
assert len(folders) == len(TOP_LEVEL_FOLDERS)
# check folder names
folder_names = [f.title for f in folders]
assert sorted(folder_names) == sorted(TOP_LEVEL_FOLDERS)
def test_folder_names():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# check folder names
folder_names = photosdb.folders
assert folder_names == TOP_LEVEL_FOLDERS
assert sorted(folder_names) == sorted(TOP_LEVEL_FOLDERS)
def test_folders_len():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.folder_info
assert len(folders[0]) == len(TOP_LEVEL_CHILDREN)
def test_folders_children():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.folder_info
# children of top level folder
children = folders[0].subfolders
children_names = [f.title for f in children]
assert sorted(children_names) == sorted(TOP_LEVEL_CHILDREN)
for child in folders[0].subfolders:
# check valid children FolderInfo
assert child.parent
assert child.parent.uuid == folders[0].uuid
# check folder names
folder_names = [f.title for f in folders]
assert sorted(folder_names) == sorted(TOP_LEVEL_FOLDERS)
def test_folders_parent():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.folder_info
# parent of top level folder should be none
for folder in folders:
assert folder.parent is None
for child in folder.subfolders:
# children's parent uuid should match folder uuid
assert child.parent
assert child.parent.uuid == folder.uuid
def test_folders_albums():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.folder_info
for folder in folders:
name = folder.title
albums = [a.title for a in folder.album_info]
assert sorted(albums) == sorted(FOLDER_ALBUM_DICT[name])
for child in folder.subfolders:
name = child.title
albums = [a.title for a in child.album_info]
assert sorted(albums) == sorted(FOLDER_ALBUM_DICT[name])
########## Test AlbumInfo ##########
def test_albums_1():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.album_info
assert len(albums) == len(ALBUM_NAMES)
# check names
album_names = [a.title for a in albums]
assert sorted(album_names) == sorted(ALBUM_NAMES)
def test_albums_parent():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.album_info
for album in albums:
parent = album.parent.title if album.parent else None
assert parent == ALBUM_PARENT_DICT[album.title]
def test_albums_folder_names():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.album_info
for album in albums:
folder_names = album.folder_names
assert folder_names == ALBUM_FOLDER_NAMES_DICT[album.title]
def test_albums_folders():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.album_info
for album in albums:
folders = album.folder_list
folder_names = [f.title for f in folders]
assert folder_names == ALBUM_FOLDER_NAMES_DICT[album.title]
def test_albums_len():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.album_info
for album in albums:
assert len(album) == ALBUM_LEN_DICT[album.title]
def test_albums_photos():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.album_info
for album in albums:
photos = album.photos
assert len(photos) == ALBUM_LEN_DICT[album.title]
assert len(photos) == len(album)
for photo in photos:
assert photo.uuid in ALBUM_PHOTO_UUID_DICT[album.title]
def test_photoinfo_albums():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
photos = photosdb.photos(uuid=ALBUM_PHOTO_UUID_DICT["Pumpkin Farm"])
albums = photos[0].albums
assert "Pumpkin Farm" in albums

View File

@ -15,7 +15,7 @@ KEYWORDS = [
"United Kingdom", "United Kingdom",
] ]
PERSONS = ["Katie", "Suzy", "Maria"] PERSONS = ["Katie", "Suzy", "Maria"]
ALBUMS = ["Pumpkin Farm"] ALBUMS = ["Pumpkin Farm", "AlbumInFolder", "TestAlbum"]
KEYWORDS_DICT = { KEYWORDS_DICT = {
"Kids": 4, "Kids": 4,
"wedding": 2, "wedding": 2,
@ -28,7 +28,7 @@ KEYWORDS_DICT = {
"United Kingdom": 1, "United Kingdom": 1,
} }
PERSONS_DICT = {"Katie": 3, "Suzy": 2, "Maria": 1} PERSONS_DICT = {"Katie": 3, "Suzy": 2, "Maria": 1}
ALBUM_DICT = {"Pumpkin Farm": 3} ALBUM_DICT = {"Pumpkin Farm": 3, "TestAlbum": 1, "AlbumInFolder": 1}
def test_init(): def test_init():
@ -123,7 +123,7 @@ def test_attributes():
) )
assert p.description == "Girl holding pumpkin" assert p.description == "Girl holding pumpkin"
assert p.title == "I found one!" assert p.title == "I found one!"
assert p.albums == ["Pumpkin Farm"] assert sorted(p.albums) == ["AlbumInFolder", "Pumpkin Farm"]
assert p.persons == ["Katie"] assert p.persons == ["Katie"]
assert p.path.endswith( assert p.path.endswith(
"/tests/Test-10.13.6.photoslibrary/Masters/2019/07/26/20190726-203227/Pumkins2.jpg" "/tests/Test-10.13.6.photoslibrary/Masters/2019/07/26/20190726-203227/Pumkins2.jpg"