Skip to content

Commit

Permalink
feat(owm): response caching added
Browse files Browse the repository at this point in the history
default timeout of 10 minutes. A value of 0 disables the cache.
Original concept by boarder2
  • Loading branch information
lnu authored and JanDeDobbeleer committed Sep 24, 2021
1 parent e846f2b commit 6097d2d
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 17 deletions.
4 changes: 3 additions & 1 deletion docs/docs/segment-owm.md
Expand Up @@ -29,7 +29,8 @@ The free tier for *Current weather and forecasts collection* is sufficient.
"location": "AMSTERDAM,NL",
"units": "metric",
"enable_hyperlink" : false,
"http_timeout": 20
"http_timeout": 20,
"cache_timeout": 10
}
}
```
Expand All @@ -44,3 +45,4 @@ The free tier for *Current weather and forecasts collection* is sufficient.
Available values are standard (kelvin), metric (celsius), and imperial (fahrenheit) - defaults to `standard`
- enable_hyperlink: `bool` - Displays an hyperlink to get openweathermap data
- http_timeout: `int` - The default timeout for http request is 20ms.
- cache_timeout: `int` - The default timeout for request caching is 10m. A value of 0 disables the cache.
46 changes: 41 additions & 5 deletions src/segment_owm.go
Expand Up @@ -21,6 +21,8 @@ const (
LOCATION Property = "location"
// UNITS openweathermap units
UNITS Property = "units"
// CACHETIMEOUT cache timeout
CACHETIMEOUT Property = "cachetimeout"
)

type weather struct {
Expand Down Expand Up @@ -61,22 +63,57 @@ func (d *owm) string() string {
return text
}

func (d *owm) setStatus() error {
func (d *owm) getResult() (*OWMDataResponse, error) {
apikey := d.props.getString(APIKEY, ".")
location := d.props.getString(LOCATION, "De Bilt,NL")
units := d.props.getString(UNITS, "standard")
timeout := d.props.getInt(HTTPTimeout, DefaultHTTPTimeout)
cachetimeout := int64(d.props.getInt(CACHETIMEOUT, 10))

d.url = fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&units=%s&appid=%s", location, units, apikey)

if cachetimeout > 0 {
// check if data stored in cache
val, found := d.env.cache().get("owm_response")
// we got something from te cache
if found {
q := new(OWMDataResponse)
err := json.Unmarshal([]byte(val), q)
if err != nil {
return nil, err
}
return q, nil
}
}

url := fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&units=%s&appid=%s", location, units, apikey)
body, err := d.env.doGet(url, timeout)
body, err := d.env.doGet(d.url, timeout)
if err != nil {
return err
return new(OWMDataResponse), err
}
q := new(OWMDataResponse)
err = json.Unmarshal(body, &q)
if err != nil {
return new(OWMDataResponse), err
}

if cachetimeout > 0 {
// persist new forecasts in cache
d.env.cache().set("owm_response", string(body), cachetimeout)
if err != nil {
return nil, err
}
}
return q, nil
}

func (d *owm) setStatus() error {
units := d.props.getString(UNITS, "standard")

q, err := d.getResult()
if err != nil {
return err
}

d.temperature = q.temperature.Value
icon := ""
switch q.Data[0].TypeID {
Expand Down Expand Up @@ -118,7 +155,6 @@ func (d *owm) setStatus() error {
icon = "\ue313"
}
d.weather = icon
d.url = url
d.units = units
return nil
}
Expand Down
49 changes: 38 additions & 11 deletions src/segment_owm_test.go
Expand Up @@ -8,6 +8,10 @@ import (
"github.com/stretchr/testify/assert"
)

const (
OWMAPIURL = "http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key"
)

func TestOWMSegmentSingle(t *testing.T) {
cases := []struct {
Case string
Expand All @@ -34,15 +38,14 @@ func TestOWMSegmentSingle(t *testing.T) {
env := &MockedEnvironment{}
props := &properties{
values: map[Property]interface{}{
APIKEY: "key",
LOCATION: "AMSTERDAM,NL",
UNITS: "metric",
APIKEY: "key",
LOCATION: "AMSTERDAM,NL",
UNITS: "metric",
CACHETIMEOUT: 0,
},
}

url := "http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key"

env.On("doGet", url).Return([]byte(tc.JSONResponse), tc.Error)
env.On("doGet", OWMAPIURL).Return([]byte(tc.JSONResponse), tc.Error)

o := &owm{
props: props,
Expand Down Expand Up @@ -162,17 +165,17 @@ func TestOWMSegmentIcons(t *testing.T) {
env := &MockedEnvironment{}
props := &properties{
values: map[Property]interface{}{
APIKEY: "key",
LOCATION: "AMSTERDAM,NL",
UNITS: "metric",
APIKEY: "key",
LOCATION: "AMSTERDAM,NL",
UNITS: "metric",
CACHETIMEOUT: 0,
},
}

url := "http://api.openweathermap.org/data/2.5/weather?q=AMSTERDAM,NL&units=metric&appid=key"
response := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20}}`, tc.IconID)
expectedString := fmt.Sprintf("%s (20°C)", tc.ExpectedIconString)

env.On("doGet", url).Return([]byte(response), nil)
env.On("doGet", OWMAPIURL).Return([]byte(response), nil)

o := &owm{
props: props,
Expand All @@ -183,3 +186,27 @@ func TestOWMSegmentIcons(t *testing.T) {
assert.Equal(t, expectedString, o.string(), tc.Case)
}
}
func TestOWMSegmentFromCache(t *testing.T) {
response := fmt.Sprintf(`{"weather":[{"icon":"%s"}],"main":{"temp":20}}`, "01d")
expectedString := fmt.Sprintf("%s (20°C)", "\ufa98")

env := &MockedEnvironment{}
cache := &MockedCache{}
props := &properties{
values: map[Property]interface{}{
APIKEY: "key",
LOCATION: "AMSTERDAM,NL",
UNITS: "metric",
},
}
o := &owm{
props: props,
env: env,
}
cache.On("get", "owm_response").Return(response, true)
cache.On("set").Return()
env.On("cache", nil).Return(cache)

assert.Nil(t, o.setStatus())
assert.Equal(t, expectedString, o.string())
}
6 changes: 6 additions & 0 deletions themes/schema.json
Expand Up @@ -1547,6 +1547,12 @@
},
"http_timeout": {
"$ref": "#/definitions/http_timeout"
},
"cache_timeout": {
"type": "integer",
"title": "cache timeout",
"description": "The number of minutes the response is cached. A value of 0 disables the cache.",
"default": 10
}
}
}
Expand Down

0 comments on commit 6097d2d

Please sign in to comment.