#!/bin/bash # Upload all stock avatar props to the server. # # Usage: ./stockavatar/upload-stockavatars.sh [--force|-f] [HOST] # # Options: # --force, -f Update existing props instead of failing with 409 Conflict # # HOST defaults to http://localhost:3001 (owner admin port) # # Prerequisites: # 1. Run the dev server: ./run-dev.sh -f # 2. Wait for it to finish building: ./run-dev.sh -s # # The owner admin server (port 3001) uses the chattyness_owner DB role # which bypasses RLS, so no authentication is required. set -e # Parse arguments FORCE="" HOST="http://localhost:3001" for arg in "$@"; do case "$arg" in --force|-f) FORCE="?force=true" ;; http://*) HOST="$arg" ;; esac done # Script directory is the stockavatar directory STOCKAVATAR_DIR="$(cd "$(dirname "$0")" && pwd)" echo "Uploading stock avatars to $HOST/api/admin/props" echo "Source directory: $STOCKAVATAR_DIR" echo "" # Check if server is running echo "Checking server health..." health_response=$(curl -s -o /dev/null -w "%{http_code}" "$HOST/api/admin/health" 2>/dev/null || echo "000") if [ "$health_response" != "200" ]; then echo "ERROR: Server is not responding at $HOST (HTTP $health_response)" echo "" echo "Make sure the server is running:" echo " ./run-dev.sh -f" echo " ./run-dev.sh -s # Check status" exit 1 fi echo "Server is healthy!" echo "" # Function to capitalize first letter capitalize() { echo "$1" | sed 's/.*/\u&/' } # Function to determine tags based on filename # Tags complement default_layer/default_emotion - avoid redundant info get_tags() { local filename="$1" case "$filename" in face.svg) # Content layer prop - "skin" is already in default_layer echo '["base", "face"]' ;; smile.svg | happy.svg | neutral.svg | sad.svg | angry.svg | surprised.svg | thinking.svg | laughing.svg | crying.svg | love.svg | confused.svg) # Emotion props - emotion is already in default_emotion echo '["face"]' ;; sleeping.svg) # Emotion prop for sleeping echo '["face"]' ;; wink.svg) # Emotion prop for wink echo '["face"]' ;; *) echo '["prop"]' ;; esac } # Function to get positioning fields based on filename # Returns: "layer:" for content layer props, "emotion:" for emotion props, "none" for generic props get_positioning() { local filename="$1" case "$filename" in face.svg) # Base face is a content layer prop (skin layer) echo "layer:skin" ;; neutral.svg) echo "emotion:neutral" ;; smile.svg) echo "emotion:happy" ;; sad.svg) echo "emotion:sad" ;; angry.svg) echo "emotion:angry" ;; surprised.svg) echo "emotion:surprised" ;; thinking.svg) echo "emotion:thinking" ;; laughing.svg) echo "emotion:laughing" ;; crying.svg) echo "emotion:crying" ;; love.svg) echo "emotion:love" ;; confused.svg) echo "emotion:confused" ;; sleeping.svg) echo "emotion:sleeping" ;; wink.svg) echo "emotion:wink" ;; *) echo "none" ;; esac } # Track success/failure counts success_count=0 fail_count=0 # Upload each SVG file for file in "$STOCKAVATAR_DIR"/*.svg; do if [ ! -f "$file" ]; then continue fi filename=$(basename "$file") name_without_ext="${filename%.svg}" display_name=$(capitalize "$name_without_ext") tags=$(get_tags "$filename") positioning=$(get_positioning "$filename") echo "Uploading: $filename -> $display_name (positioning: $positioning)" # Build positioning fields based on type positioning_type="${positioning%%:*}" positioning_value="${positioning#*:}" case "$positioning_type" in layer) # Content layer prop positioning_json="\"default_layer\": \"$positioning_value\", \"default_position\": 4" ;; emotion) # Emotion layer prop positioning_json="\"default_emotion\": \"$positioning_value\", \"default_position\": 4" ;; *) # Generic prop (no default positioning) positioning_json="" ;; esac # Create metadata JSON if [ -n "$positioning_json" ]; then metadata=$( cat <