Restore React client source, add hall-to-hall navigation via painting influences grouped by movement, and update documentation. Co-authored-by: Cursor <cursoragent@cursor.com>
3.5 KiB
Art Gallery — data and images
How catalog content and artwork files enter the system.
Principles
- No runtime hot-linking — the UI reads from
/images/…(local disk). External URLs are used only during ingest. - No AI-generated art or text — biographies and descriptions come from Wikipedia; influence notes from curated art-history sources.
- Local copies — every displayed image should exist under
data/images/after seeding or fetch.
Directory layout
data/images/
├── portraits/ # Artist headshots
│ └── Claude_Monet.jpg
└── paintings/
├── Claude_Monet_Water_Lilies.jpg
└── thumbs/
└── Claude_Monet_Water_Lilies_thumb.jpg
File names are sanitised {Artist}_{Title}.{ext}. The image service can rediscover files on disk even when DB paths are empty (server/image-service.js → syncPaintingFromDisk).
Seeding pipeline
npm run seed runs scripts/seed-wikipedia.js, which:
- Inserts historical eras and art movements (curated date ranges and colours).
- For each curated artist:
- Fetches Wikipedia intro text for
bio_short/bio_full. - Downloads a Commons portrait into
portraits/. - Creates artist periods and paintings.
- Downloads painting images into
paintings/.
- Fetches Wikipedia intro text for
- Writes painting_influences edges from curated scholarship references.
Those influence edges also power 3D hall navigation: predecessors and successors at each artist’s exit doorway are computed from this table (see GET /api/artists/:id/navigation in API.md).
Artists are grouped by movement and century; the seed list targets at most ~100 artists per century.
On-demand image resolution
When a painting has no local file, GET /api/paintings/:id/image triggers ensurePaintingImages():
- Check DB paths → verify file on disk.
- Scan disk by
{artist}_{title}pattern. - If still missing and
wikipedia_titleis set, callscripts/image-fetcher.js:- Wikidata → Wikimedia Commons → Wikipedia page image
- Fallbacks: Met Museum, Art Institute of Chicago, Rijksmuseum APIs
- Save full + thumbnail, update DB, serve file.
Requests are deduplicated (inflight map) and timeout after 15 seconds. A 2.5 s delay between external requests reduces rate-limit risk.
Preload before 3D gallery
POST /api/artists/:id/preload-images runs local-only linking — no network. Call this when entering an artist’s 3D hall so textures use files already on disk.
The 3D scene uses galleryImageUrl(), which never hits the on-demand API (remote latency breaks WebGL texture loading).
Placeholders
When no image is available:
/placeholder-portrait.svg— timeline / movement band portraits/placeholder-art.svg— paintings in lists and detail view
These live in client/public/ (and client/dist/ after build).
Adding new artists manually
- Insert rows into
artists,artist_periods,paintings(or extend theARTISTSarray in the seed script). - Place image files under
data/images/using the naming convention. - Run
npm run sync-image-pathsif that script is available, or rely on preload / on-demand sync. - Add influence rows to
painting_influenceswith citation fields where possible.
Image fetcher overrides
scripts/image-fetcher.js includes hand-maintained overrides for ambiguous Wikipedia titles and direct URLs (e.g. works whose Commons name does not match the article title). Extend PAINTING_WIKI_OVERRIDES and DIRECT_IMAGE_OVERRIDES when automated resolution fails.