Added --sidecar-drop-ext, issue #291

This commit is contained in:
Rhet Turnbull
2020-12-28 11:54:02 -08:00
parent 7bd189e9b2
commit dce002cdfe
5 changed files with 75 additions and 5 deletions

View File

@@ -328,6 +328,18 @@ Options:
photoname.ext.json; For a list of tags photoname.ext.json; For a list of tags
exported in the JSON and exiftool sidecar, exported in the JSON and exiftool sidecar,
see '--exiftool'. see '--exiftool'.
--sidecar-drop-ext Drop the photo's extension when naming
sidecar files. By default, sidecar files are
named in format
'photo_filename.photo_ext.sidecar_ext', e.g.
'IMG_1234.JPG.json'. Use '--sidecar-drop-
ext' to ignore the photo extension.
Resulting sidecar files will have name in
format 'IMG_1234.json'. Warning: this may
result in sidecar filename collisions if
there are files of different types but the
same name in the output directory, e.g.
'IMG_1234.JPG' and 'IMG_1234.MOV'.
--exiftool Use exiftool to write metadata directly to --exiftool Use exiftool to write metadata directly to
exported photos. To use this option, exported photos. To use this option,
exiftool must be installed and in the path. exiftool must be installed and in the path.

View File

@@ -1357,6 +1357,16 @@ def query(
"Sidecar filename is in format photoname.ext.json; " "Sidecar filename is in format photoname.ext.json; "
"For a list of tags exported in the JSON and exiftool sidecar, see '--exiftool'.", "For a list of tags exported in the JSON and exiftool sidecar, see '--exiftool'.",
) )
@click.option(
"--sidecar-drop-ext",
is_flag=True,
help="Drop the photo's extension when naming sidecar files. "
"By default, sidecar files are named in format 'photo_filename.photo_ext.sidecar_ext', "
"e.g. 'IMG_1234.JPG.json'. Use '--sidecar-drop-ext' to ignore the photo extension. "
"Resulting sidecar files will have name in format 'IMG_1234.json'. "
"Warning: this may result in sidecar filename collisions if there are files of different "
"types but the same name in the output directory, e.g. 'IMG_1234.JPG' and 'IMG_1234.MOV'.",
)
@click.option( @click.option(
"--exiftool", "--exiftool",
is_flag=True, is_flag=True,
@@ -1571,6 +1581,7 @@ def export(
convert_to_jpeg, convert_to_jpeg,
jpeg_quality, jpeg_quality,
sidecar, sidecar,
sidecar_drop_ext,
only_photos, only_photos,
only_movies, only_movies,
burst, burst,
@@ -2036,6 +2047,7 @@ def export(
verbose=verbose, verbose=verbose,
export_by_date=export_by_date, export_by_date=export_by_date,
sidecar=sidecar, sidecar=sidecar,
sidecar_drop_ext=sidecar_drop_ext,
update=update, update=update,
ignore_signature=ignore_signature, ignore_signature=ignore_signature,
export_as_hardlink=export_as_hardlink, export_as_hardlink=export_as_hardlink,
@@ -2084,6 +2096,7 @@ def export(
verbose=verbose, verbose=verbose,
export_by_date=export_by_date, export_by_date=export_by_date,
sidecar=sidecar, sidecar=sidecar,
sidecar_drop_ext=sidecar_drop_ext,
update=update, update=update,
ignore_signature=ignore_signature, ignore_signature=ignore_signature,
export_as_hardlink=export_as_hardlink, export_as_hardlink=export_as_hardlink,
@@ -2616,6 +2629,7 @@ def export_photo(
verbose=None, verbose=None,
export_by_date=None, export_by_date=None,
sidecar=None, sidecar=None,
sidecar_drop_ext=False,
update=None, update=None,
ignore_signature=None, ignore_signature=None,
export_as_hardlink=None, export_as_hardlink=None,
@@ -2654,6 +2668,7 @@ def export_photo(
verbose: boolean; print verbose output verbose: boolean; print verbose output
export_by_date: boolean; create export folder in form dest/YYYY/MM/DD export_by_date: boolean; create export folder in form dest/YYYY/MM/DD
sidecar: list zero, 1 or 2 of ["json","xmp"] of sidecar variety to export sidecar: list zero, 1 or 2 of ["json","xmp"] of sidecar variety to export
sidecar_drop_ext: boolean; if True, drops photo extension from sidecar name
export_as_hardlink: boolean; hardlink files instead of copying them export_as_hardlink: boolean; hardlink files instead of copying them
overwrite: boolean; overwrite dest file if it already exists overwrite: boolean; overwrite dest file if it already exists
original_name: boolean; use original filename instead of current filename original_name: boolean; use original filename instead of current filename
@@ -2804,6 +2819,7 @@ def export_photo(
dest_path, dest_path,
original_filename, original_filename,
sidecar=sidecar_flags, sidecar=sidecar_flags,
sidecar_drop_ext=sidecar_drop_ext,
live_photo=export_live, live_photo=export_live,
raw_photo=export_raw, raw_photo=export_raw,
export_as_hardlink=export_as_hardlink, export_as_hardlink=export_as_hardlink,
@@ -2908,6 +2924,7 @@ def export_photo(
dest_path, dest_path,
edited_filename, edited_filename,
sidecar=sidecar_flags, sidecar=sidecar_flags,
sidecar_drop_ext=sidecar_drop_ext,
export_as_hardlink=export_as_hardlink, export_as_hardlink=export_as_hardlink,
overwrite=overwrite, overwrite=overwrite,
edited=True, edited=True,

View File

@@ -1,5 +1,5 @@
""" version info """ """ version info """
__version__ = "0.38.16" __version__ = "0.38.17"

View File

@@ -430,6 +430,7 @@ def export2(
overwrite=False, overwrite=False,
increment=True, increment=True,
sidecar=0, sidecar=0,
sidecar_drop_ext=False,
use_photos_export=False, use_photos_export=False,
timeout=120, timeout=120,
exiftool=False, exiftool=False,
@@ -475,6 +476,7 @@ def export2(
sidecar filename will be dest/filename.json; does not include exiftool tag group names (e.g. `exiftool -j`) sidecar filename will be dest/filename.json; does not include exiftool tag group names (e.g. `exiftool -j`)
SIDECAR_XMP: if set will write an XMP sidecar with IPTC data SIDECAR_XMP: if set will write an XMP sidecar with IPTC data
sidecar filename will be dest/filename.xmp sidecar filename will be dest/filename.xmp
sidecar_drop_ext: (boolean, default=False); if True, drops the photo's extension from sidecar filename (e.g. 'IMG_1234.json' instead of 'IMG_1234.JPG.json')
use_photos_export: (boolean, default=False); if True will attempt to export photo via applescript interaction with Photos 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 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 exiftool: (boolean, default = False); if True, will use exiftool to write metadata to export file
@@ -893,8 +895,9 @@ def export2(
sidecar_xmp_files_skipped = [] sidecar_xmp_files_skipped = []
sidecar_xmp_files_written = [] sidecar_xmp_files_written = []
dest_suffix = "" if sidecar_drop_ext else dest.suffix
if sidecar & SIDECAR_JSON: if sidecar & SIDECAR_JSON:
sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest.suffix}.json") sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest_suffix}.json")
sidecar_str = self._exiftool_json_sidecar( sidecar_str = self._exiftool_json_sidecar(
use_albums_as_keywords=use_albums_as_keywords, use_albums_as_keywords=use_albums_as_keywords,
use_persons_as_keywords=use_persons_as_keywords, use_persons_as_keywords=use_persons_as_keywords,
@@ -913,7 +916,7 @@ def export2(
) )
if sidecar & SIDECAR_EXIFTOOL: if sidecar & SIDECAR_EXIFTOOL:
sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest.suffix}.json") sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest_suffix}.json")
sidecar_str = self._exiftool_json_sidecar( sidecar_str = self._exiftool_json_sidecar(
use_albums_as_keywords=use_albums_as_keywords, use_albums_as_keywords=use_albums_as_keywords,
use_persons_as_keywords=use_persons_as_keywords, use_persons_as_keywords=use_persons_as_keywords,
@@ -933,7 +936,7 @@ def export2(
) )
if sidecar & SIDECAR_XMP: if sidecar & SIDECAR_XMP:
sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest.suffix}.xmp") sidecar_filename = dest.parent / pathlib.Path(f"{dest.stem}{dest_suffix}.xmp")
sidecar_str = self._xmp_sidecar( sidecar_str = self._xmp_sidecar(
use_albums_as_keywords=use_albums_as_keywords, use_albums_as_keywords=use_albums_as_keywords,
use_persons_as_keywords=use_persons_as_keywords, use_persons_as_keywords=use_persons_as_keywords,

View File

@@ -306,6 +306,11 @@ CLI_EXPORT_BY_DATE_NEED_TOUCH_TIMES = [1538165227, 1539436692]
CLI_EXPORT_BY_DATE = ["2018/09/28/Pumpkins3.jpg", "2018/09/28/Pumkins1.jpg"] CLI_EXPORT_BY_DATE = ["2018/09/28/Pumpkins3.jpg", "2018/09/28/Pumkins1.jpg"]
CLI_EXPORT_SIDECAR_FILENAMES = ["Pumkins2.jpg", "Pumkins2.jpg.json", "Pumkins2.jpg.xmp"] CLI_EXPORT_SIDECAR_FILENAMES = ["Pumkins2.jpg", "Pumkins2.jpg.json", "Pumkins2.jpg.xmp"]
CLI_EXPORT_SIDECAR_DROP_EXT_FILENAMES = [
"Pumkins2.jpg",
"Pumkins2.json",
"Pumkins2.xmp",
]
CLI_EXPORT_LIVE = [ CLI_EXPORT_LIVE = [
"51F2BEF7-431A-4D31-8AC1-3284A57826AE.jpeg", "51F2BEF7-431A-4D31-8AC1-3284A57826AE.jpeg",
@@ -1974,6 +1979,7 @@ def test_query_deleted_4():
def test_export_sidecar(): def test_export_sidecar():
""" test --sidecar """
import glob import glob
import os import os
import os.path import os.path
@@ -2003,6 +2009,38 @@ def test_export_sidecar():
assert sorted(files) == sorted(CLI_EXPORT_SIDECAR_FILENAMES) assert sorted(files) == sorted(CLI_EXPORT_SIDECAR_FILENAMES)
def test_export_sidecar_drop_ext():
""" test --sidecar with --sidecar-drop-ext option """
import glob
import os
import os.path
import osxphotos
from osxphotos.__main__ import cli
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
cli,
[
"export",
"--db",
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"--sidecar=json",
"--sidecar=xmp",
"--sidecar-drop-ext",
f"--uuid={CLI_EXPORT_UUID}",
"-V",
],
)
assert result.exit_code == 0
files = glob.glob("*.*")
assert sorted(files) == sorted(CLI_EXPORT_SIDECAR_DROP_EXT_FILENAMES)
def test_export_sidecar_exiftool(): def test_export_sidecar_exiftool():
""" test --sidecar exiftool """ """ test --sidecar exiftool """
import glob import glob