Added folder support for Photos <= 4, closes #93

This commit is contained in:
Rhet Turnbull
2020-04-18 12:21:08 -07:00
parent 6f281711e2
commit 47d1c82c03
45 changed files with 418 additions and 185 deletions

View File

@@ -9,12 +9,14 @@
<key>ExpandedSidebarItemIdentifiers</key>
<array>
<string>TopLevelAlbums</string>
<string>QtSnVvTkQ%i2z3hB834M1A</string>
<string>TopLevelSlideshows</string>
<string>N7eQ4VhfTfeHFp9PPHaJDw</string>
</array>
<key>IPXWorkspaceControllerZoomLevelsKey</key>
<dict>
<key>kZoomLevelIdentifierAlbums</key>
<integer>10</integer>
<integer>5</integer>
<key>kZoomLevelIdentifierVersions</key>
<integer>7</integer>
</dict>
@@ -23,11 +25,11 @@
<key>key</key>
<integer>1</integer>
<key>lastKnownDisplayName</key>
<string>Test Album (1)</string>
<string>Pumpkin Farm (1)</string>
<key>type</key>
<string>album</string>
<key>uuid</key>
<string>Uq6qsKihRRSjMHTiD+0Azg</string>
<string>xJ8ya3NBRWC24gKhcwwNeQ</string>
</dict>
<key>lastKnownItemCounts</key>
<dict>

View File

@@ -3,8 +3,8 @@
<plist version="1.0">
<dict>
<key>PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate</key>
<date>2020-03-27T04:00:09Z</date>
<date>2020-04-18T18:01:02Z</date>
<key>PhotoAnalysisGraphLastBackgroundMemoryGenerationJobDate</key>
<date>2020-03-27T04:00:10Z</date>
<date>2020-04-18T17:22:55Z</date>
</dict>
</plist>

View File

@@ -5,7 +5,7 @@
<key>LithiumMessageTracer</key>
<dict>
<key>LastReportedDate</key>
<date>2020-03-15T20:19:24Z</date>
<date>2020-04-17T17:51:16Z</date>
</dict>
</dict>
</plist>

View File

@@ -11,6 +11,6 @@
<key>PLLastRevGeoForcedProviderOutOfDateCheckVersionKey</key>
<integer>1</integer>
<key>PLLastRevGeoVerFileFetchDateKey</key>
<date>2020-03-27T03:59:54Z</date>
<date>2020-04-17T17:49:52Z</date>
</dict>
</plist>

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>LastHistoryRowId</key>
<integer>575</integer>
<integer>606</integer>
<key>LibraryBuildTag</key>
<string>D8C4AAA1-3AB6-4A65-BEBD-99CC3E5D433E</string>
<key>LibrarySchemaVersion</key>

View File

@@ -9,7 +9,7 @@
<key>HistoricalMarker</key>
<dict>
<key>LastHistoryRowId</key>
<integer>575</integer>
<integer>606</integer>
<key>LibraryBuildTag</key>
<string>D8C4AAA1-3AB6-4A65-BEBD-99CC3E5D433E</string>
<key>LibrarySchemaVersion</key>
@@ -24,7 +24,7 @@
<key>SnapshotCompletedDate</key>
<date>2019-07-27T13:16:43Z</date>
<key>SnapshotLastValidated</key>
<date>2020-03-27T04:02:59Z</date>
<date>2020-04-17T17:51:16Z</date>
<key>SnapshotTables</key>
<dict/>
</dict>

View File

