Added support and tests for 10.12
@ -26,14 +26,15 @@ from . import _applescript
|
||||
# TODO: fix versions tested to include 10.14.6
|
||||
|
||||
# which Photos library database versions have been tested
|
||||
# Photos 2.0 (10.12.6) == 2622
|
||||
# Photos 3.0 (10.13.6) == 3301
|
||||
# Photos 4.0 (10.14.5) == 4016
|
||||
# Photos 4.0 (10.4.6) == 4025
|
||||
# TODO: Should this also use compatibleBackToVersion from LiGlobals?
|
||||
_TESTED_DB_VERSIONS = ["4025", "4016", "3301"]
|
||||
_TESTED_DB_VERSIONS = ["4025", "4016", "3301", "2622"]
|
||||
|
||||
# which major version operating systems have been tested
|
||||
_TESTED_OS_VERSIONS = ["13", "14"]
|
||||
_TESTED_OS_VERSIONS = ["12", "13", "14"]
|
||||
|
||||
_debug = False
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 541 KiB |
|
After Width: | Height: | Size: 528 KiB |
|
After Width: | Height: | Size: 574 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 500 KiB |
|
After Width: | Height: | Size: 450 KiB |
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>DatabaseMinorVersion</key>
|
||||
<integer>1</integer>
|
||||
<key>DatabaseVersion</key>
|
||||
<integer>112</integer>
|
||||
<key>LastOpenMode</key>
|
||||
<integer>2</integer>
|
||||
<key>LibrarySchemaVersion</key>
|
||||
<integer>2622</integer>
|
||||
<key>MetaSchemaVersion</key>
|
||||
<integer>2</integer>
|
||||
<key>createDate</key>
|
||||
<date>2019-08-24T02:50:48Z</date>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
tests/Test-10.12.6.photoslibrary/database/RKAlbum_name.skindex
Normal file
BIN
tests/Test-10.12.6.photoslibrary/database/RKMemory_title.skindex
Normal file
BIN
tests/Test-10.12.6.photoslibrary/database/metaSchema.db
Normal file
BIN
tests/Test-10.12.6.photoslibrary/database/photos.db
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LithiumMessageTracer</key>
|
||||
<dict>
|
||||
<key>LastReportedDate</key>
|
||||
<date>2019-08-24T02:50:48Z</date>
|
||||
</dict>
|
||||
<key>PXPeopleScreenUnlocked</key>
|
||||
<true/>
|
||||
<key>Photos</key>
|
||||
<dict>
|
||||
<key>IPXWorkspaceControllerPhotosHasContentKey</key>
|
||||
<true/>
|
||||
<key>IPXWorkspaceControllerZoomLevelsKey</key>
|
||||
<dict>
|
||||
<key>kZoomLevelIdentifierAlbums</key>
|
||||
<integer>7</integer>
|
||||
<key>kZoomLevelIdentifierVersions</key>
|
||||
<integer>7</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate</key>
|
||||
<date>2019-08-24T02:51:33Z</date>
|
||||
<key>PhotoAnalysisGraphLastBackgroundMemoryGenerationJobDate</key>
|
||||
<date>2019-08-24T13:19:30Z</date>
|
||||
</dict>
|
||||
</plist>
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 460 KiB |
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PLLanguageAndLocaleKey</key>
|
||||
<string>en-US:en_US</string>
|
||||
<key>PLLastGeoProviderIdKey</key>
|
||||
<string>7618</string>
|
||||
<key>PLLastLocationInfoFormatVer</key>
|
||||
<integer>12</integer>
|
||||
<key>PLLastRevGeoForcedProviderOutOfDateCheckVersionKey</key>
|
||||
<integer>1</integer>
|
||||
<key>PLLastRevGeoVerFileFetchDateKey</key>
|
||||
<date>2019-08-24T02:51:30Z</date>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LastHistoryRowId</key>
|
||||
<integer>414</integer>
|
||||
<key>LibraryBuildTag</key>
|
||||
<string>E3E46F2A-7168-4973-AB3E-5848F80BFC7D</string>
|
||||
<key>LibrarySchemaVersion</key>
|
||||
<integer>2622</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>FileVersion</key>
|
||||
<integer>11</integer>
|
||||
<key>Source</key>
|
||||
<dict>
|
||||
<key>35230</key>
|
||||
<dict>
|
||||
<key>CountryMinVersions</key>
|
||||
<dict>
|
||||
<key>OTHER</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>CurrentVersion</key>
|
||||
<integer>1</integer>
|
||||
<key>NoResultErrorIsSuccess</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>57879</key>
|
||||
<dict>
|
||||
<key>CountryMinVersions</key>
|
||||
<dict>
|
||||
<key>OTHER</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>CurrentVersion</key>
|
||||
<integer>1</integer>
|
||||
<key>NoResultErrorIsSuccess</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>7618</key>
|
||||
<dict>
|
||||
<key>AddCountyIfNeeded</key>
|
||||
<true/>
|
||||
<key>CountryMinVersions</key>
|
||||
<dict>
|
||||
<key>OTHER</key>
|
||||
<integer>10</integer>
|
||||
</dict>
|
||||
<key>CurrentVersion</key>
|
||||
<integer>10</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 272 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 276 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 330 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 297 KiB |
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>DatabaseMinorVersion</key>
|
||||
<integer>1</integer>
|
||||
<key>DatabaseVersion</key>
|
||||
<integer>112</integer>
|
||||
<key>HistoricalMarker</key>
|
||||
<dict>
|
||||
<key>LastHistoryRowId</key>
|
||||
<integer>403</integer>
|
||||
<key>LibraryBuildTag</key>
|
||||
<string>E3E46F2A-7168-4973-AB3E-5848F80BFC7D</string>
|
||||
<key>LibrarySchemaVersion</key>
|
||||
<integer>2622</integer>
|
||||
</dict>
|
||||
<key>LibrarySchemaVersion</key>
|
||||
<integer>2622</integer>
|
||||
<key>MetaSchemaVersion</key>
|
||||
<integer>2</integer>
|
||||
<key>SnapshotComplete</key>
|
||||
<true/>
|
||||
<key>SnapshotCompletedDate</key>
|
||||
<date>2019-08-24T02:50:48Z</date>
|
||||
<key>SnapshotTables</key>
|
||||
<dict/>
|
||||
</dict>
|
||||
</plist>
|
||||
203
tests/test_10_12_6.py
Normal file
@ -0,0 +1,203 @@
|
||||
import pytest
|
||||
|
||||
# TODO: put some of this code into a pre-function
|
||||
# TODO: All the hardocded uuids, etc in test functions should be in some sort of config
|
||||
|
||||
PHOTOS_DB = "./tests/Test-10.12.6.photoslibrary/database/photos.db"
|
||||
KEYWORDS = [
|
||||
"Kids",
|
||||
"wedding",
|
||||
"flowers",
|
||||
"England",
|
||||
"London",
|
||||
"London 2018",
|
||||
"St. James's Park",
|
||||
"UK",
|
||||
"United Kingdom",
|
||||
]
|
||||
PERSONS = ["Katie", "Suzy", "Maria"]
|
||||
ALBUMS = ["Pumpkin Farm", "Last Import"]
|
||||
KEYWORDS_DICT = {
|
||||
"Kids": 4,
|
||||
"wedding": 2,
|
||||
"flowers": 1,
|
||||
"England": 1,
|
||||
"London": 1,
|
||||
"London 2018": 1,
|
||||
"St. James's Park": 1,
|
||||
"UK": 1,
|
||||
"United Kingdom": 1,
|
||||
}
|
||||
PERSONS_DICT = {"Katie": 3, "Suzy": 2, "Maria": 1}
|
||||
ALBUM_DICT = {"Pumpkin Farm": 3, "Last Import": 1}
|
||||
|
||||
|
||||
def test_init():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
assert isinstance(photosdb, osxphotos.PhotosDB)
|
||||
|
||||
|
||||
def test_db_version():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
assert photosdb.get_db_version() in osxphotos._TESTED_DB_VERSIONS
|
||||
|
||||
|
||||
def test_os_version():
|
||||
import osxphotos
|
||||
|
||||
(_, major, _) = osxphotos._get_os_version()
|
||||
assert major in osxphotos._TESTED_OS_VERSIONS
|
||||
|
||||
|
||||
def test_persons():
|
||||
import osxphotos
|
||||
import collections
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
assert "Katie" in photosdb.persons()
|
||||
assert collections.Counter(PERSONS) == collections.Counter(photosdb.persons())
|
||||
|
||||
|
||||
def test_keywords():
|
||||
import osxphotos
|
||||
import collections
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
assert "wedding" in photosdb.keywords()
|
||||
assert collections.Counter(KEYWORDS) == collections.Counter(photosdb.keywords())
|
||||
|
||||
|
||||
def test_albums():
|
||||
import osxphotos
|
||||
import collections
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
assert "Pumpkin Farm" in photosdb.albums()
|
||||
assert collections.Counter(ALBUMS) == collections.Counter(photosdb.albums())
|
||||
|
||||
|
||||
def test_keywords_dict():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
keywords = photosdb.keywords_as_dict()
|
||||
assert keywords["wedding"] == 2
|
||||
assert keywords == KEYWORDS_DICT
|
||||
|
||||
|
||||
def test_persons_as_dict():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
persons = photosdb.persons_as_dict()
|
||||
assert persons["Maria"] == 1
|
||||
assert persons == PERSONS_DICT
|
||||
|
||||
|
||||
def test_albums_as_dict():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
albums = photosdb.albums_as_dict()
|
||||
assert albums["Pumpkin Farm"] == 3
|
||||
assert albums == ALBUM_DICT
|
||||
|
||||
|
||||
def test_attributes():
|
||||
import datetime
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
photos = photosdb.photos(uuid=["sE5LlfekS8ykEE7o0cuMVA"])
|
||||
assert len(photos) == 1
|
||||
p = photos[0]
|
||||
assert p.keywords() == ["Kids"]
|
||||
assert p.filename() == "Pumkins2.jpg"
|
||||
assert p.date() == datetime.datetime(2018, 9, 28, 16, 7, 7,0,datetime.timezone(datetime.timedelta(seconds=-14400)))
|
||||
assert p.description() == "Girl holding pumpkin"
|
||||
assert p.name() == "I found one!"
|
||||
assert p.albums() == ["Pumpkin Farm"]
|
||||
assert p.persons() == ["Katie"]
|
||||
assert (
|
||||
p.path()
|
||||
== "./tests/Test-10.12.6.photoslibrary/Masters/2019/08/24/20190824-030824/Pumkins2.jpg"
|
||||
)
|
||||
assert p.ismissing() == False
|
||||
|
||||
|
||||
def test_missing():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
photos = photosdb.photos(uuid=["Pj99JmYjQkeezdY2OFuSaw"])
|
||||
assert len(photos) == 1
|
||||
p = photos[0]
|
||||
assert p.path() == None
|
||||
assert p.ismissing() == True
|
||||
|
||||
|
||||
def test_count():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
photos = photosdb.photos()
|
||||
assert len(photos) == 7
|
||||
|
||||
|
||||
def test_keyword_2():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
photos = photosdb.photos(keywords=["wedding"])
|
||||
assert len(photos) == 2
|
||||
|
||||
|
||||
def test_keyword_not_in_album():
|
||||
import osxphotos
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
|
||||
# find all photos with keyword "Kids" not in the album "Pumpkin Farm"
|
||||
photos1 = photosdb.photos(albums=["Pumpkin Farm"])
|
||||
photos2 = photosdb.photos(keywords=["Kids"])
|
||||
photos3 = [p for p in photos2 if p not in photos1]
|
||||
assert len(photos3) == 1
|
||||
assert photos3[0].uuid() == "Pj99JmYjQkeezdY2OFuSaw"
|
||||
|
||||
|
||||
# def main():
|
||||
# photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||
# print(photosdb.keywords())
|
||||
# print(photosdb.persons())
|
||||
# print(photosdb.albums())
|
||||
|
||||
# print(photosdb.keywords_as_dict())
|
||||
# print(photosdb.persons_as_dict())
|
||||
# print(photosdb.albums_as_dict())
|
||||
|
||||
# # # find all photos with Keyword = Foo and containing John Smith
|
||||
# # photos = photosdb.photos(keywords=["Foo"],persons=["John Smith"])
|
||||
# #
|
||||
# # # find all photos that include Alice Smith but do not contain the keyword Bar
|
||||
# # photos = [p for p in photosdb.photos(persons=["Alice Smith"])
|
||||
# # if p not in photosdb.photos(keywords=["Bar"]) ]
|
||||
# photos = photosdb.photos()
|
||||
# for p in photos:
|
||||
# print(
|
||||
# p.uuid(),
|
||||
# p.filename(),
|
||||
# p.date(),
|
||||
# p.description(),
|
||||
# p.name(),
|
||||
# p.keywords(),
|
||||
# p.albums(),
|
||||
# p.persons(),
|
||||
# p.path(),
|
||||
# )
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# main()
|
||||