From a4b4f1c2889a039219d7b4ba983fc240e92d0a20 Mon Sep 17 00:00:00 2001 From: Rhet Turnbull Date: Sat, 8 Apr 2023 14:34:08 -0700 Subject: [PATCH] Feature help no selection 1036 (#1042) * Added validation for --selected * Added test for #999 (project_info) that I missed on last branch --- osxphotos/cli/cli_params.py | 49 +++++++++++++++++++++++++++++-- tests/test_cli_export_projects.py | 23 +++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/test_cli_export_projects.py diff --git a/osxphotos/cli/cli_params.py b/osxphotos/cli/cli_params.py index c6a6c33c..23c2629c 100644 --- a/osxphotos/cli/cli_params.py +++ b/osxphotos/cli/cli_params.py @@ -1,12 +1,13 @@ """Common options & parameters for osxphotos CLI commands""" + from __future__ import annotations import functools from typing import Any, Callable - import click - +import contextlib +from textwrap import dedent from .common import OSXPHOTOS_HIDDEN, print_version from .param_types import * @@ -25,6 +26,49 @@ __all__ = [ ] +def validate_selected(ctx, param, value): + """ "Validate photos are actually selected when --selected is used""" + + if not value: + # --selected not used, just return + return value + + # imports here to avoid conflict with linux port + # TODO: fix this once linux port is complete + import photoscript + from applescript import ScriptError + + selection = None + with contextlib.suppress(ScriptError): + # ScriptError raised if selection made in edit mode or Smart Albums (on older versions of Photos) + selection = photoscript.PhotosLibrary().selection + + if not selection: + click.echo( + dedent( + """ + --selected option used but no photos selected in Photos. + + To select photos in Photos use one of the following methods: + + - Select a single photo: Click the photo, or press the arrow keys to quickly navigate to and select the photo. + + - Select a group of adjacent photos in a day: Click the first photo, then hold down the Shift key while you click the last photo. + You can also hold down Shift and press the arrow keys, or simply drag to enclose the photos within the selection rectangle. + + - Select photos in a day that are not adjacent to each other: Hold down the Command key as you click each photo. + + - Deselect specific photos: Hold down the Command key and click the photos you want to deselect. + + - Deselect all photos: Click an empty space in the window (not a photo). + """ + ), + err=True, + ) + ctx.exit(1) + return value + + def _param_memo(f: Callable[..., Any], param: click.Parameter) -> None: """Add param to the list of params for a click.Command This is directly from the click source code and @@ -557,6 +601,7 @@ _QUERY_PARAMETERS_DICT = { ["--selected"], is_flag=True, help="Filter for photos that are currently selected in Photos.", + callback=validate_selected, ), "--exif": click.Option( ["--exif"], diff --git a/tests/test_cli_export_projects.py b/tests/test_cli_export_projects.py new file mode 100644 index 00000000..74177965 --- /dev/null +++ b/tests/test_cli_export_projects.py @@ -0,0 +1,23 @@ +"""Test that libraries containing projects are handled correctly, #999""" + +import os + +import pytest +from click.testing import CliRunner + +from osxphotos.cli import export + +PHOTOS_DB_PROJECTS = "./tests/Test-iPhoto-Projects-10.15.7.photoslibrary" + + +def test_export_projects(): + """test basic export with library containing projects""" + runner = CliRunner() + cwd = os.getcwd() + # pylint: disable=not-context-manager + with runner.isolated_filesystem(): + result = runner.invoke( + export, ["--library", os.path.join(cwd, PHOTOS_DB_PROJECTS), ".", "-V"] + ) + assert result.exit_code == 0 + assert "error: 0" in result.output