diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 11dc6663..e60fbec2 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.42.41" +__version__ = "0.42.42" diff --git a/osxphotos/photoinfo/_photoinfo_export.py b/osxphotos/photoinfo/_photoinfo_export.py index c6d5160d..652570af 100644 --- a/osxphotos/photoinfo/_photoinfo_export.py +++ b/osxphotos/photoinfo/_photoinfo_export.py @@ -221,6 +221,7 @@ def _export_photo_uuid_applescript( timeout=120, burst=False, dry_run=False, + overwrite=False, ): """Export photo to dest path using applescript to control Photos If photo is a live photo, exports both the photo and associated .mov file @@ -300,6 +301,8 @@ def _export_photo_uuid_applescript( # use the name Photos provided dest_new = dest / path.name if not dry_run: + if overwrite and dest_new.exists(): + FileUtil.unlink(dest_new) FileUtil.copy(str(path), str(dest_new)) exported_paths.append(str(dest_new)) return exported_paths @@ -1194,6 +1197,7 @@ def _export_photo_with_photos_export( timeout=timeout, burst=self.burst, dry_run=dry_run, + overwrite=overwrite, ) all_results.exported.extend(exported) except ExportError as e: @@ -1244,6 +1248,7 @@ def _export_photo_with_photos_export( timeout=timeout, burst=self.burst, dry_run=dry_run, + overwrite=overwrite, ) all_results.exported.extend(exported) except ExportError as e: diff --git a/tests/test_cli.py b/tests/test_cli.py index 4a5f4970..32cca43a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -40,6 +40,8 @@ UUID_BURST_ALBUM = { ], } +UUID_DOWNLOAD_MISSING = "C6C712C5-9316-408D-A3C3-125661422DA9" # IMG_8844.JPG + UUID_FILE = "tests/uuid_from_file.txt" CLI_OUTPUT_NO_SUBCOMMAND = [ @@ -5933,6 +5935,55 @@ def test_export_burst_folder_album(): assert sorted(files) == sorted(UUID_BURST_ALBUM[uuid]) +@pytest.mark.skipif( + "OSXPHOTOS_TEST_EXPORT" not in os.environ, + reason="Skip if not running on author's personal library.", +) +def test_export_download_missing_file_exists(): + """test --download-missing with file exists and --update, issue #456""" + import glob + import os + import os.path + import pathlib + from osxphotos.cli 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_RHET), + ".", + "-V", + "--uuid", + UUID_DOWNLOAD_MISSING, + "--download-missing", + "--use-photos-export", + ], + ) + assert result.exit_code == 0 + + # export again with --update + result = runner.invoke( + export, + [ + os.path.join(cwd, PHOTOS_DB_RHET), + ".", + "-V", + "--uuid", + UUID_DOWNLOAD_MISSING, + "--download-missing", + "--use-photos-export", + "--update", + ], + ) + assert result.exit_code == 0 + assert "exported: 1" in result.output + + def test_query_name(): """test query --name""" import json @@ -6446,7 +6497,7 @@ def test_export_post_command_bad_command(): def test_export_directory_template_function(): - """Test --directory with template function """ + """Test --directory with template function""" import os.path import pathlib from osxphotos.cli import cli @@ -6456,7 +6507,7 @@ def test_export_directory_template_function(): # pylint: disable=not-context-manager with runner.isolated_filesystem(): with open("foo.py", "w") as f: - f.writelines(["def foo(photo, **kwargs):\n"," return 'foo/bar'"]) + f.writelines(["def foo(photo, **kwargs):\n", " return 'foo/bar'"]) tempdir = os.getcwd() result = runner.invoke( @@ -6470,9 +6521,8 @@ def test_export_directory_template_function(): "--uuid", CLI_EXPORT_UUID, "--directory", - "{function:"+f"{tempdir}" + "/foo.py::foo}" + "{function:" + f"{tempdir}" + "/foo.py::foo}", ], ) assert result.exit_code == 0 assert pathlib.Path(f"foo/bar/{CLI_EXPORT_UUID_FILENAME}").is_file() -