diff --git a/README.md b/README.md index d8870e98..909ce88f 100644 --- a/README.md +++ b/README.md @@ -2263,18 +2263,22 @@ Returns the absolute path to the edited photo on disk as a string. If the photo **Note**: will also return None if the edited photo is missing on disk. #### `path_derivatives` -Returns list of paths to any derivative preview images associated with the photo. These will be named like: +Returns list of paths to any derivative preview images associated with the photo. These will be named something like this on Photos 5+: - `F19E06B8-A712-4B5C-907A-C007D37BDA16_1_101_o.jpeg` - `F19E06B8-A712-4B5C-907A-C007D37BDA16_1_102_o.jpeg` - `F19E06B8-A712-4B5C-907A-C007D37BDA16_1_105_c.jpeg` +On Photos <=4, they'll be named something like: + +- `UNADJUSTEDNONRAW_mini_6.jpg` +- `UNADJUSTEDNONRAW_thumb_6.jpg` +- `Y6OofYkbR96spbS6XgwOQw_mini_1.jpg` + I've not yet decoded the suffixes to know which preview is used for which purpose but in general, if you look for the largest file, you'll get the highest resolution preview. Returns empty list if no preview images are found. -**Note**: only implemented for Photos 5+ - #### `path_raw` Returns the absolute path to the associated raw photo on disk as a string, if photo is part of a RAW+JPEG pair, otherwise returns None. See [notes on Raw Photos](#raw-photos). diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 83ba5d3a..520443bb 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.42.18" +__version__ = "0.42.19" diff --git a/osxphotos/photoinfo/photoinfo.py b/osxphotos/photoinfo/photoinfo.py index 8b9a592f..792d5a88 100644 --- a/osxphotos/photoinfo/photoinfo.py +++ b/osxphotos/photoinfo/photoinfo.py @@ -820,10 +820,9 @@ class PhotoInfo: @property def path_derivatives(self): - """ Return any derivative (preview) images associated with the photo as a list of paths, - currently only implemented for Photos >= 5 """ + """ Return any derivative (preview) images associated with the photo as a list of paths """ if self._db._db_version <= _PHOTOS_4_VERSION: - return [] + return self._path_derivatives_4() directory = self._uuid[0] # first char of uuid derivative_path = ( @@ -836,6 +835,40 @@ class PhotoInfo: # return list of filename but skip .THM files (these are actually low-res thumbnails in JPEG format but with .THM extension) return [str(filename) for filename in files if filename.suffix != ".THM"] + def _path_derivatives_4(self): + """ Return paths to all derivative (preview) files for Photos <= 4""" + modelid = self._info["masterModelID"] + if modelid is None: + return [] + folder_id, file_id = _get_resource_loc(modelid) + derivatives_root = ( + pathlib.Path(self._db._library_path) + / "resources" + / "proxies" + / "derivatives" + / folder_id + ) + + # photos appears to usually be in "00" subfolder but + # could be elsewhere--I haven't figured out this logic yet + # first see if it's in 00 + + derivatives_path = derivatives_root / "00" / file_id + if derivatives_path.is_dir(): + files = derivatives_path.glob("*") + return [str(filename) for filename in files] + + # didn't find derivatives path + for subdir in derivatives_root.glob("*"): + if subdir.is_dir(): + derivatives_path = derivatives_root / subdir / file_id + if derivatives_path.is_dir(): + files = derivatives_path.glob("*") + return [str(filename) for filename in files] + + # didn't find a derivatives path + return [] + @property def panorama(self): """ Returns True if photo is a panorama, otherwise False """ diff --git a/tests/test_mojave_10_14_6.py b/tests/test_mojave_10_14_6.py index 5561ac70..a165314a 100644 --- a/tests/test_mojave_10_14_6.py +++ b/tests/test_mojave_10_14_6.py @@ -425,8 +425,15 @@ def test_path_derivatives(photosdb): photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]]) p = photos[0] - path = p.path_derivatives - assert path == [] + derivs = sorted( + [ + "/resources/proxies/derivatives/00/00/1/Y6OofYkbR96spbS6XgwOQw_thumb_1.jpg", + "/resources/proxies/derivatives/00/00/1/Y6OofYkbR96spbS6XgwOQw_mini_1.jpg", + ] + ) + path = sorted(p.path_derivatives) + for i, p in enumerate(path): + assert p.endswith(derivs[i]) def test_path_edited2(photosdb):