diff --git a/README.md b/README.md index dc7b635a..2dc46085 100644 --- a/README.md +++ b/README.md @@ -1578,9 +1578,15 @@ Returns `True` if the picture has been marked as a favorite, otherwise `False` #### `hidden` Returns `True` if the picture has been marked as hidden, otherwise `False` +#### `visible` +Returns `True` if the picture is visible in library, otherwise `False`. e.g. non-selected burst photos are not hidden but also not visible + #### `intrash` Returns `True` if the picture is in the trash ('Recently Deleted' folder), otherwise `False` +#### `date_trashed` +Returns the date the photo was placed in the trash as a datetime.datetime object or None if photo is not in the trash + #### `location` Returns latitude and longitude as a tuple of floats (latitude, longitude). If location is not set, latitude and longitude are returned as `None` diff --git a/osxphotos/_version.py b/osxphotos/_version.py index fef818b1..e97324d6 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,5 +1,5 @@ """ version info """ -__version__ = "0.39.11" +__version__ = "0.39.12" diff --git a/osxphotos/photoinfo/photoinfo.py b/osxphotos/photoinfo/photoinfo.py index 28878afb..a65a0cf8 100644 --- a/osxphotos/photoinfo/photoinfo.py +++ b/osxphotos/photoinfo/photoinfo.py @@ -113,15 +113,15 @@ class PhotoInfo: # lastmodifieddate anytime photo database record is updated (e.g. adding tags) # only report lastmodified date for Photos <=4 if photo is edited; # even in this case, the date could be incorrect - if self.hasadjustments or self._db._db_version > _PHOTOS_4_VERSION: - imagedate = self._info["lastmodifieddate"] - if imagedate: - seconds = self._info["imageTimeZoneOffsetSeconds"] or 0 - delta = timedelta(seconds=seconds) - tz = timezone(delta) - return imagedate.astimezone(tz=tz) - else: - return None + if not self.hasadjustments and self._db._db_version <= _PHOTOS_4_VERSION: + return None + + imagedate = self._info["lastmodifieddate"] + if imagedate: + seconds = self._info["imageTimeZoneOffsetSeconds"] or 0 + delta = timedelta(seconds=seconds) + tz = timezone(delta) + return imagedate.astimezone(tz=tz) else: return None @@ -501,37 +501,52 @@ class PhotoInfo: downloaded from cloud to local storate their status in the database might still show isMissing = 1 """ - return True if self._info["isMissing"] == 1 else False + return self._info["isMissing"] == 1 @property def hasadjustments(self): """ True if picture has adjustments / edits """ - return True if self._info["hasAdjustments"] == 1 else False + return self._info["hasAdjustments"] == 1 @property def external_edit(self): """ Returns True if picture was edited outside of Photos using external editor """ - return ( - True - if self._info["adjustmentFormatID"] == "com.apple.Photos.externalEdit" - else False - ) + return self._info["adjustmentFormatID"] == "com.apple.Photos.externalEdit" @property def favorite(self): """ True if picture is marked as favorite """ - return True if self._info["favorite"] == 1 else False + return self._info["favorite"] == 1 @property def hidden(self): """ True if picture is hidden """ - return True if self._info["hidden"] == 1 else False + return self._info["hidden"] == 1 + + @property + def visible(self): + """ True if picture is visble """ + return self._info["visible"] @property def intrash(self): """ True if picture is in trash ('Recently Deleted' folder)""" return self._info["intrash"] + @property + def date_trashed(self): + """ Date asset was placed in the trash or None """ + # TODO: add add_timezone(dt, offset_seconds) to datetime_utils + # also update date_modified + trasheddate = self._info["trasheddate"] + if trasheddate: + seconds = self._info["imageTimeZoneOffsetSeconds"] or 0 + delta = timedelta(seconds=seconds) + tz = timezone(delta) + return trasheddate.astimezone(tz=tz) + else: + return None + @property def location(self): """ returns (latitude, longitude) as float in degrees or None """ @@ -551,14 +566,15 @@ class PhotoInfo: """Returns Uniform Type Identifier (UTI) for the image for example: public.jpeg or com.apple.quicktime-movie """ - if self._db._db_version <= _PHOTOS_4_VERSION: - if self.hasadjustments: - return self._info["UTI_edited"] - elif self.has_raw and self.raw_original: - # return UTI of the non-raw image to match Photos 5+ behavior - return self._info["raw_pair_info"]["UTI"] - else: - return self._info["UTI"] + if self._db._db_version <= _PHOTOS_4_VERSION and self.hasadjustments: + return self._info["UTI_edited"] + elif ( + self._db._db_version <= _PHOTOS_4_VERSION + and self.has_raw + and self.raw_original + ): + # return UTI of the non-raw image to match Photos 5+ behavior + return self._info["raw_pair_info"]["UTI"] else: return self._info["UTI"] @@ -597,12 +613,12 @@ class PhotoInfo: @property def ismovie(self): """Returns True if file is a movie, otherwise False""" - return True if self._info["type"] == _MOVIE_TYPE else False + return self._info["type"] == _MOVIE_TYPE @property def isphoto(self): """Returns True if file is an image, otherwise False""" - return True if self._info["type"] == _PHOTO_TYPE else False + return self._info["type"] == _PHOTO_TYPE @property def incloud(self): diff --git a/osxphotos/photosdb/photosdb.py b/osxphotos/photosdb/photosdb.py index c4d3a0b3..8ee49216 100644 --- a/osxphotos/photosdb/photosdb.py +++ b/osxphotos/photosdb/photosdb.py @@ -887,7 +887,9 @@ class PhotosDB: RKMaster.width, RKMaster.orientation, RKMaster.fileSize, - RKVersion.subType + RKVersion.subType, + RKVersion.inTrashDate, + RKVersion.showInLibrary FROM RKVersion, RKMaster WHERE RKVersion.masterUuid = RKMaster.uuid""" ) @@ -915,7 +917,9 @@ class PhotosDB: RKMaster.width, RKMaster.orientation, RKMaster.originalFileSize, - RKVersion.subType + RKVersion.subType, + RKVersion.inTrashDate, + RKVersion.showInLibrary FROM RKVersion, RKMaster WHERE RKVersion.masterUuid = RKMaster.uuid""" ) @@ -962,6 +966,8 @@ class PhotosDB: # 38 RKMaster.orientation, # 39 RKMaster.originalFileSize # 40 RKVersion.subType + # 41 RKVersion.inTrashDate + # 42 RKVersion.showInLibrary -- is item visible in library (e.g. non-selected burst images are not visible) for row in c: uuid = row[0] @@ -1136,7 +1142,14 @@ class PhotosDB: ) # recently deleted items - self._dbphotos[uuid]["intrash"] = True if row[32] == 1 else False + self._dbphotos[uuid]["intrash"] = row[32] == 1 + self._dbphotos[uuid]["trasheddate_timestamp"] = row[41] + try: + self._dbphotos[uuid]["trasheddate"] = datetime.fromtimestamp( + row[41] + TIME_DELTA + ) + except (ValueError, TypeError): + self._dbphotos[uuid]["trasheddate"] = None # height/width/orientation self._dbphotos[uuid]["height"] = row[33] @@ -1147,6 +1160,10 @@ class PhotosDB: self._dbphotos[uuid]["original_orientation"] = row[38] self._dbphotos[uuid]["original_filesize"] = row[39] + # visibility state + self._dbphotos[uuid]["visibility_state"] = row[42] + self._dbphotos[uuid]["visible"] = row[42] == 1 + # import session not yet handled for Photos 4 self._dbphotos[uuid]["import_session"] = None self._dbphotos[uuid]["import_uuid"] = None @@ -1840,7 +1857,9 @@ class PhotosDB: ZADDITIONALASSETATTRIBUTES.ZORIGINALORIENTATION, ZADDITIONALASSETATTRIBUTES.ZORIGINALFILESIZE, {depth_state}, - {asset_table}.ZADJUSTMENTTIMESTAMP + {asset_table}.ZADJUSTMENTTIMESTAMP, + {asset_table}.ZVISIBILITYSTATE, + {asset_table}.ZTRASHEDDATE FROM {asset_table} JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = {asset_table}.Z_PK ORDER BY {asset_table}.ZUUID """ @@ -1885,6 +1904,8 @@ class PhotosDB: # 35 ZADDITIONALASSETATTRIBUTES.ZORIGINALFILESIZE # 36 ZGENERICASSET.ZDEPTHSTATES / ZASSET.ZDEPTHTYPE # 37 ZGENERICASSET.ZADJUSTMENTTIMESTAMP -- when was photo edited? + # 38 ZGENERICASSET.ZVISIBILITYSTATE -- 0 if visible, 2 if not (e.g. a burst image) + # 39 ZGENERICASSET.ZTRASHEDDATE -- date item placed in the trash or null if not in trash for row in c: uuid = row[0] @@ -1901,9 +1922,7 @@ class PhotosDB: info["lastmodifieddate_timestamp"] = row[37] try: info["lastmodifieddate"] = datetime.fromtimestamp(row[37] + TIME_DELTA) - except ValueError: - info["lastmodifieddate"] = None - except TypeError: + except (ValueError, TypeError): info["lastmodifieddate"] = None info["imageTimeZoneOffsetSeconds"] = row[6] @@ -2046,6 +2065,11 @@ class PhotosDB: # recently deleted items info["intrash"] = True if row[28] == 1 else False + info["trasheddate_timestamp"] = row[39] + try: + info["trasheddate"] = datetime.fromtimestamp(row[39] + TIME_DELTA) + except (ValueError, TypeError): + info["trasheddate"] = None # height/width/orientation info["height"] = row[29] @@ -2056,6 +2080,11 @@ class PhotosDB: info["original_orientation"] = row[34] info["original_filesize"] = row[35] + # visibility state, visible (True) if 0, otherwise not visible (False) + # only values I've seen are 0 for visible, 2 for not-visible + info["visibility_state"] = row[38] + info["visible"] = row[38] == 0 + # initialize import session info which will be filled in later # not every photo has an import session so initialize all records now info["import_session"] = None diff --git a/osxphotos/utils.py b/osxphotos/utils.py index a0a1e08d..de1cf8c6 100644 --- a/osxphotos/utils.py +++ b/osxphotos/utils.py @@ -63,8 +63,8 @@ def noop(*args, **kwargs): def _get_os_version(): - # returns tuple containing OS version - # e.g. 10.13.6 = (10, 13, 6) + # returns tuple of str containing OS version + # e.g. 10.13.6 = ("10", "13", "6") version = platform.mac_ver()[0].split(".") if len(version) == 2: (ver, major) = version diff --git a/tests/search_info_test_data_10_15_7.json b/tests/search_info_test_data_10_15_7.json index 09e272b2..03c1d945 100644 --- a/tests/search_info_test_data_10_15_7.json +++ b/tests/search_info_test_data_10_15_7.json @@ -1 +1 @@ -{"UUID_SEARCH_INFO": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["Food", "Butter"], "place_names": ["Durham Bulls Athletic Park"], "streets": ["Blackwell St"], "neighborhoods": ["American Tobacco District", "Downtown Durham"], "city": "Durham", "locality_names": ["Durham"], "state": "North Carolina", "state_abbreviation": "NC", "country": "United States", "bodies_of_water": [], "month": "October", "year": "2018", "holidays": [], "activities": ["Dinner", "Travel", "Entertainment", "Dining", "Trip"], "season": "Fall", "venues": ["Luna Rotisserie and Empanadas", "Copa", "Pie Pusher's", "The Pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Desert", "Land", "Sky", "Sunset Sunrise", "Outdoor"], "place_names": ["Royal Palms State Beach"], "streets": [], "neighborhoods": ["San Pedro"], "city": "Los Angeles", "locality_names": [], "state": "California", "state_abbreviation": "", "country": "United States", "bodies_of_water": ["Catalina Channel"], "month": "November", "year": "2017", "holidays": [], "activities": ["Beach Activity", "Activity"], "season": "Fall", "venues": [], "venue_types": [], "media_types": ["Live Photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["Bench", "Furniture", "Water Body", "Land", "People", "Water", "Plant", "Outdoor", "Vegetation", "Forest"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "December", "year": "2014", "holidays": ["Christmas Day"], "activities": ["Celebration", "Holiday"], "season": "Winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["food", "butter"], "place_names": ["durham bulls athletic park"], "streets": ["blackwell st"], "neighborhoods": ["american tobacco district", "downtown durham"], "city": "durham", "locality_names": ["durham"], "state": "north carolina", "state_abbreviation": "nc", "country": "united states", "bodies_of_water": [], "month": "october", "year": "2018", "holidays": [], "activities": ["dinner", "travel", "entertainment", "dining", "trip"], "season": "fall", "venues": ["luna rotisserie and empanadas", "copa", "pie pusher's", "the pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["desert", "land", "sky", "sunset sunrise", "outdoor"], "place_names": ["royal palms state beach"], "streets": [], "neighborhoods": ["san pedro"], "city": "los angeles", "locality_names": [], "state": "california", "state_abbreviation": "", "country": "united states", "bodies_of_water": ["catalina channel"], "month": "november", "year": "2017", "holidays": [], "activities": ["beach activity", "activity"], "season": "fall", "venues": [], "venue_types": [], "media_types": ["live photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["bench", "furniture", "water body", "land", "people", "water", "plant", "outdoor", "vegetation", "forest"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "december", "year": "2014", "holidays": ["christmas day"], "activities": ["celebration", "holiday"], "season": "winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_ALL": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["Food", "Butter", "Durham Bulls Athletic Park", "Blackwell St", "American Tobacco District", "Downtown Durham", "Durham", "Dinner", "Travel", "Entertainment", "Dining", "Trip", "Luna Rotisserie and Empanadas", "Copa", "Pie Pusher's", "The Pinhook", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Desert", "Land", "Sky", "Sunset Sunrise", "Outdoor", "Royal Palms State Beach", "San Pedro", "Catalina Channel", "Beach Activity", "Activity", "Live Photos", "Los Angeles", "California", "United States", "November", "2017", "Fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["Bench", "Furniture", "Water Body", "Land", "People", "Water", "Plant", "Outdoor", "Vegetation", "Forest", "Christmas Day", "Celebration", "Holiday", "December", "2014", "Winter"]}, "UUID_SEARCH_INFO_ALL_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["food", "butter", "durham bulls athletic park", "blackwell st", "american tobacco district", "downtown durham", "durham", "dinner", "travel", "entertainment", "dining", "trip", "luna rotisserie and empanadas", "copa", "pie pusher's", "the pinhook", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["desert", "land", "sky", "sunset sunrise", "outdoor", "royal palms state beach", "san pedro", "catalina channel", "beach activity", "activity", "live photos", "los angeles", "california", "united states", "november", "2017", "fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["bench", "furniture", "water body", "land", "people", "water", "plant", "outdoor", "vegetation", "forest", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} +{"UUID_SEARCH_INFO": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["Food", "Butter"], "place_names": ["Durham Bulls Athletic Park"], "streets": ["Blackwell St"], "neighborhoods": ["American Tobacco District", "Downtown Durham"], "city": "Durham", "locality_names": ["Durham"], "state": "North Carolina", "state_abbreviation": "NC", "country": "United States", "bodies_of_water": [], "month": "October", "year": "2018", "holidays": [], "activities": ["Entertainment", "Travel", "Dining", "Dinner", "Trip"], "season": "Fall", "venues": ["Copa", "Luna Rotisserie and Empanadas", "The Pinhook", "Pie Pusher's"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Desert", "Land", "Outdoor", "Sky", "Sunset Sunrise"], "place_names": ["Royal Palms State Beach"], "streets": [], "neighborhoods": ["San Pedro"], "city": "Los Angeles", "locality_names": [], "state": "California", "state_abbreviation": "", "country": "United States", "bodies_of_water": ["Catalina Channel"], "month": "November", "year": "2017", "holidays": [], "activities": ["Beach Activity", "Activity"], "season": "Fall", "venues": [], "venue_types": [], "media_types": ["Live Photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["Furniture", "Bench", "People", "Vegetation", "Forest", "Water", "Water Body", "Outdoor", "Land"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "December", "year": "2014", "holidays": ["Christmas Day"], "activities": ["Celebration", "Holiday"], "season": "Winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["food", "butter"], "place_names": ["durham bulls athletic park"], "streets": ["blackwell st"], "neighborhoods": ["american tobacco district", "downtown durham"], "city": "durham", "locality_names": ["durham"], "state": "north carolina", "state_abbreviation": "nc", "country": "united states", "bodies_of_water": [], "month": "october", "year": "2018", "holidays": [], "activities": ["entertainment", "travel", "dining", "dinner", "trip"], "season": "fall", "venues": ["copa", "luna rotisserie and empanadas", "the pinhook", "pie pusher's"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["desert", "land", "outdoor", "sky", "sunset sunrise"], "place_names": ["royal palms state beach"], "streets": [], "neighborhoods": ["san pedro"], "city": "los angeles", "locality_names": [], "state": "california", "state_abbreviation": "", "country": "united states", "bodies_of_water": ["catalina channel"], "month": "november", "year": "2017", "holidays": [], "activities": ["beach activity", "activity"], "season": "fall", "venues": [], "venue_types": [], "media_types": ["live photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["furniture", "bench", "people", "vegetation", "forest", "water", "water body", "outdoor", "land"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "december", "year": "2014", "holidays": ["christmas day"], "activities": ["celebration", "holiday"], "season": "winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_ALL": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["Food", "Butter", "Durham Bulls Athletic Park", "Blackwell St", "American Tobacco District", "Downtown Durham", "Durham", "Entertainment", "Travel", "Dining", "Dinner", "Trip", "Copa", "Luna Rotisserie and Empanadas", "The Pinhook", "Pie Pusher's", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Desert", "Land", "Outdoor", "Sky", "Sunset Sunrise", "Royal Palms State Beach", "San Pedro", "Catalina Channel", "Beach Activity", "Activity", "Live Photos", "Los Angeles", "California", "United States", "November", "2017", "Fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["Furniture", "Bench", "People", "Vegetation", "Forest", "Water", "Water Body", "Outdoor", "Land", "Christmas Day", "Celebration", "Holiday", "December", "2014", "Winter"]}, "UUID_SEARCH_INFO_ALL_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["food", "butter", "durham bulls athletic park", "blackwell st", "american tobacco district", "downtown durham", "durham", "entertainment", "travel", "dining", "dinner", "trip", "copa", "luna rotisserie and empanadas", "the pinhook", "pie pusher's", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["desert", "land", "outdoor", "sky", "sunset sunrise", "royal palms state beach", "san pedro", "catalina channel", "beach activity", "activity", "live photos", "los angeles", "california", "united states", "november", "2017", "fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["furniture", "bench", "people", "vegetation", "forest", "water", "water body", "outdoor", "land", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} diff --git a/tests/test_catalina_10_15_7.py b/tests/test_catalina_10_15_7.py index fb4bd5a0..ab76b3ee 100644 --- a/tests/test_catalina_10_15_7.py +++ b/tests/test_catalina_10_15_7.py @@ -13,6 +13,11 @@ import pytest import osxphotos from osxphotos._constants import _UNKNOWN_PERSON +from osxphotos.utils import _get_os_version + +OS_VERSION = _get_os_version() +SKIP_TEST = "OSXPHOTOS_TEST_EXPORT" not in os.environ or OS_VERSION[1] != "15" +PHOTOS_DB_LOCAL = os.path.expanduser("~/Pictures/Photos Library.photoslibrary") PHOTOS_DB = "tests/Test-10.15.7.photoslibrary/database/photos.db" PHOTOS_DB_PATH = "/Test-10.15.7.photoslibrary/database/photos.db" @@ -98,6 +103,11 @@ UUID_DICT = { "movie": "D1359D09-1373-4F3B-B0E3-1A4DE573E4A3", } +UUID_DICT_LOCAL = { + "not_visible": "ABF00253-78E7-4FD6-953B-709307CD489D", + "burst": "44AF1FCA-AC2D-4FA5-B288-E67DC18F9CA8", +} + UUID_PUMPKIN_FARM = [ "F12384F6-CD17-4151-ACBA-AE0E3688539E", "D79B8D77-BFFC-460B-9312-034F2877D35B", @@ -194,6 +204,11 @@ def photosdb(): return osxphotos.PhotosDB(dbfile=PHOTOS_DB) +@pytest.fixture(scope="module") +def photosdb_local(): + return osxphotos.PhotosDB(dbfile=PHOTOS_DB_LOCAL) + + def test_init1(): # test named argument @@ -413,6 +428,22 @@ def test_not_hidden(photosdb): assert p.hidden == False +def test_visible(photosdb): + """ test visible """ + photos = photosdb.photos(uuid=[UUID_DICT["not_hidden"]]) + assert len(photos) == 1 + p = photos[0] + assert p.visible + + +def test_not_burst(photosdb): + """ test not burst """ + photos = photosdb.photos(uuid=[UUID_DICT["not_hidden"]]) + assert len(photos) == 1 + p = photos[0] + assert not p.burst + + def test_location_1(photosdb): # test photo with lat/lon info @@ -546,6 +577,7 @@ def test_photoinfo_intrash_1(photosdb): p = photosdb.photos(uuid=[UUID_DICT["intrash"]], intrash=True)[0] assert p.intrash + assert p.date_trashed.isoformat() == "2120-06-10T11:24:47.685857-05:00" def test_photoinfo_intrash_2(photosdb): @@ -587,6 +619,7 @@ def test_photoinfo_not_intrash(photosdb): p = photosdb.photos(uuid=[UUID_DICT["not_intrash"]])[0] assert not p.intrash + assert p.date_trashed is None def test_keyword_2(photosdb): @@ -973,7 +1006,7 @@ def test_from_to_date(photosdb): time.tzset() photos = photosdb.photos(from_date=datetime.datetime(2018, 10, 28)) - assert len(photos) == 10 + assert len(photos) == 10 photos = photosdb.photos(to_date=datetime.datetime(2018, 10, 28)) assert len(photos) == 7 @@ -1133,3 +1166,22 @@ def test_original_filename(photosdb): assert photo.original_filename == ORIGINAL_FILENAME_DICT["filename"] photo._info["originalFilename"] = original_filename + +# The following tests only run on the author's personal library +# They test things difficult to test in the test libraries +@pytest.mark.skipif(SKIP_TEST, reason="Skip if not running on author's local machine.") +def test_not_visible_burst(photosdb_local): + """ test not visible and burst (needs image from local library) """ + photo = photosdb_local.get_photo(UUID_DICT_LOCAL["not_visible"]) + assert not photo.visible + assert photo.burst + + +@pytest.mark.skipif(SKIP_TEST, reason="Skip if not running on author's local machine.") +def test_visible_burst(photosdb_local): + """ test not visible and burst (needs image from local library) """ + photo = photosdb_local.get_photo(UUID_DICT_LOCAL["burst"]) + assert photo.visible + assert photo.burst + assert len(photo.burst_photos) == 4 + diff --git a/tests/test_export_catalina_10_15_6_use_photos_export.py b/tests/test_export_catalina_10_15_7_use_photos_export.py similarity index 92% rename from tests/test_export_catalina_10_15_6_use_photos_export.py rename to tests/test_export_catalina_10_15_7_use_photos_export.py index 6a84ffe6..a39f07bc 100644 --- a/tests/test_export_catalina_10_15_6_use_photos_export.py +++ b/tests/test_export_catalina_10_15_7_use_photos_export.py @@ -2,14 +2,15 @@ import os import pytest from osxphotos._constants import _UNKNOWN_PERSON +from osxphotos.utils import _get_os_version -skip_test = False if "OSXPHOTOS_TEST_EXPORT" in os.environ else True +OS_VERSION = _get_os_version() +SKIP_TEST = "OSXPHOTOS_TEST_EXPORT" not in os.environ or OS_VERSION[1] != "15" +PHOTOS_DB = os.path.expanduser("~/Pictures/Photos Library.photoslibrary") pytestmark = pytest.mark.skipif( - skip_test, reason="These tests only run against system photos library" + SKIP_TEST, reason="These tests only run against system photos library" ) -PHOTOS_DB = "/Users/rhet/Pictures/Photos Library.photoslibrary" - UUID_DICT = { "has_adjustments": "2B2D5434-6D31-49E2-BF47-B973D34A317B", "no_adjustments": "A8D646C3-89A9-4D74-8001-4EB46BA55B94", @@ -21,8 +22,7 @@ UUID_DICT = { def photosdb(): import osxphotos - photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) - return photosdb + return osxphotos.PhotosDB(dbfile=PHOTOS_DB) def test_export_default_name(photosdb): diff --git a/tests/test_mojave_10_14_6.py b/tests/test_mojave_10_14_6.py index 409b6b0d..65bde365 100644 --- a/tests/test_mojave_10_14_6.py +++ b/tests/test_mojave_10_14_6.py @@ -326,6 +326,22 @@ def test_not_hidden(photosdb): assert p.hidden == False +def test_visible(photosdb): + """ test visible """ + photos = photosdb.photos(uuid=[UUID_DICT["not_hidden"]]) + assert len(photos) == 1 + p = photos[0] + assert p.visible + + +def test_not_burst(photosdb): + """ test not burst """ + photos = photosdb.photos(uuid=[UUID_DICT["not_hidden"]]) + assert len(photos) == 1 + p = photos[0] + assert not p.burst + + def test_location_1(photosdb): # test photo with lat/lon info photos = photosdb.photos(uuid=[UUID_DICT["location"]]) @@ -417,6 +433,7 @@ def test_photos_intrash_2(photosdb): photos = photosdb.photos(intrash=True) for p in photos: assert p.intrash + assert p.date_trashed.isoformat() == "2305-12-17T13:19:08.978144-07:00" def test_photos_not_intrash(photosdb): @@ -424,6 +441,7 @@ def test_photos_not_intrash(photosdb): photos = photosdb.photos(intrash=False) for p in photos: assert not p.intrash + assert p.date_trashed is None def test_photoinfo_intrash_1(photosdb):