Daily Art backend: curated Met pool, daily cached pick, /api/art (prototype)
The engine for the /art room (design-independent; deploy held for Codex review).
- goodnews/art.py: harvest a curated pool of public-domain HIGHLIGHT artworks from the
Met (isHighlight+isPublicDomain+hasImages -> masterworks, never potsherds; CC0). Daily
deterministic pick from the least-recently-shown (no soon-repeats, same for everyone),
fetch metadata + download the image to OUR cache (data/art_cache) so the homepage never
waits on or hotlinks the museum. Bulletproof: bad object/image falls through candidates;
a failed day keeps the last piece (room never empty). Injectable HTTP for tests.
- Schema: art_pool + daily_art. /api/art/today (edge-cacheable) + /api/art/image/{id}
(served from cache, immutable). CLI `art [--harvest] [--force]` + a non-fatal cycle step.
- Tests (5, mocked HTTP) + verified live against the Met: harvested 1641 works,
picked/cached "Repose" by John White Alexander. 371 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -245,6 +245,32 @@ CREATE INDEX IF NOT EXISTS idx_article_places_article ON article_places(article_
|
||||
CREATE INDEX IF NOT EXISTS idx_article_places_country ON article_places(country_code);
|
||||
CREATE INDEX IF NOT EXISTS idx_article_geo_breadth ON article_geo(breadth);
|
||||
|
||||
-- Daily Art (the /art room). art_pool = a curated set of public-domain, highlighted
|
||||
-- museum object IDs (so the daily pick never hits a potsherd). daily_art = one cached
|
||||
-- piece per day (metadata + a locally-cached image), so the homepage never waits on or
|
||||
-- hotlinks the museum. shown_at lets us avoid repeating a piece too soon.
|
||||
CREATE TABLE IF NOT EXISTS art_pool (
|
||||
object_id INTEGER NOT NULL,
|
||||
source TEXT NOT NULL DEFAULT 'met',
|
||||
shown_at TEXT,
|
||||
added_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (source, object_id)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS daily_art (
|
||||
art_date TEXT PRIMARY KEY,
|
||||
source TEXT NOT NULL DEFAULT 'met',
|
||||
object_id INTEGER NOT NULL,
|
||||
title TEXT,
|
||||
artist TEXT,
|
||||
date_text TEXT,
|
||||
medium TEXT,
|
||||
department TEXT,
|
||||
credit TEXT,
|
||||
source_url TEXT,
|
||||
image_file TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Privacy-respecting, first-party analytics. NO IP / user-agent / referrer / raw
|
||||
-- URL. visitor_hash is a hash of a random localStorage token (never email/IP).
|
||||
-- The UNIQUE key dedups to one row per (kind, article, visitor, day) — that both
|
||||
|
||||
Reference in New Issue
Block a user