Files
media-batch-tools/copy_metadata.py
T

104 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""
Copy meaningful metadata from one file to another.
Run without files to type source/destination paths, or drag exactly two files
onto the script and choose which is the source.
"""
from __future__ import annotations
import sys
from pathlib import Path
from tools.console import pause_if_interactive, prompt_input
from tools.exiftool import require_exiftool
from tools.metadata_copy import copy_meaningful_metadata
def prompt_path(prompt: str) -> Path:
while True:
value = prompt_input(prompt).strip().strip('"')
path = Path(value).expanduser()
if path.is_file():
return path.resolve()
print("File not found. Enter a single file path.")
def choose_from_two(path_a: Path, path_b: Path) -> tuple[Path, Path] | None:
print("Choose metadata source:")
print(f"1: {path_a}")
print(f"2: {path_b}")
while True:
answer = prompt_input("Source file [1/2, Enter=1]: ").strip()
if answer == "" or answer == "1":
return path_a, path_b
if answer == "2":
return path_b, path_a
print("Please choose 1 or 2.")
def resolve_files(argv: list[str]) -> tuple[Path, Path] | None:
args = argv[1:]
if not args:
source = prompt_path("Source file: ")
destination = prompt_path("Destination file: ")
return source, destination
if len(args) != 2:
print("Error: provide exactly two files, or run without files to type paths.")
return None
paths = [Path(arg).expanduser().resolve() for arg in args]
missing = [path for path in paths if not path.is_file()]
if missing:
for path in missing:
print(f"File not found: {path}")
return None
return choose_from_two(paths[0], paths[1])
def copy_metadata(exiftool: str, source: Path, destination: Path) -> int:
print(f"Source: {source}")
print(f"Destination: {destination}", flush=True)
copy_meaningful_metadata(exiftool, source, destination)
return 0
def run(argv: list[str]) -> int:
try:
exiftool = require_exiftool()
except RuntimeError as exc:
print(exc)
return 1
try:
resolved = resolve_files(argv)
if resolved is None:
return 1
except RuntimeError as exc:
print(exc)
return 1
source, destination = resolved
if source == destination:
print("Source and destination must be different files.")
return 1
return_code = copy_metadata(exiftool, source, destination)
if return_code == 0:
print("Metadata copy complete.")
return return_code
def main(argv: list[str]) -> int:
try:
return run(argv)
finally:
pause_if_interactive()
if __name__ == "__main__":
raise SystemExit(main(sys.argv))