@@ -3,24 +3,24 @@
<plist version="1.0">
<dict>
<key>BackgroundHighlightCollection</key>
<date>2020-04-16T17:31:22Z</date>
<date>2020-04-17T14:33:32Z</date>
<key>BackgroundHighlightEnrichment</key>
<date>2020-04-16T17:31:21Z</date>
<date>2020-04-17T14:33:32Z</date>
<key>BackgroundJobAssetRevGeocode</key>
<date>2020-04-16T17:31:22Z</date>
<date>2020-04-17T14:33:33Z</date>
<key>BackgroundJobSearch</key>
<date>2020-04-16T17:31:22Z</date>
<date>2020-04-17T14:33:33Z</date>
<key>BackgroundPeopleSuggestion</key>
<date>2020-04-16T17:31:21Z</date>
<date>2020-04-17T14:33:31Z</date>
<key>BackgroundUserBehaviorProcessor</key>
<date>2020-04-16T06:52:39Z</date>
<date>2020-04-17T07:32:04Z</date>
<key>PhotoAnalysisGraphLastBackgroundGraphConsistencyUpdateJobDateKey</key>
<date>2020-04-16T17:38:41Z</date>
<date>2020-04-17T14:33:37Z</date>
<key>PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate</key>
<date>2020-04-16T06:52:38Z</date>
<date>2020-04-17T07:32:00Z</date>
<key>PhotoAnalysisGraphLastBackgroundMemoryGenerationJobDate</key>
<date>2020-04-16T17:31:22Z</date>
<date>2020-04-17T14:33:34Z</date>
<key>SiriPortraitDonation</key>
<date>2020-04-16T06:52:39Z</date>
<date>2020-04-17T07:32:04Z</date>
</dict>
</plist>

View File

@@ -3,8 +3,8 @@
<plist version="1.0">
<dict>
<key>FaceIDModelLastGenerationKey</key>
<date>2020-04-16T06:52:40Z</date>
<date>2020-04-17T07:32:07Z</date>
<key>LastContactClassificationKey</key>
<date>2020-04-16T06:52:42Z</date>
<date>2020-04-17T07:32:12Z</date>
</dict>
</plist>

View File

