Metadata-Version: 2.4
Name: pibooth-gallery
Version: 1.3.0
Summary: pibooth plugin: thumbnails, thumbs.json manifest and static web gallery for event photobooths
Author: peteoheat
License-Expression: MIT
Project-URL: Homepage, https://github.com/peteoheat/pibooth-gallery
Project-URL: Issues, https://github.com/peteoheat/pibooth-gallery/issues
Keywords: pibooth,photobooth,raspberrypi,gallery,thumbnails,plugin
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Other Environment
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Multimedia :: Graphics
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pibooth>=2.0.0
Requires-Dist: Pillow
Dynamic: license-file

# pibooth-gallery

A plugin for [pibooth](https://github.com/pibooth/pibooth) that, after each final picture is saved:

1. creates a thumbnail,
2. creates/updates a `thumbs.json` manifest next to the pictures (newest first, with an optional QR code entry),
3. optionally copies a static gallery HTML template beside the pictures as `gallery.html`.

It is designed to work with [pibooth-rclone-upload](https://github.com/peteoheat/pibooth-rclone-upload) (uploads the picture folder to a web host or S3) and my fork of [pibooth-qrcode](https://github.com/peteoheat/pibooth-qrcode).

Together they give you a workflow where:

1. Final images are uploaded to a website or S3 bucket and are viewable in a browser.
2. QR codes are created and uploaded with each image, enabling direct download.
3. A web gallery lets guests scroll through all uploaded images for an event.

Optionally, [gallery-protect](https://github.com/peteoheat/gallery-protect) is a Cloudflare worker that password-protects the gallery so only people with the password can view/download images.

## Installation

Requires Python 3.7+, `pibooth` and `Pillow` (both installed automatically by pip).

The plugin must be installed **into the same Python environment that pibooth runs from**. pibooth discovers it automatically through its `pibooth` entry point, so no extra configuration is needed to load it.

### Raspberry Pi OS Bookworm / Trixie (virtual environment)

Since Bookworm, Raspberry Pi OS marks the system Python as "externally managed" (PEP 668), so `pip install` outside a virtual environment fails with `error: externally-managed-environment`. Do **not** work around this with `--break-system-packages`; install into the virtual environment that pibooth uses instead.

1. Activate the virtual environment pibooth is installed in. Use whatever path you created it at; `~/venv` is used here as an example:

   ```bash
   source ~/venv/bin/activate
   ```

   Your prompt should now start with `(venv)`. To check that this is the right environment, `pip show pibooth` should print pibooth's details.

   If you have not set up pibooth yet, create the environment first. `--system-site-packages` lets it use the Raspberry Pi camera libraries (`picamera2`) installed by apt:

   ```bash
   python3 -m venv --system-site-packages ~/venv
   source ~/venv/bin/activate
   pip install pibooth
   ```

2. Install the plugin from PyPI:

   ```bash
   pip install pibooth-gallery
   ```

3. Check that pibooth sees it:

   ```bash
   pibooth --diagnostic
   ```

   or start pibooth and look for `pibooth_gallery` in the loaded plugins list in the log.

To upgrade later (with the environment activated):

```bash
pip install --upgrade pibooth-gallery
```

If pibooth is launched automatically (autostart, systemd, cron), make sure the launcher uses the venv's interpreter, e.g. `~/venv/bin/pibooth`, otherwise the plugin will not be found.

### Other systems

```bash
pip install pibooth-gallery
```

(inside a virtual environment, or on a system where pip is not externally managed).

### From source

```bash
git clone https://github.com/peteoheat/pibooth-gallery.git
pip install ./pibooth-gallery
```

### Gallery HTML templates

The HTML templates (`plain_gallery_template.html`, `seasonal_snowflake_gallery_auto_update_template.html`, `candy_cane_lane_gallery.html`) are not installed into Python's site-packages. Download the one you want from the [GitHub repository](https://github.com/peteoheat/pibooth-gallery), edit the event-specific values in it (e.g. `IMAGE_HOST_BASE`, titles), and point `template` at it in `pibooth.cfg`.

## Configuration

After the first run, pibooth adds a `[GALLERY]` section to `~/.config/pibooth/pibooth.cfg` (you can also edit it with `pibooth --config`). Option names are lower case; there is no "enable" option. To disable the plugin, list `pibooth_gallery` in `[GENERAL]` `plugins_disabled`.

```ini
[GALLERY]
size = 300x300
suffix = _thumb
quality = 85
output_folder =
keep_aspect = True

update_manifest = True
manifest_name = thumbs.json
manifest_include_base_url = True

template = /home/pi/gallery_template.html
output = gallery.html

base_url = https://example.com/event123/
```

| Option | Default | Description |
|---|---|---|
| `size` | `300x300` | Thumbnail size as `WxH`. |
| `suffix` | `_thumb` | Suffix appended to the thumbnail filename. |
| `quality` | `85` | JPEG quality for thumbnails. |
| `output_folder` | *(empty)* | Optional subfolder for thumbnails. Leave empty when using pibooth-rclone-upload, which does not upload subfolders. |
| `keep_aspect` | `True` | Keep the aspect ratio when resizing. |
| `update_manifest` | `True` | Create/update the manifest after each picture. |
| `manifest_name` | `thumbs.json` | Manifest filename, written next to the pictures. |
| `manifest_include_base_url` | `True` | Prefix manifest entries with `base_url`. |
| `template` | *(empty)* | Optional path to a gallery HTML template to copy beside the pictures. |
| `output` | `gallery.html` | Filename for the copied template. |
| `base_url` | *(empty)* | Base URL for manifest entries. Falls back to `[DOWNLOADER]` `base_url`. |

### QR code integration

This plugin never adds or modifies `[QRCODE]` settings. To find a picture's QR code it uses, in order:

1. the `qrcode_path` recorded in pibooth's picture metadata, then
2. `<picture name><suffix>.<ext>` (from `[QRCODE]` `suffix`/`ext`, default `_qrcode` / `png`), searched in `[QRCODE]` `save_path`, the `[GENERAL]` `directory` entries, then the picture's own folder.

The QR image is already on disk when this plugin runs, so no waiting is needed.

## How it works

1. pibooth saves the final picture.
2. On leaving the processing state, pibooth-gallery (running before other plugins, so uploaders see its output):
   * creates the thumbnail,
   * sets `previous_thumbnail_file` on the pibooth app for other plugins,
   * updates or creates `thumbs.json`,
   * optionally writes `gallery.html` from the template.
3. All files are written atomically, so an uploader never sees a partial file. A corrupt manifest is moved to `thumbs.json.bak` rather than overwritten. Errors are logged and never interrupt pibooth.

## Manifest format

`thumbs.json` is a list, newest first:

```json
[
  {
    "thumb": "IMG_001_thumb.jpg",
    "full": "IMG_001.jpg",
    "filename": "IMG_001.jpg",
    "qrcode": "IMG_001_qrcode.png"
  }
]
```

With `manifest_include_base_url = True` and a `base_url`, `thumb`, `full` and `qrcode` become absolute URLs such as `https://example.com/event123/IMG_001.jpg`.

## Publishing to PyPI (maintainers)

The package version comes from `__version__` in `pibooth_gallery.py`.

```bash
# 1. bump __version__ in pibooth_gallery.py, commit and tag
python -m pip install --upgrade build twine
python -m build                 # creates dist/*.tar.gz and dist/*.whl
python -m twine check dist/*

# 2. optional dry run on TestPyPI
python -m twine upload --repository testpypi dist/*

# 3. publish (use a PyPI API token: username __token__)
python -m twine upload dist/*
```

PyPI never allows a version to be re-uploaded, so bump the version for every release.

## Contributing

Pull requests are welcome. Please open an issue for feature requests or bug reports.

## License

MIT, see [LICENSE](LICENSE).
