Add metadata viewer script
This commit is contained in:
@@ -51,6 +51,32 @@ Manual grouping uses filesystem items, not media-file detection:
|
|||||||
- one empty directory does nothing
|
- one empty directory does nothing
|
||||||
- multiple files/folders are grouped as selected, without flattening folder contents
|
- 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
|
## Requirements
|
||||||
|
|
||||||
- Python 3.10 or newer
|
- Python 3.10 or newer
|
||||||
|
|||||||
@@ -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))
|
||||||
Reference in New Issue
Block a user