Filmcase is a Django application for managing Fujifilm camera recipes and browsing your image catalog. It reads EXIF data from your JPEG files, matches images to the Fujifilm recipe they were shot with, and lets you filter and group your catalog by recipe. You can push recipes directly to your camera over USB and explore relationships between recipes through an interactive graph.
Read more about it in our documentation index.

- Import Fujifilm JPEGs to build your image catalog and recipe collection, then browse them in a filterable gallery
- Push your recipes to your camera's custom slots over USB
- Browse and search your recipe collection with faceted filtering by film simulation, dynamic range, grain, and more
- Generate shareable recipe cards so other Fujifilm shooters can import your recipes
- Import recipes from a Fujifilm JPEG or a shared recipe card (QR code)
- Explore relationships between recipes through an interactive graph, compare differences side by side, and trace how your recipes evolved from one another
- View full-resolution images with their complete recipe and EXIF data
- Rate images (0–5 stars) individually or in bulk from the command line
- Sort the gallery by rating to surface your best shots first
- Customize the cover image shown for each recipe
Two installation modes are available depending on your needs:
| Lite (user-only) | Full (developer) | |
|---|---|---|
| Database | SQLite (file, no server) | PostgreSQL |
| Broker / worker | None | RabbitMQ + Celery |
| Image processing | Sequential (one at a time) | Parallel (N workers) |
| OS services to install | None | PostgreSQL, RabbitMQ |
| Best for | Personal use, small libraries | Development, large collections |
No database server or message broker required.
Clone and install system dependencies:
git clone <repo-url>
cd filmcase
./setup.sh lite # installs Python, libusb, exiftool (macOS and Ubuntu)Set up the project:
make setup-lite # creates venv, installs deps, generates SQLite config, runs migrations
make import PATH=/path/to/images # import your image collection
make run # start the development serverParallel image processing via Celery. Requires PostgreSQL and RabbitMQ.
Install system dependencies:
./setup.sh full # installs Python, libusb, exiftool, PostgreSQL, RabbitMQ (macOS and Ubuntu)This script is idempotent — re-running it skips anything already in place.
Set up the project:
make setup-full # creates venv, installs deps, generates PostgreSQL config, runs migrationsStart the server and worker:
make run # start the Django development server
make worker # start a Celery worker for parallel image processingTo pull the latest changes, install any new dependencies, and apply pending migrations in one step:
make updateFollow the steps below if you prefer to install dependencies individually.
Python 3.11+ is required.
- macOS:
brew install python - Ubuntu:
sudo apt install python3 python3-pip python3-venv
- macOS:
brew install libusb - Ubuntu:
sudo apt install libusb-1.0-0
-
macOS:
brew install postgresql@16 brew services start postgresql@16
Then create the database and user:
psql postgres
CREATE USER fujifilm_recipes WITH PASSWORD 'fujifilm_recipes'; CREATE DATABASE fujifilm_recipes OWNER fujifilm_recipes; \q
-
Ubuntu:
sudo apt install postgresql postgresql-contrib sudo systemctl start postgresql sudo -u postgres psql
CREATE USER fujifilm_recipes WITH PASSWORD 'fujifilm_recipes'; CREATE DATABASE fujifilm_recipes OWNER fujifilm_recipes; \q
- macOS:
brew install exiftool - Ubuntu:
sudo apt install libimage-exiftool-perl
- macOS:
brew install rabbitmq && brew services start rabbitmq - Ubuntu:
sudo apt install rabbitmq-server && sudo systemctl start rabbitmq-server
-
Clone the repository:
git clone <repo-url> cd filmcase
-
Create and activate a virtual environment:
python -m venv .venv source .venv/bin/activate -
Install dependencies:
pip install -r requirements.txt
-
Generate the settings file — choose one:
make env # full stack defaults (PostgreSQL, Celery) make env-lite # SQLite, sequential processing
-
Apply migrations:
python manage.py migrate
Before using the web interface, you need to process your images so their EXIF data and recipe information are stored in the database.
make import PATH=/path/to/your/imagesThe command behaves according to your install mode:
-
Lite install (
USE_ASYNC_TASKS=False): images are processed one at a time in the foreground. The terminal blocks until all images are done. -
Full install (
USE_ASYNC_TASKS=True): one Celery task is enqueued per image and processed in parallel by the worker. Start the worker first:make worker # or: celery -A src.config worker --loglevel=info --concurrency=8
Start the Django development server:
python manage.py runserverThen open http://localhost:8000/images/ in your browser to browse your image gallery. You can filter and group images by recipe, film simulation, and other settings.
Visit /images/ to see all processed images. Use the filter controls to narrow results by recipe, film simulation, white balance, and more.
Re-run make import PATH=… pointing at any directory containing new images. Already-processed images are updated in place with fresh EXIF data. Images without Fujifilm EXIF data are skipped.
Open any image in the detail view and click a star to assign a rating (0–IMAGE_MAX_RATING,
default 5). Use the ✕ button to clear it back to 0. Enable Rating first in the gallery
sidebar to sort by rating descending.
To rate a whole folder at once from the command line:
python manage.py rate_images /path/to/folder --rating=3Connect your Fujifilm camera in PTP mode, then open any image in the detail view. Name its recipe if it doesn't have one yet, and use the "Send to camera" button to write it to one of the custom slots (C1–C7).
For full information on available functionality, see docs/web_interface.md and docs/management_commands.md.
The only model this project has been tested on is the Fujifilm X-S10. Based on analysis of the PTP property codes used (custom slot registers 0xD18C–0xD1A5), any X-Trans IV camera (X-T3, X-T4, X-T30, X-T30 II, X-S10, X100V, X-Pro3, X-E4, X-H1) should work, and X-Trans V models (X-T5, X-T50, X-H2, X-H2S, X100VI, X-E5, X-M5) are likely compatible too. Earlier generations (X-Trans III and below) do not implement the custom slot registers and will not work.
If you test on a model not listed here, please open an issue to report the result.
We have observed experimentally that the camera firmware rejects invalid PTP property values — the X-S10 will not accept out-of-range or malformed writes, so mis-configured recipes should not be applied. That said, this software is provided as-is, with no warranty of any kind. We are not responsible for any damage, data loss, or malfunction caused to any camera or device by using this software. Use it at your own risk.
This project is licensed under the GNU General Public License v3.0.
Pull requests are welcome. See docs/contributing.md for the full guide: local environment setup, testing strategy, PR requirements, and review conventions.




