Changed default CLI behavior to export all photos

This commit is contained in:
Rhet Turnbull
2020-04-17 22:52:11 -07:00
parent 55daa31c71
commit ed425724a0
5 changed files with 103 additions and 46 deletions

View File

@@ -855,12 +855,6 @@ def query(
@cli.command(cls=ExportCommand)
@DB_OPTION
# @click.option(
# "--all",
# is_flag=True,
# help="Export all versions of photos including "
# "edited photos, live photos, burst photos, and RAW photos.",
# )
@click.option("--verbose", "-V", is_flag=True, help="Print verbose output.")
@query_options
@click.option(
@@ -878,29 +872,26 @@ def query(
"(e.g. DEST/2019/12/20/photoname.jpg).",
)
@click.option(
"--export-edited",
"--skip-edited",
is_flag=True,
help="Also export edited version of photo if an edited version exists. "
'Edited photo will be named in form of "photoname_edited.ext"',
help="Do not export edited version of photo if an edited version exists.",
)
@click.option(
"--export-bursts",
"--skip-bursts",
is_flag=True,
help="If a photo is a burst photo export all associated burst images in the library. "
"Not currently compatible with --download-misssing; see note on --download-missing.",
help="Do not export all associated burst images in the library if a photo is a burst photo. ",
)
@click.option(
"--export-live",
"--skip-live",
is_flag=True,
help="If a photo is a live photo export the associated live video component."
" Live video will have same name as photo but with .mov extension. ",
help="Do not export the associated live video component of a live photo.",
)
@click.option(
"--export-raw",
"--skip-raw",
is_flag=True,
help="If a photo was imported in RAW format with associated jpeg, also export the "
"RAW photo in addition to the jpeg. (By default, Photos treats the jpeg as the "
"original image.)",
help="Do not export associated RAW images of a RAW/jpeg pair. "
"Note: this does not skip RAW photos if the RAW photo does not have an associated jpeg image "
"(e.g. the RAW file was imported to Photos without a jpeg preview.",
)
@click.option(
"--original-name",
@@ -986,10 +977,10 @@ def export(
verbose,
overwrite,
export_by_date,
export_edited,
export_bursts,
export_live,
export_raw,
skip_edited,
skip_bursts,
skip_live,
skip_raw,
original_name,
sidecar,
only_photos,
@@ -1027,6 +1018,10 @@ def export(
if more than one option is provided, they are treated as "AND"
(e.g. search for photos matching all options).
If no query options are provided, all photos will be exported.
By default, all versions of all photos will be exported including edited
versions, live photo movies, burst photos, and associated RAW images.
See --skip-edited, --skip-live, --skip-bursts, and --skip-raw options
to modify this behavior.
"""
if not os.path.isdir(dest):
@@ -1055,6 +1050,12 @@ def export(
click.echo(cli.commands["export"].get_help(ctx), err=True)
return
# initialize export flags
# by default, will export all versions of photos unless skip flag is set
(export_edited, export_bursts, export_live, export_raw) = [
not x for x in [skip_edited, skip_bursts, skip_live, skip_raw]
]
# verify exiftool installed an in path
if exiftool:
try:

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.27.7"
__version__ = "0.28.0"

View File

@@ -718,7 +718,7 @@ class PhotoInfo:
# Photo's often converts .JPG to .jpeg
suffixes = sorted([x.lower() for x in [dest.suffix, actual_suffix]])
if dest.suffix != actual_suffix and suffixes != [".jpeg", ".jpg"]:
logging.warning(
logging.debug(
f"Invalid destination suffix: {dest.suffix}, should be {actual_suffix}"
)

View File

@@ -206,6 +206,25 @@ def test_export():
import osxphotos
from osxphotos.__main__ import export
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export, [os.path.join(cwd, CLI_PHOTOS_DB), ".", "--original-name", "-V"]
)
assert result.exit_code == 0
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_FILENAMES)
def test_export_skip_edited():
import glob
import os
import os.path
import osxphotos
from osxphotos.__main__ import export
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
@@ -215,14 +234,14 @@ def test_export():
[
os.path.join(cwd, CLI_PHOTOS_DB),
".",
"--skip-edited",
"--original-name",
"--export-edited",
"-V",
],
)
assert result.exit_code == 0
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_FILENAMES)
assert "St James Park_edited.jpeg" not in files
def test_query_date():
@@ -290,6 +309,25 @@ def test_export_live():
import osxphotos
from osxphotos.__main__ import export
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export,
[os.path.join(cwd, LIVE_PHOTOS_DB), ".", "--live", "--original-name", "-V"],
)
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_LIVE_ORIGINAL)
def test_export_skip_live():
import glob
import os
import os.path
import osxphotos
from osxphotos.__main__ import export
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
@@ -299,14 +337,13 @@ def test_export_live():
[
os.path.join(cwd, LIVE_PHOTOS_DB),
".",
"--live",
"--skip-live",
"--original-name",
"--export-live",
"-V",
],
)
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_LIVE_ORIGINAL)
assert "img_0728.mov" not in [f.lower() for f in files]
def test_export_raw():
@@ -320,11 +357,33 @@ def test_export_raw():
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(export, [os.path.join(cwd, RAW_PHOTOS_DB), ".", "-V"])
result = runner.invoke(
export, [os.path.join(cwd, RAW_PHOTOS_DB), ".", "--skip-edited", "-V"]
)
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_RAW)
# TODO: Update this once RAW db is added
# def test_skip_raw():
# import glob
# import os
# import os.path
# import osxphotos
# from osxphotos.__main__ import export
# runner = CliRunner()
# cwd = os.getcwd()
# # pylint: disable=not-context-manager
# with runner.isolated_filesystem():
# result = runner.invoke(
# export, [os.path.join(cwd, RAW_PHOTOS_DB), ".", "--skip-raw", "-V"]
# )
# files = glob.glob("*")
# for rawname in CLI_EXPORT_RAW:
# assert rawname.lower() not in [f.lower() for f in files]
def test_export_raw_original():
import glob
import os
@@ -337,7 +396,14 @@ def test_export_raw_original():
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export, [os.path.join(cwd, RAW_PHOTOS_DB), ".", "--original-name", "-V"]
export,
[
os.path.join(cwd, RAW_PHOTOS_DB),
".",
"--skip-edited",
"--original-name",
"-V",
],
)
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_RAW_ORIGINAL)
@@ -354,9 +420,7 @@ def test_export_raw_edited():
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export, [os.path.join(cwd, RAW_PHOTOS_DB), ".", "--export-edited", "-V"]
)
result = runner.invoke(export, [os.path.join(cwd, RAW_PHOTOS_DB), ".", "-V"])
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_RAW_EDITED)
@@ -373,14 +437,7 @@ def test_export_raw_edited_original():
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export,
[
os.path.join(cwd, RAW_PHOTOS_DB),
".",
"--export-edited",
"--original-name",
"-V",
],
export, [os.path.join(cwd, RAW_PHOTOS_DB), ".", "--original-name", "-V"]
)
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_RAW_EDITED_ORIGINAL)

View File

@@ -104,7 +104,7 @@ def test_export_edited_default():
assert pathlib.Path(got_dest).name == FILENAME_DICT["current_edited"]
def test_export_edited_wrong_suffix(caplog):
def test_export_edited_wrong_suffix():
# export edited file with name provided but wrong suffix
# should produce a warning via logging.warning
import os
@@ -126,7 +126,6 @@ def test_export_edited_wrong_suffix(caplog):
expected_dest = os.path.join(dest, filename)
got_dest = photos[0].export(dest, filename, edited=True)[0]
assert "Invalid destination suffix" in caplog.text
# assert "Invalid destination suffix" in caplog.text
assert got_dest == expected_dest
assert pathlib.Path(got_dest).name == filename