← back to Dw Slideshow Gen

drip-resume.sh

47 lines

#!/bin/zsh
# drip-resume.sh — finish staging the DW 500-SKU carousel batch to Postiz, slowly.
# Postiz cloud throttles WRITES on a long window; a burst trips a quota that even a
# single write 429s against. So we (a) gate on a cheap write-probe and wait the window
# out, then (b) stage ONE carousel at a time with a 12s gap — a sustained rate well
# under what tripped the quota. Idempotent (per-dir posted.json) so it resumes after
# any reboot/kill. Self-exits when all 500 are staged.
setopt NO_NOMATCH
# launchd runs with a minimal PATH that lacks node/curl — make them findable.
export PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
cd "$HOME/Projects/dw-slideshow-gen" || exit 1
LOG=output/postiz-drip.log
CH="tiktok,instagram-standalone"
KEY=$(grep '^POSTIZ_API_KEY=' .env | cut -d= -f2 | tr -d ' \r')
count() { find output/renders -name posted.json | wc -l | tr -d ' '; }
probe() { curl -s -o /dev/null -w "%{http_code}" -X POST https://api.postiz.com/public/v1/posts \
            -H "Authorization: $KEY" -H "Content-Type: application/json" -d '{"probe":true}'; }

echo "$(date '+%F %T') drip start — $(count)/500 staged" >> $LOG
while true; do
  # next unstaged carousel
  next=""
  for m in output/renders/*/render-manifest.json; do
    d=${m:h}; [[ -f "$d/posted.json" ]] || { next=$d; break; }
  done
  if [[ -z "$next" ]]; then
    echo "$(date '+%F %T') ALL 500 STAGED — done" >> $LOG
    touch output/.drip-done
    break
  fi
  # gate: is the write throttle window open?
  st=$(probe)
  if [[ "$st" == "429" ]]; then
    echo "$(date '+%F %T') throttle hot (429) — waiting 90s [$(count)/500]" >> $LOG
    sleep 90; continue
  fi
  # window open — stage one carousel
  node index.js post --postiz --channel $CH --confirm "$next" >> $LOG 2>&1
  if [[ -f "$next/posted.json" ]]; then
    echo "$(date '+%F %T') OK [$(count)/500] ${next:t}" >> $LOG
    sleep 12
  else
    echo "$(date '+%F %T') FAIL ${next:t} — backoff 60s" >> $LOG
    sleep 60
  fi
done