---
name: catalog-work
description: Ingest a downloaded scan into the archive without OOMing the 2 GB VPS. Use when adding a work, generating thumbs, writing public/art JPEGs, computing PPI, or placing a print master versus a zoom view.
---

# Catalog Work

Pull pixels with the `pull-*` scripts into `tmp-scans/`. Then run this. Do not open the original in PIL, Sharp, ImageMagick, or `vips copy`.

## Layout

- `tmp-scans/` — originals. Gitignored. Disk, not `/tmp`. Print masters stay here.
- `public/art/thumbs/<slug>.jpg` — 480 px shelf card. The only pixel file that stays on this VPS and in git.
- R2 — default. Uploads the ≤16000 view, 2560 preview, Deep Zoom tiles, and optional print master to `morgangoins-art` and serves them from `https://media.morgangoins.org`.
- `--overflow local` — keep the full JPEG on this box. Do not use this for new works.

`catalog()` defaults every work to R2. Set `view` only when it is a smaller derivative of a huge print master (Europa). Set `overflow: "local"` only if a scan must stay on the VPS.

## Command

```
node scripts/catalog-work.mjs --from tmp-scans/original.jpg --slug rm-laughing
node scripts/catalog-work.mjs --from tmp-scans/europa-16k.jpg --slug rm-abduction-europa --pixels-from tmp-scans/europa-42k.jpg
node scripts/catalog-work.mjs --from tmp-scans/as11-40-5927.jpg --slug eagle-tranquility --inches 2.20
node scripts/r2.mjs ensure
```

Prints width, height, and PPI if `--inches` is set (`31x25.4375` or `2.20`). Apollo stills are `2.20×2.20`.

The script refuses a `--from` file whose long edge is over 20000 px. Downsample off-box or pass a pre-made ≤16000 viewer file and `--pixels-from` the original. Do not `vips thumbnail` the 42k Europa on this box. `vips` on this VPS also refuses those files; do not set `VIPS_NO_MEMCAP=1`.

`--pixels-from` is measured for `pixels` / `ppi` and uploaded to `art/masters/<slug>.jpg`. The viewer never loads that key. After a successful R2 catalog, the `--from` file is removed from `tmp-scans/` if it is not also the print master.

Needs `rclone` plus `R2_ACCESS_KEY_ID` / `R2_SECRET_ACCESS_KEY` in `.env` so large files are not read into RAM.

## Queued until more RAM

This 2 GB box cannot catalog these. When RAM is upgraded, remind the owner and ingest:

1. Commons `File:The Night Watch - HD.jpg` (`57813×48438`) — 16k view + `--pixels-from`, R2 overflow. Commons `?width=16000` still returns 3840.
2. Commons *Return of the Prodigal Son* GAP (`22991×30000`) — same pattern.
3. Still do not stitch Operation Night Watch (717 GP / 5.6 TB). dezoomify-rs does not support Micrio.

## Thumbs for the whole shelf

```
python3 scripts/generate-thumbs.py
```

Uses `vips thumbnail`, not PIL. Skips files over 20000 px. R2 overflow works have no local original, so generate their thumbs from `tmp-scans/` during catalog.

## Collection row

Keep `sourceImage` as the URL we downloaded and set `recordUrl`. `pixels` and `ppi` are from the original, not the 16k view. Same artwork only — see `known-source-failures`.

Deploy writes every work into `/.well-known/image-sources.json` and the generated lists in the `pull-*` / `museum-records` skills. Do not maintain those lists by hand.
