← back to Parked Landers

gen-images.py

92 lines

import os,json,time,urllib.request,urllib.error,subprocess
BASE=os.path.expanduser("~/Projects/parked-landers/sites")
TOKEN=subprocess.check_output(
  "grep -E '^REPLICATE_API_TOKEN=' ~/Projects/secrets-manager/.env | head -1 | cut -d= -f2-",
  shell=True).decode().strip()
LOG=os.path.expanduser("~/Projects/parked-landers/gen-images.log")
def log(m):
  open(LOG,"a").write(m+"\n"); print(m,flush=True)

NEG="no text, no words, no letters, no watermark, no logo, no people, no hands"
BOX="premium curated monthly subscription box, elegant minimalist packaging, apothecary glass jars, botanical still life, soft natural light, editorial product photography, marble and neutral tones, "+NEG
PROMPTS={
 "protectyourspec.com":[
  "an architect's desk with material finish samples fanned over technical drawings, editorial photography, "+NEG,
  "close-up of architectural specification documents and finish swatches in a binder, "+NEG,
  "a modern commercial office interior with premium wall finishes and clean lines, "+NEG,
  "a designer material library shelf lined with tile, fabric and wood samples, "+NEG,
  "flat lay of finish sample chips and a floor plan on a neutral desk, "+NEG,
  "an elegant boardroom with design finish boards on the wall, "+NEG],
 "cannabisofthemonthclub.com":[BOX,"flat lay of a curated wellness subscription box with tissue paper and small glass jars, "+NEG,
  "premium apothecary jars with dried botanicals on a marble surface, "+NEG,
  "minimalist kraft gift box with a card and botanical sprigs, top-down, "+NEG,
  "elegant botanical still life with amber glass jars and linen, "+NEG,
  "a tasteful monthly delivery box with premium neutral packaging, "+NEG],
 "hempofthemonthclub.com":["flat lay of natural hemp fiber, hemp textile and seeds on linen, editorial, "+NEG,
  "premium hemp wellness products in minimalist packaging, marble surface, "+NEG,BOX,
  "green hemp plant leaves arranged as a botanical still life, "+NEG,
  "natural hemp rope, fabric and neutral packaging flat lay, "+NEG,
  "apothecary jars of hemp botanicals with soft window light, "+NEG],
 "marijuanaofthemonthclub.com":[BOX,"elegant botanical apothecary flat lay with amber jars and dried herbs, "+NEG,
  "premium neutral subscription box with tissue and a card, top-down, "+NEG,
  "minimalist herbal wellness packaging on a marble slab, "+NEG,
  "botanical still life with glass jars and linen napkin, soft light, "+NEG,
  "curated monthly gift box with premium matte packaging, "+NEG],
 "potofthemonthclub.com":[BOX,"a rustic-modern flat lay of a monthly botanical box with kraft paper, "+NEG,
  "apothecary shelf with labeled amber jars and dried botanicals, "+NEG,
  "minimalist herbal subscription packaging on a wood table, "+NEG,
  "botanical still life with a small ceramic pot and dried herbs, "+NEG,
  "elegant curated wellness box with neutral tones, top-down, "+NEG],
 "weedofthemonthclub.com":[BOX,"botanical apothecary flat lay with green herbs and amber glass, "+NEG,
  "premium minimalist subscription box with tissue paper, top-down, "+NEG,
  "dried botanical bundle and glass jars on linen, editorial, "+NEG,
  "neutral matte packaging and botanical sprigs flat lay, "+NEG,
  "curated monthly wellness delivery with elegant packaging, "+NEG],
 "mymemosamples.com":[  # 01 already exists (skip)
  "SKIP",
  "a designer fanning wallcovering sample swatches over a desk, editorial, "+NEG,
  "close-up macro of layered textile swatch edges and textures, "+NEG,
  "an open wallcovering sample book with tabbed pages, top-down, "+NEG,
  "a memo sample mailer envelope with fabric swatches spilling out, "+NEG,
  "neatly organized fabric swatch cards in a fan on marble, "+NEG],
 "hospitalitysalesrepresentatives.com":[
  "a luxury boutique hotel lobby with elegant contract furnishings, "+NEG,
  "an upscale restaurant dining room interior, warm evening light, "+NEG,
  "a modern hotel reception desk with premium materials, "+NEG,
  "a stylish hospitality lounge with designer seating and textiles, "+NEG,
  "a boutique hotel guest room with tailored contract furniture, "+NEG,
  "a hotel bar interior with rich materials and ambient light, "+NEG],
}
def gen(prompt):
  body=json.dumps({"input":{"prompt":prompt,"aspect_ratio":"4:3","num_outputs":1,"output_format":"jpg","output_quality":88}}).encode()
  req=urllib.request.Request("https://api.replicate.com/v1/models/black-forest-labs/flux-schnell/predictions",
    data=body,headers={"Authorization":"Bearer "+TOKEN,"Content-Type":"application/json","Prefer":"wait"})
  r=json.load(urllib.request.urlopen(req,timeout=150))
  # poll if not done
  for _ in range(30):
    if r.get("status")=="succeeded": break
    if r.get("status") in ("failed","canceled"): return None
    time.sleep(3)
    r=json.load(urllib.request.urlopen(urllib.request.Request(r["urls"]["get"],
      headers={"Authorization":"Bearer "+TOKEN}),timeout=30))
  o=r.get("output"); url=o[0] if isinstance(o,list) and o else o
  return url
open(LOG,"w").write("")
n=0; ok=0
for dom,prompts in PROMPTS.items():
  d=os.path.join(BASE,dom,"img"); os.makedirs(d,exist_ok=True)
  for i,p in enumerate(prompts,1):
    fp=os.path.join(d,f"{i:02d}.jpg")
    if p=="SKIP" or os.path.exists(fp):
      log(f"skip {dom}/{i:02d}.jpg"); ok+=1; continue
    n+=1
    try:
      url=gen(p)
      if not url: log(f"FAIL {dom}/{i:02d} (no url)"); continue
      urllib.request.urlretrieve(url,fp)
      sz=os.path.getsize(fp); ok+=1
      log(f"ok   {dom}/{i:02d}.jpg  {sz}B")
    except Exception as e:
      log(f"ERR  {dom}/{i:02d}: {e}")
log(f"DONE generated={n} present={ok}/48  est_cost=${n*0.003:.3f}")