85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
package weather
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"git.leaktechnologies.dev/Leak_Technologies/Skyfeed/internal/config"
|
|
)
|
|
|
|
// Cache file path
|
|
var cacheFile = filepath.Join(config.DataDir, "last_weather.json")
|
|
|
|
// CacheTTL defines how long cached weather data is considered "fresh".
|
|
// Default: 30 minutes.
|
|
const CacheTTL = 30 * time.Minute
|
|
|
|
// LoadFromCache loads cached weather data if available and still fresh.
|
|
// Returns (WeatherData, isFresh, error)
|
|
func LoadFromCache() (WeatherData, bool, error) {
|
|
file, err := os.Open(cacheFile)
|
|
if err != nil {
|
|
return WeatherData{}, false, fmt.Errorf("no cache found")
|
|
}
|
|
defer file.Close()
|
|
|
|
var data WeatherData
|
|
if err := json.NewDecoder(file).Decode(&data); err != nil {
|
|
return WeatherData{}, false, fmt.Errorf("failed to decode cache: %w", err)
|
|
}
|
|
|
|
ts, err := time.Parse(time.RFC3339, data.Timestamp)
|
|
if err != nil {
|
|
// handle legacy or non-RFC timestamps
|
|
return data, false, nil
|
|
}
|
|
|
|
age := time.Since(ts)
|
|
if age > CacheTTL {
|
|
fmt.Printf("[weather] Cache is stale (%.0f min old)\n", age.Minutes())
|
|
return data, false, nil
|
|
}
|
|
|
|
fmt.Println("[weather] Loaded fresh cache (", int(age.Minutes()), "min old )")
|
|
return data, true, nil
|
|
}
|
|
|
|
// SaveToCache writes a WeatherData object to disk.
|
|
func SaveToCache(data WeatherData) error {
|
|
if err := os.MkdirAll(filepath.Dir(cacheFile), 0755); err != nil {
|
|
return fmt.Errorf("failed to create cache dir: %w", err)
|
|
}
|
|
|
|
file, err := os.Create(cacheFile)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to write cache: %w", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
data.Timestamp = time.Now().UTC().Format(time.RFC3339)
|
|
|
|
enc := json.NewEncoder(file)
|
|
enc.SetIndent("", " ")
|
|
if err := enc.Encode(data); err != nil {
|
|
return fmt.Errorf("failed to encode cache: %w", err)
|
|
}
|
|
|
|
fmt.Println("[weather] Cache saved →", cacheFile)
|
|
return nil
|
|
}
|
|
|
|
// ClearCache removes the current cached file if present.
|
|
func ClearCache() error {
|
|
if _, err := os.Stat(cacheFile); os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
if err := os.Remove(cacheFile); err != nil {
|
|
return fmt.Errorf("failed to clear cache: %w", err)
|
|
}
|
|
fmt.Println("[weather] Cache cleared.")
|
|
return nil
|
|
}
|