cache weather

This commit is contained in:
Gabriel Augendre 2024-09-16 00:28:43 +02:00
parent 3f61e50330
commit 0d991a2771
3 changed files with 63 additions and 4 deletions

View file

@ -37,6 +37,7 @@ func main() {
weatherClient := weather.New(nil, weather.Config{ weatherClient := weather.New(nil, weather.Config{
APIKey: os.Getenv("WEATHER_API_KEY"), APIKey: os.Getenv("WEATHER_API_KEY"),
CacheLocation: os.Getenv("WEATHER_CACHE_LOCATION"),
}) })
if err := run(ctx, transportsClient, feteClient, weatherClient); err != nil { if err := run(ctx, transportsClient, feteClient, weatherClient); err != nil {

View file

@ -42,8 +42,8 @@ func run(ctx context.Context, transportsClient *transports.Client, feteClient *f
log.Printf("error looping: %v\n", err) log.Printf("error looping: %v\n", err)
} }
log.Println("time.Sleep(30s)") log.Println("time.Sleep(10m)")
time.Sleep(30 * time.Second) time.Sleep(10 * time.Minute)
} }
} }

View file

@ -2,13 +2,19 @@ package weather
import ( import (
"context" "context"
"encoding/json"
"errors"
"fmt" "fmt"
"github.com/carlmjohnson/requests" "github.com/carlmjohnson/requests"
"log"
"net/http" "net/http"
"os"
"time"
) )
type Config struct { type Config struct {
APIKey string APIKey string
CacheLocation string
} }
type Client struct { type Client struct {
@ -61,6 +67,47 @@ type Prevision struct {
} `json:"alerts"` } `json:"alerts"`
} }
var errTooOld = errors.New("prevision is too old")
func loadFromDisk(location string) (Prevision, error) {
stat, err := os.Stat(location)
if err != nil {
return Prevision{}, fmt.Errorf("getting file info: %w", err)
}
if stat.ModTime().Add(10 * time.Minute).Before(time.Now()) {
return Prevision{}, errTooOld
}
file, err := os.Open(location)
if err != nil {
return Prevision{}, fmt.Errorf("opening prevision: %w", err)
}
defer file.Close()
var res Prevision
if err = json.NewDecoder(file).Decode(&res); err != nil {
return Prevision{}, fmt.Errorf("decoding prevision: %w", err)
}
return res, nil
}
func (p Prevision) dumpToDisk(location string) error {
file, err := os.Create(location)
if err != nil {
return fmt.Errorf("creating prevision: %w", err)
}
defer file.Close()
if err = json.NewEncoder(file).Encode(p); err != nil {
return fmt.Errorf("dumping prevision: %w", err)
}
return nil
}
type Daily struct { type Daily struct {
Dt int `json:"dt"` Dt int `json:"dt"`
Sunrise int `json:"sunrise"` Sunrise int `json:"sunrise"`
@ -104,6 +151,13 @@ type Weather struct {
} }
func (c *Client) GetWeather(ctx context.Context) (res *Prevision, err error) { func (c *Client) GetWeather(ctx context.Context) (res *Prevision, err error) {
if val, err := loadFromDisk(c.config.CacheLocation); nil == err {
log.Println("found weather in cache")
return &val, nil
}
log.Println("querying weather")
err = requests.URL("https://api.openweathermap.org/data/3.0/onecall"). err = requests.URL("https://api.openweathermap.org/data/3.0/onecall").
Client(c.client). Client(c.client).
Param("lat", "45.78"). Param("lat", "45.78").
@ -118,5 +172,9 @@ func (c *Client) GetWeather(ctx context.Context) (res *Prevision, err error) {
return nil, fmt.Errorf("calling openweathermap: %w", err) return nil, fmt.Errorf("calling openweathermap: %w", err)
} }
if err := res.dumpToDisk(c.config.CacheLocation); err != nil {
log.Printf("error dumping files to disk: %v\n", err)
}
return res, nil return res, nil
} }