@@ -4,32 +4,33 @@ from osxphotos._constants import _UNKNOWN_PERSON
PHOTOS_DB = "./tests/Test-10.14.6.photoslibrary/database/photos.db"
# TOP_LEVEL_FOLDERS = ["Folder1"]
TOP_LEVEL_FOLDERS = ["Folder1"]
# TOP_LEVEL_CHILDREN = ["SubFolder1", "SubFolder2"]
TOP_LEVEL_CHILDREN = ["SubFolder1", "SubFolder2"]
# FOLDER_ALBUM_DICT = {"Folder1": [], "SubFolder1": [], "SubFolder2": ["AlbumInFolder"]}
FOLDER_ALBUM_DICT = {"Folder1": [], "SubFolder1": [], "SubFolder2": ["AlbumInFolder"]}
# ALBUM_NAMES = ["Pumpkin Farm", "AlbumInFolder", "Test Album", "Test Album"]
ALBUM_NAMES = ["Pumpkin Farm", "Test Album", "Test Album (1)"]
ALBUM_NAMES = ["Pumpkin Farm", "AlbumInFolder", "Test Album", "Test Album (1)"]
# ALBUM_PARENT_DICT = {
# "Pumpkin Farm": None,
# "AlbumInFolder": "SubFolder2",
# "Test Album": None,
# }
ALBUM_PARENT_DICT = {
"Pumpkin Farm": None,
"AlbumInFolder": "SubFolder2",
"Test Album": None,
"Test Album (1)": None,
}
# ALBUM_FOLDER_NAMES_DICT = {
# "Pumpkin Farm": [],
# "AlbumInFolder": ["Folder1", "SubFolder2"],
# "Test Album": [],
# }
ALBUM_FOLDER_NAMES_DICT = {
"Pumpkin Farm": [],
"AlbumInFolder": ["Folder1", "SubFolder2"],
"Test Album": [],
"Test Album (1)": [],
}
ALBUM_LEN_DICT = {
"Pumpkin Farm": 3,
"Test Album": 1,
"Test Album (1)": 1,
# "AlbumInFolder": 2,
"AlbumInFolder": 1,
}
ALBUM_PHOTO_UUID_DICT = {
@@ -40,10 +41,7 @@ ALBUM_PHOTO_UUID_DICT = {
],
"Test Album": ["8SOE9s0XQVGsuq4ONohTng"],
"Test Album (1)": ["15uNd7%8RguTEgNPKHfTWw"],
# "AlbumInFolder": [
# "3DD2C897-F19E-4CA6-8C22-B027D5A71907",
# "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51",
# ],
"AlbumInFolder": ["15uNd7%8RguTEgNPKHfTWw"],
}
UUID_DICT = {"two_albums": "8SOE9s0XQVGsuq4ONohTng"}
@@ -51,62 +49,57 @@ UUID_DICT = {"two_albums": "8SOE9s0XQVGsuq4ONohTng"}
######### Test FolderInfo ##########
def test_folders_1(caplog):
def test_folders_1():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
folders = photosdb.folders
assert folders == []
assert "Folders not yet implemented for this DB version" in caplog.text
# # top level folders
# folders = photosdb.folders
# assert len(folders) == 1
# top level folders
folders = photosdb.folder_info
assert len(folders) == 1
# # check folder names
# folder_names = [f.title for f in folders]
# assert sorted(folder_names) == sorted(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(caplog):
def test_folder_names():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# check folder names
folder_names = photosdb.folders
assert folder_names == []
assert "Folders not yet implemented for this DB version" in caplog.text
# assert sorted(folder_names) == sorted(TOP_LEVEL_FOLDERS)
assert folder_names == TOP_LEVEL_FOLDERS
assert sorted(folder_names) == sorted(TOP_LEVEL_FOLDERS)
@pytest.mark.skip(reason="Folders not yet impleted in Photos < 5")
def test_folders_len():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.folders
folders = photosdb.folder_info
assert len(folders[0]) == len(TOP_LEVEL_CHILDREN)
@pytest.mark.skip(reason="Folders not yet impleted in Photos < 5")
def test_folders_children():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.folders
folders = photosdb.folder_info
# children of top level folder
children = folders[0].folders
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].folders:
for child in folders[0].subfolders:
# check valid children FolderInfo
assert child.parent
assert child.parent.uuid == folders[0].uuid
@@ -116,38 +109,36 @@ def test_folders_children():
assert sorted(folder_names) == sorted(TOP_LEVEL_FOLDERS)
@pytest.mark.skip(reason="Folders not yet impleted in Photos < 5")
def test_folders_parent():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.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.folders:
for child in folder.subfolders:
# children's parent uuid should match folder uuid
assert child.parent
assert child.parent.uuid == folder.uuid
@pytest.mark.skip(reason="Folders not yet impleted in Photos < 5")
def test_folders_albums():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.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.folders:
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])
@@ -162,14 +153,14 @@ def test_albums_1():
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.album_info
assert len(albums) == 3
assert len(albums) == 4
# check names
album_names = [a.title for a in albums]
assert sorted(album_names) == sorted(ALBUM_NAMES)
def test_albums_parent(caplog):
def test_albums_parent():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
@@ -178,11 +169,10 @@ def test_albums_parent(caplog):
for album in albums:
parent = album.parent.title if album.parent else None
assert "Folders not yet implemented for this DB version" in caplog.text
# assert parent == ALBUM_PARENT_DICT[album.title]
assert parent == ALBUM_PARENT_DICT[album.title]
def test_albums_folder_names(caplog):
def test_albums_folder_names():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
@@ -191,11 +181,10 @@ def test_albums_folder_names(caplog):
for album in albums:
folder_names = album.folder_names
assert "Folders not yet implemented for this DB version" in caplog.text
# assert folder_names == ALBUM_FOLDER_NAMES_DICT[album.title]
assert folder_names == ALBUM_FOLDER_NAMES_DICT[album.title]
def test_albums_folders(caplog):
def test_albums_folders():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
@@ -204,9 +193,8 @@ def test_albums_folders(caplog):
for album in albums:
folders = album.folder_list
assert "Folders not yet implemented for this DB version" in caplog.text
# folder_names = [f.title for f in folders]
# assert folder_names == ALBUM_FOLDER_NAMES_DICT[album.title]
folder_names = [f.title for f in folders]
assert folder_names == ALBUM_FOLDER_NAMES_DICT[album.title]
def test_albums_len():

View File

@@ -780,7 +780,7 @@ def test_no_folder_2_15():
assert item["albums"] == ["AlbumInFolder"]
def test_no_folder_1_14(caplog):
def test_no_folder_1_14():
# test --folder on 10.14
import json
import os
@@ -797,6 +797,5 @@ def test_no_folder_1_14(caplog):
)
assert result.exit_code == 0
json_got = json.loads(result.output)
assert len(json_got) == 0 # single element
assert "not yet implemented" in caplog.text
assert len(json_got) == 1 # single element
assert json_got[0]["uuid"] == "15uNd7%8RguTEgNPKHfTWw"

