85 lines
1.7 KiB
Go
85 lines
1.7 KiB
Go
package weather
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
|
|
"git.kill0.net/chill9/beepboop/lib"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type (
|
|
WeatherClient struct {
|
|
token string
|
|
}
|
|
)
|
|
|
|
const (
|
|
OpenWeatherMapURI = "https://api.openweathermap.org"
|
|
)
|
|
|
|
var (
|
|
EndpointWeather = lib.BuildURI(OpenWeatherMapURI, "/data/2.5/weather")
|
|
ErrUnmarshal = errors.New("unmarshaling JSON failed")
|
|
ErrReadingResponse = errors.New("reading HTTP response failed")
|
|
ErrRequestFailed = errors.New("HTTP request failed")
|
|
ErrCreateRequestFailed = errors.New("failed to create new HTTP request")
|
|
)
|
|
|
|
func NewClient(token string) *WeatherClient {
|
|
return &WeatherClient{token}
|
|
}
|
|
|
|
func (c *WeatherClient) Get(loc string) (w Weather, err error) {
|
|
var werr WeatherError
|
|
|
|
req, err := http.NewRequest("GET", EndpointWeather, nil)
|
|
if err != nil {
|
|
err = fmt.Errorf("%s: %s", ErrCreateRequestFailed, err)
|
|
return
|
|
}
|
|
|
|
q := req.URL.Query()
|
|
q.Add("q", loc)
|
|
q.Add("appid", c.token)
|
|
req.URL.RawQuery = q.Encode()
|
|
|
|
resp, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
err = fmt.Errorf("%s: %s", ErrRequestFailed, err)
|
|
return
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
err = fmt.Errorf("%s: %s", ErrReadingResponse, err)
|
|
return
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
err = json.Unmarshal(body, &werr)
|
|
if err != nil {
|
|
log.Debugf("%s", body)
|
|
err = fmt.Errorf("%s: %s", ErrUnmarshal, err)
|
|
return
|
|
}
|
|
|
|
err = fmt.Errorf("error: (%s) %s", resp.Status, werr.Message)
|
|
return
|
|
}
|
|
|
|
err = json.Unmarshal(body, &w)
|
|
if err != nil {
|
|
log.Debugf("%s", body)
|
|
err = fmt.Errorf("%s: %s", ErrUnmarshal, err)
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|