Metadata-Version: 2.5
Name: mkgallery
Version: 0.1.0rc2
Summary: Summarise a photo collection as a single gallery page
License-Expression: PolyForm-Noncommercial-1.0.0
License-File: LICENSE.txt
Requires-Python: >=3.10
Requires-Dist: click
Requires-Dist: imagehash
Requires-Dist: jinja2
Requires-Dist: numpy
Requires-Dist: pillow>=10
Requires-Dist: platformdirs
Requires-Dist: pyexiftool
Requires-Dist: rawpy
Requires-Dist: scikit-learn
Requires-Dist: scipy
Description-Content-Type: text/markdown

# mkgallery

Summarise a large photo collection — say, a year — as **one static page**: a title and a
gallery of the most interesting pictures, picked automatically.

```
mkgallery ~/Photos/2025 --title "2025"
```

writes `2025.html` and a `2025_assets/` directory next to it. Nothing in the source
directory is touched, and no configuration is read from it.

## Requirements

- Python ≥ 3.10
- [`exiftool`](https://exiftool.org/) on `PATH`
- Formats: JPEG, PNG, WebP, TIFF and RAW (CR2, CR3, NEF, ARW, DNG)

## Install

```
pipx install .        # or: hatch run mkgallery …
```

## Usage

```
mkgallery SRC --title TITLE [options]
```

| Option | Default | |
|---|---|---|
| `-t, --title` | required | Page title; also names `TITLE.html` / `TITLE_assets/` |
| `-n, --count` | 48 | Number of images shown |
| `-o, --output-dir` | `.` | Where to write the output (must not be inside `SRC`) |
| `--order` | `chronological` | `chronological`, or `varied` (neighbours are as dissimilar as possible) |
| `--event-quota / --no-event-quota` | off | Every event (a run of days with photos, gaps over 24 h split events) gets at least one image; the other slots are shared in proportion to the square root of the event size |
| `--balance` | 1 | 0–1. Down-weights images in crowded regions when clustering: 0 treats every image alike, 1 gives sparse regions the same weight as dense ones |
| `--cache-dir` | user cache dir | Analysis cache (must not be inside `SRC`) |
| `--no-cache` | | Do not read or write the cache |
| `-j, --jobs` | CPU count | Parallel workers |

## How images are chosen

The selection is ported from [mkmapdiary](https://github.com/bytehexe/mkmapdiary)'s front page:

1. Each image is analysed from a small preview (for RAW files the embedded JPEG — nothing
   is developed at this stage): sharpness, contrast, entropy, perceptual and colour hashes.
   Results are cached by path, size and modification time.
2. Near-duplicates (per day), unusually soft images and flat, low-entropy images are dropped.
3. The rest is clustered by colour and capture time into `--count` groups; the sharpest,
   best-contrast image of each group is chosen. The picks therefore spread over the whole
   year and over different looks. With `--event-quota` (off by default) this is done per event,
   so a few photos from a small trip are not lost among thousands from a long holiday.
4. Only the chosen images are converted (RAW files are developed here) into a thumbnail and
   a 1600 px version.

## Credits and licences

mkgallery is licensed under the [PolyForm Noncommercial License 1.0.0](LICENSE.txt).

The generated page bundles these libraries (all MIT licensed). Their licence texts and
copyright notices are shipped in `TITLE_assets/lib/<name>/` and in
`src/mkgallery/vendor/`:

- [jQuery](https://jquery.com)
- [Justified Gallery](https://github.com/miromannino/Justified-Gallery) — the row layout
- [GLightbox](https://github.com/biati-digital/glightbox) — the lightbox

The selection approach and metric code are adapted from mkmapdiary (same author).
