Added --add-to-album to query
This commit is contained in:
@@ -1,3 +1,3 @@
|
|||||||
""" version info """
|
""" version info """
|
||||||
|
|
||||||
__version__ = "0.42.14"
|
__version__ = "0.42.15"
|
||||||
|
|||||||
@@ -1630,8 +1630,9 @@ def export(
|
|||||||
for filename in export_results.exported
|
for filename in export_results.exported
|
||||||
]
|
]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
click.echo(
|
click.secho(
|
||||||
f"Error adding photo {p.original_filename} ({p.uuid}) to album {album_export.name}: {e}",
|
f"Error adding photo {p.original_filename} ({p.uuid}) to album {album_export.name}: {e}",
|
||||||
|
fg=CLI_COLOR_ERROR,
|
||||||
err=True,
|
err=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1643,8 +1644,9 @@ def export(
|
|||||||
for filename in export_results.skipped
|
for filename in export_results.skipped
|
||||||
]
|
]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
click.echo(
|
click.secho(
|
||||||
f"Error adding photo {p.original_filename} ({p.uuid}) to album {album_skipped.name}: {e}",
|
f"Error adding photo {p.original_filename} ({p.uuid}) to album {album_skipped.name}: {e}",
|
||||||
|
fg=CLI_COLOR_ERROR,
|
||||||
err=True,
|
err=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1656,8 +1658,9 @@ def export(
|
|||||||
for filename in export_results.missing
|
for filename in export_results.missing
|
||||||
]
|
]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
click.echo(
|
click.secho(
|
||||||
f"Error adding photo {p.original_filename} ({p.uuid}) to album {album_missing.name}: {e}",
|
f"Error adding photo {p.original_filename} ({p.uuid}) to album {album_missing.name}: {e}",
|
||||||
|
fg=CLI_COLOR_ERROR,
|
||||||
err=True,
|
err=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1807,6 +1810,14 @@ def help(ctx, topic, **kw):
|
|||||||
is_flag=True,
|
is_flag=True,
|
||||||
help="Search for photos that are not in iCloud (have not been synched)",
|
help="Search for photos that are not in iCloud (have not been synched)",
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"--add-to-album",
|
||||||
|
metavar="ALBUM",
|
||||||
|
help="Add all photos from query to album ALBUM in Photos. Album ALBUM will be created "
|
||||||
|
"if it doesn't exist. All photos in the query results will be added to this album. "
|
||||||
|
"This only works if the Photos library being queried is the last-opened (default) library in Photos. "
|
||||||
|
"This feature is currently experimental. I don't know how well it will work on large query sets.",
|
||||||
|
)
|
||||||
@DB_ARGUMENT
|
@DB_ARGUMENT
|
||||||
@click.pass_obj
|
@click.pass_obj
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
@@ -1884,6 +1895,7 @@ def query(
|
|||||||
max_size,
|
max_size,
|
||||||
regex,
|
regex,
|
||||||
query_eval,
|
query_eval,
|
||||||
|
add_to_album,
|
||||||
):
|
):
|
||||||
"""Query the Photos database using 1 or more search options;
|
"""Query the Photos database using 1 or more search options;
|
||||||
if more than one option is provided, they are treated as "AND"
|
if more than one option is provided, they are treated as "AND"
|
||||||
@@ -2054,6 +2066,24 @@ def query(
|
|||||||
|
|
||||||
# below needed for to make CliRunner work for testing
|
# below needed for to make CliRunner work for testing
|
||||||
cli_json = cli_obj.json if cli_obj is not None else None
|
cli_json = cli_obj.json if cli_obj is not None else None
|
||||||
|
|
||||||
|
if add_to_album and photos:
|
||||||
|
album_query = PhotosAlbum(add_to_album, verbose=None)
|
||||||
|
photo_len = len(photos)
|
||||||
|
photo_word = "photos" if photo_len > 1 else "photo"
|
||||||
|
click.echo(
|
||||||
|
f"Adding {photo_len} {photo_word} to album '{album_query.name}'. Note: Photos may prompt you to confirm this action.",
|
||||||
|
err=True,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
album_query.add_list(photos)
|
||||||
|
except Exception as e:
|
||||||
|
click.secho(
|
||||||
|
f"Error adding photos to album {add_to_album}",
|
||||||
|
fg=CLI_COLOR_ERROR,
|
||||||
|
err=True,
|
||||||
|
)
|
||||||
|
|
||||||
print_photo_info(photos, cli_json or json_)
|
print_photo_info(photos, cli_json or json_)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
""" PhotosAlbum class to create an album in default Photos library and add photos to it """
|
""" PhotosAlbum class to create an album in default Photos library and add photos to it """
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional, List
|
||||||
import photoscript
|
import photoscript
|
||||||
from .photoinfo import PhotoInfo
|
from .photoinfo import PhotoInfo
|
||||||
from .utils import noop
|
from .utils import noop
|
||||||
@@ -25,50 +25,12 @@ class PhotosAlbum:
|
|||||||
f"Added {photo.original_filename} ({photo.uuid}) to album {self.name}"
|
f"Added {photo.original_filename} ({photo.uuid}) to album {self.name}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def add_list(self, photo_list: List[PhotoInfo]):
|
||||||
|
photos = [photoscript.Photo(p.uuid) for p in photo_list]
|
||||||
|
self.album.add(photos)
|
||||||
|
photo_len = len(photos)
|
||||||
|
photo_word = "photos" if photo_len > 1 else "photo"
|
||||||
|
self.verbose(f"Added {photo_len} {photo_word} to album {self.name}")
|
||||||
|
|
||||||
def photos(self):
|
def photos(self):
|
||||||
return self.album.photos()
|
return self.album.photos()
|
||||||
|
|
||||||
|
|
||||||
# def add_photo_to_album(photo, album_pairs, results):
|
|
||||||
# # todo: class PhotoAlbum
|
|
||||||
# # keeps a name, maintains state
|
|
||||||
# """ add photo to album(s) as defined in album_pairs
|
|
||||||
|
|
||||||
# Args:
|
|
||||||
# photo: PhotoInfo object
|
|
||||||
# album_pairs: list of tuples with [(album name, results_list)]
|
|
||||||
# results: ExportResults object
|
|
||||||
|
|
||||||
# Returns:
|
|
||||||
# updated ExportResults object
|
|
||||||
# """
|
|
||||||
# for album, result_list in album_pairs:
|
|
||||||
# try:
|
|
||||||
# if album_export is None:
|
|
||||||
# # first time fetching the album, see if it exists already
|
|
||||||
# album_export = photos_library.album(
|
|
||||||
# add_exported_to_album
|
|
||||||
# )
|
|
||||||
# if album_export is None:
|
|
||||||
# # album doesn't exist, so create it
|
|
||||||
# verbose_(
|
|
||||||
# f"Creating Photos album '{add_exported_to_album}'"
|
|
||||||
# )
|
|
||||||
# album_export = photos_library.create_album(
|
|
||||||
# add_exported_to_album
|
|
||||||
# )
|
|
||||||
# exported_photo = photoscript.Photo(p.uuid)
|
|
||||||
# album_export.add([exported_photo])
|
|
||||||
# verbose_(
|
|
||||||
# f"Added {p.original_filename} ({p.uuid}) to album {add_exported_to_album}"
|
|
||||||
# )
|
|
||||||
# exported_album = [
|
|
||||||
# (filename, add_exported_to_album)
|
|
||||||
# for filename in export_results.exported
|
|
||||||
# ]
|
|
||||||
# export_results.exported_album = exported_album
|
|
||||||
# if
|
|
||||||
# except Exception as e:
|
|
||||||
# click.echo(
|
|
||||||
# f"Error adding photo {p.original_filename} ({p.uuid}) to album {add_exported_to_album}"
|
|
||||||
# )
|
|
||||||
|
|||||||
@@ -90,3 +90,26 @@ def test_export_add_to_album(addalbum_library):
|
|||||||
got_uuids = [p.uuid for p in missing_album.photos()]
|
got_uuids = [p.uuid for p in missing_album.photos()]
|
||||||
assert sorted(got_uuids) == sorted(list(UUID_MISSING.keys()))
|
assert sorted(got_uuids) == sorted(list(UUID_MISSING.keys()))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.addalbum
|
||||||
|
def test_query_add_to_album(addalbum_library):
|
||||||
|
from osxphotos.cli import query
|
||||||
|
|
||||||
|
runner = CliRunner()
|
||||||
|
cwd = os.getcwd()
|
||||||
|
with runner.isolated_filesystem():
|
||||||
|
QUERY_ALBUM = "OSXPhotos Query"
|
||||||
|
|
||||||
|
uuid_opt = [f"--uuid={uuid}" for uuid in UUID_EXPORT]
|
||||||
|
|
||||||
|
result = runner.invoke(query, ["--add-to-album", QUERY_ALBUM, *uuid_opt])
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
photoslib = photoscript.PhotosLibrary()
|
||||||
|
album = photoslib.album(QUERY_ALBUM)
|
||||||
|
assert album is not None
|
||||||
|
|
||||||
|
assert len(album) == len(UUID_EXPORT)
|
||||||
|
got_uuids = [p.uuid for p in album.photos()]
|
||||||
|
assert sorted(got_uuids) == sorted(list(UUID_EXPORT.keys()))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user