Lots of work on export code

This commit is contained in:
Rhet Turnbull
2020-03-15 10:08:56 -07:00
parent c11afbaa6e
commit 0940f039d3
11 changed files with 370 additions and 238 deletions

View File

@@ -1344,7 +1344,7 @@ def export_photo(
overwrite=overwrite,
use_photos_export=use_photos_export,
exiftool=exiftool,
)
)[0]
# if export-edited, also export the edited version
# verify the photo has adjustments and valid path to avoid raising an exception

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.22.21"
__version__ = "0.22.23"

View File

@@ -505,7 +505,7 @@ class PhotoInfo:
):
""" export photo
dest: must be valid destination path (or exception raised)
filename: (optional): name of picture; if not provided, will use current filename
filename: (optional): name of exported picture; if not provided, will use current filename
**NOTE**: if provided, user must ensure file extension (suffix) is correct.
For example, if photo is .CR2 file, edited image may be .jpeg.
If you provide an extension different than what the actual file is,
@@ -525,12 +525,17 @@ class PhotoInfo:
use_photos_export: (boolean, default=False); if True will attempt to export photo via applescript interaction with Photos
timeout: (int, default=120) timeout in seconds used with use_photos_export
exiftool: (boolean, default = False); if True, will use exiftool to write metadata to export file
returns the full path to the exported file """
returns list of full paths to the exported files """
# list of all files exported during this call to export
exported_files = []
logging.debug(f"dest ={dest}.filename={filename}")
# check edited and raise exception trying to export edited version of
# photo that hasn't been edited
if edited and not self.hasadjustments:
raise ValueError(
"Photo does not have adjustments, cannot export edited version"
)
# check arguments and get destination path and filename (if provided)
if filename and len(filename) > 2:
@@ -545,8 +550,8 @@ class PhotoInfo:
raise FileNotFoundError("Invalid path passed to export")
if filename and len(filename) == 1:
# if filename passed, use it, but verify extension
filename = filename[0]
# if filename passed, use it
fname = filename[0]
else:
# no filename provided so use the default
# if edited file requested, use filename but add _edited
@@ -560,25 +565,26 @@ class PhotoInfo:
)
edited_name = pathlib.Path(self.path_edited).name
edited_suffix = pathlib.Path(edited_name).suffix
filename = (
pathlib.Path(self.filename).stem + "_edited" + edited_suffix
)
fname = pathlib.Path(self.filename).stem + "_edited" + edited_suffix
else:
filename = self.filename
fname = self.filename
# check destination path
dest = pathlib.Path(dest)
filename = pathlib.Path(filename)
logging.debug(f"dest ={dest}.filename={filename}")
dest = dest / filename
fname = pathlib.Path(fname)
dest = dest / fname
# check extension of destination
if edited and self.path_edited is not None:
# use suffix from edited file
actual_suffix = pathlib.Path(self.path_edited).suffix
elif edited:
logging.warning("Invalid suffix check for missing edited file")
actual_suffix = ""
# use .jpeg as that's probably correct
# if edited and path_edited is None, will raise FileNotFoundError below
# unless use_photos_export is True
actual_suffix = ".jpeg"
else:
# use suffix from the non-edited file
actual_suffix = pathlib.Path(self.filename).suffix
if dest.suffix != actual_suffix:
@@ -613,16 +619,11 @@ class PhotoInfo:
# get path to source file and verify it's not None and is valid file
# TODO: how to handle ismissing or not hasadjustments and edited=True cases?
if edited:
if not self.hasadjustments:
logging.warning(
"Attempting to export edited photo but hasadjustments=False"
)
if self.path_edited is not None:
src = self.path_edited
else:
raise FileNotFoundError(
f"edited=True but path_edited is none; hasadjustments: {self.hasadjustments}"
f"Cannot export edited photo if path_edited is None"
)
else:
if self.ismissing:
@@ -630,13 +631,10 @@ class PhotoInfo:
f"Attempting to export photo with ismissing=True: path = {self.path}"
)
if self.path is None:
logging.warning(
f"Attempting to export photo but path is None: ismissing = {self.ismissing}"
)
raise FileNotFoundError("Cannot export photo if path is None")
else:
if self.path is not None:
src = self.path
else:
raise FileNotFoundError("Cannot export photo if path is None")
if not os.path.isfile(src):
raise FileNotFoundError(f"{src} does not appear to exist")
@@ -675,16 +673,18 @@ class PhotoInfo:
else:
# didn't get passed a filename, add _edited
filestem = f"{dest.stem}_edited"
exported = _export_photo_uuid_applescript(
self.uuid,
dest.parent,
filestem=filestem,
original=False,
edited=True,
live_photo=live_photo,
timeout=timeout,
burst=self.burst,
)
dest = dest.parent / f"{filestem}.jpeg"
exported = _export_photo_uuid_applescript(
self.uuid,
dest.parent,
filestem=filestem,
original=False,
edited=True,
live_photo=live_photo,
timeout=timeout,
burst=self.burst,
)
else:
# export original version and not edited
filestem = dest.stem
@@ -702,7 +702,9 @@ class PhotoInfo:
if exported is not None:
exported_files.extend(exported)
else:
logging.warning(f"Error exporting photo {self.uuid} to {dest}")
logging.warning(
f"Error exporting photo {self.uuid} to {dest} with use_photos_export"
)
if sidecar_json:
logging.debug("writing exiftool_json_sidecar")
@@ -724,14 +726,12 @@ class PhotoInfo:
logging.warning(f"Error writing xmp sidecar to {sidecar_filename}")
raise e
logging.debug(f"export exported_files: {exported_files}")
# if exiftool, write the metadata
if exiftool and exported_files:
for exported_file in exported_files:
self._write_exif_data(exported_file)
return str(dest)
return exported_files
def _write_exif_data(self, filepath):
""" write exif data to image file at filepath
@@ -771,7 +771,6 @@ class PhotoInfo:
exif = {}
exif["_CreatedBy"] = "osxphotos, https://github.com/RhetTbull/osxphotos"
exif["File:FileName"] = self.filename
if self.description:
exif["EXIF:ImageDescription"] = self.description

View File

@@ -255,7 +255,7 @@ def list_photo_libraries():
# On older MacOS versions, mdfind appears to ignore some libraries
# glob to find libraries in ~/Pictures then mdfind to find all the others
# TODO: make this more robust
lib_list = glob.glob(f"{str(Path.home())}/Pictures/*.photoslibrary")
lib_list = glob.glob(f"{str(pathlib.Path.home())}/Pictures/*.photoslibrary")
# On older OS, may not get all libraries so make sure we get the last one
last_lib = get_last_library_path()
@@ -327,7 +327,8 @@ def _export_photo_uuid_applescript(
If filestem.ext exists, it wil be overwritten
original: (boolean) if True, export original image; default = True
edited: (boolean) if True, export edited photo; default = False
will produce an error if image does not have edits/adjustments
If photo not edited and edited=True, will still export the original image
caller must verify image has been edited
*Note*: must be called with either edited or original but not both,
will raise error if called with both edited and original = True
live_photo: (boolean) if True, export associated .mov live photo; default = False
@@ -448,7 +449,7 @@ def _db_is_locked(dbname):
conn.close()
logging.debug(f"{dbname} is not locked")
locked = False
except Exception as e:
except:
logging.debug(f"{dbname} is locked")
locked = True