127 lines
4.4 KiB
Python
127 lines
4.4 KiB
Python
""" Export previews for photos in the Photos library
|
|
|
|
To run this with osxphotos on currently selected photos:
|
|
|
|
osxphotos run export_previews.py --selected export_path
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pathlib
|
|
import shutil
|
|
|
|
import click
|
|
|
|
import osxphotos
|
|
from osxphotos.cli import echo, echo_error, query_command, verbose
|
|
from osxphotos.cli.export import get_dirnames_from_template, get_filenames_from_template
|
|
from osxphotos.cli.param_types import TemplateString
|
|
from osxphotos.utils import pluralize
|
|
|
|
|
|
@query_command
|
|
@click.option("--dry-run", is_flag=True, help="Dry run, don't actually export")
|
|
@click.option(
|
|
"--directory",
|
|
type=TemplateString(),
|
|
help="Directory to export to under export_path. This is an osxphotos template string. "
|
|
"For example, to export previews to directories based on creation date: "
|
|
"--directory '{created.year}/{created.mm}/{created.dd}' ",
|
|
)
|
|
@click.option(
|
|
"--filename",
|
|
"filename_template",
|
|
type=TemplateString(),
|
|
help="Filename for exported preview. "
|
|
"This is an osxphotos template string; "
|
|
"for example, to export previews to filename based on creation date: "
|
|
"--filename '{original_name}-{created.year}-{created.mm}-{created.dd}' ",
|
|
)
|
|
@click.argument(
|
|
"export_dir", type=click.Path(exists=True, file_okay=False, dir_okay=True)
|
|
)
|
|
def export_previews(
|
|
photos: list[osxphotos.PhotoInfo],
|
|
dry_run: bool,
|
|
directory: str,
|
|
filename_template: str,
|
|
export_dir: str,
|
|
**kwargs,
|
|
):
|
|
"""Export previews for photos in the Photos library.
|
|
|
|
Pass one or more query options to select photos to export or use without query options
|
|
to export all images.
|
|
|
|
If --directory is passed, the previews will be exported to subdirectories under export_path
|
|
based on the template string passed to --directory. For example, to export previews to
|
|
directories based on creation date: --directory '{created.year}/{created.mm}/{created.dd}'
|
|
|
|
If --filename is passed, the previews will be exported with the filename specified by the
|
|
template string passed to --filename. For example, to export previews to filename based on
|
|
creation date: --filename '{original_name}-{created.year}-{created.mm}-{created.dd}'
|
|
|
|
If --dry-run is passed, the previews will not actually be exported but the export will be
|
|
simulated and the export paths printed to stdout.
|
|
"""
|
|
|
|
verbose(f"Found {len(photos)} photo(s)")
|
|
count = 0
|
|
for photo in photos:
|
|
try:
|
|
# first derivative is the largest preview, so use that one
|
|
preview = pathlib.Path(photo.path_derivatives[0])
|
|
except IndexError:
|
|
echo(f"No preview for {photo.original_filename} ({photo.uuid})")
|
|
continue
|
|
|
|
verbose(f"Found preview for {photo.original_filename}: {preview}")
|
|
count += export_preview_to_directory_with_filename(
|
|
photo, preview, export_dir, directory, filename_template, dry_run
|
|
)
|
|
echo(f"Exported {count} preview {pluralize(count, 'image', 'images')}")
|
|
|
|
|
|
def export_preview_to_directory_with_filename(
|
|
photo: osxphotos.PhotoInfo,
|
|
preview_path: pathlib.Path,
|
|
export_dir: str,
|
|
directory: str,
|
|
filename_template: str,
|
|
dry_run: bool,
|
|
) -> int:
|
|
"""Export preview for photo to directory with filename; returns count of images exported"""
|
|
count = 0
|
|
for dirname in get_dirnames_from_template(
|
|
photo=photo,
|
|
directory=directory,
|
|
export_by_date=False,
|
|
dest=export_dir,
|
|
dry_run=dry_run,
|
|
):
|
|
for filename in get_filenames_from_template(
|
|
photo=photo,
|
|
filename_template=filename_template,
|
|
export_dir=export_dir,
|
|
dest_path=dirname,
|
|
original_name=True,
|
|
):
|
|
# need to change filename extension to match preview
|
|
filename = pathlib.Path(filename).with_suffix(preview_path.suffix)
|
|
dest_path = pathlib.Path(dirname) / filename
|
|
echo(
|
|
f"Exporting preview for {photo.original_filename} ({photo.uuid}) to {dest_path}"
|
|
)
|
|
if not dry_run:
|
|
try:
|
|
shutil.copy(preview_path, dest_path)
|
|
except Exception as e:
|
|
echo_error(f"Error exporting preview: {e}")
|
|
continue
|
|
count += 1
|
|
return count
|
|
|
|
|
|
if __name__ == "__main__":
|
|
export_previews()
|