flake-update-20260201
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 "$@"