Added tests and README for AlbumInfo and FolderInfo

This commit is contained in:
Rhet Turnbull
2020-04-11 14:07:39 -07:00
parent 96365728c2
commit d6a22b765a
39 changed files with 612 additions and 22 deletions

110
README.md
View File

@@ -554,22 +554,50 @@ keywords = photosdb.keywords
Returns a list of the keywords found in the Photos library
#### `albums`
```python
# assumes photosdb is a PhotosDB object (see above)
albums = photosdb.albums
```
Returns a list of [AlbumInfo](#AlbumInfo) objects representing albums in the database or empty list if there are no albums. See also [album_names](#album_names).
#### `album_names`
```python
# assumes photosdb is a PhotosDB object (see above)
albums = photosdb.album_names
album_names = photosdb.album_names
```
Returns a list of the albums found in the Photos library.
Returns a list of the album names found in the Photos library.
**Note**: In Photos 5.0 (MacOS 10.15/Catalina), It is possible to have more than one album with the same name in Photos. Albums with duplicate names are treated as a single album and the photos in each are combined. For example, if you have two albums named "Wedding" and each has 2 photos, osxphotos will treat this as a single album named "Wedding" with 4 photos in it.
#### `album_names_shared`
Returns list of shared albums found in photos database (e.g. albums shared via iCloud photo sharing)
Returns list of shared album names found in photos database (e.g. albums shared via iCloud photo sharing)
**Note**: *Only valid for Photos 5 / MacOS 10.15*; on Photos <= 4, prints warning and returns empty list.
#### `folders`
```python
# assumes photosdb is a PhotosDB object (see above)
folders = photosdb.folders
```
Returns a list of [FolderInfo](#FolderInfo) objects representing top level folders in the database or empty list if there are no folders. See also [folder_names](#folder_names).
**Note**: Currently folders is only implemented for Photos 5 (Catalina); will return empty list and output warning if called on earlier database versions.
#### `folder_names`
```python
# assumes photosdb is a PhotosDB object (see above)
folder_names = photosdb.folder_names
```
Returns a list names of top level folder names in the database.
**Note**: Currently folders is only implemented for Photos 5 (Catalina); will return empty list and output warning if called on earlier database versions.
#### `persons`
```python
# assumes photosdb is a PhotosDB object (see above)
@@ -928,6 +956,82 @@ If overwrite=False and increment=False, export will fail if destination file alr
**Implementation Note**: Because the usual python file copy methods don't preserve all the metadata available on MacOS, export uses /usr/bin/ditto to do the copy for export. ditto preserves most metadata such as extended attributes, permissions, ACLs, etc.
### AlbumInfo
PhotosDB.albums returns a list of AlbumInfo objects. Each AlbumInfo object represents a single album in the Photos library.
#### `uuid`
Returns the universally unique identifier (uuid) of the album. This is how Photos keeps track of individual objects within the database.
#### `title`
Returns the title or name of the album.
#### `photos`
Returns a list of [PhotoInfo](#PhotoInfo) objects representing each photo contained in the album.
#### `folder_list`
Returns a hierarchical list of [FolderInfo](#FolderInfo) objects representing the folders the album is contained in. For example, if album "AlbumInFolder" is in SubFolder1 of Folder1 as illustrated below, would return a list of `FolderInfo` objects representing ["Folder1", "SubFolder2"]
```txt
Photos Library
├── Folder1
    ├── SubFolder1
  ├── SubFolder2
     └── AlbumInFolder
```
#### `folder_names`
Returns a hierarchical list of names of the folders the album is contained in. For example, if album is in SubFolder2 of Folder1 as illustrated below, would return ["Folder1", "SubFolder2"].
```txt
Photos Library
├── Folder1
    ├── SubFolder1
  ├── SubFolder2
     └── AlbumInFolder
```
#### `parent`
Returns a [FolderInfo](#FolderInfo) object representing the albums parent folder or `None` if album is not a in a folder.
### FolderInfo
PhotosDB.folders returns a list of FolderInfo objects representing the top level folders in the library. Each FolderInfo object represents a single folder in the Photos library.
#### `uuid`
Returns the universally unique identifier (uuid) of the folder. This is how Photos keeps track of individual objects within the database.
#### `title`
Returns the title or name of the folder.
#### `albums`
Returns a list of [AlbumInfo](#AlbumInfo) objects representing each album contained in the folder.
#### `folders`
Returns a list of [FolderInfo](#FolderInfo) objects representing the sub-folders of the folder.
#### `parent`
Returns a [FolderInfo](#FolderInfo) object representing the folder's parent folder or `None` if album is not a in a folder.
**Note**: FolderInfo and AlbumInfo objects effectively work as a linked list. The children of a folder are contained in `folders` and `albums` and the parent object of both `AlbumInfo` and `FolderInfo` is represented by `parent`. For example:
```python
>>> import osxphotos
>>> photosdb = osxphotos.PhotosDB()
>>> photosdb.folders
[<osxphotos.albuminfo.FolderInfo object at 0x10fcc0160>]
>>> photosdb.folders[0].title
'Folder1'
>>> photosdb.folders[0].folders[1].title
'SubFolder2'
>>> photosdb.folders[0].folders[1].albums[0].title
'AlbumInFolder'
>>> photosdb.folders[0].folders[1].albums[0].parent.title
'SubFolder2'
>>> photosdb.folders[0].folders[1].albums[0].parent.albums[0].title
'AlbumInFolder'
```
### PlaceInfo
[PhotoInfo.place](#place) returns a PlaceInfo object if the photo contains valid reverse geolocation information. PlaceInfo has the following properties.

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.26.1"
__version__ = "0.27.0"

View File

@@ -10,7 +10,9 @@ Represents a single Folder in the Photos library and provides access to the fold
PhotosDB.folders() returns a list of FolderInfo objects
"""
from ._constants import _PHOTOS_5_ALBUM_KIND, _PHOTOS_5_FOLDER_KIND
import logging
from ._constants import _PHOTOS_5_ALBUM_KIND, _PHOTOS_5_FOLDER_KIND, _PHOTOS_5_VERSION
class AlbumInfo:
@@ -50,6 +52,11 @@ class AlbumInfo:
the folder list is in form:
["Top level folder", "sub folder 1", "sub folder 2", ...]
returns empty list if album is not in any folders """
if self._db._db_version < _PHOTOS_5_VERSION:
logging.warning("Folders not yet implemented for this DB version")
return []
try:
return self._folder_names
except AttributeError:
@@ -57,11 +64,16 @@ class AlbumInfo:
return self._folder_names
@property
def folders(self):
def folder_list(self):
""" return hierarchical list of folders the album is contained in
as list of FolderInfo objects in form
["Top level folder", "sub folder 1", "sub folder 2", ...]
returns empty list if album is not in any folders """
if self._db._db_version < _PHOTOS_5_VERSION:
logging.warning("Folders not yet implemented for this DB version")
return []
try:
return self._folders
except AttributeError:
@@ -71,6 +83,10 @@ class AlbumInfo:
@property
def parent(self):
""" returns FolderInfo object for parent folder or None if no parent (e.g. top-level album) """
if self._db._db_version < _PHOTOS_5_VERSION:
logging.warning("Folders not yet implemented for this DB version")
return None
try:
return self._parent
except AttributeError:

View File

@@ -343,7 +343,8 @@ class PhotosDB:
def folders(self):
""" return list of top-level folders in the photos database """
if self._db_version < _PHOTOS_5_VERSION:
raise AttributeError("Not yet implemented for this DB version")
logging.warning("Folders not yet implemented for this DB version")
return []
folders = [
FolderInfo(db=self, uuid=album)
@@ -354,6 +355,23 @@ class PhotosDB:
]
return folders
@property
def folder_names(self):
""" return list of top-level folder names in the photos database """
if self._db_version < _PHOTOS_5_VERSION:
logging.warning("Folders not yet implemented for this DB version")
return []
folder_names = [
detail["title"]
for detail in self._dbalbum_details.values()
if detail["intrash"] == 0
and detail["kind"] == _PHOTOS_5_FOLDER_KIND
and detail["parentfolder"] == self._folder_root_pk
]
return folder_names
@property
def albums(self):
""" return list of AlbumInfo objects for each album in the photos database """
@@ -362,6 +380,7 @@ class PhotosDB:
AlbumInfo(db=self, uuid=album)
for album in self._dbalbums_album.keys()
if self._dbalbum_details[album]["cloudownerhashedpersonid"] is None
and self._dbalbum_details[album]["intrash"] == 0
]
return albums
@@ -381,6 +400,7 @@ class PhotosDB:
AlbumInfo(db=self, uuid=album)
for album in self._dbalbums_album.keys()
if self._dbalbum_details[album]["cloudownerhashedpersonid"] is not None
and self._dbalbum_details[album]["intrash"] == 0
]
return albums_shared
@@ -395,6 +415,7 @@ class PhotosDB:
self._dbalbum_details[album]["title"]
for album in self._dbalbums_album.keys()
if self._dbalbum_details[album]["cloudownerhashedpersonid"] is None
and self._dbalbum_details[album]["intrash"] == 0
}
return list(albums)
@@ -418,6 +439,7 @@ class PhotosDB:
self._dbalbum_details[album]["title"]
for album in self._dbalbums_album.keys()
if self._dbalbum_details[album]["cloudownerhashedpersonid"] is not None
and self._dbalbum_details[album]["intrash"] == 0
}
return list(albums)

View File

@@ -7,7 +7,7 @@
<key>hostuuid</key>
<string>9575E48B-8D5F-5654-ABAC-4431B1167324</string>
<key>pid</key>
<integer>1440</integer>
<integer>3212</integer>
<key>processname</key>
<string>photolibraryd</string>
<key>uid</key>

View File

@@ -6,7 +6,9 @@
<array/>
<key>ExpandedSidebarItemIdentifiers</key>
<array>
<string>88A5F8B8-5B9A-43C7-BB85-3952B81580EB/L0/020</string>
<string>92D68107-B6C7-453B-96D2-97B0F26D5B8B/L0/020</string>
<string>29EF7A97-7E76-4D5F-A5E0-CC0A93E8524C/L0/020</string>
</array>
<key>Photos</key>
<dict>

View File

@@ -3,24 +3,24 @@
<plist version="1.0">
<dict>
<key>BackgroundHighlightCollection</key>
<date>2020-04-04T17:34:35Z</date>
<date>2020-04-11T20:00:25Z</date>
<key>BackgroundHighlightEnrichment</key>
<date>2020-04-04T17:34:34Z</date>
<date>2020-04-11T20:00:25Z</date>
<key>BackgroundJobAssetRevGeocode</key>
<date>2020-04-04T20:16:33Z</date>
<date>2020-04-11T20:00:25Z</date>
<key>BackgroundJobSearch</key>
<date>2020-04-04T17:34:35Z</date>
<date>2020-04-11T20:00:25Z</date>
<key>BackgroundPeopleSuggestion</key>
<date>2020-04-04T17:34:34Z</date>
<date>2020-04-11T20:00:24Z</date>
<key>BackgroundUserBehaviorProcessor</key>
<date>2020-04-04T13:56:56Z</date>
<date>2020-04-11T20:00:25Z</date>
<key>PhotoAnalysisGraphLastBackgroundGraphConsistencyUpdateJobDateKey</key>
<date>2020-04-04T20:16:40Z</date>
<date>2020-04-11T20:10:27Z</date>
<key>PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate</key>
<date>2020-04-04T13:56:49Z</date>
<date>2020-04-11T20:00:24Z</date>
<key>PhotoAnalysisGraphLastBackgroundMemoryGenerationJobDate</key>
<date>2020-04-04T20:16:33Z</date>
<date>2020-04-11T20:00:25Z</date>
<key>SiriPortraitDonation</key>
<date>2020-04-04T13:56:56Z</date>
<date>2020-04-11T20:00:25Z</date>
</dict>
</plist>

View File

@@ -3,8 +3,8 @@
<plist version="1.0">
<dict>
<key>FaceIDModelLastGenerationKey</key>
<date>2020-04-04T13:56:59Z</date>
<date>2020-04-11T20:00:25Z</date>
<key>LastContactClassificationKey</key>
<date>2020-04-04T13:57:02Z</date>
<date>2020-04-11T20:00:26Z</date>
</dict>
</plist>

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>coalesceDate</key>
<date>2019-12-08T18:06:37Z</date>
<date>2020-04-11T19:26:12Z</date>
<key>coalescePayloadVersion</key>
<integer>1</integer>
<key>currentPayloadVersion</key>

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>coalesceDate</key>
<date>2019-12-08T18:06:37Z</date>
<date>2020-04-11T19:26:12Z</date>
<key>coalescePayloadVersion</key>
<integer>1</integer>
<key>currentPayloadVersion</key>

View File

@@ -0,0 +1,217 @@
import pytest
from osxphotos._constants import _UNKNOWN_PERSON
PHOTOS_DB = "./tests/Test-10.15.4.photoslibrary/database/photos.db"
TOP_LEVEL_FOLDERS = ["Folder1"]
TOP_LEVEL_CHILDREN = ["SubFolder1", "SubFolder2"]
FOLDER_ALBUM_DICT = {"Folder1": [], "SubFolder1": [], "SubFolder2": ["AlbumInFolder"]}
ALBUM_NAMES = ["Pumpkin Farm", "AlbumInFolder", "Test Album", "Test Album"]
ALBUM_PARENT_DICT = {
"Pumpkin Farm": None,
"AlbumInFolder": "SubFolder2",
"Test Album": None,
}
ALBUM_FOLDER_NAMES_DICT = {
"Pumpkin Farm": [],
"AlbumInFolder": ["Folder1", "SubFolder2"],
"Test Album": [],
}
ALBUM_LEN_DICT = {
"Pumpkin Farm": 3,
"AlbumInFolder": 2,
"Test Album": 1,
}
ALBUM_PHOTO_UUID_DICT = {
"Pumpkin Farm": [
"F12384F6-CD17-4151-ACBA-AE0E3688539E",
"D79B8D77-BFFC-460B-9312-034F2877D35B",
"1EB2B765-0765-43BA-A90C-0D0580E6172C",
],
"Test Album": [
"F12384F6-CD17-4151-ACBA-AE0E3688539E",
"D79B8D77-BFFC-460B-9312-034F2877D35B",
],
"AlbumInFolder": [
"3DD2C897-F19E-4CA6-8C22-B027D5A71907",
"E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51",
],
}
######### Test FolderInfo ##########
def test_folders_1():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# top level folders
folders = photosdb.folders
assert len(folders) == 1
# 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.folder_names
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.folders
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.folders
# children of top level folder
children = folders[0].folders
children_names = [f.title for f in children]
assert sorted(children_names) == sorted(TOP_LEVEL_CHILDREN)
for child in folders[0].folders:
# 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.folders
# parent of top level folder should be none
for folder in folders:
assert folder.parent is None
for child in folder.folders:
# 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.folders
for folder in folders:
name = folder.title
albums = [a.title for a in folder.albums]
assert sorted(albums) == sorted(FOLDER_ALBUM_DICT[name])
for child in folder.folders:
name = child.title
albums = [a.title for a in child.albums]
assert sorted(albums) == sorted(FOLDER_ALBUM_DICT[name])
########## Test AlbumInfo ##########
def test_albums_1():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.albums
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():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.albums
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.albums
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.albums
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.albums
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.albums
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]

View File

@@ -0,0 +1,227 @@
import pytest
from osxphotos._constants import _UNKNOWN_PERSON
PHOTOS_DB = "./tests/Test-10.14.6.photoslibrary/database/photos.db"
# TOP_LEVEL_FOLDERS = ["Folder1"]
# TOP_LEVEL_CHILDREN = ["SubFolder1", "SubFolder2"]
# 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_PARENT_DICT = {
# "Pumpkin Farm": None,
# "AlbumInFolder": "SubFolder2",
# "Test Album": None,
# }
# ALBUM_FOLDER_NAMES_DICT = {
# "Pumpkin Farm": [],
# "AlbumInFolder": ["Folder1", "SubFolder2"],
# "Test Album": [],
# }
ALBUM_LEN_DICT = {
"Pumpkin Farm": 3,
"Test Album": 1,
"Test Album (1)": 1,
# "AlbumInFolder": 2,
}
ALBUM_PHOTO_UUID_DICT = {
"Pumpkin Farm": ["HrK3ZQdlQ7qpDA0FgOYXLA","15uNd7%8RguTEgNPKHfTWw","8SOE9s0XQVGsuq4ONohTng"],
"Test Album": ["8SOE9s0XQVGsuq4ONohTng"],
"Test Album (1)": ["15uNd7%8RguTEgNPKHfTWw"],
# "AlbumInFolder": [
# "3DD2C897-F19E-4CA6-8C22-B027D5A71907",
# "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51",
# ],
}
######### Test FolderInfo ##########
def test_folders_1(caplog):
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
# # check folder names
# folder_names = [f.title for f in folders]
# assert sorted(folder_names) == sorted(TOP_LEVEL_FOLDERS)
def test_folder_names(caplog):
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# check folder names
folder_names = photosdb.folder_names
assert folder_names == []
assert "Folders not yet implemented for this DB version" in caplog.text
# 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
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
# children of top level folder
children = folders[0].folders
children_names = [f.title for f in children]
assert sorted(children_names) == sorted(TOP_LEVEL_CHILDREN)
for child in folders[0].folders:
# 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)
@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
# parent of top level folder should be none
for folder in folders:
assert folder.parent is None
for child in folder.folders:
# 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
for folder in folders:
name = folder.title
albums = [a.title for a in folder.albums]
assert sorted(albums) == sorted(FOLDER_ALBUM_DICT[name])
for child in folder.folders:
name = child.title
albums = [a.title for a in child.albums]
assert sorted(albums) == sorted(FOLDER_ALBUM_DICT[name])
########## Test AlbumInfo ##########
def test_albums_1():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.albums
assert len(albums) == 3
# check names
album_names = [a.title for a in albums]
assert sorted(album_names) == sorted(ALBUM_NAMES)
def test_albums_parent(caplog):
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.albums
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]
def test_albums_folder_names(caplog):
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.albums
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]
def test_albums_folders(caplog):
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.albums
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]
def test_albums_len():
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
albums = photosdb.albums
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.albums
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]

View File

@@ -24,6 +24,7 @@ PERSONS = ["Katie", "Suzy", "Maria", _UNKNOWN_PERSON]
ALBUMS = [
"Pumpkin Farm",
"Test Album",
"AlbumInFolder",
] # Note: there are 2 albums named "Test Album" for testing duplicate album names
KEYWORDS_DICT = {
"Kids": 4,
@@ -40,6 +41,7 @@ PERSONS_DICT = {"Katie": 3, "Suzy": 2, "Maria": 1, _UNKNOWN_PERSON: 1}
ALBUM_DICT = {
"Pumpkin Farm": 3,
"Test Album": 2,
"AlbumInFolder": 2,
} # Note: there are 2 albums named "Test Album" for testing duplicate album names
UUID_DICT = {