Updated PhotosAlbum code
This commit is contained in:
@@ -214,7 +214,7 @@ def add_photo_to_albums(
|
||||
for a in albums:
|
||||
verbose(f"Adding photo [filename]{filepath.name}[/] to album [filepath]{a}[/]")
|
||||
photos_album = PhotosAlbumPhotoScript(
|
||||
a, verbose=verbose, split_folder=split_folder
|
||||
a, verbose=verbose, split_folder=split_folder, rich=True
|
||||
)
|
||||
photos_album.add(photo)
|
||||
|
||||
|
||||
@@ -12,45 +12,6 @@ from .utils import noop, pluralize
|
||||
__all__ = ["PhotosAlbum", "PhotosAlbumPhotoScript"]
|
||||
|
||||
|
||||
class PhotosAlbum:
|
||||
"""Add osxphotos.photoinfo.PhotoInfo objects to album"""
|
||||
|
||||
def __init__(self, name: str, verbose: Optional[callable] = None):
|
||||
self.name = name
|
||||
self.verbose = verbose or noop
|
||||
self.library = photoscript.PhotosLibrary()
|
||||
|
||||
album = self.library.album(name)
|
||||
if album is None:
|
||||
self.verbose(f"Creating Photos album '{self.name}'")
|
||||
album = self.library.create_album(name)
|
||||
self.album = album
|
||||
|
||||
def add(self, photo: PhotoInfo):
|
||||
photo_ = photoscript.Photo(photo.uuid)
|
||||
self.album.add([photo_])
|
||||
self.verbose(
|
||||
f"Added {photo.original_filename} ({photo.uuid}) to album {self.name}"
|
||||
)
|
||||
|
||||
def add_list(self, photo_list: List[PhotoInfo]):
|
||||
photos = []
|
||||
for p in photo_list:
|
||||
try:
|
||||
photos.append(photoscript.Photo(p.uuid))
|
||||
except Exception as e:
|
||||
self.verbose(f"Error creating Photo object for photo {p.uuid}: {e}")
|
||||
for photolist in chunked(photos, 10):
|
||||
self.album.add(photolist)
|
||||
photo_len = len(photo_list)
|
||||
self.verbose(
|
||||
f"Added {photo_len} {pluralize(photo_len, 'photo', 'photos')} to album {self.name}"
|
||||
)
|
||||
|
||||
def photos(self):
|
||||
return self.album.photos()
|
||||
|
||||
|
||||
def folder_by_path(folders: List[str], verbose: Optional[callable] = None) -> Folder:
|
||||
"""Get (and create if necessary) a Photos Folder by path (passed as list of folder names)"""
|
||||
library = PhotosLibrary()
|
||||
@@ -81,54 +42,105 @@ def album_by_path(
|
||||
album_name = folders_album.pop()
|
||||
folder = folder_by_path(folders_album, verbose)
|
||||
album = folder.album(album_name)
|
||||
if not album:
|
||||
if album is None:
|
||||
verbose(f"Creating album '{album_name}'")
|
||||
album = folder.create_album(album_name)
|
||||
else:
|
||||
# only have album name
|
||||
album_name = folders_album[0]
|
||||
album = library.album(album_name, top_level=True)
|
||||
if not album:
|
||||
if album is None:
|
||||
verbose(f"Creating album '{album_name}'")
|
||||
album = library.create_album(album_name)
|
||||
|
||||
return album
|
||||
|
||||
|
||||
class PhotosAlbumPhotoScript:
|
||||
"""Add photoscript.Photo objects to album"""
|
||||
class PhotosAlbum:
|
||||
"""Add osxphotos.photoinfo.PhotoInfo objects to album"""
|
||||
|
||||
def __init__(
|
||||
self, name: str, verbose: Optional[callable] = None, split_folder: Optional[str] = None
|
||||
self,
|
||||
name: str,
|
||||
verbose: Optional[callable] = None,
|
||||
split_folder: Optional[str] = None,
|
||||
rich: bool = False,
|
||||
):
|
||||
"""Return a PhotosAlbumPhotoScript object, creating the album if necessary
|
||||
"""Return a PhotosAlbum object, creating the album if necessary
|
||||
|
||||
Args:
|
||||
name: Name of album
|
||||
verbose: optional callable to print verbose output
|
||||
split_folder: if set, split album name on value of split_folder to create folders if necessary,
|
||||
e.g. if name = 'folder1/folder2/album' and split_folder='/',
|
||||
e.g. if name = 'folder1/folder2/album' and split_folder='/',
|
||||
then folders 'folder1' and 'folder2' will be created and album 'album' will be created in 'folder2';
|
||||
if not set, album 'folder1/folder2/album' will be created
|
||||
rich: if True, use rich themes for verbose output
|
||||
"""
|
||||
self.verbose = verbose or noop
|
||||
self.library = PhotosLibrary()
|
||||
self.library = photoscript.PhotosLibrary()
|
||||
|
||||
folders_album = name.split(split_folder) if split_folder else [name]
|
||||
self.album = album_by_path(folders_album, verbose=verbose)
|
||||
self.name = name
|
||||
self.rich = rich
|
||||
|
||||
def add(self, photo: PhotoInfo):
|
||||
photo_ = photoscript.Photo(photo.uuid)
|
||||
self.album.add([photo_])
|
||||
self.verbose(
|
||||
f"Added {self._format_name(photo.original_filename)} ({self._format_uuid(photo.uuid)}) to album {self._format_album(self.name)}"
|
||||
)
|
||||
|
||||
def add_list(self, photo_list: List[PhotoInfo]):
|
||||
photos = []
|
||||
for p in photo_list:
|
||||
try:
|
||||
photos.append(photoscript.Photo(p.uuid))
|
||||
except Exception as e:
|
||||
self.verbose(
|
||||
f"Error creating Photo object for photo {self._format_uuid(p.uuid)}: {e}"
|
||||
)
|
||||
for photolist in chunked(photos, 10):
|
||||
self.album.add(photolist)
|
||||
photo_len = len(photo_list)
|
||||
self.verbose(
|
||||
f"Added {self._format_num(photo_len)} {pluralize(photo_len, 'photo', 'photos')} to album {self._format_album(self.name)}"
|
||||
)
|
||||
|
||||
def photos(self):
|
||||
return self.album.photos()
|
||||
|
||||
def _format_uuid(self, uuid: str) -> str:
|
||||
""" "Format uuid for verbose output"""
|
||||
return f"[uuid]{uuid}[/uuid]" if self.rich else uuid
|
||||
|
||||
def _format_album(self, album: str) -> str:
|
||||
""" "Format album name for verbose output"""
|
||||
return f"[filepath]{album}[/filepath]" if self.rich else album
|
||||
|
||||
def _format_name(self, name: str) -> str:
|
||||
""" "Format name for verbose output"""
|
||||
return f"[filename]{name}[/filename]" if self.rich else name
|
||||
|
||||
def _format_num(self, num: int) -> str:
|
||||
""" "Format number for verbose output"""
|
||||
return f"[num]{num}[/num]" if self.rich else str(num)
|
||||
|
||||
|
||||
class PhotosAlbumPhotoScript(PhotosAlbum):
|
||||
"""Add photoscript.Photo objects to album"""
|
||||
|
||||
def add(self, photo: Photo):
|
||||
self.album.add([photo])
|
||||
self.verbose(f"Added {photo.filename} ({photo.uuid}) to album {self.name}")
|
||||
self.verbose(
|
||||
f"Added {self._format_name(photo.filename)} ({self._format_uuid(photo.uuid)}) to album {self._format_album(self.name)}"
|
||||
)
|
||||
|
||||
def add_list(self, photo_list: List[Photo]):
|
||||
for photolist in chunked(photo_list, 10):
|
||||
self.album.add(photolist)
|
||||
photo_len = len(photo_list)
|
||||
self.verbose(
|
||||
f"Added {photo_len} {pluralize(photo_len, 'photo', 'photos')} to album {self.name}"
|
||||
f"Added {self._format_num(photo_len)} {pluralize(photo_len, 'photo', 'photos')} to album {self._format_album(self.name)}"
|
||||
)
|
||||
|
||||
def photos(self):
|
||||
return self.album.photos()
|
||||
|
||||
@@ -1562,7 +1562,7 @@ class PhotoTemplate:
|
||||
# if no uuid, then template is being validated but not actually run
|
||||
# so don't run the function
|
||||
values = []
|
||||
elif caller == "export":
|
||||
elif caller in ["export", "query"]:
|
||||
# function signature is:
|
||||
# def example(photo: PhotoInfo, options: ExportOptions, args: Optional[str] = None, **kwargs) -> Union[List, str]:
|
||||
values = template_func(self.photo, options=self.options, args=field_arg)
|
||||
|
||||
@@ -206,7 +206,7 @@ def copy_photos_library(photos_library, delay=0):
|
||||
|
||||
@pytest.fixture
|
||||
def addalbum_library():
|
||||
copy_photos_library(delay=10)
|
||||
copy_photos_library(TEST_LIBRARY, delay=10)
|
||||
|
||||
|
||||
def copy_photos_library_to_path(photos_library_path: str, dest_path: str) -> str:
|
||||
|
||||
@@ -38,8 +38,8 @@ def test_export_add_to_album(addalbum_library):
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert f"Creating Photos album '{EXPORT_ALBUM}'" in result.output
|
||||
assert f"Creating Photos album '{SKIP_ALBUM}'" in result.output
|
||||
assert f"Creating album '{EXPORT_ALBUM}'" in result.output
|
||||
assert f"Creating album '{SKIP_ALBUM}'" in result.output
|
||||
|
||||
photoslib = photoscript.PhotosLibrary()
|
||||
album = photoslib.album(EXPORT_ALBUM)
|
||||
@@ -69,9 +69,9 @@ def test_export_add_to_album(addalbum_library):
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert f"Creating Photos album '{EXPORT_ALBUM}'" not in result.output
|
||||
assert f"Creating Photos album '{SKIP_ALBUM}'" not in result.output
|
||||
assert f"Creating Photos album '{MISSING_ALBUM}'" in result.output
|
||||
assert f"Creating album '{EXPORT_ALBUM}'" not in result.output
|
||||
assert f"Creating album '{SKIP_ALBUM}'" not in result.output
|
||||
assert f"Creating album '{MISSING_ALBUM}'" in result.output
|
||||
|
||||
photoslib = photoscript.PhotosLibrary()
|
||||
export_album = photoslib.album(EXPORT_ALBUM)
|
||||
|
||||
Reference in New Issue
Block a user