diff --git a/src/photools3/metadata_writer.py b/src/photools3/metadata_writer.py index e2d8b8f..253193d 100644 --- a/src/photools3/metadata_writer.py +++ b/src/photools3/metadata_writer.py @@ -22,14 +22,14 @@ SIDECAR_EXTENSIONS = {".dng", ".nef", ".cr2", ".cr3", ".arw", ".raf", ".orf", ". XmpKey = Annotated[str, StringConstraints(pattern=r"^\w+\:\w+")] -type Caption = str | None +type Caption = str type Keywords = list[str] | None type Color = str | None type XmpMetadata = dict[str, Any] -XMO_KEYS_CAPTION: list[XmpKey] = [ - "EXIF:ImageDescription", +XMP_KEYS_CAPTION: list[XmpKey] = [ "XMP:Description", + "EXIF:ImageDescription", "IPTC:Caption-Abstract", ] @@ -44,12 +44,8 @@ def _prefixed(txt: str) -> str: return f"{settings.metadata_prefix} {txt}" -def read_metadata(path: Path) -> XmpMetadata | None: - try: - with exiftool.ExifToolHelper() as exif: - return exif.get_metadata([str(path)])[0] - except Exception as exc: # noqa: BLE001 - log.error(f"Could not read metadata from {path}: {exc}") +def _is_prefixed(txt: str) -> bool: + return txt.startswith(settings.metadata_prefix) class MetadataWriter: @@ -59,28 +55,64 @@ class MetadataWriter: """ def __init__( - self, force_sidecar: bool = False, append: bool = True, prefix: str = "photools" + self, + path: Path, + force_sidecar: bool = False, + append: bool = True, ): + self.path = Path self.force_sidecar = force_sidecar self.append = append - self.prefix = prefix - def write_caption(self, path: Path, caption: Caption): ... + self._metadata: XmpMetadata | None = None - def write_keywords(self, path: Path, keywords: Keywords): ... + @property + def sidecar_path(self) -> Path: + ... + return Path() - def write_color(self, path: Path, color: Color): ... + @property + def metadata(self) -> XmpMetadata: + try: + with exiftool.ExifToolHelper() as exif: + metadata = exif.get_metadata([str(self.path)])[0] + except Exception as exc: # noqa: BLE001 + log.error(f"Could not read metadata from {self.path}: {exc}") + assert metadata + return metadata + + def set_metadata(self): + if self.sidecar_path.exists(): + params=["-overwrite_original"] + else: + params=["-o", "%f.xmp"] + # TODO + ... + + def write_caption(self, caption: Caption): + existing = self.metadata.get(XMP_KEYS_CAPTION[0], "") + is_existing_prefixed = _is_prefixed(existing) + if existing and is_existing_prefixed: + return + elif existing and not is_existing_prefixed: + caption = f"{existing}. {_prefixed(caption)}" + metadata_tags = {key: caption for key in XMP_KEYS_CAPTION} + # TODO + ... + + def write_keywords(self, keywords: Keywords): ... + + def write_color(self, color: Color): ... def write( self, - path: Path, - caption: Caption = None, + caption: Caption | None = None, keywords: Keywords = None, color: Color = None, ): if caption is not None: - self.write_caption(path, caption) + self.write_caption(caption) if keywords is not None: - self.write_keywords(path, keywords) + self.write_keywords(keywords) if color is not None: - self.write_color(path, color) + self.write_color(color)