Metadata writer #17
@@ -48,6 +48,11 @@ def _is_prefixed(txt: str) -> bool:
|
|||||||
return txt.startswith(settings.metadata_prefix)
|
return txt.startswith(settings.metadata_prefix)
|
||||||
|
|
||||||
|
|
||||||
|
def _separate_prefixed_caption(txt: str) -> tuple[str, str | None]:
|
||||||
|
separated = [x.strip() for x in txt.split(settings.metadata_prefix)]
|
||||||
|
return (separated[0], separated[1] if len(separated) > 1 else None)
|
||||||
|
|
||||||
|
|
||||||
class MetadataWriter:
|
class MetadataWriter:
|
||||||
"""
|
"""
|
||||||
Write metadata (captions and keywords) to image files.
|
Write metadata (captions and keywords) to image files.
|
||||||
@@ -112,14 +117,23 @@ class MetadataWriter:
|
|||||||
def write_caption(
|
def write_caption(
|
||||||
self, caption: Caption, include_prefix: bool = True, override: bool = True
|
self, caption: Caption, include_prefix: bool = True, override: bool = True
|
||||||
):
|
):
|
||||||
if include_prefix:
|
existing_no_prefix, existing_prefix = _separate_prefixed_caption(
|
||||||
caption = _prefixed(caption)
|
self.get_caption()
|
||||||
existing = self.get_caption()
|
)
|
||||||
is_existing_prefixed = _is_prefixed(existing)
|
if existing_no_prefix:
|
||||||
if existing and is_existing_prefixed and not override:
|
existing_no_prefix = (
|
||||||
|
f"{existing_no_prefix}."
|
||||||
|
if not existing_no_prefix.endswith(".")
|
||||||
|
else existing_no_prefix
|
||||||
|
)
|
||||||
|
existing_no_prefix = f"{existing_no_prefix} "
|
||||||
|
|
||||||
|
if include_prefix and existing_prefix and not override:
|
||||||
return
|
return
|
||||||
elif existing and not is_existing_prefixed:
|
if not include_prefix and existing_no_prefix and not override:
|
||||||
caption = f"{existing}. {_prefixed(caption)}"
|
return
|
||||||
|
if include_prefix:
|
||||||
|
caption = settings.metadata_prefix.join([existing_no_prefix, f" {caption}"])
|
||||||
metadata_tags = {key: caption for key in XMP_KEYS_CAPTION}
|
metadata_tags = {key: caption for key in XMP_KEYS_CAPTION}
|
||||||
self.set_metadata(metadata_tags)
|
self.set_metadata(metadata_tags)
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ def make_dng_file(tmp_path):
|
|||||||
return _make
|
return _make
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def metadata_writer_on_existing(make_dng_file):
|
||||||
|
metadata_writer = MetadataWriter(make_dng_file(PATHS_DNG_EXAMPLES[0]))
|
||||||
|
metadata_writer.write_caption(
|
||||||
|
"Let's pretend this is the caption of the original image",
|
||||||
|
include_prefix=False,
|
||||||
|
)
|
||||||
|
return metadata_writer
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES)
|
@pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES)
|
||||||
def test_read_metadata(make_dng_file, pic):
|
def test_read_metadata(make_dng_file, pic):
|
||||||
"""primitive test for `MetadataWriter`"""
|
"""primitive test for `MetadataWriter`"""
|
||||||
@@ -49,22 +59,47 @@ def test_is_prefixed():
|
|||||||
def test_read_metadata_sidecar_path(make_dng_file, pic):
|
def test_read_metadata_sidecar_path(make_dng_file, pic):
|
||||||
file_path = make_dng_file(pic)
|
file_path = make_dng_file(pic)
|
||||||
metadata_writer = MetadataWriter(file_path)
|
metadata_writer = MetadataWriter(file_path)
|
||||||
print(metadata_writer.sidecar_path)
|
|
||||||
assert isinstance(metadata_writer.sidecar_path, Path)
|
assert isinstance(metadata_writer.sidecar_path, Path)
|
||||||
assert str(metadata_writer.sidecar_path).lower().endswith(".dng.xmp")
|
assert str(metadata_writer.sidecar_path).lower().endswith(".dng.xmp")
|
||||||
|
|
||||||
|
# file does not exits yet, only the name
|
||||||
|
assert not metadata_writer.sidecar_path.exists()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES)
|
@pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES)
|
||||||
def test_set_caption(make_dng_file, pic):
|
def test_set_caption(make_dng_file, pic):
|
||||||
metadata_writer = MetadataWriter(make_dng_file(pic))
|
metadata_writer = MetadataWriter(make_dng_file(pic))
|
||||||
|
assert not metadata_writer.sidecar_path.exists() # sidecar does not exist yet ...
|
||||||
metadata_writer.write_caption("This is a test")
|
metadata_writer.write_caption("This is a test")
|
||||||
|
assert metadata_writer.sidecar_path.exists() # ... but now!
|
||||||
result = metadata_writer.get_caption()
|
result = metadata_writer.get_caption()
|
||||||
assert result
|
assert result
|
||||||
|
assert result == "photools: This is a test"
|
||||||
|
|
||||||
|
|
||||||
def test_set_caption_on_existing():
|
def test_set_caption_on_existing(metadata_writer_on_existing):
|
||||||
# TODO
|
assert (
|
||||||
...
|
metadata_writer_on_existing.get_caption()
|
||||||
|
== "Let's pretend this is the caption of the original image"
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_writer_on_existing.write_caption("Another caption")
|
||||||
|
assert (
|
||||||
|
metadata_writer_on_existing.get_caption()
|
||||||
|
== "Let's pretend this is the caption of the original image. photools: Another caption"
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_writer_on_existing.write_caption("Updated caption")
|
||||||
|
assert (
|
||||||
|
metadata_writer_on_existing.get_caption()
|
||||||
|
== "Let's pretend this is the caption of the original image. photools: Updated caption"
|
||||||
|
)
|
||||||
|
|
||||||
|
metadata_writer_on_existing.write_caption("Don't do this!", override=False)
|
||||||
|
assert (
|
||||||
|
metadata_writer_on_existing.get_caption()
|
||||||
|
== "Let's pretend this is the caption of the original image. photools: Updated caption"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES)
|
@pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES)
|
||||||
|
|||||||
Reference in New Issue
Block a user