diff --git a/README.md b/README.md index 926aa873..2be6c83b 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,15 @@ Options: Deleted' folder. --update Only export new or updated files. See notes below on export and --update. + --ignore-signature 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. --dry-run Dry run (test) the export but don't actually export any files; most useful with --verbose. @@ -439,7 +448,10 @@ the export folder. If a file is changed in the export folder (for example, you edited the 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. +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 withsubsequent --update, +use --ignore-signature which will match filename but not file signature when +exporting. Note: The number of files reported for export and the number actually exported may differ due to live photos, associated raw images, and edited photos which diff --git a/osxphotos/__main__.py b/osxphotos/__main__.py index b26cd84f..fbe2f2a1 100644 --- a/osxphotos/__main__.py +++ b/osxphotos/__main__.py @@ -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, diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 9a344e50..7be53fc7 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,5 +1,5 @@ """ version info """ -__version__ = "0.38.4" +__version__ = "0.38.5" diff --git a/osxphotos/photoinfo/_photoinfo_export.py b/osxphotos/photoinfo/_photoinfo_export.py index 1d4974f5..da58fbd3 100644 --- a/osxphotos/photoinfo/_photoinfo_export.py +++ b/osxphotos/photoinfo/_photoinfo_export.py @@ -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())) diff --git a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite index c79bbeca..87846fe6 100644 Binary files a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite and b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite differ diff --git a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-shm b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-shm index 289453e7..a51adeee 100644 Binary files a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-shm and b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-shm differ diff --git a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-wal b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-wal index 7e30fe57..e8e8707e 100644 Binary files a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-wal and b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite-wal differ diff --git a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite.lock b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite.lock index f36aa599..0bdc3788 100644 --- a/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite.lock +++ b/tests/Test-10.15.7.photoslibrary/database/Photos.sqlite.lock @@ -7,7 +7,7 @@ hostuuid 9575E48B-8D5F-5654-ABAC-4431B1167324 pid - 464 + 485 processname photolibraryd uid diff --git a/tests/Test-10.15.7.photoslibrary/database/search/psi.sqlite b/tests/Test-10.15.7.photoslibrary/database/search/psi.sqlite index 9d06d36a..c1637828 100644 Binary files a/tests/Test-10.15.7.photoslibrary/database/search/psi.sqlite and b/tests/Test-10.15.7.photoslibrary/database/search/psi.sqlite differ diff --git a/tests/Test-10.15.7.photoslibrary/originals/2/2CE332F2-D578-4769-AEFA-7631BB77AA41.mp4 b/tests/Test-10.15.7.photoslibrary/originals/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3.mp4 similarity index 100% rename from tests/Test-10.15.7.photoslibrary/originals/2/2CE332F2-D578-4769-AEFA-7631BB77AA41.mp4 rename to tests/Test-10.15.7.photoslibrary/originals/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3.mp4 diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-shm b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-shm index 0faab6dd..67ccc9bf 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-shm and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-shm differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-wal b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-wal index 2c0c5ec7..d9e5a097 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-wal and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.POI.sqlite-wal differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.ROI.sqlite-shm b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.ROI.sqlite-shm index 7a377b0e..dbbe086d 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.ROI.sqlite-shm and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSBusinessCategoryCache.ROI.sqlite-shm differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSLocationCache.sqlite-shm b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSLocationCache.sqlite-shm index 14dd2830..6b157f88 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSLocationCache.sqlite-shm and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/CLSLocationCache.sqlite-shm differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-shm b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-shm index 11a25db2..b851287e 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-shm and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-shm differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-wal b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-wal index 88684e24..bc43af9d 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-wal and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGCurationCache.sqlite.sqlite-wal differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGSearchComputationCache.plist b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGSearchComputationCache.plist index a908128c..34c963ba 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGSearchComputationCache.plist and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PGSearchComputationCache.plist differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotoAnalysisServicePreferences.plist b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotoAnalysisServicePreferences.plist index c4cf5f46..0c8b569e 100644 --- a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotoAnalysisServicePreferences.plist +++ b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotoAnalysisServicePreferences.plist @@ -3,24 +3,24 @@ BackgroundHighlightCollection - 2020-10-17T23:45:25Z + 2020-12-16T05:41:43Z BackgroundHighlightEnrichment - 2020-10-17T23:45:25Z + 2020-12-16T05:41:42Z BackgroundJobAssetRevGeocode - 2020-10-17T23:45:25Z + 2020-12-16T05:41:43Z BackgroundJobSearch - 2020-10-17T23:45:25Z + 2020-12-16T05:41:43Z BackgroundPeopleSuggestion - 2020-10-17T23:45:25Z + 2020-12-16T05:41:41Z BackgroundUserBehaviorProcessor - 2020-10-17T23:45:25Z + 2020-12-16T05:41:43Z PhotoAnalysisGraphLastBackgroundGraphConsistencyUpdateJobDateKey 2020-10-17T23:45:33Z PhotoAnalysisGraphLastBackgroundGraphRebuildJobDate 2020-10-17T23:45:24Z PhotoAnalysisGraphLastBackgroundMemoryGenerationJobDate - 2020-10-17T23:45:26Z + 2020-12-16T05:41:44Z SiriPortraitDonation - 2020-10-17T23:45:25Z + 2020-12-16T05:41:43Z diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotosGraph/photosgraph.kgdb b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotosGraph/photosgraph.kgdb index 10a7c95f..34f3fc41 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotosGraph/photosgraph.kgdb and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/PhotosGraph/photosgraph.kgdb differ diff --git a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/changetoken.plist b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/changetoken.plist index 13b3a1e5..1a02b725 100644 Binary files a/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/changetoken.plist and b/tests/Test-10.15.7.photoslibrary/private/com.apple.photoanalysisd/caches/graph/changetoken.plist differ diff --git a/tests/Test-10.15.7.photoslibrary/resources/derivatives/2/2CE332F2-D578-4769-AEFA-7631BB77AA41.THM b/tests/Test-10.15.7.photoslibrary/resources/derivatives/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3.THM similarity index 100% rename from tests/Test-10.15.7.photoslibrary/resources/derivatives/2/2CE332F2-D578-4769-AEFA-7631BB77AA41.THM rename to tests/Test-10.15.7.photoslibrary/resources/derivatives/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3.THM diff --git a/tests/Test-10.15.7.photoslibrary/resources/derivatives/2/2CE332F2-D578-4769-AEFA-7631BB77AA41_1_102_o.jpeg b/tests/Test-10.15.7.photoslibrary/resources/derivatives/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3_1_102_o.jpeg similarity index 100% rename from tests/Test-10.15.7.photoslibrary/resources/derivatives/2/2CE332F2-D578-4769-AEFA-7631BB77AA41_1_102_o.jpeg rename to tests/Test-10.15.7.photoslibrary/resources/derivatives/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3_1_102_o.jpeg diff --git a/tests/Test-10.15.7.photoslibrary/resources/derivatives/2/2CE332F2-D578-4769-AEFA-7631BB77AA41_1_105_c.jpeg b/tests/Test-10.15.7.photoslibrary/resources/derivatives/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3_1_105_c.jpeg similarity index 100% rename from tests/Test-10.15.7.photoslibrary/resources/derivatives/2/2CE332F2-D578-4769-AEFA-7631BB77AA41_1_105_c.jpeg rename to tests/Test-10.15.7.photoslibrary/resources/derivatives/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3_1_105_c.jpeg diff --git a/tests/Test-10.15.7.photoslibrary/resources/derivatives/masters/2/2CE332F2-D578-4769-AEFA-7631BB77AA41_4_5005_c.jpeg b/tests/Test-10.15.7.photoslibrary/resources/derivatives/masters/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3_4_5005_c.jpeg similarity index 100% rename from tests/Test-10.15.7.photoslibrary/resources/derivatives/masters/2/2CE332F2-D578-4769-AEFA-7631BB77AA41_4_5005_c.jpeg rename to tests/Test-10.15.7.photoslibrary/resources/derivatives/masters/D/D1359D09-1373-4F3B-B0E3-1A4DE573E4A3_4_5005_c.jpeg diff --git a/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/3305.ithmb b/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/3305.ithmb index 43bde3fa..9cb4e8aa 100644 Binary files a/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/3305.ithmb and b/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/3305.ithmb differ diff --git a/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4031.ithmb b/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4031.ithmb index 5fd64a61..9facb58f 100644 Binary files a/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4031.ithmb and b/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4031.ithmb differ diff --git a/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4132.ithmb b/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4132.ithmb index 9756ac08..9063f25e 100644 Binary files a/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4132.ithmb and b/tests/Test-10.15.7.photoslibrary/resources/derivatives/thumbs/4132.ithmb differ diff --git a/tests/Test-10.15.7.photoslibrary/resources/journals/Asset-change.plj b/tests/Test-10.15.7.photoslibrary/resources/journals/Asset-change.plj index 22ddaffe..a199b705 100644 Binary files a/tests/Test-10.15.7.photoslibrary/resources/journals/Asset-change.plj and b/tests/Test-10.15.7.photoslibrary/resources/journals/Asset-change.plj differ diff --git a/tests/Test-10.15.7.photoslibrary/resources/journals/HistoryToken.plist b/tests/Test-10.15.7.photoslibrary/resources/journals/HistoryToken.plist index ea0ac84b..683ebaa7 100644 Binary files a/tests/Test-10.15.7.photoslibrary/resources/journals/HistoryToken.plist and b/tests/Test-10.15.7.photoslibrary/resources/journals/HistoryToken.plist differ diff --git a/tests/Test-10.15.7.photoslibrary/resources/journals/ImportSession-change.plj b/tests/Test-10.15.7.photoslibrary/resources/journals/ImportSession-change.plj index 94fce56a..fc0ca6b4 100644 Binary files a/tests/Test-10.15.7.photoslibrary/resources/journals/ImportSession-change.plj and b/tests/Test-10.15.7.photoslibrary/resources/journals/ImportSession-change.plj differ diff --git a/tests/test_catalina_10_15_7.py b/tests/test_catalina_10_15_7.py index c75ac4db..f9b57017 100644 --- a/tests/test_catalina_10_15_7.py +++ b/tests/test_catalina_10_15_7.py @@ -21,7 +21,7 @@ PHOTOS_LIBRARY_PATH = "/Test-10.15.7.photoslibrary" PHOTOS_DB_LEN = 18 PHOTOS_NOT_IN_TRASH_LEN = 16 PHOTOS_IN_TRASH_LEN = 2 -PHOTOS_DB_IMPORT_SESSIONS = 12 +PHOTOS_DB_IMPORT_SESSIONS = 13 KEYWORDS = [ "Kids", @@ -93,7 +93,7 @@ UUID_DICT = { "not_intrash": "DC99FBDD-7A52-4100-A5BB-344131646C30", "intrash_person_keywords": "6FD38366-3BF2-407D-81FE-7153EB6125B6", "import_session": "8846E3E6-8AC8-4857-8448-E3D025784410", - "movie": "2CE332F2-D578-4769-AEFA-7631BB77AA41", + "movie": "D1359D09-1373-4F3B-B0E3-1A4DE573E4A3", } UUID_PUMPKIN_FARM = [ diff --git a/tests/test_cli.py b/tests/test_cli.py index 69ac1070..e12642fa 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -59,6 +59,8 @@ CLI_EXPORT_FILENAMES = [ "wedding_edited.jpeg", ] +CLI_EXPORT_IGNORE_SIGNATURE_FILENAMES = ["Tulips.jpg", "wedding.jpg"] + CLI_EXPORT_FILENAMES_ALBUM = ["Pumkins1.jpg", "Pumkins2.jpg", "Pumpkins3.jpg"] CLI_EXPORT_FILENAMES_ALBUM_UNICODE = ["IMG_4547.jpg"] @@ -372,10 +374,10 @@ CLI_EXIFTOOL_QUICKTIME = { "QuickTime:CreateDate": "2020:01:05 22:13:13", "QuickTime:ModifyDate": "2020:01:05 22:13:13", }, - "2CE332F2-D578-4769-AEFA-7631BB77AA41": { - "File:FileName": "Jellyfish.mp4", + "D1359D09-1373-4F3B-B0E3-1A4DE573E4A3": { + "File:FileName": "Jellyfish1.mp4", "XMP:Description": "Jellyfish Video", - "XMP:Title": "Jellyfish", + "XMP:Title": "Jellyfish1", "XMP:TagsList": "Travel", "XMP:Subject": "Travel", "QuickTime:GPSCoordinates": "34.053345 -118.242349", @@ -516,6 +518,12 @@ UUID_NO_LIKES = [ ] +def modify_file(filename): + """ appends data to a file to modify it """ + with open(filename, "ab") as fd: + fd.write(b"foo") + + @pytest.fixture(autouse=True) def reset_globals(): """ reset globals in __main__ that tests may have changed """ @@ -3787,6 +3795,54 @@ def test_export_touch_files_exiftool_update(): assert "skipped: 18" in result.output +def test_export_ignore_signature(): + """ test export with --ignore-signature """ + from osxphotos.__main__ import export + + runner = CliRunner() + cwd = os.getcwd() + + # pylint: disable=not-context-manager + with runner.isolated_filesystem(): + # first, export some files + result = runner.invoke(export, [os.path.join(cwd, PHOTOS_DB_15_7), ".", "-V"]) + assert result.exit_code == 0 + + # modify a couple of files + for filename in CLI_EXPORT_IGNORE_SIGNATURE_FILENAMES: + modify_file(f"./{filename}") + + # export with --update and --ignore-signature + # which should ignore the two modified files + result = runner.invoke( + export, + [ + os.path.join(cwd, PHOTOS_DB_15_7), + ".", + "-V", + "--update", + "--ignore-signature", + ], + ) + assert result.exit_code == 0 + assert "exported: 0, updated: 0" in result.output + + # export with --update and not --ignore-signature + # which should updated the two modified files + result = runner.invoke( + export, [os.path.join(cwd, PHOTOS_DB_15_7), ".", "-V", "--update"] + ) + assert result.exit_code == 0 + assert "updated: 2" in result.output + + # run --update again, should be 0 files exported + result = runner.invoke( + export, [os.path.join(cwd, PHOTOS_DB_15_7), ".", "-V", "--update"] + ) + assert result.exit_code == 0 + assert "exported: 0, updated: 0" in result.output + + def test_labels(): """Test osxphotos labels """ import json