Photo gallery widget and management system for Wild Apricot organizations. Features AI-powered tagging, face recognition, event matching, and an embeddable gallery widget.
Repository: https://github.com/sbnctech/clubgallery
- Photo Submission: Accept photos via email or web upload
- AI Processing: Automatic EXIF extraction, GPS-based event matching, face recognition
- Face Recognition: Match faces to members, prioritize event RSVPs
- Admin Review: Web interface for approving photos and confirming face IDs
- Gallery Widget: nanogallery2-based display with filtering by member, event, activity, year
- Wild Apricot Integration: Sync members, events, and registrations
- Python 3.10+
- SQLite (built-in)
- System packages:
- cmake, boost (for dlib/face_recognition)
- exiftool (for EXIF writing)
# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install Python packages
pip install -r requirements.txt
# System dependencies
# Ubuntu: sudo apt install cmake libboost-all-dev libimage-exiftool-perl
# macOS: brew install cmake boost exiftoolcp .env.example .env
# Edit .env with your credentialspython -c "from app.database import init_db; init_db()"python -c "from app.main import create_admin_user; create_admin_user('admin@example.com', 'password', is_super_admin=True)"# Sync members and events from Wild Apricot
python scripts/sync_wa_data.py
# Build face database from member photos
python scripts/build_face_database.pypython app/main.pyVisit:
- Gallery: http://localhost:5000/gallery
- Admin: http://localhost:5000/admin
- Upload: http://localhost:5000/upload
clubgallery/
├── app/
│ ├── config.py # Configuration
│ ├── database.py # SQLite database
│ ├── main.py # Flask app factory
│ ├── ingest/ # Photo ingestion
│ │ ├── email_monitor.py # IMAP inbox processing
│ │ ├── upload_handler.py # Web uploads
│ │ └── queue_manager.py # Processing queue
│ ├── processing/ # AI processing
│ │ ├── exif_extractor.py # EXIF metadata
│ │ ├── event_matcher.py # GPS/date event matching
│ │ ├── face_detector.py # Face recognition
│ │ ├── thumbnail_creator.py
│ │ ├── tag_generator.py
│ │ └── pipeline.py # Full processing workflow
│ ├── sync/ # Wild Apricot sync
│ │ ├── wa_api.py # WA API client
│ │ ├── member_sync.py # Member/event sync
│ │ └── wa_webdav.py # WebDAV backup
│ ├── admin/ # Admin interface
│ │ ├── routes.py
│ │ ├── auth.py
│ │ ├── templates/
│ │ └── static/
│ └── gallery/ # Public gallery
│ ├── routes.py
│ ├── static/sbnc-gallery-widget.js
│ └── templates/
├── scripts/ # Utility scripts
├── data/ # SQLite database (gitignored)
├── photos/ # Photo storage (gitignored)
├── requirements.txt
└── .env # Configuration (gitignored)
- Submission: Photo received via email or web upload
- Queue: Added to processing queue
- EXIF Extraction: Date, GPS, camera info extracted
- Event Matching: Match to WA event by date + GPS
- Face Detection: Find all faces in photo
- Face Recognition: Match faces to members (prioritize event RSVPs)
- Tag Generation: Create searchable tags
- Admin Review: Confirm face IDs, approve for publishing
- Gallery: Display in public gallery with smart filtering
GET /api/gallery.json- Gallery data for nanogallery2GET /api/events.json- Events list for filtersGET /api/members.json- Members list for searchGET /api/activities.json- Activity groups
GET /admin/- DashboardGET /admin/queue- Review queueGET /admin/photo/<id>- Photo editorPOST /admin/photo/<id>/face- Update face IDPOST /admin/photo/<id>/approve- Approve photo
See .env.example for all configuration options.
Key settings:
WA_API_KEY- Wild Apricot API keyWA_ACCOUNT_ID- Wild Apricot account IDIMAP_HOST- Email server for photo submissionsIMAP_USER- Email account usernameIMAP_PASSWORD- Email account passwordFACE_MATCH_HIGH_CONFIDENCE- Threshold for auto-tagging (default 0.4)
- Architecture Overview - System design and data model
- Wild Apricot Embed Instructions - Embedding the widget
See docs/ for deployment guides:
- Nginx configuration
- Gunicorn/systemd setup
- Cron job scheduling
- clubcalendar - Event calendar widget for Wild Apricot
MIT License - see LICENSE file