Added --missing to export, see issue #277

This commit is contained in:
Rhet Turnbull
2020-11-29 15:30:45 -08:00
parent d9dcf0917a
commit 25eacc7cad
4 changed files with 108 additions and 11 deletions

View File

@@ -227,6 +227,9 @@ Options:
--no-comment Search for photos with no comments.
--has-likes Search for photos that have likes.
--no-likes Search for photos with no likes.
--missing Export only photos missing from the Photos
library; must be used with --download-
missing.
--deleted Include photos from the 'Recently Deleted'
folder.
--deleted-only Include only photos from the 'Recently
@@ -234,7 +237,8 @@ Options:
--update Only export new or updated files. See notes
below on export and --update.
--dry-run Dry run (test) the export but don't actually
export any files; most useful with --verbose
export any files; most useful with
--verbose.
--export-as-hardlink Hardlink files instead of copying them.
Cannot be used with --exiftool which creates
copies of the files with embedded EXIF data.

View File

@@ -98,7 +98,7 @@ class DateTimeISO8601(click.ParamType):
def convert(self, value, param, ctx):
try:
return datetime.datetime.fromisoformat(value)
except:
except Exception:
self.fail(
f"Invalid value for --{param.name}: invalid datetime format {value}. "
"Valid format: YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]"
@@ -651,7 +651,7 @@ def debug_dump(ctx, cli_obj, db, photos_library, dump, uuid, verbose_):
val = getattr(photosdb, attr)
print(f"{attr}:")
pprint.pprint(val)
except:
except Exception:
print(f"Did not find attribute {attr} in PhotosDB")
@@ -846,12 +846,12 @@ def places(ctx, cli_obj, db, json_, photos_library):
if photo.place:
try:
place_names[photo.place.name] += 1
except:
except Exception:
place_names[photo.place.name] = 1
else:
try:
place_names[_UNKNOWN_PLACE] += 1
except:
except Exception:
place_names[_UNKNOWN_PLACE] = 1
# sort by place count
@@ -1199,6 +1199,11 @@ def query(
@DB_OPTION
@click.option("--verbose", "-V", "verbose_", is_flag=True, help="Print verbose output.")
@query_options
@click.option(
"--missing",
is_flag=True,
help="Export only photos missing from the Photos library; must be used with --download-missing.",
)
@deleted_options
@click.option(
"--update",
@@ -1208,7 +1213,7 @@ def query(
@click.option(
"--dry-run",
is_flag=True,
help="Dry run (test) the export but don't actually export any files; most useful with --verbose",
help="Dry run (test) the export but don't actually export any files; most useful with --verbose.",
)
@click.option(
"--export-as-hardlink",
@@ -1451,6 +1456,7 @@ def export(
from_date,
to_date,
verbose_,
missing,
update,
dry_run,
export_as_hardlink,
@@ -1567,6 +1573,20 @@ def export(
click.echo(cli.commands["export"].get_help(ctx), err=True)
return
if export_as_hardlink and download_missing:
click.echo(
"Incompatible export options: --export-as-hardlink is not compatible with --download-missing",
err=True,
)
raise click.Abort()
if missing and not download_missing:
click.echo(
"Incompatible export options: --missing must be used with --download-missing",
err=True,
)
raise click.Abort()
if use_photokit and not check_photokit_authorization():
click.echo(
"Requesting access to use your Photos library. Click 'OK' on the dialog box to grant access."
@@ -1674,7 +1694,7 @@ def export(
not_favorite=not_favorite,
hidden=hidden,
not_hidden=not_hidden,
missing=None, # missing -- won't export these but will warn user
missing=missing,
not_missing=None,
shared=shared,
not_shared=not_shared,
@@ -2575,7 +2595,7 @@ def export_photo(
verbose(f"Skipped up to date file {skipped}")
for touched in export_results.touched:
verbose(f"Touched date on file {touched}")
except:
except Exception:
click.echo(
f"Error exporting photo {photo.original_filename} ({photo.filename}) as {original_filename}",
err=True,
@@ -2603,7 +2623,7 @@ def export_photo(
f"{edited_filename.stem}{edited_suffix}{edited_ext}"
)
verbose(
f"Exporting edited version of {filename} as {edited_filename}"
f"Exporting edited version of {photo.original_filename} ({photo.filename}) as {edited_filename}"
)
try:
export_results_edited = photo.export2(
@@ -2666,7 +2686,7 @@ def export_photo(
verbose(f"Skipped up to date file {skipped}")
for touched in export_results_edited.touched:
verbose(f"Touched date on file {touched}")
except:
except Exception:
click.echo(
f"Error exporting photo {filename} as {edited_filename}",
err=True,

View File

@@ -1,4 +1,4 @@
""" version info """
__version__ = "0.37.1"
__version__ = "0.37.2"

View File

@@ -17,6 +17,7 @@ PLACES_PHOTOS_DB_13 = "tests/Test-Places-High-Sierra-10.13.6.photoslibrary"
PHOTOS_DB_15_4 = "tests/Test-10.15.4.photoslibrary"
PHOTOS_DB_15_5 = "tests/Test-10.15.5.photoslibrary"
PHOTOS_DB_15_6 = "tests/Test-10.15.6.photoslibrary"
PHOTOS_DB_15_7 = "tests/Test-10.15.7.photoslibrary"
PHOTOS_DB_TOUCH = PHOTOS_DB_15_6
PHOTOS_DB_14_6 = "tests/Test-10.14.6.photoslibrary"
@@ -3804,3 +3805,75 @@ def test_export_report_not_a_file():
assert result.exit_code != 0
assert "Aborted!" in result.output
def test_export_as_hardlink_download_missing():
""" test export with incompatible export options """
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, CLI_PHOTOS_DB),
".",
"-V",
"--download-missing",
"--export-as-hardlink",
".",
],
)
assert result.exit_code != 0
assert "Aborted!" in result.output
def test_export_missing():
""" test export with --missing """
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, PHOTOS_DB_15_7),
".",
"-V",
"--missing",
"--download-missing",
".",
],
)
assert result.exit_code == 0
assert "Exporting 2 photos" in result.output
def test_export_missing_not_download_missing():
""" test export with incompatible export options """
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, CLI_PHOTOS_DB), ".", "-V", "--missing", "."]
)
assert result.exit_code != 0
assert "Aborted!" in result.output