← back to CelebritySignatures
snapshot before removing alive celebrities
3c6f4922a957426a12b7734dd837a0a20a9d18d3 · 2026-06-19 09:35:00 -0700 · SteveStudio2
Files touched
M scripts/build-collages.pyM scripts/build-portrait-murals.py
Diff
commit 3c6f4922a957426a12b7734dd837a0a20a9d18d3
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Fri Jun 19 09:35:00 2026 -0700
snapshot before removing alive celebrities
---
scripts/build-collages.py | 19 +++++++++++++++++--
scripts/build-portrait-murals.py | 26 +++++++++++++++++++++++---
2 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/scripts/build-collages.py b/scripts/build-collages.py
index 19c8616..2ac15a1 100644
--- a/scripts/build-collages.py
+++ b/scripts/build-collages.py
@@ -260,12 +260,27 @@ def build(category, rows):
return made
+def _death_year(r):
+ m = re.search(r"\b(1[0-9]\d\d|20\d\d)\b", str(r.get("death_date") or ""))
+ return int(m.group(1)) if m else None
+
+
def main():
+ # SAFE_ONLY: keep only people who died ≤1956 — clear of California's 70-year
+ # postmortem right of publicity (§3344.1) for commercial sale.
+ safe_only = bool(os.environ.get("SAFE_ONLY"))
data = json.load(open(DATA))
by = {}
for r in data:
- if r["usable_in_commercial_collage"] == "yes":
- by.setdefault(r["category"], []).append(r)
+ if r["usable_in_commercial_collage"] != "yes":
+ continue
+ if safe_only:
+ y = _death_year(r)
+ if y is None or y > 1956:
+ continue
+ by.setdefault(r["category"], []).append(r)
+ if safe_only:
+ print("⚖️ PUBLICITY-SAFE mode: only people who died ≤1956\n")
order = ["Declaration of Independence", "Politics", "Sports", "Hollywood", "Movies (Classic)", "Movies", "TV"]
made = []
print(f"QR target host: {BASE_URL}\n")
diff --git a/scripts/build-portrait-murals.py b/scripts/build-portrait-murals.py
index f942105..9a3fdad 100644
--- a/scripts/build-portrait-murals.py
+++ b/scripts/build-portrait-murals.py
@@ -214,7 +214,8 @@ def render(category, cells, named, slug, with_portrait, total):
"Portraits used only where public-domain / openly licensed; others shown by signature alone. Living-celebrity rows excluded.",
font=font(13), fill=MUTED)
suffix = "-named" if named else ""
- path = os.path.join(OUT, f"portrait-{slug}{suffix}.png")
+ prefix = "portrait-safe-" if os.environ.get("SAFE_ONLY") else "portrait-"
+ path = os.path.join(OUT, f"{prefix}{slug}{suffix}.png")
canvas.save(path, "PNG")
print(f"[{category}] -> {os.path.basename(path)} ({n} cells, {with_portrait} portraits, {cols}×{rows_ct}, {W}×{H})")
return path
@@ -249,12 +250,31 @@ def build(category, rows, slug):
render(category, cells, False, slug, with_portrait, len(cells))]
+def death_year(r):
+ m = re.search(r"\b(1[0-9]\d\d|20\d\d)\b", str(r.get("death_date") or ""))
+ return int(m.group(1)) if m else None
+
+
+# Publicity-rights gate: California §3344.1 protects a deceased personality's
+# name/likeness/signature for 70 YEARS after death. So only people who died on or
+# before this cutoff are clear of right-of-publicity exposure for commercial sale.
+PUBLICITY_SAFE_CUTOFF = 1956 # 2026 − 70
+
+
def main():
which = (sys.argv[1] if len(sys.argv) > 1 else "all").lower()
+ safe_only = bool(os.environ.get("SAFE_ONLY"))
data = json.load(open(DATA)); by = {}
for r in data:
- if r["usable_in_commercial_collage"] == "yes":
- by.setdefault(r["category"], []).append(r)
+ if r["usable_in_commercial_collage"] != "yes":
+ continue
+ if safe_only:
+ y = death_year(r)
+ if y is None or y > PUBLICITY_SAFE_CUTOFF: # unknown/too-recent → exclude
+ continue
+ by.setdefault(r["category"], []).append(r)
+ if safe_only:
+ print("⚖️ PUBLICITY-SAFE mode: only people who died ≤", PUBLICITY_SAFE_CUTOFF, "\n")
order = ["Declaration of Independence", "Politics", "Sports", "Hollywood", "Movies (Classic)", "TV"]
print(f"Portrait murals · QR host {BASE_URL}\n")
made = []
← 11d1aad Accounts + save-your-placement: zero-dep email/password auth
·
back to CelebritySignatures
·
remove all living celebrities; keep only deceased (publicity 8def5d9 →