diff --git a/README.md b/README.md index ae3c3adf..dd52b483 100644 --- a/README.md +++ b/README.md @@ -1394,7 +1394,7 @@ Returns a list of the keywords found in the Photos library albums = photosdb.album_info ``` -Returns a list of [AlbumInfo](#AlbumInfo) objects representing albums in the database or empty list if there are no albums. See also [albums](#albums). +Returns a list of [AlbumInfo](#AlbumInfo) objects representing albums in the database or empty list if there are no albums. See also [albums](#albums) and [burst_album_info](#burst_album_info). #### `albums` ```python @@ -1402,7 +1402,7 @@ Returns a list of [AlbumInfo](#AlbumInfo) objects representing albums in the dat album_names = photosdb.albums ``` -Returns a list of the album names found in the Photos library. +Returns a list of the album names found in the Photos library. See also [burst_albums](#burst_albums). **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. @@ -1838,6 +1838,9 @@ Returns Uniform Type Identifier (UTI) for the associated raw image, if there is Returns True if photos is a burst image (e.g. part of a set of burst images), otherwise False. See [burst_photos](#burst_photos) +#### `burst_selected` +Returns True if photo is a burst photo and has been selected from the burst set by the user, otherwise False. + #### `burst_photos` If photo is a burst image (see [burst](#burst)), returns a list of PhotoInfo objects for all other photos in the same burst set. If not a burst image, returns empty list. @@ -1861,6 +1864,12 @@ IMG_9854.JPG IMG_9855.JPG ``` +#### `burst_albums` +If photo is a non-selected burst photo, returns a list of albums any other photos in the same burst set, are contained in. Otherwise, returns `PhotoInfo.albums`. If a burst photo which has unselected burst images (e.g. the burst images are in the library but haven't been selected by the user using the "Make a selection" feature) is placed in a an album, Photos treats only the selected "key" photo as in the album. The unselected burst images, while associated with the photo in the album, are not technically in the album. If you are handling one of these unselected burst photos and want to know which album it would be in based on which albums it's selected key images are in, use `burst_albums`. See also [burst_album_info](#burst_album_info) and [albums](#albums). + +#### `burst_album_info` +If photo is non-selected burst photo, teturns a list of [AlbumInfo](#AlbumInfo) objects representing the albums any other photos in the same burst set are contained in. Otherwise, returns `PhotoInfo.album_info`. See also [burst_albums](#burst_albums) and [album_info](#album_info). + #### `live_photo` Returns True if photo is an Apple live photo (ie. it has an associated "live" video component), otherwise returns False. See [path_live_photo](#path_live_photo). diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 683b9a8b..a1e88379 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.41.4" +__version__ = "0.41.5" diff --git a/osxphotos/cli.py b/osxphotos/cli.py index 79adcaea..84c1ef85 100644 --- a/osxphotos/cli.py +++ b/osxphotos/cli.py @@ -1408,6 +1408,9 @@ def export( is_reference=is_reference, in_album=in_album, not_in_album=not_in_album, + burst_photos=export_bursts, + # skip missing bursts if using --download-missing by itself as AppleScript otherwise causes errors + missing_bursts=(download_missing and use_photokit) or not download_missing, ) if photos: @@ -1416,13 +1419,6 @@ def export( previous_uuids = {uuid: 1 for uuid in export_db.get_previous_uuids()} photos = [p for p in photos if p.uuid not in previous_uuids] - if export_bursts: - # add the burst_photos to the export set - photos_burst = [p for p in photos if p.burst] - for burst in photos_burst: - burst_set = [p for p in burst.burst_photos if not p.ismissing] - photos.extend(burst_set) - num_photos = len(photos) # TODO: photos or photo appears several times, pull into a separate function photo_str = "photos" if num_photos > 1 else "photo" @@ -2019,6 +2015,8 @@ def _query( is_reference=False, in_album=False, not_in_album=False, + burst_photos=None, + missing_bursts=None, ): """Run a query against PhotosDB to extract the photos based on user supply criteria used by query and export commands @@ -2262,6 +2260,27 @@ def _query( if to_time: photos = [p for p in photos if p.date.time() <= to_time] + if burst_photos: + # add the burst_photos to the export set + photos_burst = [p for p in photos if p.burst] + for burst in photos_burst: + if missing_bursts: + # include burst photos that are missing + photos.extend(burst.burst_photos) + else: + # don't include missing burst images (these can't be downloaded with AppleScript) + photos.extend([p for p in burst.burst_photos if not p.ismissing]) + + # remove duplicates as each burst photo in the set that's selected would + # result in the entire set being added above + # can't use set() because PhotoInfo not hashable + seen_uuids = {} + for p in photos: + if p.uuid in seen_uuids: + continue + seen_uuids[p.uuid] = p + photos = list(seen_uuids.values()) + return photos diff --git a/osxphotos/photoinfo/photoinfo.py b/osxphotos/photoinfo/photoinfo.py index f75e4d52..7d9afd2d 100644 --- a/osxphotos/photoinfo/photoinfo.py +++ b/osxphotos/photoinfo/photoinfo.py @@ -453,9 +453,24 @@ class PhotoInfo: ) return self._albums + @property + def burst_albums(self): + """If photo is non-selected burst photo, list of albums any other images in the same burst set are contained in, otherwise returns self.albums""" + if self.burst_selected or not self.burst: + return self.albums + + try: + return self._burst_albums + except AttributeError: + burst_albums = [] + for photo in self.burst_photos: + burst_albums.extend(photo.albums) + self._burst_albums = list(set(burst_albums)) + return self._burst_albums + @property def album_info(self): - """ list of AlbumInfo objects representing albums the photos is contained in """ + """ list of AlbumInfo objects representing albums the photo is contained in """ try: return self._album_info except AttributeError: @@ -465,6 +480,21 @@ class PhotoInfo: ] return self._album_info + @property + def burst_album_info(self): + """ If photo is a non-selected burst photo, returns list of AlbumInfo objects representing albums any other photos in the same burst set are contained in, otherwise returns self.album_info """ + if self.burst_selected or not self.burst: + return self.album_info + + try: + return self._burst_album_info + except AttributeError: + burst_album_info = [] + for photo in self.burst_photos: + burst_album_info.extend(photo.album_info) + self._burst_album_info = list(set(burst_album_info)) + return self._burst_album_info + @property def import_info(self): """ ImportInfo object representing import session for the photo or None if no import session """ @@ -680,6 +710,11 @@ class PhotoInfo: """ Returns True if photo is part of a Burst photo set, otherwise False """ return self._info["burst"] + @property + def burst_selected(self): + """ Returns True if photo is a burst photo and has been selected from the burst set by the user, otherwise False """ + return self._info["burst_key"] + @property def burst_photos(self): """If photo is a burst photo, returns list of PhotoInfo objects diff --git a/osxphotos/phototemplate.py b/osxphotos/phototemplate.py index 18f5f492..4ebc396d 100644 --- a/osxphotos/phototemplate.py +++ b/osxphotos/phototemplate.py @@ -840,7 +840,7 @@ class PhotoTemplate: """ return list of values for a multi-valued template field """ values = [] if field == "album": - values = self.photo.albums + values = self.photo.burst_albums if self.photo.burst else self.photo.albums elif field == "keyword": values = self.photo.keywords elif field == "person": @@ -854,7 +854,11 @@ class PhotoTemplate: elif field == "folder_album": values = [] # photos must be in an album to be in a folder - for album in self.photo.album_info: + if self.photo.burst: + album_info = self.photo.burst_album_info + else: + album_info = self.photo.album_info + for album in album_info: if album.folder_names: # album in folder if dirname: diff --git a/tests/search_info_test_data_10_15_7.json b/tests/search_info_test_data_10_15_7.json index c717611b..154b06c2 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 Pushers", "The Pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Desert", "Sky", "Sunset Sunrise", "Outdoor", "Land"], "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", "Water Body", "Land", "People", "Furniture", "Water", "Forest", "Plant", "Outdoor", "Vegetation"], "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 pushers", "the pinhook"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["desert", "sky", "sunset sunrise", "outdoor", "land"], "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", "water body", "land", "people", "furniture", "water", "forest", "plant", "outdoor", "vegetation"], "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 Pushers", "The Pinhook", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Desert", "Sky", "Sunset Sunrise", "Outdoor", "Land", "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", "Water Body", "Land", "People", "Furniture", "Water", "Forest", "Plant", "Outdoor", "Vegetation", "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 pushers", "the pinhook", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["desert", "sky", "sunset sunrise", "outdoor", "land", "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", "water body", "land", "people", "furniture", "water", "forest", "plant", "outdoor", "vegetation", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} +{"UUID_SEARCH_INFO": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["Butter", "Food"], "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", "Pie Pushers", "Luna Rotisserie and Empanadas", "The Pinhook"], "venue_types": ["Nightlife", "Cocktail Bar", "Pizza", "Restaurant", "Bar", "Tapas & Small Plates", "Food", "Empanadas", "Arts & Entertainment", "Chicken Wings", "Latin American", "Cuban", "Music Venue"], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Land", "Desert", "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": ["Water Body", "Water", "People", "Bench", "Vegetation", "Forest", "Outdoor", "Land", "Furniture"], "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": ["butter", "food"], "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", "pie pushers", "luna rotisserie and empanadas", "the pinhook"], "venue_types": ["nightlife", "cocktail bar", "pizza", "restaurant", "bar", "tapas & small plates", "food", "empanadas", "arts & entertainment", "chicken wings", "latin american", "cuban", "music venue"], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["land", "desert", "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": ["water body", "water", "people", "bench", "vegetation", "forest", "outdoor", "land", "furniture"], "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": ["Butter", "Food", "Durham Bulls Athletic Park", "Blackwell St", "American Tobacco District", "Downtown Durham", "Durham", "Entertainment", "Travel", "Dining", "Dinner", "Trip", "Copa", "Pie Pushers", "Luna Rotisserie and Empanadas", "The Pinhook", "Nightlife", "Cocktail Bar", "Pizza", "Restaurant", "Bar", "Tapas & Small Plates", "Food", "Empanadas", "Arts & Entertainment", "Chicken Wings", "Latin American", "Cuban", "Music Venue", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Land", "Desert", "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": ["Water Body", "Water", "People", "Bench", "Vegetation", "Forest", "Outdoor", "Land", "Furniture", "Christmas Day", "Celebration", "Holiday", "December", "2014", "Winter"]}, "UUID_SEARCH_INFO_ALL_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["butter", "food", "durham bulls athletic park", "blackwell st", "american tobacco district", "downtown durham", "durham", "entertainment", "travel", "dining", "dinner", "trip", "copa", "pie pushers", "luna rotisserie and empanadas", "the pinhook", "nightlife", "cocktail bar", "pizza", "restaurant", "bar", "tapas & small plates", "food", "empanadas", "arts & entertainment", "chicken wings", "latin american", "cuban", "music venue", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["land", "desert", "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": ["water body", "water", "people", "bench", "vegetation", "forest", "outdoor", "land", "furniture", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} diff --git a/tests/test_cli.py b/tests/test_cli.py index 43655e2c..6951543c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -22,6 +22,17 @@ PHOTOS_DB_TOUCH = PHOTOS_DB_15_6 PHOTOS_DB_14_6 = "tests/Test-10.14.6.photoslibrary" PHOTOS_DB_MOVIES = "tests/Test-Movie-5_0.photoslibrary" +# my personal library which some tests require +PHOTOS_DB_RHET = os.path.expanduser("~/Pictures/Photos Library.photoslibrary") +UUID_BURST_ALBUM = "9F90DC00-AAAF-4A05-9A65-61FEEE0D67F2" # in my personal library +BURST_ALBUM_FILES = [ + "IMG_9812.JPG", + "IMG_9813.JPG", + "IMG_9814.JPG", + "IMG_9815.JPG", + "IMG_9816.JPG", +] + UUID_FILE = "tests/uuid_from_file.txt" CLI_OUTPUT_NO_SUBCOMMAND = [ @@ -5649,3 +5660,42 @@ def test_export_jpeg_ext_convert_to_jpeg_movie(): assert f"{filename}.jpg".lower() not in files assert f"{filename}.{ext}".lower() in files assert f"{filename}_edited.{ext}".lower() in files + + +@pytest.mark.skipif( + "OSXPHOTOS_TEST_EXPORT" not in os.environ, + reason="Skip if not running on author's personal library.", +) +def test_export_burst_folder_album(): + """ test non-selected burst photos are exported with the album their key photo is in, issue #401 """ + import glob + import os + import os.path + import pathlib + from osxphotos.cli import export + + runner = CliRunner() + cwd = os.getcwd() + # pylint: disable=not-context-manager + with runner.isolated_filesystem(): + result = runner.invoke( + export, + [ + os.path.join(cwd, PHOTOS_DB_RHET), + ".", + "-V", + "--directory", + "{folder_album}", + "--uuid", + UUID_BURST_ALBUM, + "--download-missing", + "--use-photokit", + ], + ) + assert result.exit_code == 0 + folder_album = pathlib.Path("TestBurst") + assert folder_album.is_dir() + for filename in BURST_ALBUM_FILES: + path = folder_album / filename + assert path.is_file() + diff --git a/tests/test_export_catalina_10_15_7_use_photos_export.py b/tests/test_export_catalina_10_15_7_use_photos_export.py index e9479b20..38538558 100644 --- a/tests/test_export_catalina_10_15_7_use_photos_export.py +++ b/tests/test_export_catalina_10_15_7_use_photos_export.py @@ -17,6 +17,34 @@ UUID_DICT = { "live": "BFF29EBD-22DF-4FCF-9817-317E7104EA50", } +UUID_BURSTS = { + "9F90DC00-AAAF-4A05-9A65-61FEEE0D67F2": { + "selected": True, + "filename": "IMAGE_9812.JPG", + "albums": ["TestBurst"], + }, + "964F457D-5FFC-47B9-BEAD-56B0A83FEF63": { + "selected": True, + "filename": "IMG_9816.JPG", + "albums": [], + }, + "A385FA13-DF8E-482F-A8C5-970EDDF54C2F": { + "selected": False, + "filename": "IMG_9813.JPG", + "albums": ["TestBurst", "TestBurst2"], + }, + "38F8F30C-FF6D-49DA-8092-18497F1D6628": { + "selected": True, + "filename": "IMG_9814.JPG", + "albums": ["TestBurst2"], + }, + "E3863443-9EA8-417F-A90B-8F7086623DAD": { + "selected": False, + "filename": "IMG_9815.JPG", + "albums": ["TestBurst", "TestBurst2"], + }, +} + @pytest.fixture(scope="module") def photosdb(): @@ -156,3 +184,13 @@ def test_export_edited_no_edit(photosdb): with pytest.raises(Exception) as e: assert photos[0].export(dest, use_photos_export=True, edited=True) assert e.type == ValueError + + +def test_burst_albums(photosdb): + """Test burst_selected, burst_albums""" + + for uuid in UUID_BURSTS: + photo = photosdb.get_photo(uuid) + assert photo.burst + assert photo.burst_selected == UUID_BURSTS[uuid]["selected"] + assert sorted(photo.burst_albums) == sorted(UUID_BURSTS[uuid]["albums"])