Eats by Snorlax

Photos → places

Turn the camera roll into the food map. Three commands.

# 1. FIND — read the Photos library, match geotagged food photos to _places/
python3 tools/photo-scan.py --scan 2025 2026

# 2. PICK — open a contact sheet, choose the keepers, fix wrong names
python3 tools/photo-picker.py --candidates

# 3. IMPORT — convert only what you picked, into the repo
python3 tools/photo-import.py ~/Downloads/selections.json          # dry run
python3 tools/photo-import.py ~/Downloads/selections.json --apply

Then git status, look at what changed, commit.

Why three steps

The scan is slow (~2 min per year) and cached. Picking is the part only you can do. Importing is cheap. Keeping them separate means you scan once and pick as many times as you like.

Scanning

Merges into .photo-scan-cache.json by photo ID, so it’s resumable — run a year, stop, come back. Filters to photos Apple labelled Food, Meal, Dish, Restaurant, Dessert, Seafood or Fast Food, which cut 2026 from 2,884 geotagged photos to 848. --all-photos turns that off.

Picking

Work a slice at a time — the whole decade at once is a wall:

python3 tools/photo-picker.py --city "Chicago"
python3 tools/photo-picker.py --from-date 2026-06-01
python3 tools/photo-picker.py --candidates      # clusters with no pin yet

Each block is one sitting — photos split on a 3-hour gap, because a bunch of photos is a meal. Two dinners at one address are two blocks.

In the page: click to keep, shift-click to set the cover, edit the name if the match is wrong. Picks are saved in the browser as you go.

The thing to watch

Coordinate matching cannot say “none of these” — it snaps to the nearest pin within 40m even when the real restaurant was never pinned. 42 photos matched “Dim Sum Palace” from 52m away when they were taken at BINONDO by Kabisera. Headers flag the shaky ones (“34m from the pin”, “also near…”). Hit ✗ wrong place, type the real name, and the import creates that place at the photos’ own coordinates.

What gets written

img/places/<slug>/NN.jpg plus a .webp sibling, 1600px long edge. Both are required: bgImage() serves them as an image-set pair and image-set does not fall back on a 404, so a missing .webp is a broken background.

Originals are never copied in. A 12MP HEIC in git is carried in history forever, even after deletion.

Needs

brew install exiftool webp and brew install rhettbull/osxphotos/osxphotos, plus Full Disk Access for the terminal so osxphotos can read the library.