@@ -1778,6 +1778,8 @@ def export(
|
|||||||
results_sidecar_json_skipped = []
|
results_sidecar_json_skipped = []
|
||||||
results_sidecar_xmp_written = []
|
results_sidecar_xmp_written = []
|
||||||
results_sidecar_xmp_skipped = []
|
results_sidecar_xmp_skipped = []
|
||||||
|
results_missing = []
|
||||||
|
results_error = []
|
||||||
if verbose_:
|
if verbose_:
|
||||||
for p in photos:
|
for p in photos:
|
||||||
results = export_photo(
|
results = export_photo(
|
||||||
@@ -1826,6 +1828,8 @@ def export(
|
|||||||
results_sidecar_json_skipped.extend(results.sidecar_json_skipped)
|
results_sidecar_json_skipped.extend(results.sidecar_json_skipped)
|
||||||
results_sidecar_xmp_written.extend(results.sidecar_xmp_written)
|
results_sidecar_xmp_written.extend(results.sidecar_xmp_written)
|
||||||
results_sidecar_xmp_skipped.extend(results.sidecar_xmp_skipped)
|
results_sidecar_xmp_skipped.extend(results.sidecar_xmp_skipped)
|
||||||
|
results_missing.extend(results.missing)
|
||||||
|
results_error.extend(results.error)
|
||||||
|
|
||||||
# if convert_to_jpeg and p.isphoto and p.uti != "public.jpeg":
|
# if convert_to_jpeg and p.isphoto and p.uti != "public.jpeg":
|
||||||
# for photo_file in set(
|
# for photo_file in set(
|
||||||
@@ -1883,6 +1887,8 @@ def export(
|
|||||||
results_sidecar_json_skipped.extend(results.sidecar_json_skipped)
|
results_sidecar_json_skipped.extend(results.sidecar_json_skipped)
|
||||||
results_sidecar_xmp_written.extend(results.sidecar_xmp_written)
|
results_sidecar_xmp_written.extend(results.sidecar_xmp_written)
|
||||||
results_sidecar_xmp_skipped.extend(results.sidecar_xmp_skipped)
|
results_sidecar_xmp_skipped.extend(results.sidecar_xmp_skipped)
|
||||||
|
results_missing.extend(results.missing)
|
||||||
|
results_error.extend(results.error)
|
||||||
|
|
||||||
stop_time = time.perf_counter()
|
stop_time = time.perf_counter()
|
||||||
# print summary results
|
# print summary results
|
||||||
@@ -1895,6 +1901,8 @@ def export(
|
|||||||
# print(f"results_converted: {results_converted}")
|
# print(f"results_converted: {results_converted}")
|
||||||
# print(f"results_sidecar_json: {results_sidecar_json}")
|
# print(f"results_sidecar_json: {results_sidecar_json}")
|
||||||
# print(f"results_sidecar_xmp: {results_sidecar_xmp}")
|
# print(f"results_sidecar_xmp: {results_sidecar_xmp}")
|
||||||
|
# print(f"results_missing: {results_missing}")
|
||||||
|
# print(f"results_error: {results_error}")
|
||||||
|
|
||||||
if report:
|
if report:
|
||||||
verbose(f"Writing export report to {report}")
|
verbose(f"Writing export report to {report}")
|
||||||
@@ -1911,27 +1919,28 @@ def export(
|
|||||||
results_sidecar_json_skipped=results_sidecar_json_skipped,
|
results_sidecar_json_skipped=results_sidecar_json_skipped,
|
||||||
results_sidecar_xmp_written=results_sidecar_xmp_written,
|
results_sidecar_xmp_written=results_sidecar_xmp_written,
|
||||||
results_sidecar_xmp_skipped=results_sidecar_xmp_skipped,
|
results_sidecar_xmp_skipped=results_sidecar_xmp_skipped,
|
||||||
|
results_missing=results_missing,
|
||||||
|
results_error=results_error,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
photo_str_total = "photos" if len(photos) != 1 else "photo"
|
||||||
if update:
|
if update:
|
||||||
photo_str_new = "photos" if len(results_new) != 1 else "photo"
|
|
||||||
photo_str_updated = "photos" if len(results_updated) != 1 else "photo"
|
|
||||||
photo_str_skipped = "photos" if len(results_skipped) != 1 else "photo"
|
|
||||||
photo_str_exif_updated = (
|
|
||||||
"photos" if len(results_exif_updated) != 1 else "photo"
|
|
||||||
)
|
|
||||||
summary = (
|
summary = (
|
||||||
f"Exported: {len(results_new)} {photo_str_new}, "
|
f"Processed: {len(photos)} {photo_str_total}, "
|
||||||
f"updated: {len(results_updated)} {photo_str_updated}, "
|
f"exported: {len(results_new)}, "
|
||||||
f"skipped: {len(results_skipped)} {photo_str_skipped}, "
|
f"updated: {len(results_updated)}, "
|
||||||
f"updated EXIF data: {len(results_exif_updated)} {photo_str_exif_updated}"
|
f"skipped: {len(results_skipped)}, "
|
||||||
|
f"updated EXIF data: {len(results_exif_updated)}, "
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
photo_str = "photos" if len(results_exported) != 1 else "photo"
|
summary = (
|
||||||
summary = f"Exported: {len(results_exported)} {photo_str}"
|
f"Processed: {len(photos)} {photo_str_total}, "
|
||||||
photo_str_touched = "photos" if len(results_touched) != 1 else "photo"
|
f"exported: {len(results_exported)}, "
|
||||||
|
)
|
||||||
|
summary += f"missing: {len(results_missing)}, "
|
||||||
|
summary += f"error: {len(results_error)}"
|
||||||
if touch_file:
|
if touch_file:
|
||||||
summary += f", touched date: {len(results_touched)} {photo_str_touched}"
|
summary += f", touched date: {len(results_touched)}"
|
||||||
click.echo(summary)
|
click.echo(summary)
|
||||||
click.echo(f"Elapsed time: {(stop_time-start_time):.3f} seconds")
|
click.echo(f"Elapsed time: {(stop_time-start_time):.3f} seconds")
|
||||||
else:
|
else:
|
||||||
@@ -2462,19 +2471,61 @@ def export_photo(
|
|||||||
if photo.ismissing:
|
if photo.ismissing:
|
||||||
space = " " if not verbose_ else ""
|
space = " " if not verbose_ else ""
|
||||||
verbose(f"{space}Skipping missing photo {photo.original_filename}")
|
verbose(f"{space}Skipping missing photo {photo.original_filename}")
|
||||||
return ExportResults([], [], [], [], [], [], [], [], [], [], [])
|
return ExportResults(
|
||||||
|
exported=[],
|
||||||
|
new=[],
|
||||||
|
updated=[],
|
||||||
|
skipped=[],
|
||||||
|
exif_updated=[],
|
||||||
|
touched=[],
|
||||||
|
converted_to_jpeg=[],
|
||||||
|
sidecar_json_written=[],
|
||||||
|
sidecar_json_skipped=[],
|
||||||
|
sidecar_xmp_written=[],
|
||||||
|
sidecar_xmp_skipped=[],
|
||||||
|
missing=[f"{photo.original_filename} ({photo.uuid})"],
|
||||||
|
error=[],
|
||||||
|
)
|
||||||
elif photo.path is None:
|
elif photo.path is None:
|
||||||
space = " " if not verbose_ else ""
|
space = " " if not verbose_ else ""
|
||||||
verbose(
|
verbose(
|
||||||
f"{space}WARNING: photo {photo.original_filename} ({photo.uuid}) is missing but ismissing=False, "
|
f"{space}WARNING: photo {photo.original_filename} ({photo.uuid}) is missing but ismissing=False, "
|
||||||
f"skipping {photo.original_filename}"
|
f"skipping {photo.original_filename}"
|
||||||
)
|
)
|
||||||
return ExportResults([], [], [], [], [], [], [], [], [], [], [])
|
return ExportResults(
|
||||||
|
exported=[],
|
||||||
|
new=[],
|
||||||
|
updated=[],
|
||||||
|
skipped=[],
|
||||||
|
exif_updated=[],
|
||||||
|
touched=[],
|
||||||
|
converted_to_jpeg=[],
|
||||||
|
sidecar_json_written=[],
|
||||||
|
sidecar_json_skipped=[],
|
||||||
|
sidecar_xmp_written=[],
|
||||||
|
sidecar_xmp_skipped=[],
|
||||||
|
missing=[f"{photo.original_filename} ({photo.uuid})"],
|
||||||
|
error=[],
|
||||||
|
)
|
||||||
elif photo.ismissing and not photo.iscloudasset and not photo.incloud:
|
elif photo.ismissing and not photo.iscloudasset and not photo.incloud:
|
||||||
verbose(
|
verbose(
|
||||||
f"Skipping missing {photo.original_filename}: not iCloud asset or missing from cloud"
|
f"Skipping missing {photo.original_filename}: not iCloud asset or missing from cloud"
|
||||||
)
|
)
|
||||||
return ExportResults([], [], [], [], [], [], [], [], [], [], [])
|
return ExportResults(
|
||||||
|
exported=[],
|
||||||
|
new=[],
|
||||||
|
updated=[],
|
||||||
|
skipped=[],
|
||||||
|
exif_updated=[],
|
||||||
|
touched=[],
|
||||||
|
converted_to_jpeg=[],
|
||||||
|
sidecar_json_written=[],
|
||||||
|
sidecar_json_skipped=[],
|
||||||
|
sidecar_xmp_written=[],
|
||||||
|
sidecar_xmp_skipped=[],
|
||||||
|
missing=[f"{photo.original_filename} ({photo.uuid})"],
|
||||||
|
error=[],
|
||||||
|
)
|
||||||
|
|
||||||
results_exported = []
|
results_exported = []
|
||||||
results_new = []
|
results_new = []
|
||||||
@@ -2487,6 +2538,7 @@ def export_photo(
|
|||||||
results_sidecar_json_skipped = []
|
results_sidecar_json_skipped = []
|
||||||
results_sidecar_xmp_written = []
|
results_sidecar_xmp_written = []
|
||||||
results_sidecar_xmp_skipped = []
|
results_sidecar_xmp_skipped = []
|
||||||
|
results_error = []
|
||||||
|
|
||||||
export_original = not (skip_original_if_edited and photo.hasadjustments)
|
export_original = not (skip_original_if_edited and photo.hasadjustments)
|
||||||
|
|
||||||
@@ -2612,6 +2664,7 @@ def export_photo(
|
|||||||
f"Error exporting photo {photo.original_filename} ({photo.filename}) as {original_filename}",
|
f"Error exporting photo {photo.original_filename} ({photo.filename}) as {original_filename}",
|
||||||
err=True,
|
err=True,
|
||||||
)
|
)
|
||||||
|
results_error.extend(dest)
|
||||||
else:
|
else:
|
||||||
verbose(f"Skipping original version of {photo.original_filename}")
|
verbose(f"Skipping original version of {photo.original_filename}")
|
||||||
|
|
||||||
@@ -2703,19 +2756,22 @@ def export_photo(
|
|||||||
f"Error exporting photo {filename} as {edited_filename}",
|
f"Error exporting photo {filename} as {edited_filename}",
|
||||||
err=True,
|
err=True,
|
||||||
)
|
)
|
||||||
|
results_error.extend(dest)
|
||||||
|
|
||||||
return ExportResults(
|
return ExportResults(
|
||||||
results_exported,
|
exported=results_exported,
|
||||||
results_new,
|
new=results_new,
|
||||||
results_updated,
|
updated=results_updated,
|
||||||
results_skipped,
|
skipped=results_skipped,
|
||||||
results_exif_updated,
|
exif_updated=results_exif_updated,
|
||||||
results_touched,
|
touched=results_touched,
|
||||||
results_converted,
|
converted_to_jpeg=results_converted,
|
||||||
results_sidecar_json_written,
|
sidecar_json_written=results_sidecar_json_written,
|
||||||
results_sidecar_json_skipped,
|
sidecar_json_skipped=results_sidecar_json_skipped,
|
||||||
results_sidecar_xmp_written,
|
sidecar_xmp_written=results_sidecar_xmp_written,
|
||||||
results_sidecar_xmp_skipped,
|
sidecar_xmp_skipped=results_sidecar_xmp_skipped,
|
||||||
|
missing=[],
|
||||||
|
error=results_error,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -2880,6 +2936,8 @@ def write_export_report(
|
|||||||
results_sidecar_json_skipped,
|
results_sidecar_json_skipped,
|
||||||
results_sidecar_xmp_written,
|
results_sidecar_xmp_written,
|
||||||
results_sidecar_xmp_skipped,
|
results_sidecar_xmp_skipped,
|
||||||
|
results_missing,
|
||||||
|
results_error,
|
||||||
):
|
):
|
||||||
|
|
||||||
""" write CSV report with results from export """
|
""" write CSV report with results from export """
|
||||||
@@ -2898,6 +2956,8 @@ def write_export_report(
|
|||||||
"converted_to_jpeg": 0,
|
"converted_to_jpeg": 0,
|
||||||
"sidecar_xmp": 0,
|
"sidecar_xmp": 0,
|
||||||
"sidecar_json": 0,
|
"sidecar_json": 0,
|
||||||
|
"missing": 0,
|
||||||
|
"error": 0,
|
||||||
}
|
}
|
||||||
for result in results_exported
|
for result in results_exported
|
||||||
+ results_new
|
+ results_new
|
||||||
@@ -2910,6 +2970,8 @@ def write_export_report(
|
|||||||
+ results_sidecar_json_skipped
|
+ results_sidecar_json_skipped
|
||||||
+ results_sidecar_xmp_written
|
+ results_sidecar_xmp_written
|
||||||
+ results_sidecar_xmp_skipped
|
+ results_sidecar_xmp_skipped
|
||||||
|
+ results_missing
|
||||||
|
+ results_error
|
||||||
}
|
}
|
||||||
|
|
||||||
for result in results_exported:
|
for result in results_exported:
|
||||||
@@ -2949,6 +3011,12 @@ def write_export_report(
|
|||||||
all_results[result]["sidecar_json"] = 1
|
all_results[result]["sidecar_json"] = 1
|
||||||
all_results[result]["skipped"] = 1
|
all_results[result]["skipped"] = 1
|
||||||
|
|
||||||
|
for result in results_missing:
|
||||||
|
all_results[result]["missing"] = 1
|
||||||
|
|
||||||
|
for result in results_error:
|
||||||
|
all_results[result]["error"] = 1
|
||||||
|
|
||||||
report_columns = [
|
report_columns = [
|
||||||
"filename",
|
"filename",
|
||||||
"exported",
|
"exported",
|
||||||
@@ -2960,6 +3028,8 @@ def write_export_report(
|
|||||||
"converted_to_jpeg",
|
"converted_to_jpeg",
|
||||||
"sidecar_xmp",
|
"sidecar_xmp",
|
||||||
"sidecar_json",
|
"sidecar_json",
|
||||||
|
"missing",
|
||||||
|
"error",
|
||||||
]
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
""" version info """
|
""" version info """
|
||||||
|
|
||||||
__version__ = "0.37.4"
|
__version__ = "0.37.5"
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ ExportResults = namedtuple(
|
|||||||
"sidecar_json_skipped",
|
"sidecar_json_skipped",
|
||||||
"sidecar_xmp_written",
|
"sidecar_xmp_written",
|
||||||
"sidecar_xmp_skipped",
|
"sidecar_xmp_skipped",
|
||||||
|
"missing",
|
||||||
|
"error",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -389,9 +391,21 @@ def export2(
|
|||||||
ignore_date_modified: for use with sidecar and exiftool; if True, sets EXIF:ModifyDate to EXIF:DateTimeOriginal even if date_modified is set
|
ignore_date_modified: for use with sidecar and exiftool; if True, sets EXIF:ModifyDate to EXIF:DateTimeOriginal even if date_modified is set
|
||||||
verbose: optional callable function to use for printing verbose text during processing; if None (default), does not print output.
|
verbose: optional callable function to use for printing verbose text during processing; if None (default), does not print output.
|
||||||
|
|
||||||
Returns: ExportResults namedtuple with fields: exported, new, updated, skipped
|
Returns: ExportResults namedtuple with fields:
|
||||||
where each field is a list of file paths
|
"exported",
|
||||||
|
"new",
|
||||||
|
"updated",
|
||||||
|
"skipped",
|
||||||
|
"exif_updated",
|
||||||
|
"touched",
|
||||||
|
"converted_to_jpeg",
|
||||||
|
"sidecar_json_written",
|
||||||
|
"sidecar_json_skipped",
|
||||||
|
"sidecar_xmp_written",
|
||||||
|
"sidecar_xmp_skipped",
|
||||||
|
"missing",
|
||||||
|
"error"
|
||||||
|
|
||||||
Note: to use dry run mode, you must set dry_run=True and also pass in memory version of export_db,
|
Note: to use dry run mode, you must set dry_run=True and also pass in memory version of export_db,
|
||||||
and no-op fileutil (e.g. ExportDBInMemory and FileUtilNoOp)
|
and no-op fileutil (e.g. ExportDBInMemory and FileUtilNoOp)
|
||||||
"""
|
"""
|
||||||
@@ -926,17 +940,19 @@ def export2(
|
|||||||
touched_files = list(set(touched_files))
|
touched_files = list(set(touched_files))
|
||||||
|
|
||||||
results = ExportResults(
|
results = ExportResults(
|
||||||
exported_files,
|
exported=exported_files,
|
||||||
update_new_files,
|
new=update_new_files,
|
||||||
update_updated_files,
|
updated=update_updated_files,
|
||||||
update_skipped_files,
|
skipped=update_skipped_files,
|
||||||
exif_files_updated,
|
exif_updated=exif_files_updated,
|
||||||
touched_files,
|
touched=touched_files,
|
||||||
converted_to_jpeg_files,
|
converted_to_jpeg=converted_to_jpeg_files,
|
||||||
sidecar_json_files_written,
|
sidecar_json_written=sidecar_json_files_written,
|
||||||
sidecar_json_files_skipped,
|
sidecar_json_skipped=sidecar_json_files_skipped,
|
||||||
sidecar_xmp_files_written,
|
sidecar_xmp_written=sidecar_xmp_files_written,
|
||||||
sidecar_xmp_files_skipped,
|
sidecar_xmp_skipped=sidecar_xmp_files_skipped,
|
||||||
|
missing=[],
|
||||||
|
error=[],
|
||||||
)
|
)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@@ -997,7 +1013,6 @@ def _export_photo(
|
|||||||
|
|
||||||
dest_str = str(dest)
|
dest_str = str(dest)
|
||||||
dest_exists = dest.exists()
|
dest_exists = dest.exists()
|
||||||
op_desc = "export_as_hardlink" if export_as_hardlink else "export_by_copying"
|
|
||||||
|
|
||||||
if update: # updating
|
if update: # updating
|
||||||
cmp_touch, cmp_orig = False, False
|
cmp_touch, cmp_orig = False, False
|
||||||
@@ -1103,17 +1118,19 @@ def _export_photo(
|
|||||||
fileutil.utime(dest, (ts, ts))
|
fileutil.utime(dest, (ts, ts))
|
||||||
|
|
||||||
return ExportResults(
|
return ExportResults(
|
||||||
exported_files + update_new_files + update_updated_files,
|
exported=exported_files + update_new_files + update_updated_files,
|
||||||
update_new_files,
|
new=update_new_files,
|
||||||
update_updated_files,
|
updated=update_updated_files,
|
||||||
update_skipped_files,
|
skipped=update_skipped_files,
|
||||||
[],
|
exif_updated=[],
|
||||||
touched_files,
|
touched=touched_files,
|
||||||
converted_to_jpeg_files,
|
converted_to_jpeg=converted_to_jpeg_files,
|
||||||
[],
|
sidecar_json_written=[],
|
||||||
[],
|
sidecar_json_skipped=[],
|
||||||
[],
|
sidecar_xmp_written=[],
|
||||||
[],
|
sidecar_xmp_skipped=[],
|
||||||
|
missing=[],
|
||||||
|
error=[],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1054,7 +1054,7 @@ def test_export_exiftool_quicktime():
|
|||||||
exif = ExifTool(CLI_EXIFTOOL_QUICKTIME[uuid]["File:FileName"]).asdict()
|
exif = ExifTool(CLI_EXIFTOOL_QUICKTIME[uuid]["File:FileName"]).asdict()
|
||||||
for key in CLI_EXIFTOOL_QUICKTIME[uuid]:
|
for key in CLI_EXIFTOOL_QUICKTIME[uuid]:
|
||||||
assert exif[key] == CLI_EXIFTOOL_QUICKTIME[uuid][key]
|
assert exif[key] == CLI_EXIFTOOL_QUICKTIME[uuid][key]
|
||||||
|
|
||||||
# clean up exported files to avoid name conflicts
|
# clean up exported files to avoid name conflicts
|
||||||
for filename in files:
|
for filename in files:
|
||||||
os.unlink(filename)
|
os.unlink(filename)
|
||||||
@@ -2983,7 +2983,7 @@ def test_export_update_basic():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert (
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 8 photos, updated EXIF data: 0 photos"
|
"Processed: 7 photos, exported: 0, updated: 0, skipped: 8, updated EXIF data: 0, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3067,7 +3067,7 @@ def test_export_update_exiftool():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert (
|
||||||
"Exported: 0 photos, updated: 8 photos, skipped: 0 photos, updated EXIF data: 8 photos"
|
"Processed: 7 photos, exported: 0, updated: 8, skipped: 0, updated EXIF data: 8, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3077,7 +3077,7 @@ def test_export_update_exiftool():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert (
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 8 photos, updated EXIF data: 0 photos"
|
"Processed: 7 photos, exported: 0, updated: 0, skipped: 8, updated EXIF data: 0, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3114,7 +3114,7 @@ def test_export_update_hardlink():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert (
|
||||||
"Exported: 0 photos, updated: 8 photos, skipped: 0 photos, updated EXIF data: 0 photos"
|
"Processed: 7 photos, exported: 0, updated: 8, skipped: 0, updated EXIF data: 0, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
assert not os.path.samefile(CLI_EXPORT_UUID_FILENAME, photo.path)
|
assert not os.path.samefile(CLI_EXPORT_UUID_FILENAME, photo.path)
|
||||||
@@ -3153,7 +3153,7 @@ def test_export_update_hardlink_exiftool():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert (
|
||||||
"Exported: 0 photos, updated: 8 photos, skipped: 0 photos, updated EXIF data: 8 photos"
|
"Processed: 7 photos, exported: 0, updated: 8, skipped: 0, updated EXIF data: 8, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
assert not os.path.samefile(CLI_EXPORT_UUID_FILENAME, photo.path)
|
assert not os.path.samefile(CLI_EXPORT_UUID_FILENAME, photo.path)
|
||||||
@@ -3191,7 +3191,7 @@ def test_export_update_edits():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert (
|
||||||
"Exported: 1 photo, updated: 1 photo, skipped: 6 photos, updated EXIF data: 0 photos"
|
"Processed: 7 photos, exported: 1, updated: 1, skipped: 6, updated EXIF data: 0, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3227,7 +3227,7 @@ def test_export_update_no_db():
|
|||||||
# edited files will be re-exported because there won't be an edited signature
|
# edited files will be re-exported because there won't be an edited signature
|
||||||
# in the database
|
# in the database
|
||||||
assert (
|
assert (
|
||||||
"Exported: 0 photos, updated: 2 photos, skipped: 6 photos, updated EXIF data: 0 photos"
|
"Processed: 7 photos, exported: 0, updated: 2, skipped: 6, updated EXIF data: 0, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
assert os.path.isfile(OSXPHOTOS_EXPORT_DB)
|
assert os.path.isfile(OSXPHOTOS_EXPORT_DB)
|
||||||
@@ -3266,7 +3266,7 @@ def test_export_then_hardlink():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Exported: 8 photos" in result.output
|
assert "Processed: 7 photos, exported: 8, missing: 1, error: 0" in result.output
|
||||||
assert os.path.samefile(CLI_EXPORT_UUID_FILENAME, photo.path)
|
assert os.path.samefile(CLI_EXPORT_UUID_FILENAME, photo.path)
|
||||||
|
|
||||||
|
|
||||||
@@ -3286,7 +3286,7 @@ def test_export_dry_run():
|
|||||||
export, [os.path.join(cwd, CLI_PHOTOS_DB), ".", "-V", "--dry-run"]
|
export, [os.path.join(cwd, CLI_PHOTOS_DB), ".", "-V", "--dry-run"]
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Exported: 8 photos" in result.output
|
assert "Processed: 7 photos, exported: 8, missing: 1, error: 0" in result.output
|
||||||
for filepath in CLI_EXPORT_FILENAMES:
|
for filepath in CLI_EXPORT_FILENAMES:
|
||||||
assert f"Exported {filepath}" in result.output
|
assert f"Exported {filepath}" in result.output
|
||||||
assert not os.path.isfile(filepath)
|
assert not os.path.isfile(filepath)
|
||||||
@@ -3330,7 +3330,7 @@ def test_export_update_edits_dry_run():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert (
|
||||||
"Exported: 1 photo, updated: 1 photo, skipped: 6 photos, updated EXIF data: 0 photos"
|
"Processed: 7 photos, exported: 1, updated: 1, skipped: 6, updated EXIF data: 0, missing: 1, error: 0"
|
||||||
in result.output
|
in result.output
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3365,7 +3365,7 @@ def test_export_directory_template_1_dry_run():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "Exported: 8 photos" in result.output
|
assert "exported: 8" in result.output
|
||||||
workdir = os.getcwd()
|
workdir = os.getcwd()
|
||||||
for filepath in CLI_EXPORTED_DIRECTORY_TEMPLATE_FILENAMES1:
|
for filepath in CLI_EXPORTED_DIRECTORY_TEMPLATE_FILENAMES1:
|
||||||
assert f"Exported {filepath}" in result.output
|
assert f"Exported {filepath}" in result.output
|
||||||
@@ -3401,7 +3401,8 @@ def test_export_touch_files():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert "Exported: 18 photos, touched date: 16 photos" in result.output
|
assert "exported: 18" in result.output
|
||||||
|
assert "touched date: 16" in result.output
|
||||||
|
|
||||||
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
||||||
st = os.stat(fname)
|
st = os.stat(fname)
|
||||||
@@ -3433,7 +3434,7 @@ def test_export_touch_files_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert "Exported: 18 photos" in result.output
|
assert "exported: 18" in result.output
|
||||||
|
|
||||||
assert not pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
assert not pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
||||||
|
|
||||||
@@ -3443,7 +3444,7 @@ def test_export_touch_files_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert "Exported: 18 photos" in result.output
|
assert "exported: 18" in result.output
|
||||||
|
|
||||||
assert pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
assert pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
||||||
|
|
||||||
@@ -3454,10 +3455,7 @@ def test_export_touch_files_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert (
|
assert "skipped: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos"
|
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
# --update --touch-file --dry-run
|
# --update --touch-file --dry-run
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
@@ -3472,10 +3470,8 @@ def test_export_touch_files_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert "skipped: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos, touched date: 16 photos"
|
assert "touched date: 16" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
for fname, mtime in zip(
|
for fname, mtime in zip(
|
||||||
CLI_EXPORT_BY_DATE_NEED_TOUCH, CLI_EXPORT_BY_DATE_NEED_TOUCH_TIMES
|
CLI_EXPORT_BY_DATE_NEED_TOUCH, CLI_EXPORT_BY_DATE_NEED_TOUCH_TIMES
|
||||||
@@ -3495,10 +3491,8 @@ def test_export_touch_files_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert "skipped: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos, touched date: 16 photos"
|
assert "touched date: 16" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
for fname, mtime in zip(
|
for fname, mtime in zip(
|
||||||
CLI_EXPORT_BY_DATE_NEED_TOUCH, CLI_EXPORT_BY_DATE_NEED_TOUCH_TIMES
|
CLI_EXPORT_BY_DATE_NEED_TOUCH, CLI_EXPORT_BY_DATE_NEED_TOUCH_TIMES
|
||||||
@@ -3521,10 +3515,8 @@ def test_export_touch_files_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert "updated: 1, skipped: 17" in result.output
|
||||||
"Exported: 0 photos, updated: 1 photo, skipped: 17 photos, updated EXIF data: 0 photos, touched date: 1 photo"
|
assert "touched date: 1" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
||||||
st = os.stat(fname)
|
st = os.stat(fname)
|
||||||
@@ -3537,10 +3529,7 @@ def test_export_touch_files_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert (
|
assert "skipped: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos"
|
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip("TODO: This fails on some machines but not all")
|
@pytest.mark.skip("TODO: This fails on some machines but not all")
|
||||||
@@ -3570,7 +3559,7 @@ def test_export_touch_files_exiftool_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert "Exported: 18 photos" in result.output
|
assert "exported: 18" in result.output
|
||||||
|
|
||||||
assert not pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
assert not pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
||||||
|
|
||||||
@@ -3580,7 +3569,7 @@ def test_export_touch_files_exiftool_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert "Exported: 18 photos" in result.output
|
assert "exported: 18" in result.output
|
||||||
|
|
||||||
assert pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
assert pathlib.Path(CLI_EXPORT_BY_DATE[0]).is_file()
|
||||||
|
|
||||||
@@ -3591,10 +3580,7 @@ def test_export_touch_files_exiftool_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert (
|
assert "skipped: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos"
|
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
# --update --exiftool --dry-run
|
# --update --exiftool --dry-run
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
@@ -3610,10 +3596,8 @@ def test_export_touch_files_exiftool_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert (
|
assert "updated: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 18 photos, skipped: 0 photos, updated EXIF data: 18 photos"
|
assert "updated EXIF data: 18" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
# --update --exiftool
|
# --update --exiftool
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
@@ -3627,11 +3611,8 @@ def test_export_touch_files_exiftool_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
assert "updated: 18" in result.output
|
||||||
assert (
|
assert "updated EXIF data: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 18 photos, skipped: 0 photos, updated EXIF data: 18 photos"
|
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
# --update --touch-file --exiftool --dry-run
|
# --update --touch-file --exiftool --dry-run
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
@@ -3647,10 +3628,8 @@ def test_export_touch_files_exiftool_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert "skipped: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos, touched date: 18 photos"
|
assert "touched date: 18" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
# --update --touch-file --exiftool
|
# --update --touch-file --exiftool
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
@@ -3665,10 +3644,8 @@ def test_export_touch_files_exiftool_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert "skipped: 18" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos, touched date: 18 photos"
|
assert "touched date: 18" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
||||||
st = os.stat(fname)
|
st = os.stat(fname)
|
||||||
@@ -3690,10 +3667,10 @@ def test_export_touch_files_exiftool_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert "updated: 1" in result.output
|
||||||
"Exported: 0 photos, updated: 1 photo, skipped: 17 photos, updated EXIF data: 1 photo, touched date: 1 photo"
|
assert "skipped: 17" in result.output
|
||||||
in result.output
|
assert "updated EXIF data: 1" in result.output
|
||||||
)
|
assert "touched date: 1" in result.output
|
||||||
|
|
||||||
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
for fname, mtime in zip(CLI_EXPORT_BY_DATE, CLI_EXPORT_BY_DATE_TOUCH_TIMES):
|
||||||
st = os.stat(fname)
|
st = os.stat(fname)
|
||||||
@@ -3712,10 +3689,8 @@ def test_export_touch_files_exiftool_update():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert (
|
assert "exported: 0" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos, touched date: 0 photos"
|
assert "skipped: 18" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
# run update without --touch-file
|
# run update without --touch-file
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
@@ -3730,10 +3705,8 @@ def test_export_touch_files_exiftool_update():
|
|||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|
||||||
assert (
|
assert "exported: 0" in result.output
|
||||||
"Exported: 0 photos, updated: 0 photos, skipped: 18 photos, updated EXIF data: 0 photos"
|
assert "skipped: 18" in result.output
|
||||||
in result.output
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_labels():
|
def test_labels():
|
||||||
|
|||||||
Reference in New Issue
Block a user