diff --git a/README.md b/README.md index c4197ab..942e29a 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,32 @@ Manual grouping uses filesystem items, not media-file detection: - one empty directory does nothing - multiple files/folders are grouped as selected, without flattening folder contents +### `view_metadata.py` + +Show all readable metadata for the first file provided: + +```bash +python3 view_metadata.py path/to/file/or/directory [...] +``` + +This script only displays one file. If several files are given, it displays the first one. If a directory is given, it searches recursively and displays the first file it finds. + +It runs ExifTool as: + +```bash +exiftool -a -u -ee -G0:1 -s file +``` + +The important choices are: + +- `-a` shows duplicate tag names instead of hiding later duplicates. +- `-u` includes unknown tags ExifTool can identify well enough to print. +- `-ee` extracts embedded metadata where ExifTool supports it, which is useful for some video/container formats. +- `-G0:1` shows both the broad metadata container and the more exact location, such as `EXIF:IFD0` or `QuickTime:Track1`. +- `-s` uses compact tag names, which are easier to copy into scripts than the descriptive labels. + +The old `-G` style shows broad groups like `EXIF`, `File`, or `QuickTime`. That is readable, but it can hide where inside a container a value came from. Family 1 groups, from `-G1`, show more exact locations like `IFD0`, `ExifIFD`, `MakerNotes`, or `Track1`, but sometimes lose the broader context. `-G0:1` combines both, so it is the most useful default for debugging metadata without changing which normal tags are extracted. The organization option changes labels, not the underlying metadata extraction; `-a` and `-u` are the parts that affect whether duplicate or unknown printed tags are included. + ## Requirements - Python 3.10 or newer diff --git a/view_metadata.py b/view_metadata.py new file mode 100644 index 0000000..e9799a7 --- /dev/null +++ b/view_metadata.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +""" +Show metadata for one file. + +Drag a file onto this script, or run: + python3 view_metadata.py path/to/file/or/directory [...] + +If more than one file is provided or found, only the first file is shown. +""" + +from __future__ import annotations + +import subprocess +import sys +from pathlib import Path +from shutil import which + + +def first_file_from_path(path: Path) -> Path | None: + path = path.expanduser() + if path.is_file(): + return path.resolve() + if path.is_dir(): + for child in sorted(path.rglob("*"), key=lambda item: str(item).lower()): + if child.is_file(): + return child.resolve() + return None + + +def choose_file(args: list[str]) -> Path | None: + for arg in args: + file_path = first_file_from_path(Path(arg)) + if file_path is not None: + return file_path + return None + + +def pause_if_interactive() -> None: + if sys.stdin.isatty(): + try: + input("\nPress Enter to close...") + except EOFError: + pass + + +def run(argv: list[str]) -> int: + if len(argv) < 2: + print("Usage: python3 view_metadata.py path/to/file/or/directory [...]") + return 2 + + exiftool = which("exiftool") + if exiftool is None: + print("exiftool was not found on PATH.") + return 1 + + file_path = choose_file(argv[1:]) + if file_path is None: + print("No file found.") + return 1 + + print(f"Showing metadata for: {file_path}\n", flush=True) + command = [ + exiftool, + "-a", + "-u", + "-ee", + "-G0:1", + "-s", + "-charset", + "filename=UTF8", + str(file_path), + ] + return subprocess.run(command).returncode + + +def main(argv: list[str]) -> int: + try: + return run(argv) + finally: + pause_if_interactive() + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv))