feat(owm): add template support

This commit is contained in:
lnu 2021-11-03 07:33:15 +01:00 committed by Jan De Dobbeleer
parent 545213022f
commit 67ce40e7d7
4 changed files with 68 additions and 23 deletions

View file

@ -30,7 +30,8 @@ The free tier for *Current weather and forecasts collection* is sufficient.
"units": "metric", "units": "metric",
"enable_hyperlink" : false, "enable_hyperlink" : false,
"http_timeout": 20, "http_timeout": 20,
"cache_timeout": 10 "cache_timeout": 10,
"template": "{{.Weather}} ({{.Temperature}}{{.UnitIcon}})"
} }
} }
``` ```
@ -46,3 +47,12 @@ The free tier for *Current weather and forecasts collection* is sufficient.
- enable_hyperlink: `bool` - Displays an hyperlink to get openweathermap data - enable_hyperlink: `bool` - Displays an hyperlink to get openweathermap data
- http_timeout: `int` - The default timeout for http request is 20ms. - 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. - cache_timeout: `int` - The default timeout for request caching is 10m. A value of 0 disables the cache.
- template: `string` - A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the
properties below. Defaults to `{{.Weather}} ({{.Temperature}}{{.UnitIcon}})`
## Template Properties
- `.Weather`: `string` - the current weather icon
- `.Temperature`: `string` - the current temperature
- `.UnitIcon`: `string` - the current unit icon(based on units property)
- `.URL`: `string` - the url of the current api call

View file

@ -8,10 +8,11 @@ import (
type owm struct { type owm struct {
props *properties props *properties
env environmentInfo env environmentInfo
temperature float64 Temperature float64
weather string Weather string
url string URL string
units string units string
UnitIcon string
} }
const ( const (
@ -25,7 +26,7 @@ const (
CacheTimeout Property = "cache_timeout" CacheTimeout Property = "cache_timeout"
// CacheKeyResponse key used when caching the response // CacheKeyResponse key used when caching the response
CacheKeyResponse string = "owm_response" CacheKeyResponse string = "owm_response"
// CacheKeyUrl key used when caching the url responsible for the response // CacheKeyURL key used when caching the url responsible for the response
CacheKeyURL string = "owm_url" CacheKeyURL string = "owm_url"
) )
@ -38,7 +39,7 @@ type temperature struct {
Value float64 `json:"temp"` Value float64 `json:"temp"`
} }
type OWMDataResponse struct { type owmDataResponse struct {
Data []weather `json:"weather"` Data []weather `json:"weather"`
temperature `json:"main"` temperature `json:"main"`
} }
@ -49,27 +50,34 @@ func (d *owm) enabled() bool {
} }
func (d *owm) string() string { func (d *owm) string() string {
unitIcon := "\ue33e" d.UnitIcon = "\ue33e"
switch d.units { switch d.units {
case "imperial": case "imperial":
unitIcon = "°F" // \ue341" d.UnitIcon = "°F" // \ue341"
case "metric": case "metric":
unitIcon = "°C" // \ue339" d.UnitIcon = "°C" // \ue339"
case "": case "":
fallthrough fallthrough
case "standard": case "standard":
unitIcon = "°K" // \ufa05" d.UnitIcon = "°K" // \ufa05"
} }
text := fmt.Sprintf("%s (%g%s)", d.weather, d.temperature, unitIcon) segmentTemplate := d.props.getString(SegmentTemplate, "{{.Weather}} ({{.Temperature}}{{.UnitIcon}})")
if d.props.getBool(EnableHyperlink, false) { template := &textTemplate{
text = fmt.Sprintf("[%s](%s)", text, d.url) Template: segmentTemplate,
Context: d,
Env: d.env,
} }
text, err := template.render()
if err != nil {
return err.Error()
}
return text return text
} }
func (d *owm) getResult() (*OWMDataResponse, error) { func (d *owm) getResult() (*owmDataResponse, error) {
cacheTimeout := int64(d.props.getInt(CacheTimeout, DefaultCacheTimeout)) cacheTimeout := int64(d.props.getInt(CacheTimeout, DefaultCacheTimeout))
response := new(OWMDataResponse) response := new(owmDataResponse)
if cacheTimeout > 0 { if cacheTimeout > 0 {
// check if data stored in cache // check if data stored in cache
val, found := d.env.cache().get(CacheKeyResponse) val, found := d.env.cache().get(CacheKeyResponse)
@ -79,7 +87,7 @@ func (d *owm) getResult() (*OWMDataResponse, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
d.url, _ = d.env.cache().get(CacheKeyURL) d.URL, _ = d.env.cache().get(CacheKeyURL)
return response, nil return response, nil
} }
} }
@ -88,21 +96,21 @@ func (d *owm) getResult() (*OWMDataResponse, error) {
location := d.props.getString(Location, "De Bilt,NL") location := d.props.getString(Location, "De Bilt,NL")
units := d.props.getString(Units, "standard") units := d.props.getString(Units, "standard")
httpTimeout := d.props.getInt(HTTPTimeout, DefaultHTTPTimeout) httpTimeout := d.props.getInt(HTTPTimeout, DefaultHTTPTimeout)
d.url = fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?q=%s&units=%s&appid=%s", location, units, apikey) d.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(d.url, httpTimeout) body, err := d.env.doGet(d.URL, httpTimeout)
if err != nil { if err != nil {
return new(OWMDataResponse), err return new(owmDataResponse), err
} }
err = json.Unmarshal(body, &response) err = json.Unmarshal(body, &response)
if err != nil { if err != nil {
return new(OWMDataResponse), err return new(owmDataResponse), err
} }
if cacheTimeout > 0 { if cacheTimeout > 0 {
// persist new forecasts in cache // persist new forecasts in cache
d.env.cache().set(CacheKeyResponse, string(body), cacheTimeout) d.env.cache().set(CacheKeyResponse, string(body), cacheTimeout)
d.env.cache().set(CacheKeyURL, d.url, cacheTimeout) d.env.cache().set(CacheKeyURL, d.URL, cacheTimeout)
} }
return response, nil return response, nil
} }
@ -115,7 +123,7 @@ func (d *owm) setStatus() error {
return err return err
} }
d.temperature = q.temperature.Value d.Temperature = q.temperature.Value
icon := "" icon := ""
switch q.Data[0].TypeID { switch q.Data[0].TypeID {
case "01n": case "01n":
@ -155,7 +163,7 @@ func (d *owm) setStatus() error {
case "50d": case "50d":
icon = "\ue313" icon = "\ue313"
} }
d.weather = icon d.Weather = icon
d.units = units d.units = units
return nil return nil
} }

View file

@ -18,6 +18,7 @@ func TestOWMSegmentSingle(t *testing.T) {
JSONResponse string JSONResponse string
ExpectedString string ExpectedString string
ExpectedEnabled bool ExpectedEnabled bool
Template string
Error error Error error
}{ }{
{ {
@ -26,6 +27,20 @@ func TestOWMSegmentSingle(t *testing.T) {
ExpectedString: "\ufa98 (20°C)", ExpectedString: "\ufa98 (20°C)",
ExpectedEnabled: true, ExpectedEnabled: true,
}, },
{
Case: "Sunny Display",
JSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
ExpectedString: "\ufa98 (20°C)",
ExpectedEnabled: true,
Template: "{{.Weather}} ({{.Temperature}}{{.UnitIcon}})",
},
{
Case: "Sunny Display",
JSONResponse: `{"weather":[{"icon":"01d"}],"main":{"temp":20}}`,
ExpectedString: "\ufa98 ",
ExpectedEnabled: true,
Template: "{{.Weather}} ",
},
{ {
Case: "Error in retrieving data", Case: "Error in retrieving data",
JSONResponse: "nonsense", JSONResponse: "nonsense",
@ -47,6 +62,10 @@ func TestOWMSegmentSingle(t *testing.T) {
env.On("doGet", OWMAPIURL).Return([]byte(tc.JSONResponse), tc.Error) env.On("doGet", OWMAPIURL).Return([]byte(tc.JSONResponse), tc.Error)
if tc.Template != "" {
props.values[SegmentTemplate] = tc.Template
}
o := &owm{ o := &owm{
props: props, props: props,
env: env, env: env,
@ -204,6 +223,8 @@ func TestOWMSegmentIcons(t *testing.T) {
env.On("doGet", OWMAPIURL).Return([]byte(response), nil) env.On("doGet", OWMAPIURL).Return([]byte(response), nil)
props.values[SegmentTemplate] = "[{{.Weather}} ({{.Temperature}}{{.UnitIcon}})]({{.URL}})"
o := &owm{ o := &owm{
props: props, props: props,
env: env, env: env,
@ -253,6 +274,9 @@ func TestOWMSegmentFromCacheWithHyperlink(t *testing.T) {
EnableHyperlink: true, EnableHyperlink: true,
}, },
} }
props.values[SegmentTemplate] = "[{{.Weather}} ({{.Temperature}}{{.UnitIcon}})]({{.URL}})"
o := &owm{ o := &owm{
props: props, props: props,
env: env, env: env,

View file

@ -1647,6 +1647,9 @@
"title": "cache timeout", "title": "cache timeout",
"description": "The number of minutes the response is cached. A value of 0 disables the cache.", "description": "The number of minutes the response is cached. A value of 0 disables the cache.",
"default": 10 "default": 10
},
"template": {
"$ref": "#/definitions/template"
} }
} }
} }