-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmetadata.py
More file actions
56 lines (41 loc) · 1.85 KB
/
metadata.py
File metadata and controls
56 lines (41 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import subprocess
from pathlib import Path
from vision import TagResult
# Formats that support IPTC embedding via exiftool
_IPTC_FORMATS = {".jpg", ".jpeg"}
def _set_list(args: list, flag: str, values: list[str]) -> None:
"""Append exiftool args to replace a list tag with the given values."""
if values:
args.append(f"-{flag}={values[0]}")
for v in values[1:]:
args.append(f"-{flag}+={v}")
else:
args.append(f"-{flag}=")
def write_metadata(path: str, result: TagResult) -> None:
"""Write bilingual tags and captions to image metadata in-place using exiftool.
XMP is used for all formats (HEIC, HEIF, JPEG):
- XMP:Subject — all keywords (EN + DE combined)
- XMP-dc:Description-en — English caption (language alternative)
- XMP-dc:Description-de — German caption (language alternative)
IPTC is added for JPEG only:
- IPTC:Keywords — all keywords (EN + DE combined)
- IPTC:Caption-Abstract — English caption (IPTC has no language tagging)
"""
suffix = Path(path).suffix.lower()
args = ["exiftool", "-overwrite_original", "-charset", "UTF8"]
all_tags = result.tags_en + result.tags_de
# --- XMP (universal) ---
_set_list(args, "XMP:Subject", all_tags)
if result.caption_en:
args.append(f"-XMP-dc:Description-en={result.caption_en}")
if result.caption_de:
args.append(f"-XMP-dc:Description-de={result.caption_de}")
# --- IPTC (JPEG only) ---
if suffix in _IPTC_FORMATS:
_set_list(args, "IPTC:Keywords", all_tags)
if result.caption_en:
args.append(f"-IPTC:Caption-Abstract={result.caption_en}")
args.append(path)
proc = subprocess.run(args, capture_output=True, text=True)
if proc.returncode != 0:
raise RuntimeError(f"exiftool error: {proc.stderr.strip()}")