| docs | ||
| src | ||
| .gitignore | ||
| 0xIMG_50R7-1.0-1.rockspec | ||
| Makefile | ||
| README.md | ||
0xIMG_50R7
A photo organization tool that sorts images by trip and date.
Why?
Because I have a giant mess of travel photos, and some of them have been in Darktable.
Overview
0xIMG_50R7 organizes directories of photos by extracting EXIF date information and arranging them into a structured hierarchy. The tool supports resumable operations, allowing you to pause and restart processing without losing progress.
Input: A base directory that contains multiple trips with messy, nested folder structures:
input/
├── trip_1/
│ ├── Camera_Roll/
│ │ ├── IMG_1234.JPG (taken 2024-03-15 09:30:00)
│ │ ├── IMG_1234.JPG.xmp
│ │ └── IMG_1235.JPG (taken 2024-03-15 14:20:00)
│ ├── Phone_Backup/
│ │ ├── IMG_1234.JPG (duplicate, no xmp)
│ │ ├── IMG_9876.JPG (taken 2024-03-16 08:15:00)
│ │ ├── IMG_9876.JPG.xmp
│ │ └── random_subfolder/
│ │ ├── IMG_5555.JPG (taken 2024-03-15 09:35:00)
│ │ └── IMG_5555.JPG.xmp
│ └── Downloads/
│ └── edited_photo.jpg (taken 2024-03-16 10:00:00)
└── trip_2/
├── Day1/
│ ├── DSC_0001.NEF (taken 2023-08-10 06:00:00)
│ ├── DSC_0001.NEF.xmp
│ └── DSC_0002.NEF (taken 2023-08-10 06:05:00)
└── Day2/
├── DSC_0001.NEF (duplicate of Day1, same MD5)
└── DSC_0003.NEF (taken 2023-08-11 12:30:00)
Output: Clean hierarchy organized by trip and date with time-sorted, sequentially numbered files:
output/
├── trip_1/
│ ├── 2024-03-15/
│ │ ├── 2024-03-15_01.JPG (IMG_1234 from Camera_Roll)
│ │ ├── 2024-03-15_01.JPG.xmp (preserved from Camera_Roll)
│ │ ├── 2024-03-15_02.JPG (IMG_5555 from random_subfolder)
│ │ ├── 2024-03-15_02.JPG.xmp (preserved from random_subfolder)
│ │ └── 2024-03-15_03.JPG (IMG_1235)
│ └── 2024-03-16/
│ ├── 2024-03-16_01.JPG (IMG_9876)
│ ├── 2024-03-16_01.JPG.xmp (preserved)
│ └── 2024-03-16_02.jpg (edited_photo)
└── trip_2/
├── 2023-08-10/
│ ├── 2023-08-10_01.NEF (DSC_0001)
│ ├── 2023-08-10_01.NEF.xmp (preserved)
│ └── 2023-08-10_02.NEF (DSC_0002)
└── 2023-08-11/
└── 2023-08-11_01.NEF (DSC_0003)
Note: Duplicates are detected via MD5 and skipped. Files with XMP sidecars are prioritized over duplicates without sidecars.
Features
- Extracts and uses EXIF date/time metadata for sorting
- Organizes photos by trip and date
- Resumable processing with JSONL state tracking
- Duplicate detection via MD5 checksums
- Preserves XMP sidecar files
- Progress reporting and statistics
Sorting Logic
Photos are sorted using a multi-level approach:
- Primary sort: By date (from EXIF data)
- Secondary sort: By time with millisecond/microsecond precision when available
- Tertiary sort: By original filename order for photos with identical timestamps
Installation
Dependencies
- Lua 5.1 or later
- exiftool (for EXIF metadata extraction)
- dkjson 2.8-1 (Lua JSON library)
Installing Dependencies
Install dependencies using LuaRocks:
luarocks install --only-deps 0xIMG_50R7-1.0-1.rockspec
# or
luarocks install dkjson 2.8-1
Usage
Basic Usage
cd src
lua 0xIMG_50R7.lua <input_directory> <output_directory>
State Management
The tool uses a JSONL (JSON Lines) state tracking system that records:
- Processing progress for each day
- Completed file transfers
- Scan results and duplicate detection
- Trip-level processing cache
State files are stored in the output directory under .0xIMG_50R7_state/ and allow the tool to resume interrupted operations.
Processing Strategy
- Each trip is processed independently
- Images are not duplicated across trips
- No cross-trip deduplication is performed
- State is tracked per-day within each trip
File Naming
Output files are numbered sequentially within each day:
YYYY-MM-DD_01.jpg
YYYY-MM-DD_02.jpg
YYYY-MM-DD_03.jpg
Zero-padding adjusts based on the number of photos in each day.