#!/usr/bin/env bash # price-monitor.sh - Pris-overvagning for produkter (homeshop.dk + pricerunner.dk) # Brug: bash price-monitor.sh # Eksempel: bash price-monitor.sh dewalt-dcd996nt set -euo pipefail PRODUCT_ID="${1:-dewalt-dcd996nt}" DB_FILE="/home/alex/clawd/data/prices/${PRODUCT_ID}.json" if [[ ! -f "$DB_FILE" ]]; then echo "FEJL: Database ikke fundet: $DB_FILE" >&2 exit 1 fi # Les konfiguration fra database URL=$(python3 -c "import json,sys; d=json.load(open('$DB_FILE')); print(d['url'])") BASELINE=$(python3 -c "import json,sys; d=json.load(open('$DB_FILE')); print(d['baseline_price'])") THRESHOLD=$(python3 -c "import json,sys; d=json.load(open('$DB_FILE')); print(d['alert_threshold_pct'])") BUY_UNDER=$(python3 -c "import json,sys; d=json.load(open('$DB_FILE')); print(d['buy_under_dkk'])") PRODUCT=$(python3 -c "import json,sys; d=json.load(open('$DB_FILE')); print(d['product'])") PR_SEARCH=$(python3 -c "import json,sys; d=json.load(open('$DB_FILE')); print(d.get('pricerunner_search', ''))") echo "=== Pris-check: $PRODUCT ===" echo "Baseline: ${BASELINE} DKK | Threshold: ${THRESHOLD}% | Kobsgraense: ${BUY_UNDER} DKK" echo "" # ------------------------------------------------------- # Funktion: Scrape homeshop.dk # ------------------------------------------------------- scrape_homeshop() { python3 /home/alex/clawd/tools/scrape-price.py "$URL" 2>/dev/null } # ------------------------------------------------------- # Funktion: Scrape pricerunner.dk sogeside # ------------------------------------------------------- scrape_pricerunner() { local search_url="$1" if [[ -z "$search_url" ]]; then echo "N/A" return fi python3 /home/alex/clawd/tools/scrape-price.py "$search_url" 2>/dev/null } # ------------------------------------------------------- # Hent priser fra begge kilder # ------------------------------------------------------- echo "Henter pris fra homeshop.dk..." HOMESHOP_PRICE=$(scrape_homeshop) echo "Henter pris fra pricerunner.dk..." PR_PRICE=$(scrape_pricerunner "$PR_SEARCH") # ------------------------------------------------------- # Find laveste pris # ------------------------------------------------------- BEST_SOURCE="homeshop.dk" BEST_PRICE_RAW="$HOMESHOP_PRICE" if [[ "$HOMESHOP_PRICE" == "ERROR" || -z "$HOMESHOP_PRICE" ]]; then echo "ADVARSEL: Kunne ikke hente pris fra homeshop.dk" >&2 HOMESHOP_PRICE="N/A" fi CURRENT_INT="" if [[ "$HOMESHOP_PRICE" != "N/A" && "$HOMESHOP_PRICE" != "ERROR" ]]; then CURRENT_INT=$(python3 -c "print(int(float('$HOMESHOP_PRICE')))" 2>/dev/null || echo "") fi # Sammenlign med PriceRunner hvis tilgaengelig PR_INT="" if [[ "$PR_PRICE" != "N/A" && -n "$PR_PRICE" ]]; then PR_INT=$(python3 -c "print(int(float('$PR_PRICE')))" 2>/dev/null || echo "") fi # Vaelg laveste pris som "best" if [[ -n "$PR_INT" && -n "$CURRENT_INT" ]]; then BEST=$(python3 -c " hs = $CURRENT_INT pr = $PR_INT if pr < hs: print(f'pr:{pr}') else: print(f'hs:{hs}') ") if [[ "$BEST" == pr:* ]]; then BEST_SOURCE="pricerunner.dk" BEST_PRICE_RAW="$PR_INT" CURRENT_INT="$PR_INT" fi elif [[ -n "$PR_INT" && -z "$CURRENT_INT" ]]; then BEST_SOURCE="pricerunner.dk" CURRENT_INT="$PR_INT" fi echo "" echo "--- Priser ---" [[ "$HOMESHOP_PRICE" != "N/A" && "$HOMESHOP_PRICE" != "ERROR" ]] && \ echo " homeshop.dk: ${HOMESHOP_PRICE%.*} DKK" [[ -n "$PR_INT" ]] && echo " pricerunner.dk: ${PR_INT} DKK (laveste fundet)" [[ -z "$PR_INT" ]] && echo " pricerunner.dk: ikke tilgaengelig" echo "" if [[ -z "$CURRENT_INT" ]]; then echo "FEJL: Ingen priser kunne hentes fra nogen kilde" >&2 exit 1 fi echo "Bedste pris: ${CURRENT_INT} DKK (fra ${BEST_SOURCE})" # Beregn aendring fra baseline PRICE_CHANGE=$(python3 -c " baseline = float($BASELINE) current = float($CURRENT_INT) pct = ((baseline - current) / baseline) * 100 print(f'{pct:.1f}') ") echo "Aendring fra baseline (${BASELINE} DKK): ${PRICE_CHANGE}%" TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") # ------------------------------------------------------- # Gem priser i database # ------------------------------------------------------- python3 -c " import json db_file = '$DB_FILE' with open(db_file, 'r') as f: data = json.load(f) entries = [] if '$HOMESHOP_PRICE' not in ('N/A', 'ERROR', ''): entries.append({ 'price': int(float('$HOMESHOP_PRICE')), 'currency': 'DKK', 'timestamp': '$TIMESTAMP', 'source': 'homeshop.dk' }) if '$PR_INT' not in ('', 'N/A'): entries.append({ 'price': int('$PR_INT'), 'currency': 'DKK', 'timestamp': '$TIMESTAMP', 'source': 'pricerunner.dk' }) data['prices'].extend(entries) # Hold kun de 90 seneste priser if len(data['prices']) > 90: data['prices'] = data['prices'][-90:] data['last_best_price'] = $CURRENT_INT data['last_best_source'] = '$BEST_SOURCE' data['last_checked'] = '$TIMESTAMP' with open(db_file, 'w') as f: json.dump(data, f, indent=2, ensure_ascii=False) print(f'Priser gemt ({len(entries)} poster).') " # ------------------------------------------------------- # Alert-logik: baseret pa bedste pris # ------------------------------------------------------- BELOW_BUY_UNDER=$(python3 -c "print('yes' if $CURRENT_INT <= $BUY_UNDER else 'no')") TRIGGER_ALERT=$(python3 -c " baseline = float($BASELINE) current = float($CURRENT_INT) threshold = float($THRESHOLD) pct_drop = ((baseline - current) / baseline) * 100 print('yes' if pct_drop >= threshold else 'no') ") echo "" if [[ "$TRIGGER_ALERT" == "yes" ]]; then PCT_DROP=$(python3 -c " baseline = float($BASELINE) current = float($CURRENT_INT) pct = ((baseline - current) / baseline) * 100 print(f'{pct:.0f}') ") echo "ALERT: Pris faldet >=${THRESHOLD}% fra baseline!" PR_LINE="" [[ -n "$PR_INT" ]] && PR_LINE=" PriceRunner: ${PR_INT} DKK" ALERT_MSG="Prisfald! ${PRODUCT}: ${CURRENT_INT} DKK (var ${BASELINE} DKK, -${PCT_DROP}%) [${BEST_SOURCE}]${PR_LINE} ${URL}" echo "Sender Discord alert..." openclaw message send --channel discord --target "1466863360099356763" \ -m "$ALERT_MSG" 2>/dev/null || echo "ADVARSEL: Discord alert fejlede" elif [[ "$BELOW_BUY_UNDER" == "yes" && "$CURRENT_INT" -lt "$BASELINE" ]]; then echo "INFO: Pris under kobsgraense (${CURRENT_INT} <= ${BUY_UNDER} DKK)" PR_LINE="" [[ -n "$PR_INT" ]] && PR_LINE=" PriceRunner: ${PR_INT} DKK" ALERT_MSG="KOB NU! ${PRODUCT}: ${CURRENT_INT} DKK (under kobsgraensen ${BUY_UNDER} DKK!) [${BEST_SOURCE}]${PR_LINE} ${URL}" echo "Sender Discord alert (kobsgraense)..." openclaw message send --channel discord --target "1466863360099356763" \ -m "$ALERT_MSG" 2>/dev/null || echo "ADVARSEL: Discord alert fejlede" else echo "OK: Ingen alert - bedste pris stabil (${CURRENT_INT} DKK, aendring: ${PRICE_CHANGE}%)" fi echo "" echo "Pris-check fuldfert: $(date)"