#!/usr/bin/env python3 """Build Monster High picker v4. v3 + Sam's adjustments: - each burst collapses to ONE grid cell (animated first frame, gold highlight, "GIF xN") - tapping a burst cell opens its group view: all frames, tap one to enlarge + favorite - lightbox arrows/swipe navigate the full sequence (singles + burst frames in order) - static fallback (FBQ, no JS): all photos shown individually with GIF badges Usage: python3 build_picker_v4.py bursts.json """ import json, sys from pathlib import Path SHOOT = Path("/Volumes/Sam Storage/YellowMellow/2026/Monster High Theme (10:01:2026)") PRE = SHOOT / "ClientPicker" / "Previews" OUT = SHOOT / "Monster High - Photo Picker.html" ids = sorted(p.stem for p in PRE.glob("*.jpg") if not p.name.startswith("._")) assert ids, "no previews" blur_manifest = SHOOT / "BlurReview" / "BlurManifest.json" if blur_manifest.exists(): blur_ids = set(json.loads(blur_manifest.read_text()).get("confirmed", [])) ids = [pid for pid in ids if pid not in blur_ids] idset = set(ids) bursts = json.load(open(sys.argv[1])) # per burst: existing frame ids in order; lead = first burst_frames, frame_burst = {}, {} for k, v in bursts.items(): a, b = int(v["first"][4:]), int(v["last"][4:]) fr = ["7O9A%04d" % n for n in range(a, b + 1) if "7O9A%04d" % n in idset] if not fr: continue burst_frames[k] = fr for f in fr: frame_burst[f] = k cells, n_singles, n_leads = [], 0, 0 for i in ids: chip, attrs = "", "" if i in frame_burst: k = frame_burst[i] if burst_frames[k][0] == i: # lead cell = the whole sequence chip = 'GIF ×%d' % len(burst_frames[k]) attrs = ' data-burst="%s"' % k n_leads += 1 else: chip = 'GIF' attrs = ' data-burstframe="%s"' % k else: n_singles += 1 src = ("ClientPicker/Bursts/%s.webp" % k) if attrs.startswith(" data-burst=") else ("ClientPicker/Thumbs/%s.jpg" % i) cells.append( '
' '
' '%s
%s
' % (" grouplead" if attrs.startswith(" data-burst=") else "", i, attrs, src, chip, i)) js_bursts = json.dumps({k: v for k, v in burst_frames.items()}) html = """ Monster High Theme — Photo Picks
Static preview — the buttons above need JavaScript. To pick photos, simply tell Sam the numbers of the ones you like.

Monster High Theme

Tap a photo to view it larger — arrows or swipe move between photos. Tap the circle (or the button in the enlarged view) to mark favorites.
0 favorites
__CELLS__
""" html = html.replace("__CELLS__", "\n".join(cells)).replace("__BURSTS__", js_bursts) OUT.write_text(html, encoding="utf-8") print("built %d photos (%d singles + %d burst groups, %d hidden frames) -> %s (%.1f KB)" % (len(ids), n_singles, n_leads, len(ids) - n_singles - n_leads, OUT, OUT.stat().st_size / 1024))