mirror of
https://github.com/kennethreitz/photos.kennethreitz.org.git
synced 2026-06-05 06:46:13 +00:00
dbdbdea109a6f33cee63d246448bb0ed3f2414b6
- Add Inter font via Google Fonts with proper preconnect - Nav: backdrop-filter blur with semi-transparent background - Image cards: hover-reveal overlay, inner zoom, shadow on hover - Gear/collection cards: hover lift with shadow - EXIF bar: rounded card style instead of bordered lines - Search inputs: accent focus glow ring - Homepage: display site tagline, more generous hero spacing - View Transitions API for smooth cross-page fades (Chrome 126+) - Animated loading pulse for infinite scroll - Global: smooth scroll, accent selection color, focus-visible - Radius 6px→8px, font smoothing, CSS custom properties - Fix stray </div> in base template - Disable hover transforms on mobile Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
photos.kennethreitz.org
A personal photography portfolio that organizes your work by the gear, places, and subjects that define it. Powered by EXIF metadata and AI. Codename: ExifTree.
Live: photos.kennethreitz.org
Features
- Browse by gear — Every camera and lens gets its own page with infinite scroll
- AI-powered metadata — GPT-4o-mini generates titles, descriptions, and tags for every photo
- Tag cloud — Thousands of AI-generated tags with word cloud discovery
- Cities — GPS coordinates are reverse-geocoded to browsable locations, grouped by country and state
- EXIF everywhere — Camera, lens, focal length, aperture, shutter speed, ISO, date taken
- Photo manager — Bulk select, visibility controls, faceted filtering by camera/lens/year
- Search — Full-text across titles, AI descriptions, and tags
- Infinite scroll — Shuffled, session-stable ordering across all pages
- Collections — Organize photos into curated sets
- Keyboard navigation — Arrow keys between images, O for original download
Stack
- Django 6 + django-bolt (async ASGI server with API)
- PostgreSQL on Fly.io (also used as Celery broker)
- Celery for async image processing and AI description generation
- Tigris (S3-compatible) for image storage
- HTMX for infinite scroll, vanilla JS where needed
- OpenAI GPT-4o-mini with structured output for image metadata
Management Commands
manage.py import_folder /path/to/photos # Bulk import from disk
manage.py import_flickr <username> # Import from Flickr
manage.py ai_describe # Backfill AI descriptions
manage.py ai_describe --tail # Watch and describe new images
manage.py geocode # Reverse geocode GPS to cities
manage.py cleanup # Run cleanup rules
manage.py dedupe # Remove visual duplicates
manage.py reprocess # Re-process stuck images
Development
brew install redis
brew services start redis
cp .env.example .env # Configure DATABASE_URL, AWS keys, etc.
make run
Deployment
Deployed on Fly.io with two processes (web + worker).
fly deploy
Description
Languages
Python
74.5%
HTML
16.8%
CSS
8%
Dockerfile
0.4%
Makefile
0.3%