Move OpenWeatherMap code to a separate struct
This commit is contained in:
parent
af10ef4dc5
commit
7d071ebe0b
@ -1,70 +1,19 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.kill0.net/chill9/beepboop/bot"
|
"git.kill0.net/chill9/beepboop/bot"
|
||||||
"git.kill0.net/chill9/beepboop/lib"
|
"git.kill0.net/chill9/beepboop/lib/weather"
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
type WeatherHandler struct {
|
||||||
OpenWeatherMapURI = "https://api.openweathermap.org"
|
Config bot.Config
|
||||||
)
|
Name string
|
||||||
|
|
||||||
var (
|
|
||||||
EndpointWeather = lib.BuildURI(OpenWeatherMapURI, "/data/2.5/weather")
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
WeatherHandler struct {
|
|
||||||
Config bot.Config
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
Temperature float32
|
|
||||||
|
|
||||||
Weather struct {
|
|
||||||
Main struct {
|
|
||||||
Temp Temperature `json:"temp"`
|
|
||||||
FeelsLike Temperature `json:"feels_like"`
|
|
||||||
TempMin Temperature `json:"temp_min"`
|
|
||||||
TempMax Temperature `json:"temp_max"`
|
|
||||||
Pressure float32 `json:"pressure"`
|
|
||||||
Humidity float32 `json:"humidity"`
|
|
||||||
} `json:"main"`
|
|
||||||
|
|
||||||
Coord struct {
|
|
||||||
Lon float32 `json:"lon"`
|
|
||||||
Lat float32 `json:"lat"`
|
|
||||||
} `json:"coord"`
|
|
||||||
|
|
||||||
Rain struct {
|
|
||||||
H1 float32 `json:"1h"`
|
|
||||||
H3 float32 `json:"3h"`
|
|
||||||
} `json:"rain"`
|
|
||||||
}
|
|
||||||
|
|
||||||
WeatherError struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (t *Temperature) Kelvin() float32 {
|
|
||||||
return float32(*t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Temperature) Fahrenheit() float32 {
|
|
||||||
return ((float32(*t) - 273.15) * (9.0 / 5)) + 32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Temperature) Celcius() float32 {
|
|
||||||
return float32(*t) - 273.15
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWeatherHandler(s string) *WeatherHandler {
|
func NewWeatherHandler(s string) *WeatherHandler {
|
||||||
@ -79,9 +28,9 @@ func (h *WeatherHandler) SetConfig(config bot.Config) {
|
|||||||
|
|
||||||
func (h *WeatherHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) {
|
func (h *WeatherHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||||
var (
|
var (
|
||||||
loc string
|
err error
|
||||||
w Weather
|
loc string
|
||||||
werr WeatherError
|
w weather.Weather
|
||||||
)
|
)
|
||||||
|
|
||||||
if m.Author.ID == s.State.User.ID {
|
if m.Author.ID == s.State.User.ID {
|
||||||
@ -106,51 +55,17 @@ func (h *WeatherHandler) Handle(s *discordgo.Session, m *discordgo.MessageCreate
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", EndpointWeather, nil)
|
wc := weather.NewClient(h.Config.OpenWeatherMapToken)
|
||||||
|
|
||||||
|
log.Debugf("weather requested for '%s'", loc)
|
||||||
|
|
||||||
|
w, err = wc.Get(loc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to create new request: %s", err)
|
log.Errorf("weather client error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
q := req.URL.Query()
|
log.Debugf("weather returned for '%s': %+v", loc, w)
|
||||||
q.Add("q", loc)
|
|
||||||
q.Add("appid", h.Config.OpenWeatherMapToken)
|
|
||||||
req.URL.RawQuery = q.Encode()
|
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("HTTP request failed: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("reading HTTP response failed: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
|
||||||
err = json.Unmarshal(body, &werr)
|
|
||||||
if err != nil {
|
|
||||||
log.Debugf("%s\n", body)
|
|
||||||
log.Errorf("unmarshaling JSON failed: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Warnf("error: (%s) %s", resp.Status, werr.Message)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("weather requested for '%s'\n", loc)
|
|
||||||
|
|
||||||
err = json.Unmarshal(body, &w)
|
|
||||||
if err != nil {
|
|
||||||
log.Debugf("%s\n", body)
|
|
||||||
log.Errorf("unmarshaling JSON failed: %s", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("weather returned for '%s': %+v\n", loc, w)
|
|
||||||
|
|
||||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf(
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf(
|
||||||
"%s (%.1f, %.1f) — C:%.1f F:%.1f K:%.1f",
|
"%s (%.1f, %.1f) — C:%.1f F:%.1f K:%.1f",
|
||||||
|
42
lib/weather/structs.go
Normal file
42
lib/weather/structs.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package weather
|
||||||
|
|
||||||
|
type (
|
||||||
|
Temperature float32
|
||||||
|
|
||||||
|
Weather struct {
|
||||||
|
Main struct {
|
||||||
|
Temp Temperature `json:"temp"`
|
||||||
|
FeelsLike Temperature `json:"feels_like"`
|
||||||
|
TempMin Temperature `json:"temp_min"`
|
||||||
|
TempMax Temperature `json:"temp_max"`
|
||||||
|
Pressure float32 `json:"pressure"`
|
||||||
|
Humidity float32 `json:"humidity"`
|
||||||
|
} `json:"main"`
|
||||||
|
|
||||||
|
Coord struct {
|
||||||
|
Lon float32 `json:"lon"`
|
||||||
|
Lat float32 `json:"lat"`
|
||||||
|
} `json:"coord"`
|
||||||
|
|
||||||
|
Rain struct {
|
||||||
|
H1 float32 `json:"1h"`
|
||||||
|
H3 float32 `json:"3h"`
|
||||||
|
} `json:"rain"`
|
||||||
|
}
|
||||||
|
|
||||||
|
WeatherError struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t *Temperature) Kelvin() float32 {
|
||||||
|
return float32(*t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) Fahrenheit() float32 {
|
||||||
|
return ((float32(*t) - 273.15) * (9.0 / 5)) + 32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Temperature) Celcius() float32 {
|
||||||
|
return float32(*t) - 273.15
|
||||||
|
}
|
81
lib/weather/weather.go
Normal file
81
lib/weather/weather.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package weather
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"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")
|
||||||
|
)
|
||||||
|
|
||||||
|
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("failed to create new request: %s", 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("HTTP request failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("reading HTTP response failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
err = json.Unmarshal(body, &werr)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("%s", body)
|
||||||
|
err = fmt.Errorf("unmarshaling JSON failed: %s", 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)
|
||||||
|
log.Errorf("unmarshaling JSON failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user