Added --skip-uuid, --skip-uuid-from-file, #563

This commit is contained in:
Rhet Turnbull 2021-12-31 08:35:26 -08:00
parent 44594a8e43
commit 04930c3644
13 changed files with 137 additions and 18 deletions

View File

@ -615,7 +615,8 @@ Options:
FILENAME. If more than one --name options is
specified, they are treated as "OR", e.g. find
photos matching any FILENAME.
--uuid UUID Search for photos with UUID(s).
--uuid UUID Search for photos with UUID(s). May be
repeated to include multiple UUIDs.
--uuid-from-file FILE Search for photos with UUID(s) loaded from
FILE. Format is a single UUID per line. Lines
preceded with # are ignored.
@ -837,6 +838,11 @@ Options:
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).
--skip-uuid UUID Skip photos with UUID(s) during export. May be
repeated to include multiple UUIDs.
--skip-uuid-from-file FILE Skip photos with UUID(s) loaded from FILE.
Format is a single UUID per line. Lines
preceded with # are ignored.
--current-name Use photo's current filename instead of
original filename for export. Note: Starting
with Photos 5, all photos are renamed upon
@ -1715,7 +1721,7 @@ Substitution Description
{lf} A line feed: '\n', alias for {newline}
{cr} A carriage return: '\r'
{crlf} a carriage return + line feed: '\r\n'
{osxphotos_version} The osxphotos version, e.g. '0.44.0'
{osxphotos_version} The osxphotos version, e.g. '0.44.1'
{osxphotos_cmd_line} The full command line used to run osxphotos
The following substitutions may result in multiple values. Thus if specified for
@ -3617,7 +3623,7 @@ The following template field substitutions are availabe for use the templating s
|{lf}|A line feed: '\n', alias for {newline}|
|{cr}|A carriage return: '\r'|
|{crlf}|a carriage return + line feed: '\r\n'|
|{osxphotos_version}|The osxphotos version, e.g. '0.44.0'|
|{osxphotos_version}|The osxphotos version, e.g. '0.44.1'|
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|{album}|Album(s) photo is contained in|
|{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder|

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 4b8efce5e11b970d619d6d5988967d84
config: 58505ca56d322ccc59c38bc440ccc347
tags: 645f666f9bcd5a90fca523b33c5a78b7

View File

@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.44.0',
VERSION: '0.44.1',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
BUILDER: 'html',

View File

@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>osxphotos command line interface (CLI) &#8212; osxphotos 0.44.0 documentation</title>
<title>osxphotos command line interface (CLI) &#8212; osxphotos 0.44.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>

View File

@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index &#8212; osxphotos 0.44.0 documentation</title>
<title>Index &#8212; osxphotos 0.44.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>

View File

@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Welcome to osxphotoss documentation! &#8212; osxphotos 0.44.0 documentation</title>
<title>Welcome to osxphotoss documentation! &#8212; osxphotos 0.44.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>

View File

@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>osxphotos &#8212; osxphotos 0.44.0 documentation</title>
<title>osxphotos &#8212; osxphotos 0.44.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>

View File

@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>osxphotos package &#8212; osxphotos 0.44.0 documentation</title>
<title>osxphotos package &#8212; osxphotos 0.44.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>

View File

@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Search &#8212; osxphotos 0.44.0 documentation</title>
<title>Search &#8212; osxphotos 0.44.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />

View File

@ -1,3 +1,3 @@
""" version info """
__version__ = "0.44.0"
__version__ = "0.44.1"

View File

@ -298,7 +298,8 @@ def QUERY_OPTIONS(f):
metavar="UUID",
default=None,
multiple=True,
help="Search for photos with UUID(s).",
help="Search for photos with UUID(s). "
"May be repeated to include multiple UUIDs.",
),
o(
"--uuid-from-file",
@ -699,6 +700,23 @@ def cli(ctx, db, json_, debug):
"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(
"--skip-uuid",
metavar="UUID",
default=None,
multiple=True,
help="Skip photos with UUID(s) during export. "
"May be repeated to include multiple UUIDs.",
)
@click.option(
"--skip-uuid-from-file",
metavar="FILE",
default=None,
multiple=False,
help="Skip photos with UUID(s) loaded from FILE. "
"Format is a single UUID per line. Lines preceded with # are ignored.",
type=click.Path(exists=True),
)
@click.option(
"--current-name",
is_flag=True,
@ -1124,6 +1142,8 @@ def export(
skip_bursts,
skip_live,
skip_raw,
skip_uuid,
skip_uuid_from_file,
person_keyword,
album_keyword,
keyword_template,
@ -1292,6 +1312,8 @@ def export(
skip_bursts = cfg.skip_bursts
skip_live = cfg.skip_live
skip_raw = cfg.skip_raw
skip_uuid = cfg.skip_uuid
skip_uuid_from_file = cfg.skip_uuid_from_file
person_keyword = cfg.person_keyword
album_keyword = cfg.album_keyword
keyword_template = cfg.keyword_template
@ -1703,6 +1725,13 @@ def export(
else:
raise ValueError(e)
if skip_uuid:
photos = [p for p in photos if p.uuid not in skip_uuid]
if skip_uuid_from_file:
skip_uuid_list = load_uuid_from_file(skip_uuid_from_file)
photos = [p for p in photos if p.uuid not in skip_uuid_list]
if photos and only_new:
# ignore previously exported files
previous_uuids = {uuid: 1 for uuid in export_db.get_previous_uuids()}
@ -2807,7 +2836,8 @@ def _render_suffix_template(
rendered_suffix, unmatched = photo.render_template(suffix_template, options)
except ValueError as e:
raise click.BadOptionUsage(
var_name, f"Invalid template for {option_name} '{suffix_template}': {e}",
var_name,
f"Invalid template for {option_name} '{suffix_template}': {e}",
)
if not rendered_suffix or unmatched:
raise click.BadOptionUsage(
@ -3499,7 +3529,12 @@ def write_finder_tags(
def write_extended_attributes(
photo, files, xattr_template, strip=False, export_dir=None, export_db=None,
photo,
files,
xattr_template,
strip=False,
export_dir=None,
export_db=None,
):
"""Writes extended attributes to exported files
@ -3653,7 +3688,8 @@ def uninstall(packages, yes):
@click.option(
"--uuid",
metavar="UUID",
help="Use with '--dump photos' to dump only certain UUIDs",
help="Use with '--dump photos' to dump only certain UUIDs. "
"May be repeated to include multiple UUIDs.",
multiple=True,
)
@click.option("--verbose", "-V", "verbose", is_flag=True, help="Print verbose output.")
@ -4085,7 +4121,9 @@ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMA
@cli.command(name="tutorial")
@click.argument(
"WIDTH", nargs=-1, type=click.INT,
"WIDTH",
nargs=-1,
type=click.INT,
)
@click.pass_obj
@click.pass_context

View File

@ -0,0 +1,6 @@
# test file for --skip-uuid-from-file
# wedding.jpg
E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51
# Tulips.jpg
6191423D-8DB8-4D4C-92BE-9BBBA308AAC4

View File

@ -49,6 +49,7 @@ UUID_SKIP_LIVE_PHOTOKIT = {
UUID_DOWNLOAD_MISSING = "C6C712C5-9316-408D-A3C3-125661422DA9" # IMG_8844.JPG
UUID_FILE = "tests/uuid_from_file.txt"
SKIP_UUID_FILE = "tests/skip_uuid_from_file.txt"
CLI_OUTPUT_NO_SUBCOMMAND = [
"Options:",
@ -767,6 +768,14 @@ CLI_EXPORT_UUID_FROM_FILE_FILENAMES = [
"wedding_edited.jpeg",
]
CLI_EXPORT_SKIP_UUID = ["E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51", "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4"]
CLI_EXPORT_SKIP_UUID_FILENAMES = [
"Tulips.jpg",
"Tulips_edited.jpeg",
"wedding.jpg",
"wedding_edited.jpeg",
]
UUID_HAS_COMMENTS = [
"4E4944A0-3E5C-4028-9600-A8709F2FA1DB",
"4AD7C8EF-2991-4519-9D3A-7F44A6F031BE",
@ -1423,6 +1432,66 @@ def test_export_uuid_from_file():
files = glob.glob("*")
assert sorted(files) == sorted(CLI_EXPORT_UUID_FROM_FILE_FILENAMES)
def test_export_skip_uuid_from_file():
"""Test export with --skip-uuid-from-file"""
import glob
import os
import os.path
import osxphotos
from osxphotos.cli import export
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export,
[
os.path.join(cwd, PHOTOS_DB_15_7),
".",
"-V",
"--skip-uuid-from-file",
os.path.join(cwd, SKIP_UUID_FILE),
],
)
assert result.exit_code == 0
files = glob.glob("*")
for skipped_file in CLI_EXPORT_SKIP_UUID_FILENAMES:
assert skipped_file not in files
def test_export_skip_uuid():
"""Test export with --skip-uuid"""
import glob
import os
import os.path
import osxphotos
from osxphotos.cli import export
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
uuid_option = []
for uuid in CLI_EXPORT_SKIP_UUID:
uuid_option.append("--skip-uuid")
uuid_option.append(uuid)
with runner.isolated_filesystem():
result = runner.invoke(
export,
[
os.path.join(cwd, PHOTOS_DB_15_7),
".",
"-V",
*uuid_option,
],
)
assert result.exit_code == 0
files = glob.glob("*")
for skipped_file in CLI_EXPORT_SKIP_UUID_FILENAMES:
assert skipped_file not in files
def test_export_preview():
"""test export with --preview"""