From 5a00dc1ecd6b18d2407f1585380e62720197a731 Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 28 Jun 2026 18:36:12 +0200 Subject: [PATCH] feat: show EXIF field name in output (DateTimeOriginal/Digitized/DateTime) --- organize.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/organize.py b/organize.py index d62fdc0..fe43096 100644 --- a/organize.py +++ b/organize.py @@ -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