Fixed path_derivatives for shared photos, #687

This commit is contained in:
Rhet Turnbull 2022-05-08 18:30:13 -07:00
parent e7eefce5c5
commit abbb200838
7 changed files with 84 additions and 32 deletions

View File

@ -893,38 +893,37 @@ class PhotoInfo:
return photopath
@property
@cached_property
def path_derivatives(self):
"""Return any derivative (preview) images associated with the photo as a list of paths, sorted by file size (largest first)"""
try:
return self._path_derivatives
except AttributeError:
if self._db._db_version <= _PHOTOS_4_VERSION:
self._path_derivatives = self._path_derivatives_4()
return self._path_derivatives
if self._db._db_version <= _PHOTOS_4_VERSION:
return self._path_derivatives_4()
directory = self._uuid[0] # first char of uuid
derivative_path = (
pathlib.Path(self._db._library_path)
/ "resources"
/ "derivatives"
/ directory
)
files = derivative_path.glob(f"{self.uuid}*.*")
files = sorted(files, reverse=True, key=lambda f: f.stat().st_size)
# return list of filename but skip .THM files (these are actually low-res thumbnails in JPEG format but with .THM extension)
derivatives = [
str(filename) for filename in files if filename.suffix != ".THM"
]
if (
self.isphoto
and len(derivatives) > 1
and derivatives[0].endswith(".mov")
):
derivatives[1], derivatives[0] = derivatives[0], derivatives[1]
if self.shared:
return self._path_derivatives_5_shared()
self._path_derivatives = derivatives
return self._path_derivatives
directory = self._uuid[0] # first char of uuid
derivative_path = (
pathlib.Path(self._db._library_path) / f"resources/derivatives/{directory}"
)
files = list(derivative_path.glob(f"{self.uuid}*.*"))
# previews may be missing from derivatives path
# there are what appear to be low res thumbnails in the "masters" subfolder
thumb_path = (
pathlib.Path(self._db._library_path)
/ f"resources/derivatives/masters/{directory}/{self.uuid}_4_5005_c.jpeg"
)
if thumb_path.exists():
files.append(thumb_path)
files = sorted(files, reverse=True, key=lambda f: f.stat().st_size)
# return list of filename but skip .THM files (these are actually low-res thumbnails in JPEG format but with .THM extension)
derivatives = [str(filename) for filename in files if filename.suffix != ".THM"]
if self.isphoto and len(derivatives) > 1 and derivatives[0].endswith(".mov"):
derivatives[1], derivatives[0] = derivatives[0], derivatives[1]
return derivatives
def _path_derivatives_4(self):
"""Return paths to all derivative (preview) files for Photos <= 4"""
@ -934,10 +933,7 @@ class PhotoInfo:
folder_id, file_id = _get_resource_loc(modelid)
derivatives_root = (
pathlib.Path(self._db._library_path)
/ "resources"
/ "proxies"
/ "derivatives"
/ folder_id
/ f"resources/proxies/derivatives/{folder_id}"
)
# photos appears to usually be in "00" subfolder but
@ -962,6 +958,19 @@ class PhotoInfo:
# didn't find a derivatives path
return []
def _path_derivatives_5_shared(self):
"""Return paths to all derivative (preview) files for shared iCloud photos in Photos >= 5"""
directory = self._uuid[0] # first char of uuid
# only 1 derivative for shared photos and it's called 'UUID_4_5005_c.jpeg'
derivative_path = (
pathlib.Path(self._db._library_path)
/ "resources/cloudsharing/resources/derivatives/masters"
/ f"{directory}/{self.uuid}_4_5005_c.jpeg"
)
if derivative_path.exists():
return [str(derivative_path)]
return []
@property
def panorama(self):
"""Returns True if photo is a panorama, otherwise False"""

View File

@ -519,6 +519,7 @@ def test_path_derivatives(photosdb):
derivs = [
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_100_o.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_105_c.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_4_5005_c.jpeg",
]
for i, p in enumerate(path):
assert p.endswith(derivs[i])

View File

@ -625,6 +625,7 @@ def test_path_derivatives(photosdb):
derivs = [
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_100_o.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_105_c.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_4_5005_c.jpeg",
]
for i, p in enumerate(path):
assert p.endswith(derivs[i])

View File

@ -0,0 +1,33 @@
# Test cloud photos
import pytest
import osxphotos
PHOTOS_DB_CLOUD = "tests/Test-Cloud-10.16.0.photoslibrary"
UUID_DICT = {
"incloud": "FC638F58-84BE-4083-B5DE-F85BDC729062",
"shared": "2094984A-21DC-4A6E-88A6-7344F648B92E",
"cloudasset": "FC638F58-84BE-4083-B5DE-F85BDC729062",
}
@pytest.fixture(scope="module")
def photosdb():
return osxphotos.PhotosDB(dbfile=PHOTOS_DB_CLOUD)
def test_incloud(photosdb):
photos = photosdb.photos(uuid=[UUID_DICT["incloud"]])
assert photos[0].incloud
def test_cloudasset_1(photosdb):
photos = photosdb.photos(uuid=[UUID_DICT["cloudasset"]])
assert photos[0].iscloudasset
def test_path_derivatives(photosdb):
photo = photosdb.get_photo(UUID_DICT["shared"])
assert photo.path_derivatives

View File

@ -12,6 +12,7 @@ UUID_DICT = {
"not_incloud": "33000A44-E4BA-43A3-9304-62A0195AB4D9",
"cloudasset": "D11D25FF-5F31-47D2-ABA9-58418878DC15",
"not_cloudasset": "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4",
"shared": "4AD7C8EF-2991-4519-9D3A-7F44A6F031BE",
}
@ -52,3 +53,8 @@ def test_cloudasset_3():
photos = photosdb.photos(uuid=[UUID_DICT["not_cloudasset"]])
assert not photos[0].iscloudasset
def test_path_derivatives(photosdb):
photo = photosdb.get_photo(UUID_DICT["shared"])
assert photo.path_derivatives

View File

@ -524,6 +524,7 @@ def test_path_derivatives(photosdb):
derivs = [
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_100_o.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_105_c.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_4_5005_c.jpeg",
]
for i, p in enumerate(path):
assert p.endswith(derivs[i])

View File

@ -579,6 +579,7 @@ def test_path_derivatives(photosdb):
derivs = [
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_100_o.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_1_105_c.jpeg",
"D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068_4_5005_c.jpeg",
]
for i, p in enumerate(path):
assert p.endswith(derivs[i])