199 lines
6.4 KiB
Bash
Executable File
199 lines
6.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
source "$(dirname "$0")/entrypoint.sh" 2>/dev/null || true
|
|
|
|
# Master orchestration script for LWVWV member subscription automation
|
|
# This script coordinates the entire workflow:
|
|
# 1. Download roster from LWVWV portal (if download-roster.js is available)
|
|
# 2. Convert roster to CSV format, filtered by League ID per list
|
|
# 3. Subscribe members to Mailman list(s) via connector API
|
|
# 4. Cleanup temporary files
|
|
#
|
|
# Environment Variables (loaded from /app/env via entrypoint.sh):
|
|
# CONNECTOR_URL - URL of mailman-connector
|
|
# CONNECTOR_PASSWORD - Secret password for connector API
|
|
# MAILMAN_LIST_ID - Target mailing list ID(s). Format: "list_id:league_id, list_id:league_id"
|
|
# If :league_id is omitted, defaults to "ALL" (all members)
|
|
# EMAIL_TO - Email for failure notifications
|
|
# SMTP_HOST - SMTP server for notifications
|
|
#
|
|
# Examples:
|
|
# Single list, all members: "members.lists.lwvwv.org"
|
|
# Single list, WV000 only: "members.lists.lwvwv.org:WV000"
|
|
# Multiple lists: "members.lists.lwvwv.org:WV000, morgantown.lists.lwvwv.org:WV103"
|
|
|
|
set -e # Exit on error
|
|
|
|
# Configuration from environment
|
|
WORK_DIR="${WORK_DIR:-/tmp/rosters}"
|
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
ROSTER_FILE="$WORK_DIR/roster_$TIMESTAMP.csv"
|
|
|
|
log() {
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
|
}
|
|
|
|
error_exit() {
|
|
echo "[ERROR] $1" >&2
|
|
# Send alert email if configured
|
|
if [ -n "$EMAIL_TO" ] && [ -n "$SMTP_HOST" ]; then
|
|
echo "$1" | s-nail -s "LWVWV Subscription Failed" "$EMAIL_TO" 2>/dev/null || true
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
# Create work directory
|
|
mkdir -p "$WORK_DIR"
|
|
|
|
# Determine CSV input source or download
|
|
if [ -n "$1" ]; then
|
|
# CSV file provided as argument
|
|
ROSTER_FILE="$1"
|
|
log "Using provided roster file: $ROSTER_FILE"
|
|
|
|
if [ ! -f "$ROSTER_FILE" ]; then
|
|
error_exit "Roster file not found: $ROSTER_FILE"
|
|
fi
|
|
else
|
|
# No CSV provided - try to download from portal
|
|
if [ ! -f "./download-roster.js" ]; then
|
|
error_exit "No CSV file provided and download-roster.js not found"
|
|
fi
|
|
|
|
# Step 1: Download roster
|
|
log "Downloading roster from LWVWV portal..."
|
|
if ! node download-roster.js; then
|
|
error_exit "Failed to download roster"
|
|
fi
|
|
|
|
# Find the downloaded file
|
|
ROSTER_FILE=$(ls -t league_membership_state_view_*.csv 2>/dev/null | head -1)
|
|
if [ -z "$ROSTER_FILE" ]; then
|
|
error_exit "No roster file found after download"
|
|
fi
|
|
|
|
log "Downloaded roster: $ROSTER_FILE"
|
|
fi
|
|
|
|
# Validate required environment variables
|
|
if [ -z "$CONNECTOR_URL" ]; then
|
|
error_exit "CONNECTOR_URL not set. Ensure /app/env is mounted and contains \$CONNECTOR_URL"
|
|
fi
|
|
|
|
if [ -z "$CONNECTOR_PASSWORD" ]; then
|
|
error_exit "CONNECTOR_PASSWORD not set. Ensure /app/env is mounted and contains \$CONNECTOR_PASSWORD"
|
|
fi
|
|
|
|
if [ -z "$MAILMAN_LIST_ID" ]; then
|
|
error_exit "MAILMAN_LIST_ID not set. Ensure /app/env is mounted and contains \$MAILMAN_LIST_ID"
|
|
fi
|
|
|
|
if [ ! -f "./google-civic-api.pl" ]; then
|
|
error_exit "google-civic-api.pl not found for roster conversion"
|
|
fi
|
|
|
|
if [ ! -f "./subscribe-members.sh" ]; then
|
|
error_exit "subscribe-members.sh not found"
|
|
fi
|
|
|
|
# Parse multiple list configurations (comma-separated)
|
|
# Format: list_id:league_id or just list_id (defaults to ALL)
|
|
IFS=',' read -ra LIST_CONFIGS <<< "$MAILMAN_LIST_ID"
|
|
|
|
log "=========================================="
|
|
log "Starting batch subscription"
|
|
log "=========================================="
|
|
log "Roster File: $ROSTER_FILE"
|
|
log "Connector URL: $CONNECTOR_URL"
|
|
log "Total Lists: ${#LIST_CONFIGS[@]}"
|
|
log "=========================================="
|
|
|
|
# Track success/failure per list
|
|
SUCCESS_COUNT=0
|
|
FAILED_LISTS=()
|
|
|
|
# Helper function to increment counter (avoids set -e issues with arithmetic)
|
|
increment_count() {
|
|
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
|
|
}
|
|
|
|
# Loop through each list configuration
|
|
for CONFIG in "${LIST_CONFIGS[@]}"; do
|
|
# Trim whitespace
|
|
CONFIG=$(echo "$CONFIG" | xargs)
|
|
|
|
# Parse list_id and league_id (format: list_id:league_id or just list_id)
|
|
if [[ "$CONFIG" =~ ^([^:]+):(.*)$ ]]; then
|
|
LIST_ID="${BASH_REMATCH[1]}"
|
|
LEAGUE_ID="${BASH_REMATCH[2]}"
|
|
else
|
|
LIST_ID="$CONFIG"
|
|
LEAGUE_ID="ALL"
|
|
fi
|
|
|
|
log ""
|
|
log "----------------------------------------"
|
|
log "Processing List: $LIST_ID"
|
|
log "League Filter: $LEAGUE_ID"
|
|
log "----------------------------------------"
|
|
|
|
# Generate filtered CSV for this list
|
|
FILTERED_CSV="$WORK_DIR/members_${LEAGUE_ID}_${TIMESTAMP}.csv"
|
|
|
|
log "Filtering roster for League ID: $LEAGUE_ID..."
|
|
if ! ./google-civic-api.pl "$LEAGUE_ID" "$ROSTER_FILE" email-csv > "$FILTERED_CSV" 2>/dev/null; then
|
|
log "✗ Failed to filter roster for $LEAGUE_ID"
|
|
FAILED_LISTS+=("$LIST_ID")
|
|
rm -f "$FILTERED_CSV"
|
|
continue
|
|
fi
|
|
|
|
# Check if any members were found
|
|
MEMBER_COUNT=$(wc -l < "$FILTERED_CSV" | tr -d ' ')
|
|
log "Found $MEMBER_COUNT members for $LEAGUE_ID"
|
|
|
|
if [ "$MEMBER_COUNT" -eq 0 ]; then
|
|
log "⚠ No members found for League ID $LEAGUE_ID, skipping $LIST_ID"
|
|
rm -f "$FILTERED_CSV"
|
|
continue
|
|
fi
|
|
|
|
# Subscribe members to this list
|
|
log "Subscribing $MEMBER_COUNT members to $LIST_ID..."
|
|
if ./subscribe-members.sh "$FILTERED_CSV" "$CONNECTOR_PASSWORD" "$LIST_ID" "$CONNECTOR_URL"; then
|
|
log "✓ Successfully subscribed to $LIST_ID"
|
|
increment_count
|
|
# Clean up filtered CSV on success
|
|
rm -f "$FILTERED_CSV"
|
|
else
|
|
log "✗ Failed to subscribe to $LIST_ID"
|
|
FAILED_LISTS+=("$LIST_ID")
|
|
# Keep filtered CSV for debugging on failure
|
|
log " Filtered CSV retained: $FILTERED_CSV"
|
|
fi
|
|
done
|
|
|
|
# Summary
|
|
log ""
|
|
log "=========================================="
|
|
log "Subscription Summary"
|
|
log "=========================================="
|
|
log "Total Lists: ${#LIST_CONFIGS[@]}"
|
|
log "Successful: $SUCCESS_COUNT"
|
|
log "Failed: ${#FAILED_LISTS[@]}"
|
|
log "=========================================="
|
|
|
|
# Cleanup original roster if we downloaded it
|
|
if [ -z "$1" ] && [ -f "$ROSTER_FILE" ]; then
|
|
log "Cleaning up roster file..."
|
|
rm -f "$ROSTER_FILE"
|
|
fi
|
|
|
|
# If any lists failed, report error
|
|
if [ ${#FAILED_LISTS[@]} -gt 0 ]; then
|
|
error_exit "Failed to subscribe to the following list(s): ${FAILED_LISTS[*]}"
|
|
fi
|
|
|
|
log "Subscription process completed successfully"
|
|
exit 0
|