diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 57551021..e2def294 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.41.2" +__version__ = "0.41.3" diff --git a/osxphotos/cli.py b/osxphotos/cli.py index 7faf6d00..2f1376a5 100644 --- a/osxphotos/cli.py +++ b/osxphotos/cli.py @@ -1509,10 +1509,14 @@ def export( + [str(pathlib.Path(export_db_path).resolve())] ) click.echo(f"Cleaning up {dest}") - (cleaned_files, cleaned_dirs) = cleanup_files(dest, all_files, fileutil) - file_str = "files" if cleaned_files != 1 else "file" - dir_str = "directories" if cleaned_dirs != 1 else "directory" - click.echo(f"Deleted: {cleaned_files} {file_str}, {cleaned_dirs} {dir_str}") + cleaned_files, cleaned_dirs = cleanup_files(dest, all_files, fileutil) + file_str = "files" if len(cleaned_files) != 1 else "file" + dir_str = "directories" if len(cleaned_dirs) != 1 else "directory" + click.echo( + f"Deleted: {len(cleaned_files)} {file_str}, {len(cleaned_dirs)} {dir_str}" + ) + results.deleted_files = cleaned_files + results.deleted_directories = cleaned_dirs if report: verbose_(f"Writing export report to {report}") @@ -2896,8 +2900,12 @@ def write_export_report(report_file, results): "exiftool_error": "", "extended_attributes_written": 0, "extended_attributes_skipped": 0, + "cleanup_deleted_file": 0, + "cleanup_deleted_directory": 0, } for result in results.all_files() + + results.deleted_files + + results.deleted_directories } for result in results.exported: @@ -2963,6 +2971,12 @@ def write_export_report(report_file, results): for result in results.xattr_skipped: all_results[result]["extended_attributes_skipped"] = 1 + for result in results.deleted_files: + all_results[result]["cleanup_deleted_file"] = 1 + + for result in results.deleted_directories: + all_results[result]["cleanup_deleted_directory"] = 1 + report_columns = [ "filename", "exported", @@ -2981,6 +2995,8 @@ def write_export_report(report_file, results): "exiftool_error", "extended_attributes_written", "extended_attributes_skipped", + "cleanup_deleted_file", + "cleanup_deleted_directory", ] try: @@ -3007,27 +3023,27 @@ def cleanup_files(dest_path, files_to_keep, fileutil): fileutile: FileUtil object Returns: - tuple of (number of files deleted, number of directories deleted) + tuple of (list of files deleted, list of directories deleted) """ keepers = {str(filename).lower(): 1 for filename in files_to_keep} - deleted_files = 0 + deleted_files = [] for p in pathlib.Path(dest_path).rglob("*"): path = str(p).lower() if p.is_file() and path not in keepers: verbose_(f"Deleting {p}") fileutil.unlink(p) - deleted_files += 1 + deleted_files.append(str(p)) # delete empty directories - deleted_dirs = 0 + deleted_dirs = [] for p in pathlib.Path(dest_path).rglob("*"): path = str(p).lower() # if directory and directory is empty if p.is_dir() and not next(p.iterdir(), False): verbose_(f"Deleting empty directory {p}") fileutil.rmdir(p) - deleted_dirs += 1 + deleted_dirs.append(str(p)) return (deleted_files, deleted_dirs) diff --git a/osxphotos/photoinfo/_photoinfo_export.py b/osxphotos/photoinfo/_photoinfo_export.py index e4ca1561..fb362cda 100644 --- a/osxphotos/photoinfo/_photoinfo_export.py +++ b/osxphotos/photoinfo/_photoinfo_export.py @@ -87,6 +87,8 @@ class ExportResults: exiftool_error=None, xattr_written=None, xattr_skipped=None, + deleted_files=None, + deleted_directories=None, ): self.exported = exported or [] self.new = new or [] @@ -107,6 +109,8 @@ class ExportResults: self.exiftool_error = exiftool_error or [] self.xattr_written = xattr_written or [] self.xattr_skipped = xattr_skipped or [] + self.deleted_files = deleted_files or [] + self.deleted_directories = deleted_directories or [] def all_files(self): """ return all filenames contained in results """ @@ -151,6 +155,8 @@ class ExportResults: self.error += other.error self.exiftool_warning += other.exiftool_warning self.exiftool_error += other.exiftool_error + self.deleted_files += other.deleted_files + self.deleted_directories += other.deleted_directories return self def __str__(self): @@ -173,6 +179,8 @@ class ExportResults: + f",error={self.error}" + f",exiftool_warning={self.exiftool_warning}" + f",exiftool_error={self.exiftool_error}" + + f",deleted_files={self.deleted_files}" + + f",deleted_directories={self.deleted_directories}" + ")" ) diff --git a/tests/search_info_test_data_10_15_7.json b/tests/search_info_test_data_10_15_7.json index 291a2b7a..5f70e54c 100644 --- a/tests/search_info_test_data_10_15_7.json +++ b/tests/search_info_test_data_10_15_7.json @@ -1 +1 @@ -{"UUID_SEARCH_INFO": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["Food", "Butter"], "place_names": ["Durham Bulls Athletic Park"], "streets": ["Blackwell St"], "neighborhoods": ["American Tobacco District", "Downtown Durham"], "city": "Durham", "locality_names": ["Durham"], "state": "North Carolina", "state_abbreviation": "NC", "country": "United States", "bodies_of_water": [], "month": "October", "year": "2018", "holidays": [], "activities": ["Entertainment", "Travel", "Dining", "Dinner", "Trip"], "season": "Fall", "venues": ["Luna Rotisserie and Empanadas", "Copa", "The Pinhook", "Pie Pushers"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Desert", "Land", "Outdoor", "Sky", "Sunset Sunrise"], "place_names": ["Royal Palms State Beach"], "streets": [], "neighborhoods": ["San Pedro"], "city": "Los Angeles", "locality_names": [], "state": "California", "state_abbreviation": "", "country": "United States", "bodies_of_water": ["Catalina Channel"], "month": "November", "year": "2017", "holidays": [], "activities": ["Beach Activity", "Activity"], "season": "Fall", "venues": [], "venue_types": [], "media_types": ["Live Photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["Forest", "People", "Vegetation", "Outdoor", "Land", "Water", "Water Body", "Furniture", "Bench"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "December", "year": "2014", "holidays": ["Christmas Day"], "activities": ["Celebration", "Holiday"], "season": "Winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["food", "butter"], "place_names": ["durham bulls athletic park"], "streets": ["blackwell st"], "neighborhoods": ["american tobacco district", "downtown durham"], "city": "durham", "locality_names": ["durham"], "state": "north carolina", "state_abbreviation": "nc", "country": "united states", "bodies_of_water": [], "month": "october", "year": "2018", "holidays": [], "activities": ["entertainment", "travel", "dining", "dinner", "trip"], "season": "fall", "venues": ["luna rotisserie and empanadas", "copa", "the pinhook", "pie pushers"], "venue_types": [], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["desert", "land", "outdoor", "sky", "sunset sunrise"], "place_names": ["royal palms state beach"], "streets": [], "neighborhoods": ["san pedro"], "city": "los angeles", "locality_names": [], "state": "california", "state_abbreviation": "", "country": "united states", "bodies_of_water": ["catalina channel"], "month": "november", "year": "2017", "holidays": [], "activities": ["beach activity", "activity"], "season": "fall", "venues": [], "venue_types": [], "media_types": ["live photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["forest", "people", "vegetation", "outdoor", "land", "water", "water body", "furniture", "bench"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "december", "year": "2014", "holidays": ["christmas day"], "activities": ["celebration", "holiday"], "season": "winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_ALL": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["Food", "Butter", "Durham Bulls Athletic Park", "Blackwell St", "American Tobacco District", "Downtown Durham", "Durham", "Entertainment", "Travel", "Dining", "Dinner", "Trip", "Luna Rotisserie and Empanadas", "Copa", "The Pinhook", "Pie Pushers", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Desert", "Land", "Outdoor", "Sky", "Sunset Sunrise", "Royal Palms State Beach", "San Pedro", "Catalina Channel", "Beach Activity", "Activity", "Live Photos", "Los Angeles", "California", "United States", "November", "2017", "Fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["Forest", "People", "Vegetation", "Outdoor", "Land", "Water", "Water Body", "Furniture", "Bench", "Christmas Day", "Celebration", "Holiday", "December", "2014", "Winter"]}, "UUID_SEARCH_INFO_ALL_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["food", "butter", "durham bulls athletic park", "blackwell st", "american tobacco district", "downtown durham", "durham", "entertainment", "travel", "dining", "dinner", "trip", "luna rotisserie and empanadas", "copa", "the pinhook", "pie pushers", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["desert", "land", "outdoor", "sky", "sunset sunrise", "royal palms state beach", "san pedro", "catalina channel", "beach activity", "activity", "live photos", "los angeles", "california", "united states", "november", "2017", "fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["forest", "people", "vegetation", "outdoor", "land", "water", "water body", "furniture", "bench", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} +{"UUID_SEARCH_INFO": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["Butter", "Food"], "place_names": ["Durham Bulls Athletic Park"], "streets": ["Blackwell St"], "neighborhoods": ["American Tobacco District", "Downtown Durham"], "city": "Durham", "locality_names": ["Durham"], "state": "North Carolina", "state_abbreviation": "NC", "country": "United States", "bodies_of_water": [], "month": "October", "year": "2018", "holidays": [], "activities": ["Dinner", "Travel", "Entertainment", "Dining", "Trip"], "season": "Fall", "venues": ["Copa", "Pie Pushers", "The Pinhook", "Luna Rotisserie and Empanadas"], "venue_types": ["Cocktail Bar", "Nightlife", "Pizza", "Restaurant", "Bar", "Tapas & Small Plates", "Food", "Empanadas", "Chicken Wings", "Arts & Entertainment", "Latin American", "Cuban", "Music Venue"], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["Desert", "Sky", "Sunset Sunrise", "Outdoor", "Land"], "place_names": ["Royal Palms State Beach"], "streets": [], "neighborhoods": ["San Pedro"], "city": "Los Angeles", "locality_names": [], "state": "California", "state_abbreviation": "", "country": "United States", "bodies_of_water": ["Catalina Channel"], "month": "November", "year": "2017", "holidays": [], "activities": ["Beach Activity", "Activity"], "season": "Fall", "venues": [], "venue_types": [], "media_types": ["Live Photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["Bench", "Forest", "Water Body", "Water", "People", "Land", "Plant", "Outdoor", "Vegetation", "Furniture"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "December", "year": "2014", "holidays": ["Christmas Day"], "activities": ["Celebration", "Holiday"], "season": "Winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": {"labels": ["butter", "food"], "place_names": ["durham bulls athletic park"], "streets": ["blackwell st"], "neighborhoods": ["american tobacco district", "downtown durham"], "city": "durham", "locality_names": ["durham"], "state": "north carolina", "state_abbreviation": "nc", "country": "united states", "bodies_of_water": [], "month": "october", "year": "2018", "holidays": [], "activities": ["dinner", "travel", "entertainment", "dining", "trip"], "season": "fall", "venues": ["copa", "pie pushers", "the pinhook", "luna rotisserie and empanadas"], "venue_types": ["cocktail bar", "nightlife", "pizza", "restaurant", "bar", "tapas & small plates", "food", "empanadas", "chicken wings", "arts & entertainment", "latin american", "cuban", "music venue"], "media_types": []}, "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": {"labels": ["desert", "sky", "sunset sunrise", "outdoor", "land"], "place_names": ["royal palms state beach"], "streets": [], "neighborhoods": ["san pedro"], "city": "los angeles", "locality_names": [], "state": "california", "state_abbreviation": "", "country": "united states", "bodies_of_water": ["catalina channel"], "month": "november", "year": "2017", "holidays": [], "activities": ["beach activity", "activity"], "season": "fall", "venues": [], "venue_types": [], "media_types": ["live photos"]}, "2C151013-5BBA-4D00-B70F-1C9420418B86": {"labels": ["bench", "forest", "water body", "water", "people", "land", "plant", "outdoor", "vegetation", "furniture"], "place_names": [], "streets": [], "neighborhoods": [], "city": "", "locality_names": [], "state": "", "state_abbreviation": "", "country": "", "bodies_of_water": [], "month": "december", "year": "2014", "holidays": ["christmas day"], "activities": ["celebration", "holiday"], "season": "winter", "venues": [], "venue_types": [], "media_types": []}}, "UUID_SEARCH_INFO_ALL": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["Butter", "Food", "Durham Bulls Athletic Park", "Blackwell St", "American Tobacco District", "Downtown Durham", "Durham", "Dinner", "Travel", "Entertainment", "Dining", "Trip", "Copa", "Pie Pushers", "The Pinhook", "Luna Rotisserie and Empanadas", "Cocktail Bar", "Nightlife", "Pizza", "Restaurant", "Bar", "Tapas & Small Plates", "Food", "Empanadas", "Chicken Wings", "Arts & Entertainment", "Latin American", "Cuban", "Music Venue", "Durham", "North Carolina", "NC", "United States", "October", "2018", "Fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["Desert", "Sky", "Sunset Sunrise", "Outdoor", "Land", "Royal Palms State Beach", "San Pedro", "Catalina Channel", "Beach Activity", "Activity", "Live Photos", "Los Angeles", "California", "United States", "November", "2017", "Fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["Bench", "Forest", "Water Body", "Water", "People", "Land", "Plant", "Outdoor", "Vegetation", "Furniture", "Christmas Day", "Celebration", "Holiday", "December", "2014", "Winter"]}, "UUID_SEARCH_INFO_ALL_NORMALIZED": {"C8EAF50A-D891-4E0C-8086-C417E1284153": ["butter", "food", "durham bulls athletic park", "blackwell st", "american tobacco district", "downtown durham", "durham", "dinner", "travel", "entertainment", "dining", "trip", "copa", "pie pushers", "the pinhook", "luna rotisserie and empanadas", "cocktail bar", "nightlife", "pizza", "restaurant", "bar", "tapas & small plates", "food", "empanadas", "chicken wings", "arts & entertainment", "latin american", "cuban", "music venue", "durham", "north carolina", "nc", "united states", "october", "2018", "fall"], "71DFB4C3-E868-4BE4-906E-D96BD8692D7E": ["desert", "sky", "sunset sunrise", "outdoor", "land", "royal palms state beach", "san pedro", "catalina channel", "beach activity", "activity", "live photos", "los angeles", "california", "united states", "november", "2017", "fall"], "2C151013-5BBA-4D00-B70F-1C9420418B86": ["bench", "forest", "water body", "water", "people", "land", "plant", "outdoor", "vegetation", "furniture", "christmas day", "celebration", "holiday", "december", "2014", "winter"]}} diff --git a/tests/test_export_catalina_10_15_7_use_photos_export.py b/tests/test_export_catalina_10_15_7_use_photos_export.py index a39f07bc..e9479b20 100644 --- a/tests/test_export_catalina_10_15_7_use_photos_export.py +++ b/tests/test_export_catalina_10_15_7_use_photos_export.py @@ -29,7 +29,7 @@ def test_export_default_name(photosdb): # test basic export # get an unedited image and export it using default filename import os - import os.path + import pathlib import tempfile import osxphotos @@ -38,11 +38,12 @@ def test_export_default_name(photosdb): dest = tempdir.name photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]]) - filename = photos[0].filename - expected_dest = os.path.join(dest, filename) + filename = photos[0].original_filename + expected_dest = pathlib.Path(dest) / filename + expected_dest = expected_dest.parent / f"{expected_dest.stem}.jpeg" got_dest = photos[0].export(dest, use_photos_export=True)[0] - assert got_dest == expected_dest + assert got_dest == str(expected_dest) assert os.path.isfile(got_dest) @@ -82,7 +83,7 @@ def test_export_edited(photosdb): photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]]) suffix = pathlib.Path(photos[0].path_edited).suffix - filename = f"{pathlib.Path(photos[0].filename).stem}_edited{suffix}" + filename = f"{pathlib.Path(photos[0].original_filename).stem}_edited{suffix}" expected_dest = os.path.join(dest, filename) got_dest = photos[0].export(dest, use_photos_export=True, edited=True)[0] diff --git a/tests/test_export_convert_to_jpeg.py b/tests/test_export_convert_to_jpeg.py index ff43bd79..ebf981e2 100644 --- a/tests/test_export_convert_to_jpeg.py +++ b/tests/test_export_convert_to_jpeg.py @@ -16,14 +16,14 @@ UUID_DICT = { } NAMES_DICT = { - "raw": "D05A5FE3-15FB-49A1-A15D-AB3DA6F8B068.jpeg", - "heic": "7783E8E6-9CAC-40F3-BE22-81FB7051C266.jpeg", + "raw": "DSC03584.jpeg", + "heic": "IMG_3092.jpeg" } UUID_LIVE_HEIC = "612CE30B-3D8F-417A-9B14-EC42CBA10ACC" NAMES_LIVE_HEIC = [ - "612CE30B-3D8F-417A-9B14-EC42CBA10ACC.jpeg", - "612CE30B-3D8F-417A-9B14-EC42CBA10ACC.mov", + "IMG_3259.jpeg", + "IMG_3259.mov" ] diff --git a/tests/test_exportresults.py b/tests/test_exportresults.py index 41e8c1fb..58e113b9 100644 --- a/tests/test_exportresults.py +++ b/tests/test_exportresults.py @@ -21,6 +21,8 @@ EXPORT_RESULT_ATTRIBUTES = [ "error", "exiftool_warning", "exiftool_error", + "deleted_files", + "deleted_directories", ] @@ -43,6 +45,8 @@ def test_exportresults_init(): assert results.error == [] assert results.exiftool_warning == [] assert results.exiftool_error == [] + assert results.deleted_files == [] + assert results.deleted_directories == [] def test_exportresults_iadd(): @@ -64,6 +68,12 @@ def test_exportresults_iadd(): results1.exiftool_error = [("exiftool_error1", "foo")] results2.exiftool_error = [("exiftool_error2", "bar")] + results1.deleted_files = [("foo1")] + results2.deleted_files = [("foo2")] + + results1.deleted_directories = [("bar1")] + results2.deleted_directories = [("bar2")] + results1 += results2 assert results1.exiftool_warning == [ @@ -75,6 +85,9 @@ def test_exportresults_iadd(): ("exiftool_error2", "bar"), ] + assert results1.deleted_files == ["foo1", "foo2"] + assert results1.deleted_directories == ["bar1", "bar2"] + def test_all_files(): """ test ExportResults.all_files() """ @@ -84,10 +97,12 @@ def test_all_files(): results.exiftool_warning = [("exiftool_warning1", "foo")] results.exiftool_error = [("exiftool_error1", "foo")] results.error = [("error1", "foo")] + results.deleted_files = ["deleted_files1"] + results.deleted_directories = ["deleted_directories1"] - assert sorted(results.all_files()) == sorted( - [f"{x}1" for x in EXPORT_RESULT_ATTRIBUTES] - ) + assert sorted( + results.all_files() + results.deleted_files + results.deleted_directories + ) == sorted([f"{x}1" for x in EXPORT_RESULT_ATTRIBUTES]) def test_str(): @@ -95,6 +110,6 @@ def test_str(): results = ExportResults() assert ( str(results) - == "ExportResults(exported=[],new=[],updated=[],skipped=[],exif_updated=[],touched=[],converted_to_jpeg=[],sidecar_json_written=[],sidecar_json_skipped=[],sidecar_exiftool_written=[],sidecar_exiftool_skipped=[],sidecar_xmp_written=[],sidecar_xmp_skipped=[],missing=[],error=[],exiftool_warning=[],exiftool_error=[])" + == "ExportResults(exported=[],new=[],updated=[],skipped=[],exif_updated=[],touched=[],converted_to_jpeg=[],sidecar_json_written=[],sidecar_json_skipped=[],sidecar_exiftool_written=[],sidecar_exiftool_skipped=[],sidecar_xmp_written=[],sidecar_xmp_skipped=[],missing=[],error=[],exiftool_warning=[],exiftool_error=[],deleted_files=[],deleted_directories=[])" )