A photo organizer for travelers
A Python tool to organize photo libraries by extracting EXIF metadata (GPS, dates, camera) and creating trip-based albums by moving files into organized folders.
- EXIF Metadata Extraction: Extract GPS coordinates, dates, camera info from photos
- GPS-based Trip Detection: Identify countries and cities using a database of 80+ cities worldwide
- Smart Trip Grouping: Automatically detect multi-country trips (gap β€ 3 days between countries)
- Album Organization: Move files into
YEAR - CountryorYEAR - TripNamefolders - Audit System: Verify album classification accuracy
- README Generation: Auto-generate album READMEs with Unsplash city images
# macOS
brew install exiftool
# Ubuntu/Debian
sudo apt-get install libimage-exiftool-perl
# Python 3.x (usually pre-installed)
python3 --version
git clone https://github.com/KnHack/wanderlens.git
cd wanderlens
# Edit configuration in photo_organizer.py
# Set PICTURES_BASE and ALBUMS_DIR to your paths
# 1. Analyze photos and extract EXIF metadata
python3 photo_organizer.py analyze "Camera Roll/2024"
# 2. Review GPS locations
python3 photo_organizer.py locations analysis_results/metadata_*.json
# 3. Create albums (moves files)
python3 photo_organizer.py create analysis_results/metadata_*.json
# 4. Audit albums (REQUIRED - verify classification)
python3 photo_organizer.py audit
# 5. Suggest trip groupings
python3 photo_organizer.py suggest-groups
# 6. Merge multi-country trips
python3 photo_organizer.py merge "2024 - Asia" "2024 - Japan" "2024 - South Korea"
# 7. Generate READMEs
python3 photo_organizer.py readme
| Command | Description |
|---|---|
analyze <folder> |
Extract EXIF metadata from photos to JSON |
locations <json> |
Analyze GPS locations and show country distribution |
create <json> |
Create album folders and move files |
audit |
Verify year and country match for all albums |
suggest-groups |
Identify trips that can be merged (gap β€ 3 days) |
merge <trip> <albums...> |
Merge multiple country albums into one trip |
readme [album] |
Generate README files for albums |
# Dry run (preview without making changes)
python3 photo_organizer.py analyze "Camera Roll/2024" --dry-run
python3 photo_organizer.py create metadata.json --dry-run
# Process specific album
python3 photo_organizer.py readme "2024 - Japan"
Edit the constants at the top of photo_organizer.py:
# Base paths
PICTURES_BASE = "/path/to/your/Pictures"
ALBUMS_DIR = f"{PICTURES_BASE}/Albums"
# Trip grouping
MAX_GAP_DAYS = 3 # Maximum days between countries to consider same trip
# Minimum photos for album creation
MIN_PHOTOS_FOR_ALBUM = 5
The tool automatically detects multi-country trips based on date proximity:
Grouping Logic:
- If gap between end of Country A and start of Country B is β€ 3 days β Same trip
- Use descriptive names: "Eurotrip", "Asia", "Morocco & Portugal"
Examples:
2018 - Eurotrip = France (Aug 7-8) + Italy (Aug 12-16) + Greece (Aug 17-19) + Spain (Aug 21-27)
2024 - Asia = Japan (Mar 17 - Apr 2) + South Korea (Apr 4-8)
2025 - Morocco & Portugal = Morocco (Aug 7-14) + Portugal (Aug 16-24)
Do NOT group:
- Trips with gaps > 3 days between countries
- Residence albums ("Life in X")
- Countries from same year but different months
Albums/
βββ 2024 - Asia/ # Multi-country trip [JP, KR]
β βββ metadata.json # Album metadata with summary
β βββ README.md # Auto-generated with city images
β βββ *.jpg, *.dng, *.mov # Photo/video files
βββ 2024 - Germany/ # Single country trip
βββ 2024 - Life in Austria/ # Residence album
βββ WithoutGPSInfo-2024/ # Photos without GPS data
βββ README.md # Main index
The tool uses a database of 80+ cities for accurate country detection:
CITIES_GPS = {
# Asia
(35.68, 139.69): ("Tokyo", "Japan"),
(35.01, 135.77): ("Kyoto", "Japan"),
(37.57, 126.98): ("Seoul", "South Korea"),
# Europe
(48.86, 2.35): ("Paris", "France"),
(41.90, 12.50): ("Rome", "Italy"),
(52.52, 13.41): ("Berlin", "Germany"),
# Americas
(40.71, -74.01): ("New York", "USA"),
(-23.55, -46.64): ("Sao Paulo", "Brazil"),
(-34.60, -58.38): ("Buenos Aires", "Argentina"),
# ... 80+ more cities
}
Falls back to country bounding boxes when no city match is found.
Important: The tool prioritizes filename date over EXIF metadata because camera dates can be misconfigured.
# Supported filename patterns
YYYYMMDD_HHMMSS.jpg # Android
IMG_YYYYMMDD_HHMMSS.jpg # iOS/Samsung
20240703_083732345_iOS.dng
Date Source Hierarchy:
- Filename (most reliable)
- FileModifyDate
- DateTimeOriginal (can be wrong)
- CreateDate
Auto-generated READMEs include:
- Country flag emoji and trip name
- Date range
- File type distribution (DNG, MOV, JPG, etc.)
- Cities visited with photo counts
- Unsplash images for each city
- Camera models used
- Date distribution
Example:
# π―π΅ 2024 - Japan
π
**Dates:** 17 March 2024 β 02 April 2024
π **Total files:** 577
## πΊοΈ Places Visited
### πΌ Tokyo (326 photos)

### β©οΈ Kyoto (75 photos)

These countries are geographically close. Use the city database:
- Berat (40.7, 19.95) β Albania
- Kotor (42.42, 18.77) β Montenegro
Long shared border causes confusion:
- Las LeΓ±as (-35.1, -70.1) β Argentina (ski resort near Chile)
Some cameras have incorrect date settings (e.g., 2002). Always use filename date.
1. analyze β Extract EXIF metadata to JSON
2. locations β Review country distribution
3. create β Create album folders and move files
4. audit β β οΈ VERIFY classification (required!)
5. fix β Move any misclassified files
6. suggest-groups β Identify trips to merge
7. merge β Combine consecutive country albums
8. readme β Generate album READMEs
Always run audit after creating albums to catch classification errors.
- Files may show 0 bytes locally until accessed
exiftooltriggers download when reading metadata- Processing speed: ~1 file/second
- Full year: 15-30 minutes depending on file count
If analysis produces JSON with null entries:
import json
with open('file.json', 'r') as f:
content = f.read()
content = content.replace('}\nnull\n,', '},')
data = json.loads(content)
with open('file.json', 'w') as f:
json.dump(data, f, indent=2)
wanderlens/
βββ photo_organizer.py # Main unified script
βββ generate_album_readme.py # README generator with city images
βββ README.md # This file
βββ LESSONS_LEARNED.md # Common errors and solutions
βββ analysis_results/ # Cached EXIF metadata (gitignored)
- Fork the repository
- Create a feature branch
- Add cities to
CITIES_GPSif needed - Submit a pull request
MIT License - See LICENSE file for details.