← back to Rentv 2026
fix(social): harden Vimeo refresh — empty-result guard + atomic write so a bad cron run can't clobber the deploy-protected library
7f6b537b6d6b538cbdd0a11dae8befa30093817c · 2026-07-31 15:17:16 -0700 · Steve Abrams
The daily prod cron writes data/vimeo-library.json, which .deploy.conf excludes
from rsync (no deploy to heal it). Two failure modes could silently corrupt the
live library: (1) a degenerate refresh (JWT ok, API returns []) overwriting the
good 123-video catalog with count:0; (2) a crash mid json.dump leaving the file
truncated. Now: bail (keep last-good) if 0 videos, and write via temp+os.replace.
Smoke-tested: 123 videos, clean atomic rename, no stray tmp.
Files touched
M .gitignoreM scripts/pull-vimeo-library.py
Diff
commit 7f6b537b6d6b538cbdd0a11dae8befa30093817c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Jul 31 15:17:16 2026 -0700
fix(social): harden Vimeo refresh — empty-result guard + atomic write so a bad cron run can't clobber the deploy-protected library
The daily prod cron writes data/vimeo-library.json, which .deploy.conf excludes
from rsync (no deploy to heal it). Two failure modes could silently corrupt the
live library: (1) a degenerate refresh (JWT ok, API returns []) overwriting the
good 123-video catalog with count:0; (2) a crash mid json.dump leaving the file
truncated. Now: bail (keep last-good) if 0 videos, and write via temp+os.replace.
Smoke-tested: 123 videos, clean atomic rename, no stray tmp.
---
.gitignore | 3 +++
scripts/pull-vimeo-library.py | 17 ++++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
index 60ea807b..610a54a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,6 @@ public/press/media/*.mp4
# article-to-video studio artifacts (regenerable)
data/social-jobs/
public/social-videos/
+
+__pycache__/
+*.pyc
diff --git a/scripts/pull-vimeo-library.py b/scripts/pull-vimeo-library.py
index 6a753024..2acff269 100644
--- a/scripts/pull-vimeo-library.py
+++ b/scripts/pull-vimeo-library.py
@@ -84,10 +84,21 @@ def main():
except Exception:
v["thumb_local"] = ""
+ # Guard: a degenerate refresh (JWT ok but API returned nothing) must NOT clobber the
+ # last-good catalog. data/vimeo-library.json is deploy-excluded, so there's no deploy to
+ # heal a bad write — keep the previous file and fail loud for the cron log instead.
+ if not items:
+ sys.exit("refresh produced 0 videos — keeping last-good library, not overwriting")
+
eps = sum(1 for i in items if i["kind"] == "episode")
- json.dump({"source": f"https://vimeo.com/user{USER_ID}", "fetched_at": time.strftime("%Y-%m-%d"),
- "count": len(items), "episodes": eps, "clips": len(items) - eps, "items": items},
- open(OUT, "w"), indent=1)
+ payload = {"source": f"https://vimeo.com/user{USER_ID}", "fetched_at": time.strftime("%Y-%m-%d"),
+ "count": len(items), "episodes": eps, "clips": len(items) - eps, "items": items}
+ # Atomic write: fill a temp file then rename, so a crash mid-write can never leave the
+ # live (deploy-protected) library truncated.
+ tmp = OUT + ".tmp"
+ with open(tmp, "w") as f:
+ json.dump(payload, f, indent=1)
+ os.replace(tmp, OUT)
print(f"vimeo-library.json: {len(items)} videos ({eps} episodes, {len(items)-eps} clips), +{new} new thumbs")
← d3c7c5c9 chore(social): daily prod cron to auto-refresh Vimeo library
·
back to Rentv 2026
·
feat(deals): add sort + density controls to the CRE deal gri fccef3ba →