Implemented --ignore-signature, issue #286

This commit is contained in:
Rhet Turnbull
2020-12-16 20:11:01 -08:00
parent 3c14ace826
commit e394d8e6be
32 changed files with 117 additions and 18 deletions

View File

@@ -146,6 +146,9 @@ class ExportCommand(click.Command):
+ "exported image), osxphotos will detect this as a difference and re-export the original image "
+ "from the library thus overwriting the changes. If using --update, the exported library "
+ "should be treated as a backup, not a working copy where you intend to make changes. "
+ "If you do edit or process the exported files and do not want them to be overwritten with"
+ "subsequent --update, use --ignore-signature which will match filename but not file signature when "
+ "exporting."
)
formatter.write("\n")
formatter.write_text(
@@ -1218,6 +1221,15 @@ def query(
is_flag=True,
help="Only export new or updated files. See notes below on export and --update.",
)
@click.option(
"--ignore-signature",
is_flag=True,
help="When used with --update, ignores file signature when updating files. "
"This is useful if you have processed or edited exported photos changing the "
"file signature (size & modification date). In this case, --update would normally "
"re-export the processed files but with --ignore-signature, files which exist "
"in the export directory will not be re-exported.",
)
@click.option(
"--dry-run",
is_flag=True,
@@ -1496,6 +1508,7 @@ def export(
verbose,
missing,
update,
ignore_signature,
dry_run,
export_as_hardlink,
touch_file,
@@ -1621,6 +1634,7 @@ def export(
verbose = cfg.verbose
missing = cfg.missing
update = cfg.update
ignore_signature = cfg.ignore_signature
dry_run = cfg.dry_run
export_as_hardlink = cfg.export_as_hardlink
touch_file = cfg.touch_file
@@ -1714,6 +1728,7 @@ def export(
dependent_options = [
("missing", ("download_missing", "use_photos_export")),
("jpeg_quality", ("convert_to_jpeg")),
("ignore_signature", ("update")),
]
try:
cfg.validate(exclusive=exclusive_options, dependent=dependent_options, cli=True)
@@ -1932,6 +1947,7 @@ def export(
export_by_date=export_by_date,
sidecar=sidecar,
update=update,
ignore_signature=ignore_signature,
export_as_hardlink=export_as_hardlink,
overwrite=overwrite,
export_edited=export_edited,
@@ -1990,6 +2006,7 @@ def export(
export_by_date=export_by_date,
sidecar=sidecar,
update=update,
ignore_signature=ignore_signature,
export_as_hardlink=export_as_hardlink,
overwrite=overwrite,
export_edited=export_edited,
@@ -2560,6 +2577,7 @@ def export_photo(
export_by_date=None,
sidecar=None,
update=None,
ignore_signature=None,
export_as_hardlink=None,
overwrite=None,
export_edited=None,
@@ -2766,6 +2784,7 @@ def export_photo(
keyword_template=keyword_template,
description_template=description_template,
update=update,
ignore_signature=ignore_signature,
export_db=export_db,
fileutil=fileutil,
dry_run=dry_run,
@@ -2872,6 +2891,7 @@ def export_photo(
keyword_template=keyword_template,
description_template=description_template,
update=update,
ignore_signature=ignore_signature,
export_db=export_db,
fileutil=fileutil,
dry_run=dry_run,

View File

@@ -1,5 +1,5 @@
""" version info """
__version__ = "0.38.4"
__version__ = "0.38.5"

View File

@@ -285,7 +285,8 @@ def export(
when exporting metadata with exiftool or sidecar
keyword_template: (list of strings); list of template strings that will be rendered as used as keywords
description_template: string; optional template string that will be rendered for use as photo description
returns: list of photos exported
Returns: list of photos exported
"""
# Implementation note: calls export2 to actually do the work
@@ -333,6 +334,7 @@ def export2(
keyword_template=None,
description_template=None,
update=False,
ignore_signature=False,
export_db=None,
fileutil=FileUtil,
dry_run=False,
@@ -376,6 +378,7 @@ def export2(
description_template: string; optional template string that will be rendered for use as photo description
update: (boolean, default=False); if True export will run in update mode, that is, it will
not export the photo if the current version already exists in the destination
ignore_signature: (bool, default=False), ignore file signature when used with update (look only at filename)
export_db: (ExportDB_ABC); instance of a class that conforms to ExportDB_ABC with methods
for getting/setting data related to exported files to compare update state
fileutil: (FileUtilABC); class that conforms to FileUtilABC with various file utilities
@@ -606,6 +609,7 @@ def export2(
fileutil=fileutil,
edited=edited,
jpeg_quality=jpeg_quality,
ignore_signature=ignore_signature,
)
exported_files = results.exported
update_new_files = results.new
@@ -631,6 +635,7 @@ def export2(
touch_file,
False,
fileutil=fileutil,
ignore_signature=ignore_signature,
)
exported_files.extend(results.exported)
update_new_files.extend(results.new)
@@ -657,6 +662,7 @@ def export2(
convert_to_jpeg,
fileutil=fileutil,
jpeg_quality=jpeg_quality,
ignore_signature=ignore_signature,
)
exported_files.extend(results.exported)
update_new_files.extend(results.new)
@@ -963,6 +969,7 @@ def _export_photo(
fileutil=FileUtil,
edited=False,
jpeg_quality=1.0,
ignore_signature=None,
):
"""Helper function for export()
Does the actual copy or hardlink taking the appropriate
@@ -983,6 +990,7 @@ def _export_photo(
fileutil: FileUtil class that conforms to fileutil.FileUtilABC
edited: bool; set to True if exporting edited version of photo
jpeg_quality: float in range 0.0 <= jpeg_quality <= 1.0. A value of 1.0 specifies use best quality, a value of 0.0 specifies use maximum compression.
ignore_signature: bool, ignore file signature when used with update (look only at filename)
Returns:
ExportResults
@@ -1008,7 +1016,10 @@ def _export_photo(
cmp_touch, cmp_orig = False, False
if dest_exists:
# update, destination exists, but we might not need to replace it...
if exiftool:
if ignore_signature:
cmp_orig = True
cmp_touch = fileutil.cmp(src, dest, mtime1=int(self.date.timestamp()))
elif exiftool:
sig_exif = export_db.get_stat_exif_for_file(dest_str)
cmp_orig = fileutil.cmp_file_sig(dest_str, sig_exif)
sig_exif = (sig_exif[0], sig_exif[1], int(self.date.timestamp()))