Added ExportOptions to photoexporter.py, #462

This commit is contained in:
Rhet Turnbull
2022-01-15 16:12:27 -08:00
parent 231d132792
commit 9517876bd0
6 changed files with 337 additions and 573 deletions

View File

@@ -59,7 +59,7 @@ from .exiftool import get_exiftool_path
from .export_db import ExportDB, ExportDBInMemory from .export_db import ExportDB, ExportDBInMemory
from .fileutil import FileUtil, FileUtilNoOp from .fileutil import FileUtil, FileUtilNoOp
from .path_utils import is_valid_filepath, sanitize_filename, sanitize_filepath from .path_utils import is_valid_filepath, sanitize_filename, sanitize_filepath
from .photoexporter import ExportResults, PhotoExporter from .photoexporter import ExportOptions, ExportResults, PhotoExporter
from .photoinfo import PhotoInfo from .photoinfo import PhotoInfo
from .photokit import check_photokit_authorization, request_photokit_authorization from .photokit import check_photokit_authorization, request_photokit_authorization
from .photosalbum import PhotosAlbum from .photosalbum import PhotosAlbum
@@ -2960,11 +2960,8 @@ def export_photo_to_directory(
tries += 1 tries += 1
error = 0 error = 0
try: try:
exporter = PhotoExporter(photo) export_options = ExportOptions(
export_results = exporter.export2(
dest=dest_path,
edited=edited, edited=edited,
filename=filename,
sidecar=sidecar_flags, sidecar=sidecar_flags,
sidecar_drop_ext=sidecar_drop_ext, sidecar_drop_ext=sidecar_drop_ext,
live_photo=export_live, live_photo=export_live,
@@ -2997,6 +2994,10 @@ def export_photo_to_directory(
preview=export_preview or (missing and preview_if_missing), preview=export_preview or (missing and preview_if_missing),
preview_suffix=preview_suffix, preview_suffix=preview_suffix,
) )
exporter = PhotoExporter(photo)
export_results = exporter.export2(
dest=dest_path, filename=filename, options=export_options
)
for warning_ in export_results.exiftool_warning: for warning_ in export_results.exiftool_warning:
verbose_(f"exiftool warning for file {warning_[0]}: {warning_[1]}") verbose_(f"exiftool warning for file {warning_[0]}: {warning_[1]}")
for error_ in export_results.exiftool_error: for error_ in export_results.exiftool_error:
@@ -3471,12 +3472,13 @@ def write_finder_tags(
skipped = [] skipped = []
if keywords: if keywords:
# match whatever keywords would've been used in --exiftool or --sidecar # match whatever keywords would've been used in --exiftool or --sidecar
exif = PhotoExporter(photo)._exiftool_dict( export_options = ExportOptions(
use_albums_as_keywords=album_keyword, use_albums_as_keywords=album_keyword,
use_persons_as_keywords=person_keyword, use_persons_as_keywords=person_keyword,
keyword_template=keyword_template, keyword_template=keyword_template,
merge_exif_keywords=exiftool_merge_keywords, merge_exif_keywords=exiftool_merge_keywords,
) )
exif = PhotoExporter(photo)._exiftool_dict(options=export_options)
try: try:
if exif["IPTC:Keywords"]: if exif["IPTC:Keywords"]:
tags.extend(exif["IPTC:Keywords"]) tags.extend(exif["IPTC:Keywords"])
@@ -4148,7 +4150,7 @@ def repl(ctx, cli_obj, db, emacs):
from osxphotos import ExifTool, PhotoInfo, PhotosDB from osxphotos import ExifTool, PhotoInfo, PhotosDB
from osxphotos.albuminfo import AlbumInfo from osxphotos.albuminfo import AlbumInfo
from osxphotos.momentinfo import MomentInfo from osxphotos.momentinfo import MomentInfo
from osxphotos.photoexporter import ExportResults, PhotoExporter from osxphotos.photoexporter import ExportOptions, ExportResults, PhotoExporter
from osxphotos.placeinfo import PlaceInfo from osxphotos.placeinfo import PlaceInfo
from osxphotos.queryoptions import QueryOptions from osxphotos.queryoptions import QueryOptions
from osxphotos.scoreinfo import ScoreInfo from osxphotos.scoreinfo import ScoreInfo
@@ -4186,7 +4188,7 @@ def repl(ctx, cli_obj, db, emacs):
print(f"Found {len(photos)} photos in {tictoc:0.2f} seconds\n") print(f"Found {len(photos)} photos in {tictoc:0.2f} seconds\n")
print("The following classes have been imported from osxphotos:") print("The following classes have been imported from osxphotos:")
print( print(
"- AlbumInfo, ExifTool, PhotoInfo, PhotoExporter, ExportResults, PhotosDB, PlaceInfo, QueryOptions, MomentInfo, ScoreInfo, SearchInfo\n" "- AlbumInfo, ExifTool, PhotoInfo, PhotoExporter, ExportOptions, ExportResults, PhotosDB, PlaceInfo, QueryOptions, MomentInfo, ScoreInfo, SearchInfo\n"
) )
print("The following variables are defined:") print("The following variables are defined:")
print(f"- photosdb: PhotosDB() instance for {photosdb.library_path}") print(f"- photosdb: PhotosDB() instance for {photosdb.library_path}")
@@ -4420,7 +4422,7 @@ def snap(ctx, cli_obj, db):
metavar="STYLE", metavar="STYLE",
nargs=1, nargs=1,
default="monokai", default="monokai",
help = "Specify style/theme for syntax highlighting. " help="Specify style/theme for syntax highlighting. "
"Theme may be any valid pygments style (https://pygments.org/styles/). " "Theme may be any valid pygments style (https://pygments.org/styles/). "
"Default is 'monokai'.", "Default is 'monokai'.",
) )

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ import pytest
import osxphotos import osxphotos
from osxphotos._constants import _UNKNOWN_PERSON from osxphotos._constants import _UNKNOWN_PERSON
from osxphotos.exiftool import get_exiftool_path from osxphotos.exiftool import get_exiftool_path
from osxphotos.photoexporter import PhotoExporter from osxphotos.photoexporter import ExportOptions, PhotoExporter
from osxphotos.utils import dd_to_dms_str from osxphotos.utils import dd_to_dms_str
# determine if exiftool installed so exiftool tests can be skipped # determine if exiftool installed so exiftool tests can be skipped
@@ -321,7 +321,9 @@ def test_export_12(photosdb):
edited_name = pathlib.Path(photos[0].path_edited).name edited_name = pathlib.Path(photos[0].path_edited).name
edited_suffix = pathlib.Path(edited_name).suffix edited_suffix = pathlib.Path(edited_name).suffix
filename = pathlib.Path(photos[0].original_filename).stem + "_edited" + edited_suffix filename = (
pathlib.Path(photos[0].original_filename).stem + "_edited" + edited_suffix
)
expected_dest = os.path.join(dest, filename) expected_dest = os.path.join(dest, filename)
got_dest = photos[0].export(dest, edited=True)[0] got_dest = photos[0].export(dest, edited=True)[0]
@@ -418,7 +420,9 @@ def test_exiftool_json_sidecar_ignore_date_modified(photosdb):
) as fp: ) as fp:
json_expected = json.load(fp)[0] json_expected = json.load(fp)[0]
json_got = PhotoExporter(photo)._exiftool_json_sidecar(ignore_date_modified=True) json_got = PhotoExporter(photo)._exiftool_json_sidecar(
ExportOptions(ignore_date_modified=True)
)
json_got = json.loads(json_got)[0] json_got = json.loads(json_got)[0]
assert json_got == json_expected assert json_got == json_expected
@@ -449,7 +453,9 @@ def test_exiftool_json_sidecar_keyword_template_long(capsys, photosdb):
long_str = "x" * (_MAX_IPTC_KEYWORD_LEN + 1) long_str = "x" * (_MAX_IPTC_KEYWORD_LEN + 1)
photos[0]._verbose = print photos[0]._verbose = print
json_got = PhotoExporter(photos[0])._exiftool_json_sidecar(keyword_template=[long_str]) json_got = PhotoExporter(photos[0])._exiftool_json_sidecar(
ExportOptions(keyword_template=[long_str])
)
json_got = json.loads(json_got)[0] json_got = json.loads(json_got)[0]
captured = capsys.readouterr() captured = capsys.readouterr()
@@ -484,7 +490,9 @@ def test_exiftool_json_sidecar_keyword_template(photosdb):
str(pathlib.Path(SIDECAR_DIR) / f"{uuid}_keyword_template.json"), "r" str(pathlib.Path(SIDECAR_DIR) / f"{uuid}_keyword_template.json"), "r"
) as fp: ) as fp:
json_expected = json.load(fp) json_expected = json.load(fp)
json_got = PhotoExporter(photo)._exiftool_json_sidecar(keyword_template=["{folder_album}"]) json_got = PhotoExporter(photo)._exiftool_json_sidecar(
ExportOptions(keyword_template=["{folder_album}"])
)
json_got = json.loads(json_got) json_got = json.loads(json_got)
assert json_got == json_expected assert json_got == json_expected
@@ -500,7 +508,9 @@ def test_exiftool_json_sidecar_use_persons_keyword(photosdb):
) as fp: ) as fp:
json_expected = json.load(fp)[0] json_expected = json.load(fp)[0]
json_got = PhotoExporter(photo)._exiftool_json_sidecar(use_persons_as_keywords=True) json_got = PhotoExporter(photo)._exiftool_json_sidecar(
ExportOptions(use_persons_as_keywords=True)
)
json_got = json.loads(json_got)[0] json_got = json.loads(json_got)[0]
assert json_got == json_expected assert json_got == json_expected
@@ -516,7 +526,9 @@ def test_exiftool_json_sidecar_use_albums_keywords(photosdb):
) as fp: ) as fp:
json_expected = json.load(fp) json_expected = json.load(fp)
json_got = PhotoExporter(photo)._exiftool_json_sidecar(use_albums_as_keywords=True) json_got = PhotoExporter(photo)._exiftool_json_sidecar(
ExportOptions(use_albums_as_keywords=True)
)
json_got = json.loads(json_got) json_got = json.loads(json_got)
assert json_got == json_expected assert json_got == json_expected
@@ -536,7 +548,7 @@ def test_exiftool_sidecar(photosdb):
@pytest.mark.skipif(exiftool is None, reason="exiftool not installed") @pytest.mark.skipif(exiftool is None, reason="exiftool not installed")
def test_xmp_sidecar_is_valid(tmp_path, photosdb): def test_xmp_sidecar_is_valid(tmp_path, photosdb):
""" validate XMP sidecar file with exiftool """ """validate XMP sidecar file with exiftool"""
from osxphotos.exiftool import ExifTool from osxphotos.exiftool import ExifTool
photos = photosdb.photos(uuid=[UUID_DICT["xmp"]]) photos = photosdb.photos(uuid=[UUID_DICT["xmp"]])
@@ -560,7 +572,7 @@ def test_xmp_sidecar(photosdb):
def test_xmp_sidecar_extension(photosdb): def test_xmp_sidecar_extension(photosdb):
""" test XMP sidecar when no extension is passed """ """test XMP sidecar when no extension is passed"""
uuid = UUID_DICT["xmp"] uuid = UUID_DICT["xmp"]
photos = photosdb.photos(uuid=[uuid]) photos = photosdb.photos(uuid=[uuid])
@@ -581,7 +593,9 @@ def test_xmp_sidecar_use_persons_keyword(photosdb):
with open(pathlib.Path(SIDECAR_DIR) / f"{uuid}_persons_as_keywords.xmp") as fp: with open(pathlib.Path(SIDECAR_DIR) / f"{uuid}_persons_as_keywords.xmp") as fp:
xmp_expected = fp.read() xmp_expected = fp.read()
xmp_got = PhotoExporter(photo)._xmp_sidecar(use_persons_as_keywords=True, extension="jpg") xmp_got = PhotoExporter(photo)._xmp_sidecar(
ExportOptions(use_persons_as_keywords=True), extension="jpg"
)
assert xmp_got == xmp_expected assert xmp_got == xmp_expected
@@ -593,12 +607,14 @@ def test_xmp_sidecar_use_albums_keyword(photosdb):
with open(pathlib.Path(SIDECAR_DIR) / f"{uuid}_albums_as_keywords.xmp") as fp: with open(pathlib.Path(SIDECAR_DIR) / f"{uuid}_albums_as_keywords.xmp") as fp:
xmp_expected = fp.read() xmp_expected = fp.read()
xmp_got = PhotoExporter(photo)._xmp_sidecar(use_albums_as_keywords=True, extension="jpg") xmp_got = PhotoExporter(photo)._xmp_sidecar(
ExportOptions(use_albums_as_keywords=True), extension="jpg"
)
assert xmp_got == xmp_expected assert xmp_got == xmp_expected
def test_xmp_sidecar_gps(photosdb): def test_xmp_sidecar_gps(photosdb):
""" Test export XMP sidecar with GPS info """ """Test export XMP sidecar with GPS info"""
uuid = UUID_DICT["location"] uuid = UUID_DICT["location"]
photo = photosdb.get_photo(uuid) photo = photosdb.get_photo(uuid)
@@ -619,7 +635,7 @@ def test_xmp_sidecar_keyword_template(photosdb):
xmp_expected = fp.read() xmp_expected = fp.read()
xmp_got = PhotoExporter(photo)._xmp_sidecar( xmp_got = PhotoExporter(photo)._xmp_sidecar(
keyword_template=["{created.year}", "{folder_album}"], extension="jpg" ExportOptions(keyword_template=["{created.year}", "{folder_album}"]),
extension="jpg",
) )
assert xmp_got == xmp_expected assert xmp_got == xmp_expected

