#!/usr/bin/env bash # Pull user feedback from the VPS into ./feedback/ locally. # Usage: bash scripts/pull_feedback.sh set -e VPS=${1:?Usage: $0 user@host} REMOTE=/var/bincio/data/_feedback LOCAL=$(dirname "$0")/../feedback SEEN="$LOCAL/.seen" mkdir -p "$LOCAL" echo "Syncing feedback from $VPS:$REMOTE → $LOCAL" rsync -az "${VPS}:${REMOTE}/" "$LOCAL/" python3 - "$LOCAL" "$SEEN" <<'EOF' import json, sys, os from datetime import datetime, timezone local_dir, seen_file = sys.argv[1], sys.argv[2] seen = set() if os.path.exists(seen_file): seen = set(json.loads(open(seen_file).read())) new_entries = [] all_ids = [] for fname in sorted(os.listdir(local_dir)): if not fname.endswith('.json') or fname.startswith('.'): continue handle = fname[:-5] try: entries = json.load(open(os.path.join(local_dir, fname))) if not isinstance(entries, list): entries = [entries] except Exception: continue for e in entries: eid = e.get('id', '') all_ids.append(eid) if eid not in seen: new_entries.append((handle, e)) if new_entries: print(f'\n\033[1;32m=== {len(new_entries)} new submission(s) ===\033[0m') for handle, e in new_entries: ts = e.get('submitted_at', '')[:10] text = e.get('text', '').replace('\n', ' ') images = e.get('images', []) img_note = f' [{len(images)} image(s)]' if images else '' print(f'\n \033[1m@{handle}\033[0m {ts}') if text: print(f' {text[:200]}{"…" if len(text) > 200 else ""}') if img_note: print(f' {img_note}') else: print('\n=== No new feedback ===') # Print totals print('\n--- totals ---') for fname in sorted(os.listdir(local_dir)): if not fname.endswith('.json') or fname.startswith('.'): continue handle = fname[:-5] try: entries = json.load(open(os.path.join(local_dir, fname))) count = len(entries) if isinstance(entries, list) else 1 print(f' @{handle}: {count}') except Exception: pass # Save updated seen set open(seen_file, 'w').write(json.dumps(list(set(all_ids)))) EOF