diff --git a/osxphotos/photosdb.py b/osxphotos/photosdb.py index d56b4c42..c4a6be88 100644 --- a/osxphotos/photosdb.py +++ b/osxphotos/photosdb.py @@ -57,6 +57,8 @@ class PhotosDB: # Path to the Photos library database file self._dbfile = None + # the actual file with library data which on Photos 5 is Photos.sqlite instead of photos.db + self._dbfile_actual = None # Dict with information about all photos by uuid self._dbphotos = {} # Dict with information about all persons/photos by uuid @@ -115,25 +117,27 @@ class PhotosDB: logging.debug(f"dbfile = {dbfile}") - self._dbfile = dbfile + self._dbfile = self._dbfile_actual = os.path.abspath(dbfile) self._tmp_db = self._copy_db_file(self._dbfile) self._db_version = self._get_db_version() + + # If Photos >= 5, actual data isn't in photos.db but in Photos.sqlite if int(self._db_version) >= int(_PHOTOS_5_VERSION): logging.debug(f"version is {self._db_version}") dbpath = pathlib.Path(self._dbfile).parent dbfile = dbpath / "Photos.sqlite" - logging.debug(f"dbfile = {dbfile}") if not _check_file_exists(dbfile): sys.exit(f"dbfile {dbfile} does not exist") else: - self._dbfile = dbfile - self._tmp_db = self._copy_db_file(self._dbfile) + self._tmp_db = self._copy_db_file(dbfile) + self._dbfile_actual = dbfile + logging.debug( + f"_dbfile = {self._dbfile}, _dbfile_actual = {self._dbfile_actual}" + ) - # TODO: replace os.path with pathlib? - # TODO: clean this up -- library path computed twice library_path = os.path.dirname(os.path.abspath(dbfile)) - (library_path, _) = os.path.split(library_path) + (library_path, _) = os.path.split(library_path) # drop /database from path self._library_path = library_path if int(self._db_version) < int(_PHOTOS_5_VERSION): masters_path = os.path.join(library_path, "Masters") @@ -250,7 +254,7 @@ class PhotosDB: @property def albums(self): """ return list of albums found in photos database """ - + # Could be more than one album with same name # Right now, they are treated as same album and photos are combined from albums with same name @@ -268,7 +272,7 @@ class PhotosDB: def albums_shared(self): """ return list of shared albums found in photos database only valid for Photos 5; on Photos <= 4, prints warning and returns empty list """ - + # Could be more than one album with same name # Right now, they are treated as same album and photos are combined from albums with same name @@ -1119,3 +1123,10 @@ class PhotosDB: def __repr__(self): return f"osxphotos.{self.__class__.__name__}(dbfile='{self.db_path}')" + + # compare two PhotosDB objects for equality + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.__dict__ == other.__dict__ + + return False diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/DataModelVersion.plist b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/DataModelVersion.plist new file mode 100644 index 00000000..bb823f39 --- /dev/null +++ b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/DataModelVersion.plist @@ -0,0 +1,18 @@ + + + + + DatabaseMinorVersion + 1 + DatabaseVersion + 112 + LastOpenMode + 2 + LibrarySchemaVersion + 4025 + MetaSchemaVersion + 2 + createDate + 2019-12-27T23:19:08Z + + diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKAlbum_name.skindex b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKAlbum_name.skindex new file mode 100644 index 00000000..5afcbaeb Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKAlbum_name.skindex differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKMemory_title.skindex b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKMemory_title.skindex new file mode 100644 index 00000000..73e4b39a Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKMemory_title.skindex differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKVersion_searchIndexText.skindex b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKVersion_searchIndexText.skindex new file mode 100644 index 00000000..73e4b39a Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/RKVersion_searchIndexText.skindex differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/metaSchema.db b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/metaSchema.db new file mode 100644 index 00000000..a69a92eb Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/metaSchema.db differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/photos.db b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/photos.db new file mode 100644 index 00000000..106448e8 Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/photos.db differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/photos.db-wal b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/photos.db-wal new file mode 100644 index 00000000..e69de29b diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/.metadata_never_index b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/.metadata_never_index new file mode 100644 index 00000000..e69de29b diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.Photos/appPrivateData.plist b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.Photos/appPrivateData.plist new file mode 100644 index 00000000..cda865aa --- /dev/null +++ b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.Photos/appPrivateData.plist @@ -0,0 +1,25 @@ + + + + + Photos + + CollapsedSidebarSectionIdentifiers + + ExpandedSidebarItemIdentifiers + + TopLevelAlbums + TopLevelSlideshows + + lastKnownItemCounts + + other + 0 + photos + 0 + videos + 0 + + + + diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotoAnalysisServicePreferences.plist b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotoAnalysisServicePreferences.plist new file mode 100644 index 00000000..049d4380 --- /dev/null +++ b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotoAnalysisServicePreferences.plist @@ -0,0 +1,8 @@ + + + + + PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate + 2019-12-27T23:19:59Z + + diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb new file mode 100644 index 00000000..96fee1ce Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb-shm b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb-shm new file mode 100644 index 00000000..fe9ac284 Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb-shm differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb-wal b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/construction-photosgraph.graphdb-wal new file mode 100644 index 00000000..e69de29b diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph-tmp.graphdb b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph-tmp.graphdb new file mode 100644 index 00000000..96fee1ce Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph-tmp.graphdb differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb new file mode 100644 index 00000000..e5804776 Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb-shm b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb-shm new file mode 100644 index 00000000..fe9ac284 Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb-shm differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb-wal b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/private/com.apple.photoanalysisd/GraphService/PhotosGraph/photosgraph.graphdb-wal new file mode 100644 index 00000000..e69de29b diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/.metadata_never_index b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/.metadata_never_index new file mode 100644 index 00000000..e69de29b diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/analysismetadata.plist b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/analysismetadata.plist new file mode 100644 index 00000000..a66c6cf6 --- /dev/null +++ b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/analysismetadata.plist @@ -0,0 +1,14 @@ + + + + + PLLanguageAndLocaleKey + en-US:en_US + PLLastGeoProviderIdKey + 7618 + PLLastLocationInfoFormatVer + 12 + PLLastRevGeoForcedProviderOutOfDateCheckVersionKey + 1 + + diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/historicalmarker.plist b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/historicalmarker.plist new file mode 100644 index 00000000..daa13e7a --- /dev/null +++ b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/historicalmarker.plist @@ -0,0 +1,12 @@ + + + + + LastHistoryRowId + 53 + LibraryBuildTag + F176BAF5-4B7A-4878-83C4-4D4175F299BF + LibrarySchemaVersion + 4025 + + diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/needsanalysis b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/moments/needsanalysis new file mode 100644 index 00000000..e69de29b diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/Info.plist b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/Info.plist new file mode 100644 index 00000000..a945329e --- /dev/null +++ b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/Info.plist @@ -0,0 +1,31 @@ + + + + + DatabaseMinorVersion + 1 + DatabaseVersion + 112 + HistoricalMarker + + LastHistoryRowId + 53 + LibraryBuildTag + F176BAF5-4B7A-4878-83C4-4D4175F299BF + LibrarySchemaVersion + 4025 + + LibrarySchemaVersion + 4025 + MetaSchemaVersion + 2 + SnapshotComplete + + SnapshotCompletedDate + 2019-12-27T23:19:08Z + SnapshotLastValidated + 2019-12-27T23:19:08Z + SnapshotTables + + + diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKAdminData/0000000000.lij b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKAdminData/0000000000.lij new file mode 100644 index 00000000..a7589e5c Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKAdminData/0000000000.lij differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKAlbum/0000000000.lij b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKAlbum/0000000000.lij new file mode 100644 index 00000000..b53ebafb Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKAlbum/0000000000.lij differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKCustomSortOrder/0000000000.lij b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKCustomSortOrder/0000000000.lij new file mode 100644 index 00000000..c820792e Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKCustomSortOrder/0000000000.lij differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKFolder/0000000000.lij b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKFolder/0000000000.lij new file mode 100644 index 00000000..25115d92 Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKFolder/0000000000.lij differ diff --git a/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKKeyword/0000000000.lij b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKKeyword/0000000000.lij new file mode 100644 index 00000000..471f3e83 Binary files /dev/null and b/tests/Empty-Library-4.0-3461.7.150.photoslibrary/resources/recovery/RKKeyword/0000000000.lij differ diff --git a/tests/test_catalina_10_15_1.py b/tests/test_catalina_10_15_1.py index 28147211..a96cc8d9 100644 --- a/tests/test_catalina_10_15_1.py +++ b/tests/test_catalina_10_15_1.py @@ -5,7 +5,7 @@ from osxphotos._constants import _UNKNOWN_PERSON # TODO: put some of this code into a pre-function PHOTOS_DB = "./tests/Test-10.15.1.photoslibrary/database/photos.db" -PHOTOS_DB_PATH = "/Test-10.15.1.photoslibrary/database/Photos.sqlite" +PHOTOS_DB_PATH = "/Test-10.15.1.photoslibrary/database/photos.db" PHOTOS_LIBRARY_PATH = "/Test-10.15.1.photoslibrary" KEYWORDS = [ @@ -737,18 +737,34 @@ def test_export_13(): assert photos[0].export(dest) assert e.type == type(FileNotFoundError()) + def test_eq(): import osxphotos - + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos1 = photosdb.photos(uuid=[UUID_DICT["export"]]) photos2 = photosdb.photos(uuid=[UUID_DICT["export"]]) assert photos1[0] == photos2[0] + def test_not_eq(): import osxphotos - + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photos1 = photosdb.photos(uuid=[UUID_DICT["export"]]) photos2 = photosdb.photos(uuid=[UUID_DICT["missing"]]) assert photos1[0] != photos2[0] + + +def test_photosdb_repr(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + print(repr(photosdb)) + photosdb2 = eval(repr(photosdb)) + + ignore_keys = ["_tmp_db", "_tmp_files"] + assert {k: v for k, v in photosdb.__dict__.items() if k not in ignore_keys} == { + k: v for k, v in photosdb2.__dict__.items() if k not in ignore_keys + } + diff --git a/tests/test_empty_library_4_0.py b/tests/test_empty_library_4_0.py new file mode 100644 index 00000000..837764c5 --- /dev/null +++ b/tests/test_empty_library_4_0.py @@ -0,0 +1,108 @@ +import pytest + +# test empty library + +PHOTOS_DB = "./tests/Empty-Library-4.0-3461.7.150.photoslibrary/database/photos.db" +PHOTOS_DB_PATH = "/Empty-Library-4.0-3461.7.150.photoslibrary/database/photos.db" +PHOTOS_LIBRARY_PATH = "/Empty-Library-4.0-3461.7.150.photoslibrary" + +KEYWORDS = [] +PERSONS = [] +ALBUMS = [] +KEYWORDS_DICT = {} +PERSONS_DICT = {} +ALBUM_DICT = {} + + +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.db_version in osxphotos._constants._TESTED_DB_VERSIONS + assert photosdb.db_version == "4025" + + +def test_os_version(): + import osxphotos + + (_, major, _) = osxphotos.utils._get_os_version() + assert major in osxphotos._constants._TESTED_OS_VERSIONS + + +def test_persons(): + import osxphotos + import collections + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + assert photosdb.persons == [] + + +def test_keywords(): + import osxphotos + import collections + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + assert photosdb.keywords == [] + + +def test_albums(): + import osxphotos + import collections + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + assert photosdb.albums == [] + + +def test_keywords_dict(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + keywords = photosdb.keywords_as_dict + assert keywords == {} + + +def test_persons_as_dict(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + persons = photosdb.persons_as_dict + assert persons == {} + + +def test_albums_as_dict(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + albums = photosdb.albums_as_dict + assert albums == {} + + +def test_count(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + photos = photosdb.photos() + assert len(photos) == 0 + + +def test_get_db_path(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + db_path = photosdb.db_path + assert db_path.endswith(PHOTOS_DB_PATH) + + +def test_get_library_path(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + lib_path = photosdb.library_path + assert lib_path.endswith(PHOTOS_LIBRARY_PATH) diff --git a/tests/test_export_catalina_10_15_1.py b/tests/test_export_catalina_10_15_1.py index 594d396f..696cc36e 100644 --- a/tests/test_export_catalina_10_15_1.py +++ b/tests/test_export_catalina_10_15_1.py @@ -6,7 +6,7 @@ from osxphotos.utils import dd_to_dms_str # TODO: put some of this code into a pre-function PHOTOS_DB = "./tests/Test-10.15.1.photoslibrary/database/photos.db" -PHOTOS_DB_PATH = "/Test-10.15.1.photoslibrary/database/Photos.sqlite" +PHOTOS_DB_PATH = "/Test-10.15.1.photoslibrary/database/photos.db" PHOTOS_LIBRARY_PATH = "/Test-10.15.1.photoslibrary" KEYWORDS = [ diff --git a/tests/test_mojave_10_14_6.py b/tests/test_mojave_10_14_6.py index c1a04d56..55fa9955 100644 --- a/tests/test_mojave_10_14_6.py +++ b/tests/test_mojave_10_14_6.py @@ -324,3 +324,17 @@ def test_get_library_path(): photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) lib_path = photosdb.library_path assert lib_path.endswith(PHOTOS_LIBRARY_PATH) + + +def test_photosdb_repr(): + import osxphotos + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) + print(repr(photosdb)) + photosdb2 = eval(repr(photosdb)) + + ignore_keys = ["_tmp_db", "_tmp_files"] + assert {k: v for k, v in photosdb.__dict__.items() if k not in ignore_keys} == { + k: v for k, v in photosdb2.__dict__.items() if k not in ignore_keys + } + diff --git a/tests/test_shared_catalina_10_15_1.py b/tests/test_shared_catalina_10_15_1.py index 0e1ba9de..be9d4ffd 100644 --- a/tests/test_shared_catalina_10_15_1.py +++ b/tests/test_shared_catalina_10_15_1.py @@ -4,7 +4,7 @@ import pytest # TODO: put some of this code into a pre-function PHOTOS_DB = "./tests/Test-Shared-10.15.1.photoslibrary/database/photos.db" -PHOTOS_DB_PATH = "/Test-Shared-10.15.1.photoslibrary/database/Photos.sqlite" +PHOTOS_DB_PATH = "/Test-Shared-10.15.1.photoslibrary/database/photos.db" PHOTOS_LIBRARY_PATH = "/Test-Shared-10.15.1.photoslibrary" KEYWORDS = ["portrait"] diff --git a/tests/test_shared_mojave_10_14_6.py b/tests/test_shared_mojave_10_14_6.py index 645ae864..d33aedcc 100644 --- a/tests/test_shared_mojave_10_14_6.py +++ b/tests/test_shared_mojave_10_14_6.py @@ -4,7 +4,7 @@ import pytest # TODO: put some of this code into a pre-function PHOTOS_DB = "./tests/Test-10.14.6.photoslibrary/database/photos.db" -PHOTOS_DB_PATH = "/Test-10.14.6.photoslibrary/database/Photos.sqlite" +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)"]