View File

@@ -1,8 +1,9 @@
import os import os
import pytest import pytest
from osxphotos._constants import _UNKNOWN_PERSON from osxphotos._constants import _UNKNOWN_PERSON
from osxphotos.photoexporter import PhotoExporter from osxphotos.photoexporter import ExportOptions, PhotoExporter
skip_test = "OSXPHOTOS_TEST_CONVERT" not in os.environ skip_test = "OSXPHOTOS_TEST_CONVERT" not in os.environ
pytestmark = pytest.mark.skipif( pytestmark = pytest.mark.skipif(
@@ -16,16 +17,10 @@ UUID_DICT = {
"heic": "7783E8E6-9CAC-40F3-BE22-81FB7051C266", "heic": "7783E8E6-9CAC-40F3-BE22-81FB7051C266",
} }
NAMES_DICT = { NAMES_DICT = {"raw": "DSC03584.jpeg", "heic": "IMG_3092.jpeg"}
"raw": "DSC03584.jpeg",
"heic": "IMG_3092.jpeg"
}
UUID_LIVE_HEIC = "8EC216A2-0032-4934-BD3F-04C6259B3304" UUID_LIVE_HEIC = "8EC216A2-0032-4934-BD3F-04C6259B3304"
NAMES_LIVE_HEIC = [ NAMES_LIVE_HEIC = ["IMG_3259.jpeg", "IMG_3259.mov"]
"IMG_3259.jpeg",
"IMG_3259.mov"
]
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
@@ -44,7 +39,8 @@ def test_export_convert_raw_to_jpeg(photosdb):
dest = tempdir.name dest = tempdir.name
photos = photosdb.photos(uuid=[UUID_DICT["raw"]]) photos = photosdb.photos(uuid=[UUID_DICT["raw"]])
results = PhotoExporter(photos[0]).export2(dest, convert_to_jpeg=True) export_options = ExportOptions(convert_to_jpeg=True)
results = PhotoExporter(photos[0]).export2(dest, options=export_options)
got_dest = pathlib.Path(results.exported[0]) got_dest = pathlib.Path(results.exported[0])
assert got_dest.is_file() assert got_dest.is_file()
@@ -61,7 +57,8 @@ def test_export_convert_heic_to_jpeg(photosdb):
dest = tempdir.name dest = tempdir.name
photos = photosdb.photos(uuid=[UUID_DICT["heic"]]) photos = photosdb.photos(uuid=[UUID_DICT["heic"]])
results = PhotoExporter(photos[0]).export2(dest, convert_to_jpeg=True) export_options = ExportOptions(convert_to_jpeg=True)
results = PhotoExporter(photos[0]).export2(dest, options=export_options)
got_dest = pathlib.Path(results.exported[0]) got_dest = pathlib.Path(results.exported[0])
assert got_dest.is_file() assert got_dest.is_file()
@@ -88,7 +85,8 @@ def test_export_convert_live_heic_to_jpeg():
dest = tempdir.name dest = tempdir.name
photo = photosdb.get_photo(UUID_LIVE_HEIC) photo = photosdb.get_photo(UUID_LIVE_HEIC)
results = PhotoExporter(photo).export2(dest, convert_to_jpeg=True, live_photo=True) export_options = ExportOptions(convert_to_jpeg=True, live_photo=True)
results = PhotoExporter(photo).export2(dest, options=export_options)
for name in NAMES_LIVE_HEIC: for name in NAMES_LIVE_HEIC:
assert f"{tempdir.name}/{name}" in results.exported assert f"{tempdir.name}/{name}" in results.exported
@@ -96,4 +94,3 @@ def test_export_convert_live_heic_to_jpeg():
for file_ in results.exported: for file_ in results.exported:
dest = pathlib.Path(file_) dest = pathlib.Path(file_)
assert dest.is_file() assert dest.is_file()

View File

@@ -5,7 +5,7 @@ import pytest
import osxphotos import osxphotos
from osxphotos._constants import _UNKNOWN_PERSON from osxphotos._constants import _UNKNOWN_PERSON
from osxphotos.photoexporter import PhotoExporter from osxphotos.photoexporter import ExportOptions, PhotoExporter
PHOTOS_DB = "./tests/Test-10.14.6.photoslibrary/database/photos.db" PHOTOS_DB = "./tests/Test-10.14.6.photoslibrary/database/photos.db"
PHOTOS_DB_PATH = "/Test-10.14.6.photoslibrary/database/photos.db" PHOTOS_DB_PATH = "/Test-10.14.6.photoslibrary/database/photos.db"
@@ -365,7 +365,8 @@ def test_xmp_sidecar_keyword_template(photosdb):
xmp_expected = fp.read() xmp_expected = fp.read()
xmp_got = PhotoExporter(photo)._xmp_sidecar( xmp_got = PhotoExporter(photo)._xmp_sidecar(
keyword_template=["{created.year}", "{folder_album}"], extension="jpg" ExportOptions(keyword_template=["{created.year}", "{folder_album}"]),
extension="jpg",
) )
assert xmp_got == xmp_expected assert xmp_got == xmp_expected

View File

@@ -9,7 +9,7 @@ import osxphotos
from osxphotos._constants import SIDECAR_XMP from osxphotos._constants import SIDECAR_XMP
from osxphotos.exiftool import ExifTool, get_exiftool_path from osxphotos.exiftool import ExifTool, get_exiftool_path
from osxphotos.fileutil import FileUtil from osxphotos.fileutil import FileUtil
from osxphotos.photoexporter import PhotoExporter from osxphotos.photoexporter import ExportOptions, PhotoExporter
PHOTOS_DB_15_7 = "tests/Test-10.15.7.photoslibrary" PHOTOS_DB_15_7 = "tests/Test-10.15.7.photoslibrary"
@@ -40,7 +40,10 @@ def test_sidecar_xmp(photosdb):
tempdir = tempfile.TemporaryDirectory(prefix="osxphotos") tempdir = tempfile.TemporaryDirectory(prefix="osxphotos")
dest = tempdir.name dest = tempdir.name
photo = photosdb.get_photo(uuid) photo = photosdb.get_photo(uuid)
PhotoExporter(photo).export2(dest, photo.original_filename, sidecar=SIDECAR_XMP) export_options = ExportOptions(sidecar=SIDECAR_XMP)
PhotoExporter(photo).export2(
dest, photo.original_filename, options=export_options
)
filepath = str(pathlib.Path(dest) / photo.original_filename) filepath = str(pathlib.Path(dest) / photo.original_filename)
xmppath = filepath + ".xmp" xmppath = filepath + ".xmp"