auto-update-daily-20260202
  1#!/usr/bin/env bash
  2# get-location - Get current GPS coordinates
  3# Copyright (C) 2025 Vincent Demeester
  4# Part of Claude Code Journal skill
  5
  6set -euo pipefail
  7
  8# Configuration
  9CACHE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/journal-location"
 10CACHE_TIMEOUT=3600  # 1 hour in seconds
 11
 12# Colors for output
 13RED='\033[0;31m'
 14YELLOW='\033[1;33m'
 15NC='\033[0m'
 16
 17error() {
 18    echo -e "${RED}Error: $*${NC}" >&2
 19    exit 1
 20}
 21
 22debug() {
 23    if [[ "${DEBUG:-0}" == "1" ]]; then
 24        echo -e "${YELLOW}Debug: $*${NC}" >&2
 25    fi
 26}
 27
 28usage() {
 29    cat <<EOF
 30get-location - Get current GPS coordinates
 31
 32USAGE:
 33    get-location [options]
 34
 35OPTIONS:
 36    --json              Output as JSON
 37    --city              Output city name only
 38    --coords            Output coordinates only (lat,lon)
 39    --all               Output city and coordinates (default)
 40    --no-cache          Don't use cached location
 41    --help, -h          Show this help
 42
 43OUTPUT FORMATS:
 44    Default:    Saint-Denis (48.9356,2.3539)
 45    --json:     {"city":"Saint-Denis","lat":"48.9356","lon":"2.3539"}
 46    --city:     Saint-Denis
 47    --coords:   48.9356,2.3539
 48
 49LOCATION SOURCES:
 50    1. IP-based geolocation (ipinfo.io) - automatic, approximate
 51    2. Cache (${CACHE_FILE}) - reuses location for ${CACHE_TIMEOUT}s
 52
 53EXAMPLES:
 54    # Get location with city name
 55    get-location
 56
 57    # Get just coordinates for journelly-manager
 58    get-location --coords
 59
 60    # Get JSON output
 61    get-location --json
 62
 63    # Force refresh (ignore cache)
 64    get-location --no-cache
 65
 66NOTES:
 67    - IP-based location is approximate (city-level accuracy)
 68    - Location is cached for 1 hour to reduce API calls
 69    - No API key required
 70
 71VERSION:
 72    1.0.0
 73
 74AUTHOR:
 75    Vincent Demeester <vincent@demeester.fr>
 76EOF
 77}
 78
 79# Check if cache is valid
 80is_cache_valid() {
 81    [[ -f "$CACHE_FILE" ]] || return 1
 82
 83    local cache_age
 84    cache_age=$(($(date +%s) - $(stat -c %Y "$CACHE_FILE" 2>/dev/null || echo 0)))
 85
 86    [[ $cache_age -lt $CACHE_TIMEOUT ]]
 87}
 88
 89# Get location from cache
 90get_from_cache() {
 91    if [[ -f "$CACHE_FILE" ]]; then
 92        cat "$CACHE_FILE"
 93        return 0
 94    fi
 95    return 1
 96}
 97
 98# Get location from IP geolocation
 99get_from_ip() {
100    debug "Fetching location from ipinfo.io"
101
102    local response
103    response=$(curl -s --max-time 5 https://ipinfo.io/json 2>/dev/null) || {
104        error "Failed to fetch location from ipinfo.io"
105    }
106
107    # Validate response
108    if ! echo "$response" | jq -e '.loc' >/dev/null 2>&1; then
109        error "Invalid response from ipinfo.io"
110    fi
111
112    echo "$response"
113}
114
115# Parse and format output
116format_output() {
117    local data="$1"
118    local format="${2:-all}"
119
120    local city
121    local loc
122    local lat
123    local lon
124
125    city=$(echo "$data" | jq -r '.city // "Unknown"')
126    loc=$(echo "$data" | jq -r '.loc // ""')
127
128    if [[ -z "$loc" ]]; then
129        error "No location data available"
130    fi
131
132    lat=$(echo "$loc" | cut -d, -f1)
133    lon=$(echo "$loc" | cut -d, -f2)
134
135    case "$format" in
136        json)
137            jq -n \
138                --arg city "$city" \
139                --arg lat "$lat" \
140                --arg lon "$lon" \
141                '{city: $city, lat: $lat, lon: $lon}'
142            ;;
143        city)
144            echo "$city"
145            ;;
146        coords)
147            echo "$lat,$lon"
148            ;;
149        lat)
150            echo "$lat"
151            ;;
152        lon)
153            echo "$lon"
154            ;;
155        all)
156            echo "$city ($lat,$lon)"
157            ;;
158        *)
159            error "Unknown format: $format"
160            ;;
161    esac
162}
163
164# Main function
165main() {
166    local use_cache=true
167    local format="all"
168
169    # Parse arguments
170    while [[ $# -gt 0 ]]; do
171        case "$1" in
172            --json)
173                format="json"
174                ;;
175            --city)
176                format="city"
177                ;;
178            --coords)
179                format="coords"
180                ;;
181            --lat)
182                format="lat"
183                ;;
184            --lon)
185                format="lon"
186                ;;
187            --all)
188                format="all"
189                ;;
190            --no-cache)
191                use_cache=false
192                ;;
193            --help|-h)
194                usage
195                exit 0
196                ;;
197            *)
198                error "Unknown option: $1. Use --help for usage."
199                ;;
200        esac
201        shift
202    done
203
204    local data=""
205
206    # Try cache first
207    if [[ "$use_cache" == "true" ]] && is_cache_valid; then
208        debug "Using cached location"
209        data=$(get_from_cache)
210    else
211        # Fetch from IP geolocation
212        data=$(get_from_ip)
213
214        # Cache the result
215        mkdir -p "$(dirname "$CACHE_FILE")"
216        echo "$data" > "$CACHE_FILE"
217        debug "Location cached to $CACHE_FILE"
218    fi
219
220    # Format and output
221    format_output "$data" "$format"
222}
223
224main "$@"