Modular CLI toolset for automating photo workflows.
Note: This project serves as an experiment for AI-assisted development using Cursor as IDE. The codebase is a mix of hand-written and AI-generated code, developed in parallel. Project rules are defined in
.cursor/rules/*.mdcto ensure consistent AI behaviour. Contributors are welcome to use these rules or add new ones.
Features:
- Import from SD cards with automatic sorting and renaming
- EXIF/IPTC/XMP metadata management
- Album management with symlinks (saves disk space)
- RAW development to JPG (darktable-cli, ImageMagick, or RawTherapee)
- Integrity verification with checksums
# 1. External dependencies (macOS)
brew install exiftool python3 darktable imagemagick rawtherapee
# 2. Run setup (creates venv, installs Python deps)
./setup.sh
# 3. Optional: Add to PATH
echo 'export PATH="$PATH:'$(pwd)'/bin"' >> ~/.zshrcThe setup script:
- Creates a Python virtual environment (
.venv/) - Installs Python dependencies
- Checks external tools (exiftool, darktable, rawtherapee, etc.)
Note for macOS: The darktable formula may be deprecated or removed from Homebrew. You can use brew install --cask darktable, install from darktable.org, or use ImageMagick or RawTherapee with pg-develop instead.
- Creates
.envfrom template
pg-import /Volumes/EOS_DIGITAL --event "Endurotraining" --location "Stadtoldendorf"Photos are sorted into ~/Pictures/PhotoLibrary/2026-01-24/ and renamed.
For large imports (skip copy verification, skip EXIF during import, no checksum files), see doc/workflow.en.md (section Fast import).
pg-album create "Alps_Tour_Highlights"
pg-album add "Alps_Tour_Highlights" ~/Pictures/PhotoLibrary/2026-01-24/*.jpgpg-develop ~/Pictures/PhotoLibrary/2026-01-24/*.cr3 --output ~/Desktop/jpgs/pg-album export "Alps_Tour_Highlights" --to ~/Desktop/ForRiders/Run from the project root with ./setup.sh done (or add bin to PATH as in Installation). Adjust volume paths and event names.
GENERATE_CHECKSUMS=false pg-import /Volumes/EOS_DIGITAL \
--output /Volumes/SanDisk/Bilder \
--event "your_event_name" \
--location "" \
--no-verify-copy \
--no-metadata \
--no-deleteApply metadata later with pg-exif (see workflow — Fast import).
./examples/holiday-import.sh /Volumes/EOS_DIGITAL --fast --output /Volumes/SanDisk/Bilder--fast skips copy verification and disables .checksums during import; metadata from .import.yaml / .env is still written.
Copy examples/daily-offload.sh, edit the configuration block at the top, then run:
./examples/daily-offload.sh /Volumes/EOS_DIGITAL --output /Volumes/SanDisk/Bilder --fast --yes--fast uses a fast pg-import then batch pg-exif; --yes skips the script’s confirmation prompt. More detail: Examples.
| Script | Description |
|---|---|
pg-import |
Import from SD card with sorting and EXIF tagging |
pg-rename |
Rename according to configurable pattern |
pg-exif |
Set/show EXIF metadata |
pg-album |
Album management with symlinks |
pg-develop |
RAW to JPG development |
pg-verify |
Checksum-based integrity verification |
# .env - Global settings
PHOTO_LIBRARY="$HOME/Pictures/PhotoLibrary"
DEFAULT_AUTHOR="Max Mustermann"
FOLDER_STRUCTURE="{year}-{month}-{day}"# .import.yaml on SD card - Per-import settings
event: "Endurotraining Tag 1"
location: "Stadtoldendorf"Priority: CLI arguments → environment variables → .env → .import.yaml
- Workflow - Complete workflow guide
- Configuration - All settings explained
- Script Reference - Detailed options for all scripts
- Examples - Complete workflow examples
- RawTherapee preset research - Why we don't ship a Kodak-style preset; where to get one
German documentation:
Run the test suite before submitting changes:
make test # Run all tests
make test-fast # Skip slow tests
make test-coverage # Generate coverage reportTests are in tests/ using pytest. All new features require tests.
This project uses Cursor rules (.cursor/rules/*.mdc) to guide AI assistants:
| Rule | Purpose |
|---|---|
languages.mdc |
Only Bash and Python; Python must run in venv |
bash-compatibility.mdc |
Enforce Bash 3.2 compatibility (macOS default) |
bilingual-docs.mdc |
Maintain documentation in German and English |
shellcheck.mdc |
Require ShellCheck validation for all scripts |
testing-requirements.mdc |
All features require tests that pass |
git-commits.mdc |
Small commits with action-prefixed messages |
When contributing with an AI assistant, these rules ensure consistent code style and project conventions.