View File

@@ -18,7 +18,7 @@ KEYWORDS = [
"United Kingdom",
]
PERSONS = ["Katie", "Suzy", "Maria"]
ALBUMS = ["Pumpkin Farm", "Test Album", "Test Album (1)"]
ALBUMS = ["Pumpkin Farm", "AlbumInFolder", "Test Album", "Test Album (1)"]
KEYWORDS_DICT = {
"Kids": 4,
"wedding": 2,
@@ -31,7 +31,12 @@ KEYWORDS_DICT = {
"United Kingdom": 1,
}
PERSONS_DICT = {"Katie": 3, "Suzy": 2, "Maria": 1}
ALBUM_DICT = {"Pumpkin Farm": 3, "Test Album": 1, "Test Album (1)": 1}
ALBUM_DICT = {
"Pumpkin Farm": 3,
"AlbumInFolder": 1,
"Test Album": 1,
"Test Album (1)": 1,
}
UUID_DICT = {
"favorite": "6bxcNnzRQKGnK4uPrCJ9UQ",
@@ -131,7 +136,9 @@ def test_attributes():
)
assert p.description == "Girl holding pumpkin"
assert p.title == "I found one!"
assert p.albums == ["Pumpkin Farm", "Test Album (1)"]
assert sorted(p.albums) == sorted(
["Pumpkin Farm", "AlbumInFolder", "Test Album (1)"]
)
assert p.persons == ["Katie"]
assert p.path.endswith(
"/tests/Test-10.14.6.photoslibrary/Masters/2019/07/27/20190727-131650/Pumkins2.jpg"

View File

@@ -7,8 +7,13 @@ PHOTOS_DB = "./tests/Test-10.14.6.photoslibrary/database/photos.db"
PHOTOS_DB_PATH = "/Test-10.14.6.photoslibrary/database/photos.db"
PHOTOS_LIBRARY_PATH = "/Test-10.14.6.photoslibrary"
ALBUMS = ["Pumpkin Farm", "Test Album", "Test Album (1)"]
ALBUM_DICT = {"Pumpkin Farm": 3, "Test Album": 1, "Test Album (1)": 1}
ALBUMS = ["Pumpkin Farm", "AlbumInFolder", "Test Album", "Test Album (1)"]
ALBUM_DICT = {
"Pumpkin Farm": 3,
"AlbumInFolder": 1,
"Test Album": 1,
"Test Album (1)": 1,
}
def test_album_names():

View File

@@ -15,7 +15,7 @@ UUID_DICT = {
"0_2_0": "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4",
"folder_album_1": "3DD2C897-F19E-4CA6-8C22-B027D5A71907",
"folder_album_no_folder": "D79B8D77-BFFC-460B-9312-034F2877D35B",
"mojave_no_folder": "15uNd7%8RguTEgNPKHfTWw",
"mojave_album_1": "15uNd7%8RguTEgNPKHfTWw",
}
TEMPLATE_VALUES = {
@@ -341,17 +341,16 @@ def test_subst_multi_folder_albums_2():
def test_subst_multi_folder_albums_3(caplog):
""" Test substitutions for folder_album on < Photos 5 (not implemented) """
""" Test substitutions for folder_album on < Photos 5 """
import osxphotos
from osxphotos.template import render_filepath_template
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB_14_6)
# photo in an album in a folder
photo = photosdb.photos(uuid=[UUID_DICT["mojave_no_folder"]])[0]
photo = photosdb.photos(uuid=[UUID_DICT["mojave_album_1"]])[0]
template = "{folder_album}"
expected = ["Pumpkin Farm", "Test Album (1)"]
expected = ["Folder1/SubFolder2/AlbumInFolder", "Pumpkin Farm", "Test Album (1)"]
rendered, unknown = render_filepath_template(template, photo)
assert sorted(rendered) == sorted(expected)
assert unknown == []
assert "not yet implemented" in caplog.text