Feature add locations 929 (#932)
* Initial implementation of add-locations command #929 * Updated help for add-locations * Fixed handling of shared albums in sync * Added test for add-locations
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
""" pytest test configuration """
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
import photoscript
|
||||
import pytest
|
||||
@@ -21,6 +23,9 @@ TEST_IMPORT = False
|
||||
# run sync tests (configured with --test-sync)
|
||||
TEST_SYNC = False
|
||||
|
||||
# run add-locations tests (configured with --test-add-locations)
|
||||
TEST_ADD_LOCATIONS = False
|
||||
|
||||
# don't clean up crash logs (configured with --no-cleanup)
|
||||
NO_CLEANUP = False
|
||||
|
||||
@@ -51,11 +56,13 @@ if OS_VER == "15":
|
||||
TEST_LIBRARY_IMPORT = TEST_LIBRARY
|
||||
TEST_LIBRARY_SYNC = TEST_LIBRARY
|
||||
from tests.config_timewarp_catalina import TEST_LIBRARY_TIMEWARP
|
||||
|
||||
TEST_LIBRARY_ADD_LOCATIONS = None
|
||||
else:
|
||||
TEST_LIBRARY = None
|
||||
TEST_LIBRARY_TIMEWARP = None
|
||||
TEST_LIBRARY_SYNC = None
|
||||
# pytest.exit("This test suite currently only runs on MacOS Catalina ")
|
||||
TEST_LIBRARY_ADD_LOCATIONS = "tests/Test-13.0.0.photoslibrary"
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
@@ -79,6 +86,13 @@ def setup_photos_sync():
|
||||
copy_photos_library(TEST_LIBRARY_SYNC, delay=10)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def setup_photos_add_locations():
|
||||
if not TEST_ADD_LOCATIONS:
|
||||
return
|
||||
copy_photos_library(TEST_LIBRARY_ADD_LOCATIONS, delay=10)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_singletons():
|
||||
"""Need to clean up any ExifTool singletons between tests"""
|
||||
@@ -107,6 +121,12 @@ def pytest_addoption(parser):
|
||||
default=False,
|
||||
help="run `osxphotos sync` tests",
|
||||
)
|
||||
parser.addoption(
|
||||
"--test-add-locations",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="run `osxphotos add-locations` tests",
|
||||
)
|
||||
parser.addoption(
|
||||
"--no-cleanup",
|
||||
action="store_true",
|
||||
@@ -144,6 +164,10 @@ def pytest_configure(config):
|
||||
config.addinivalue_line(
|
||||
"markers", "test_sync: mark test as requiring --test-sync to run"
|
||||
)
|
||||
config.addinivalue_line(
|
||||
"markers",
|
||||
"test_add_locations: mark test as requiring --test-add-locations to run",
|
||||
)
|
||||
|
||||
# this is hacky but I can't figure out how to check config options in other fixtures
|
||||
if config.getoption("--timewarp"):
|
||||
@@ -158,6 +182,10 @@ def pytest_configure(config):
|
||||
global TEST_SYNC
|
||||
TEST_SYNC = True
|
||||
|
||||
if config.getoption("--test-add-locations"):
|
||||
global TEST_ADD_LOCATIONS
|
||||
TEST_ADD_LOCATIONS = True
|
||||
|
||||
if config.getoption("--no-cleanup"):
|
||||
global NO_CLEANUP
|
||||
NO_CLEANUP = True
|
||||
@@ -196,17 +224,25 @@ def pytest_collection_modifyitems(config, items):
|
||||
if "test_sync" in item.keywords:
|
||||
item.add_marker(skip_test_sync)
|
||||
|
||||
if not (
|
||||
config.getoption("--test-add-locations")
|
||||
and TEST_LIBRARY_ADD_LOCATIONS is not None
|
||||
):
|
||||
skip_test_sync = pytest.mark.skip(
|
||||
reason="need --test-add-locations option and MacOS Ventura to run"
|
||||
)
|
||||
for item in items:
|
||||
if "test_add_locations" in item.keywords:
|
||||
item.add_marker(skip_test_sync)
|
||||
|
||||
def copy_photos_library(photos_library, delay=0):
|
||||
|
||||
def copy_photos_library(photos_library, delay=0, open=True):
|
||||
"""copy the test library and open Photos, returns path to copied library"""
|
||||
script = AppleScript(
|
||||
"""
|
||||
tell application "Photos"
|
||||
quit
|
||||
end tell
|
||||
"""
|
||||
)
|
||||
script.run()
|
||||
|
||||
# quit Photos if it's running
|
||||
photoslib = photoscript.PhotosLibrary()
|
||||
photoslib.quit()
|
||||
|
||||
src = pathlib.Path(os.getcwd()) / photos_library
|
||||
picture_folder = (
|
||||
pathlib.Path(os.environ["PHOTOSCRIPT_PICTURES_FOLDER"])
|
||||
@@ -216,27 +252,34 @@ def copy_photos_library(photos_library, delay=0):
|
||||
picture_folder = picture_folder.expanduser()
|
||||
if not picture_folder.is_dir():
|
||||
pytest.exit(f"Invalid picture folder: '{picture_folder}'")
|
||||
dest = picture_folder / photos_library
|
||||
ditto(src, dest)
|
||||
script = AppleScript(
|
||||
f"""
|
||||
set tries to 0
|
||||
repeat while tries < 5
|
||||
try
|
||||
tell application "Photos"
|
||||
activate
|
||||
delay 3
|
||||
open POSIX file "{dest}"
|
||||
delay {delay}
|
||||
end tell
|
||||
set tries to 5
|
||||
on error
|
||||
set tries to tries + 1
|
||||
end try
|
||||
end repeat
|
||||
dest = picture_folder / pathlib.Path(photos_library).name
|
||||
|
||||
# copy src directory to dest directory, removing it if it already exists
|
||||
shutil.rmtree(str(dest), ignore_errors=True)
|
||||
|
||||
print(f"copying {src} to {picture_folder} ...")
|
||||
copyFolder = AppleScript(
|
||||
"""
|
||||
on copyFolder(sourceFolder, destinationFolder)
|
||||
-- sourceFolder and destinationFolder are strings of POSIX paths
|
||||
set sourceFolder to POSIX file sourceFolder
|
||||
set destinationFolder to POSIX file destinationFolder
|
||||
tell application "Finder"
|
||||
duplicate sourceFolder to destinationFolder
|
||||
end tell
|
||||
end copyFolder
|
||||
"""
|
||||
)
|
||||
script.run()
|
||||
copyFolder.call("copyFolder", str(src), str(picture_folder))
|
||||
|
||||
# open Photos
|
||||
if open:
|
||||
# sometimes doesn't open the first time
|
||||
time.sleep(delay)
|
||||
photoslib.open(str(dest))
|
||||
time.sleep(delay)
|
||||
photoslib.open(str(dest))
|
||||
|
||||
return dest
|
||||
|
||||
|
||||
|
||||
52
tests/test_cli_add_locations.py
Normal file
52
tests/test_cli_add_locations.py
Normal file
@@ -0,0 +1,52 @@
|
||||
"""Test osxphotos add-locations command"""
|
||||
|
||||
import photoscript
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
from osxphotos.cli.add_locations import add_locations
|
||||
|
||||
UUID_TEST_PHOTO_1 = "F12384F6-CD17-4151-ACBA-AE0E3688539E" # Pumkins1.jpg
|
||||
UUID_TEST_PHOTO_LOCATION = "D79B8D77-BFFC-460B-9312-034F2877D35B" # Pumkins2.jpg
|
||||
TEST_LOCATION = (41.26067, -95.94056) # Omaha, NE
|
||||
|
||||
|
||||
@pytest.mark.test_add_locations
|
||||
def test_add_locations():
|
||||
"""Test add-locations command"""
|
||||
|
||||
with CliRunner().isolated_filesystem():
|
||||
# need to clear location data from test photo
|
||||
test_photo = photoscript.Photo(UUID_TEST_PHOTO_1)
|
||||
test_photo.location = None
|
||||
source_photo = photoscript.Photo(UUID_TEST_PHOTO_LOCATION)
|
||||
source_photo.location = TEST_LOCATION
|
||||
|
||||
# now run add-locations
|
||||
result = CliRunner().invoke(
|
||||
add_locations,
|
||||
[
|
||||
"--window",
|
||||
"2 hours",
|
||||
"--dry-run",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
# should find 3 matching locations: Pumkins1.jpg, Pumpkins3.jpg, Pumpkins4.jpg
|
||||
assert "found location: 3" in result.output
|
||||
|
||||
# verify location not really added
|
||||
assert test_photo.location == (None, None)
|
||||
|
||||
# run again without dry-run
|
||||
result = CliRunner().invoke(
|
||||
add_locations,
|
||||
[
|
||||
"--window",
|
||||
"2 hours",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
# should find 3 matching locations: Pumkins1.jpg, Pumpkins3.jpg, Pumpkins4.jpg
|
||||
assert "found location: 3" in result.output
|
||||
assert test_photo.location == TEST_LOCATION
|
||||
Reference in New Issue
Block a user