diff --git a/site-cookbooks/kosmos-bitcoin/templates/btc-price-tracker-daily.sh.erb b/site-cookbooks/kosmos-bitcoin/templates/btc-price-tracker-daily.sh.erb index 7d3a2ce..1209749 100644 --- a/site-cookbooks/kosmos-bitcoin/templates/btc-price-tracker-daily.sh.erb +++ b/site-cookbooks/kosmos-bitcoin/templates/btc-price-tracker-daily.sh.erb @@ -1,49 +1,86 @@ #!/bin/bash +set -e +set -o pipefail # Calculate yesterday's date in YYYY-MM-DD format YESTERDAY=$(date -d "yesterday" +%Y-%m-%d) echo "Starting price tracking for $YESTERDAY" >&2 +# Helper function to perform HTTP requests with retries +# Usage: make_request [data] [header1] [header2] ... +make_request() { + local retries=$1 + local method=$2 + local url=$3 + local data=$4 + shift 4 + local headers=("$@") + + local count=0 + local wait_time=3 + local response + + while [ "$count" -lt "$retries" ]; do + local curl_opts=(-s -S -f -X "$method") + + if [ -n "$data" ]; then + curl_opts+=(-d "$data") + fi + + for h in "${headers[@]}"; do + curl_opts+=(-H "$h") + done + + if response=$(curl "${curl_opts[@]}" "$url"); then + echo "$response" + return 0 + fi + + echo "Request to $url failed (Attempt $((count+1))/$retries). Retrying in ${wait_time}s..." >&2 + sleep "$wait_time" + count=$((count + 1)) + done + + echo "ERROR: Request to $url failed after $retries attempts" >&2 + return 1 +} + # Fetch and process rates for a fiat currency get_price_data() { local currency=$1 local data avg open24 last - data=$(curl -s "https://www.bitstamp.net/api/v2/ticker/btc${currency,,}/") - if [ $? -eq 0 ] && [ ! -z "$data" ]; then + if data=$(make_request 3 "GET" "https://www.bitstamp.net/api/v2/ticker/btc${currency,,}/" ""); then echo "Successfully retrieved ${currency} price data" >&2 open24=$(echo "$data" | jq -r '.open_24') last=$(echo "$data" | jq -r '.last') - avg=$(( (${open24%.*} + ${last%.*}) / 2 )) + avg=$(echo "$open24 $last" | awk '{printf "%.0f", ($1 + $2) / 2}') echo $avg else echo "ERROR: Failed to retrieve ${currency} price data" >&2 - exit 1 + return 1 fi } # Get price data for each currency -usd_avg=$(get_price_data "USD") -eur_avg=$(get_price_data "EUR") -gbp_avg=$(get_price_data "GBP") +usd_avg=$(get_price_data "USD") || exit 1 +eur_avg=$(get_price_data "EUR") || exit 1 +gbp_avg=$(get_price_data "GBP") || exit 1 # Create JSON -json="{\"EUR\":$eur_avg,\"USD\":$usd_avg,\"GBP\":$gbp_avg}" +json=$(jq -n \ + --argjson eur "$eur_avg" \ + --argjson usd "$usd_avg" \ + --argjson gbp "$gbp_avg" \ + '{"EUR": $eur, "USD": $usd, "GBP": $gbp}') echo "Rates: $json" >&2 # PUT in remote storage -response=$(curl -X PUT \ - -H "Authorization: Bearer $RS_AUTH" \ - -H "Content-Type: application/json" \ - -d "$json" \ - -w "%{http_code}" \ - -s \ - -o /dev/null \ - "<%= @rs_base_url %>/$YESTERDAY") - -if [ "$response" -eq 200 ] || [ "$response" -eq 201 ]; then +if make_request 3 "PUT" "<%= @rs_base_url %>/$YESTERDAY" "$json" \ + "Authorization: Bearer $RS_AUTH" \ + "Content-Type: application/json" > /dev/null; then echo "Successfully uploaded price data" >&2 else - echo "ERROR: Failed to upload price data. HTTP status: $response" >&2 + echo "ERROR: Failed to upload price data" >&2 exit 1 fi