← back to Dw Slideshow Gen
postiz: unattended drip-resume watcher (throttle-gated, 12s/item, launchd reboot-survivable) to finish the 500-SKU batch
a2137677807bacc04fa4f6cf016c006cf384fd54 · 2026-06-29 15:45:43 -0700 · steve@designerwallcoverings.com
Files touched
Diff
commit a2137677807bacc04fa4f6cf016c006cf384fd54
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date: Mon Jun 29 15:45:43 2026 -0700
postiz: unattended drip-resume watcher (throttle-gated, 12s/item, launchd reboot-survivable) to finish the 500-SKU batch
---
drip-resume.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/drip-resume.sh b/drip-resume.sh
new file mode 100755
index 0000000..7e337ea
--- /dev/null
+++ b/drip-resume.sh
@@ -0,0 +1,44 @@
+#!/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
+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
← d018d37 auto-save: 2026-06-29T14:53:15 (2 files) — index.js lib/post
·
back to Dw Slideshow Gen
·
fix(drip): export PATH so launchd run finds node/curl (was s 324ce36 →