feat: show EXIF field name in output (DateTimeOriginal/Digitized/DateTime)
This commit is contained in:
1 parent
6a0fe3c163
commit
5a00dc1ecd
1 file changed
+26
-9
+26
-9
@@ -83,6 +83,17 @@ def _c(text: str, colour: str, *, no_color: bool = False) -> str:
|
||||
|
||||
# ── EXIF extraction (JPEG — piexif, 5-10x faster than PIL) ──────────────────
|
||||
|
||||
# Tracks the last EXIF field name used (for display in output)
|
||||
_last_exif_field = ''
|
||||
|
||||
_EXIF_FIELD_NAMES = {36867: 'DateTimeOriginal', 36868: 'DateTimeDigitized', 306: 'DateTime'}
|
||||
|
||||
|
||||
def _set_last_field(tag_id: int) -> None:
|
||||
global _last_exif_field
|
||||
_last_exif_field = _EXIF_FIELD_NAMES.get(tag_id, f'Tag#{tag_id}')
|
||||
|
||||
|
||||
def _read_jpeg_exif_piexif(path: Path) -> str | None:
|
||||
"""Read DateTimeOriginal from a JPEG using piexif (no PIL needed).
|
||||
|
||||
@@ -97,13 +108,14 @@ def _read_jpeg_exif_piexif(path: Path) -> str | None:
|
||||
|
||||
exif = exif_dict.get('Exif', {})
|
||||
image = exif_dict.get('Image', {})
|
||||
raw = (exif.get(piexif.ExifIFD.DateTimeOriginal) or
|
||||
image.get(piexif.ImageIFD.DateTime))
|
||||
if raw:
|
||||
try:
|
||||
return raw.decode('utf-8')
|
||||
except Exception:
|
||||
return None
|
||||
for tag_id in (piexif.ExifIFD.DateTimeOriginal, piexif.ExifIFD.DateTimeDigitized, piexif.ImageIFD.DateTime):
|
||||
raw = exif.get(tag_id) or image.get(tag_id)
|
||||
if raw:
|
||||
_set_last_field(tag_id)
|
||||
try:
|
||||
return raw.decode('utf-8')
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
@@ -125,9 +137,10 @@ def _read_jpeg_exif_pil(path: Path) -> str | None:
|
||||
return None
|
||||
|
||||
tag_map = {v: k for k, v in TAGS.items()}
|
||||
for tag_name in ('DateTimeOriginal', 'DateTime'):
|
||||
for tag_name in ('DateTimeOriginal', 'DateTime', 'DateTimeDigitized'):
|
||||
tag_code = tag_map.get(tag_name)
|
||||
if tag_code and tag_code in raw:
|
||||
_set_last_field(tag_code)
|
||||
return raw[tag_code]
|
||||
return None
|
||||
|
||||
@@ -168,9 +181,10 @@ def _read_other_exif_pil(path: Path) -> str | None:
|
||||
return None
|
||||
|
||||
tag_map = {v: k for k, v in TAGS.items()}
|
||||
for tag_name in ('DateTimeOriginal', 'DateTime'):
|
||||
for tag_name in ('DateTimeOriginal', 'DateTime', 'DateTimeDigitized'):
|
||||
tag_code = tag_map.get(tag_name)
|
||||
if tag_code and tag_code in raw:
|
||||
_set_last_field(tag_code)
|
||||
return raw[tag_code]
|
||||
return None
|
||||
|
||||
@@ -189,6 +203,7 @@ def _read_cr2_exif(path: Path) -> str | None:
|
||||
):
|
||||
raw_val = exif_dict.get(ifd_name, {}).get(tag_id)
|
||||
if raw_val:
|
||||
_set_last_field(tag_id)
|
||||
return raw_val.decode('utf-8')
|
||||
except Exception:
|
||||
pass
|
||||
@@ -204,6 +219,7 @@ def _read_cr2_exif(path: Path) -> str | None:
|
||||
for tag_code in (36867, 36868, 306): # DateTimeOriginal, Digitized, DateTime
|
||||
val = raw.get(tag_code)
|
||||
if val:
|
||||
_set_last_field(tag_code)
|
||||
return val
|
||||
except Exception:
|
||||
pass
|
||||
@@ -358,6 +374,7 @@ def organize(
|
||||
# ── Track stats ────────────────────────────────────────────────
|
||||
if from_exif:
|
||||
exif_count += 1
|
||||
date_source_label = _last_exif_field or 'EXIF'
|
||||
else:
|
||||
fs_count += 1
|
||||
year_counts[dt.year] += 1
|
||||
|
||||
Reference in new issue
Block a user