Feature custom sidecar 1123 cache (#1131)

* Added caching to Template, fixed typos

* Added additional sidecar tests
This commit is contained in:
Rhet Turnbull 2023-07-25 06:44:39 -07:00 committed by GitHub
parent 02b6698c80
commit 3999e54f6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 6 deletions

View File

@ -1,6 +1,11 @@
<%doc> <%doc>
Mako template to dump a full json representation of the photo object Mako template to dump a full json representation of the photo object
Can be run from the command line with: Can be run from the command line with:
osxphotos export /path/to/export --sidecar-template custom_sidecar_json.mako "{filepath}.json" yes no yes osxphotos export /path/to/export --sidecar-template custom_sidecar_json.mako "{filepath}.json" yes no yes
The template will be passed three variables for rendering:
photo: a PhotoInfo object for the photo being exported
photo_path: a pathlib.Path object for the photo file being exported
sidecar_path: a pathlib.Path object for the sidecar file being written
</%doc> </%doc>
${photo.json(shallow=False, indent=4)} ${photo.json(shallow=False, indent=4)}

View File

@ -358,9 +358,9 @@ from .verbose import get_verbose_console, verbose_print
"The template will passed the following variables: photo (PhotoInfo object for the photo being exported), " "The template will passed the following variables: photo (PhotoInfo object for the photo being exported), "
"sidecar_path (pathlib.Path object for the path to the sidecar being written), and " "sidecar_path (pathlib.Path object for the path to the sidecar being written), and "
"photo_path (pathlib.Path object for the path to the exported photo. " "photo_path (pathlib.Path object for the path to the exported photo. "
"SIDECAR_TEMPLATE_FILENAME must be a valid template string (see Templating System in help) " "SIDECAR_FILENAME_TEMPLATE must be a valid template string (see Templating System in help) "
"which will be rendered to generate the filename of the sidecar file. " "which will be rendered to generate the filename of the sidecar file. "
"The `{filepath}` template variable may be used in the SIDECAR_TEMPLATE_FILENAME to refer to the filename of the " "The `{filepath}` template variable may be used in the SIDECAR_FILENAME_TEMPLATE to refer to the filename of the "
"photo being exported. " "photo being exported. "
"WRITE_SKIPPED is a boolean value (true/false, yes/no, 1/0 are all valid values) and indicates whether or not " "WRITE_SKIPPED is a boolean value (true/false, yes/no, 1/0 are all valid values) and indicates whether or not "
"write the sidecar file even if the photo is skipped during export. " "write the sidecar file even if the photo is skipped during export. "

View File

@ -3,6 +3,7 @@
from __future__ import annotations from __future__ import annotations
import pathlib import pathlib
from functools import cache
from typing import Callable from typing import Callable
import click import click
@ -13,6 +14,12 @@ from osxphotos.photoinfo import PhotoInfo
from osxphotos.phototemplate import PhotoTemplate, RenderOptions from osxphotos.phototemplate import PhotoTemplate, RenderOptions
@cache
def get_template(template: str) -> Template:
"""Get template from cache or load from file"""
return Template(filename=template)
def generate_user_sidecar( def generate_user_sidecar(
photo: PhotoInfo, photo: PhotoInfo,
export_results: ExportResults, export_results: ExportResults,
@ -123,7 +130,7 @@ def _render_sidecar_and_write_data(
dry_run: bool, dry_run: bool,
): ):
"""Render sidecar template and write data to file""" """Render sidecar template and write data to file"""
sidecar = Template(filename=template_file) sidecar = get_template(template_file)
sidecar_data = sidecar.render( sidecar_data = sidecar.render(
photo=photo, photo=photo,
sidecar_path=pathlib.Path(template_filename), sidecar_path=pathlib.Path(template_filename),

View File

@ -15,6 +15,7 @@ PHOTOS_DB = "./tests/Test-10.15.7.photoslibrary"
PHOTO_UUID = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51" # wedding.jpg PHOTO_UUID = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51" # wedding.jpg
SIDECAR_FILENAME = "wedding.jpg.txt" SIDECAR_FILENAME = "wedding.jpg.txt"
SIDECAR_FILENAME_2 = "wedding.jpg.sidecar"
SIDECAR_DATA = """ SIDECAR_DATA = """
@ -23,6 +24,14 @@ Sidecar: wedding.jpg.txt
UUID: E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51 UUID: E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51
Rating: Rating:
""" """
SIDECAR_DATA_2 = """
Sidecar: wedding.jpg.sidecar
Photo: wedding.jpg
UUID: E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51
Rating:
"""
def test_export_sidecar_template_1(): def test_export_sidecar_template_1():
@ -401,3 +410,69 @@ def test_export_sidecar_template_report_db():
else: else:
assert row[1] == 0 assert row[1] == 0
assert found_sidecar assert found_sidecar
def test_export_sidecar_template_multiple():
"""test export with multiple --sidecar-template options"""
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export,
[
"--library",
os.path.join(cwd, PHOTOS_DB),
".",
"-V",
"--uuid",
PHOTO_UUID,
"--sidecar-template",
os.path.join(cwd, "tests", "custom_sidecar.mako"),
"{filepath}.txt",
"no",
"no",
"no",
"--sidecar-template",
os.path.join(cwd, "tests", "custom_sidecar.mako"),
"{filepath}.sidecar",
"no",
"no",
"no",
],
)
assert result.exit_code == 0
sidecar_file = pathlib.Path(SIDECAR_FILENAME)
assert sidecar_file.exists()
sidecar_data = sidecar_file.read_text()
assert sidecar_data == SIDECAR_DATA
sidecar_file = pathlib.Path(SIDECAR_FILENAME_2)
assert sidecar_file.exists()
sidecar_data = sidecar_file.read_text()
assert sidecar_data == SIDECAR_DATA_2
def test_export_sidecar_template_full_library():
"""test export with --sidecar-template option against full library (repeated calls to generate sidecar files))"""
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
result = runner.invoke(
export,
[
"--library",
os.path.join(cwd, PHOTOS_DB),
".",
"-V",
"--sidecar-template",
os.path.join(cwd, "tests", "custom_sidecar.mako"),
"{filepath}.txt",
"no",
"no",
"no",
],
)
assert result.exit_code == 0