diff --git a/README.md b/README.md index 8fe1185c..bb9c2600 100644 --- a/README.md +++ b/README.md @@ -1556,7 +1556,7 @@ Returns a JSON representation of all photo info. Returns a dictionary representation of all photo info. #### `export()` -`export(dest, *filename, edited=False, live_photo=False, export_as_hardlink=False, overwrite=False, increment=True, sidecar_json=False, sidecar_xmp=False, use_photos_export=False, timeout=120, exiftool=False, use_albums_as_keywords=False, use_persons_as_keywords=False)` +`export(dest, *filename, edited=False, live_photo=False, export_as_hardlink=False, overwrite=False, increment=True, sidecar_json=False, sidecar_exiftool=False, sidecar_xmp=False, use_photos_export=False, timeout=120, exiftool=False, use_albums_as_keywords=False, use_persons_as_keywords=False)` Export photo from the Photos library to another destination on disk. - dest: must be valid destination path as str (or exception raised). @@ -1567,6 +1567,8 @@ Export photo from the Photos library to another destination on disk. - live_photo: boolean; if True (default=False), will also export the associted .mov for live photos; exported live photo will be named filename.mov - increment: boolean; if True (default=True), will increment file name until a non-existent name is found - sidecar_json: (boolean, default = False); if True will also write a json sidecar with metadata in format readable by exiftool; sidecar filename will be dest/filename.json where filename is the stem of the photo name +- sidecar_json: (boolean, default = False); if True will also write a json sidecar with metadata in format readable by exiftool; sidecar filename will be dest/filename.json where filename is the stem of the photo name; resulting json file will include tag group names (e.g. `exiftool -G -j`) +- sidecar_exiftool: (boolean, default = False); if True will also write a json sidecar with metadata in format readable by exiftool; sidecar filename will be dest/filename.json where filename is the stem of the photo name; resulting json file will not include tag group names (e.g. `exiftool -j`) - sidecar_xmp: (boolean, default = False); if True will also write a XMP sidecar with metadata; sidecar filename will be dest/filename.xmp where filename is the stem of the photo name - use_photos_export: boolean; (default=False), if True will attempt to export photo via applescript interaction with Photos; useful for forcing download of missing photos. This only works if the Photos library being used is the default library (last opened by Photos) as applescript will directly interact with whichever library Photos is currently using. - timeout: (int, default=120) timeout in seconds used with use_photos_export diff --git a/osxphotos/__main__.py b/osxphotos/__main__.py index e41fdb14..4a7065f8 100644 --- a/osxphotos/__main__.py +++ b/osxphotos/__main__.py @@ -21,9 +21,12 @@ from ._constants import ( _UNKNOWN_PLACE, CLI_COLOR_ERROR, CLI_COLOR_WARNING, - DEFAULT_JPEG_QUALITY, DEFAULT_EDITED_SUFFIX, + DEFAULT_JPEG_QUALITY, DEFAULT_ORIGINAL_SUFFIX, + SIDECAR_EXIFTOOL, + SIDECAR_JSON, + SIDECAR_XMP, UNICODE_FORMAT, ) from ._version import __version__ @@ -2754,13 +2757,13 @@ def export_photo( ) sidecar = [s.lower() for s in sidecar] - sidecar_json, sidecar_xmp, sidecar_exiftool = False, False, False + sidecar_flags = 0 if "json" in sidecar: - sidecar_json = True + sidecar_flags |= SIDECAR_JSON if "xmp" in sidecar: - sidecar_xmp = True + sidecar_flags |= SIDECAR_XMP if "exiftool" in sidecar: - sidecar_exiftool = True + sidecar_flags |= SIDECAR_EXIFTOOL # if download_missing and the photo is missing or path doesn't exist, # try to download with Photos @@ -2789,9 +2792,7 @@ def export_photo( export_results = photo.export2( dest_path, original_filename, - sidecar_json=sidecar_json, - sidecar_exiftool=sidecar_exiftool, - sidecar_xmp=sidecar_xmp, + sidecar=sidecar_flags, live_photo=export_live, raw_photo=export_raw, export_as_hardlink=export_as_hardlink, @@ -2895,9 +2896,7 @@ def export_photo( export_results_edited = photo.export2( dest_path, edited_filename, - sidecar_json=sidecar_json, - sidecar_exiftool=sidecar_exiftool, - sidecar_xmp=sidecar_xmp, + sidecar=sidecar_flags, export_as_hardlink=export_as_hardlink, overwrite=overwrite, edited=True, diff --git a/osxphotos/_constants.py b/osxphotos/_constants.py index 109f1e38..f44b1a5a 100644 --- a/osxphotos/_constants.py +++ b/osxphotos/_constants.py @@ -178,3 +178,8 @@ DEFAULT_ORIGINAL_SUFFIX = "" # Colors for print CLI messages CLI_COLOR_ERROR = "red" CLI_COLOR_WARNING = "yellow" + +# Bit masks for --sidecar +SIDECAR_JSON = 0x1 +SIDECAR_EXIFTOOL = 0x2 +SIDECAR_XMP = 0x4 \ No newline at end of file diff --git a/osxphotos/photoinfo/_photoinfo_export.py b/osxphotos/photoinfo/_photoinfo_export.py index 088434c1..d615c9d7 100644 --- a/osxphotos/photoinfo/_photoinfo_export.py +++ b/osxphotos/photoinfo/_photoinfo_export.py @@ -33,6 +33,9 @@ from .._constants import ( _TEMPLATE_DIR, _UNKNOWN_PERSON, _XMP_TEMPLATE_NAME, + SIDECAR_JSON, + SIDECAR_EXIFTOOL, + SIDECAR_XMP, ) from ..datetime_utils import datetime_tz_to_utc from ..exiftool import ExifTool @@ -364,12 +367,12 @@ def export( overwrite: (boolean, default=False); if True will overwrite files if they alreay exist increment: (boolean, default=True); if True, will increment file name until a non-existant name is found if overwrite=False and increment=False, export will fail if destination file already exists - sidecar_json: (boolean, default = False); if True will also write a json sidecar with data in format readable by exiftool - sidecar filename will be dest/filename.json, includes exiftool tag group names (e.g. `exiftool -G -j`) - sidecar_exiftool: (boolean, default = False); if True will also write a json sidecar with data in format readable by exiftool + sidecar_json: if set will write a json sidecar with data in format readable by exiftool + sidecar filename will be dest/filename.json; includes exiftool tag group names (e.g. `exiftool -G -j`) + sidecar_exiftool: if set will write a json sidecar with data in format readable by exiftool sidecar filename will be dest/filename.json; does not include exiftool tag group names (e.g. `exiftool -j`) - sidecar_xmp: (boolean, default = False); if True will also write a XMP sidecar with IPTC data - sidecar filename will be dest/filename.xmp + sidecar_xmp: if set will write an XMP sidecar with IPTC data + sidecar filename will be dest/filename.xmp 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 @@ -386,6 +389,14 @@ def export( # Implementation note: calls export2 to actually do the work + sidecar = 0 + if sidecar_json: + sidecar |= SIDECAR_JSON + if sidecar_exiftool: + sidecar |= SIDECAR_EXIFTOOL + if sidecar_xmp: + sidecar |= SIDECAR_XMP + results = self.export2( dest, *filename, @@ -395,9 +406,7 @@ def export( export_as_hardlink=export_as_hardlink, overwrite=overwrite, increment=increment, - sidecar_json=sidecar_json, - sidecar_exiftool=sidecar_exiftool, - sidecar_xmp=sidecar_xmp, + sidecar=sidecar, use_photos_export=use_photos_export, timeout=timeout, exiftool=exiftool, @@ -420,9 +429,7 @@ def export2( export_as_hardlink=False, overwrite=False, increment=True, - sidecar_json=False, - sidecar_exiftool=False, - sidecar_xmp=False, + sidecar=0, use_photos_export=False, timeout=120, exiftool=False, @@ -461,11 +468,12 @@ def export2( overwrite: (boolean, default=False); if True will overwrite files if they alreay exist increment: (boolean, default=True); if True, will increment file name until a non-existant name is found if overwrite=False and increment=False, export will fail if destination file already exists - sidecar_json: (boolean, default = False); if True will also write a json sidecar with data in format readable by exiftool + sidecar: bit field: set to one or more of SIDECAR_XMP, SIDECAR_JSON, SIDECAR_EXIFTOOL + SIDECAR_JSON: if set will write a json sidecar with data in format readable by exiftool sidecar filename will be dest/filename.json; includes exiftool tag group names (e.g. `exiftool -G -j`) - sidecar_exiftool: (boolean, default = False); if True will also write a json sidecar with data in format readable by exiftool + SIDECAR_EXIFTOOL: if set will write a json sidecar with data in format readable by exiftool sidecar filename will be dest/filename.json; does not include exiftool tag group names (e.g. `exiftool -j`) - sidecar_xmp: (boolean, default = False); if True will also write a XMP sidecar with IPTC data + SIDECAR_XMP: if set will write an XMP sidecar with IPTC data sidecar filename will be dest/filename.xmp 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 @@ -880,7 +888,7 @@ def export2( # TODO: repetitive code here is prime for refactoring sidecar_json_files_skipped = [] sidecar_json_files_written = [] - if sidecar_json: + if sidecar & SIDECAR_JSON: sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest.suffix}.json") sidecar_str = self._exiftool_json_sidecar( use_albums_as_keywords=use_albums_as_keywords, @@ -918,7 +926,7 @@ def export2( sidecar_exiftool_files_skipped = [] sidecar_exiftool_files_written = [] - if sidecar_exiftool: + if sidecar & SIDECAR_EXIFTOOL: sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest.suffix}.json") sidecar_str = self._exiftool_json_sidecar( use_albums_as_keywords=use_albums_as_keywords, @@ -957,7 +965,7 @@ def export2( sidecar_xmp_files_skipped = [] sidecar_xmp_files_written = [] - if sidecar_xmp: + if sidecar & SIDECAR_XMP: sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest.suffix}.xmp") sidecar_str = self._xmp_sidecar( use_albums_as_keywords=use_albums_as_keywords,